aboutsummaryrefslogtreecommitdiffstats
path: root/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-03-14 10:48:44 +0100
committerSven Gothel <[email protected]>2013-03-14 10:48:44 +0100
commit896e8b021b39e9415040a57a1d540d7d24b02db1 (patch)
treec031248b4a464602aaa150b4d088235b9db065f0 /src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
parent58f6f4e5665ae2c72ec6bbd86ad5a36bef00de07 (diff)
OSX/CALayer: Revise CALayer 'RunOnMainThread' utilization, avoiding deadlocks
RunOnMainThread(waitUntilDone:=true,..) can deadlock the main-thread if called from AWT-EDT, since the main-thread may call back to AWT-EDT while injecting a new main-thread task. This patch revises all RunOnMainThread CALayer usage, resulting in only one required left: - OSXUtil.AddCASublayer() w/ waitUntilDone:=false Hence the CALayer code has no more potential to deadlock main-thread/AWT-EDT. OSXUtil.AddCASublayer() must be performed on main-thread, otherwise the CALayer attachment will fail - no visible rendering result. +++ Note: A good trigger to test this deadlock is to magnify/zoom the OSX desktop (click background + ctrl-mouse_wheel) before running some unit tests. TestGLCanvasAWTActionDeadlock01AWT and TestAddRemove02GLWindowNewtCanvasAWT also have the potential to trigger the mentioned deadlock.
Diffstat (limited to 'src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m')
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m36
1 files changed, 15 insertions, 21 deletions
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
index abc9d7958..f93f15241 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -131,11 +131,10 @@ extern GLboolean glIsVertexArray (GLuint array);
{
@private
GLfloat gl_texCoords[8];
- NSOpenGLContext* myCtx;
+ NSOpenGLContext* glContext;
Bool isGLEnabled;
@protected
- NSOpenGLContext* parentCtx;
GLuint gl3ShaderProgramName;
GLuint vboBufVert;
GLuint vboBufTexCoord;
@@ -247,7 +246,7 @@ static const GLfloat gl_verts[] = {
@implementation MyNSOpenGLLayer
-- (id) setupWithContext: (NSOpenGLContext*) _parentCtx
+- (id) setupWithContext: (NSOpenGLContext*) parentCtx
gl3ShaderProgramName: (GLuint) _gl3ShaderProgramName
pixelFormat: (NSOpenGLPixelFormat*) _parentPixelFmt
pbuffer: (NSOpenGLPixelBuffer*) p
@@ -262,20 +261,19 @@ static const GLfloat gl_verts[] = {
pthread_mutex_init(&renderLock, &renderLockAttr); // recursive
pthread_cond_init(&renderSignal, NULL); // no attribute
- myCtx = NULL;
{
int i;
for(i=0; i<8; i++) {
gl_texCoords[i] = 0.0f;
}
}
- parentCtx = _parentCtx;
+ parentPixelFmt = [_parentPixelFmt retain]; // until destruction
+ glContext = [[MyNSOpenGLContext alloc] initWithFormat:parentPixelFmt shareContext:parentCtx];
gl3ShaderProgramName = _gl3ShaderProgramName;
vboBufVert = 0;
vboBufTexCoord = 0;
vertAttrLoc = 0;
texCoordAttrLoc = 0;
- parentPixelFmt = [_parentPixelFmt retain]; // until destruction
swapInterval = 1; // defaults to on (as w/ new GL profiles)
swapIntervalCounter = 0;
timespec_now(&lastWaitTime);
@@ -338,12 +336,12 @@ static const GLfloat gl_verts[] = {
#ifdef VERBOSE_ON
CGRect lRect = [self bounds];
if(NULL != pbuffer) {
- DBG_PRINT("MyNSOpenGLLayer::init (pbuffer) %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, bounds: %lf/%lf %lfx%lf, displayLink %p (refcnt %d)\n",
- self, parentCtx, parentPixelFmt, pbuffer, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
+ DBG_PRINT("MyNSOpenGLLayer::init (pbuffer) %p, pctx %p, pfmt %p, pbuffer %p, ctx %p, opaque %d, pbuffer %dx%d -> tex %dx%d, bounds: %lf/%lf %lfx%lf, displayLink %p (refcnt %d)\n",
+ self, parentCtx, parentPixelFmt, pbuffer, glContext, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight,
lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, displayLink, (int)[self retainCount]);
} else {
- DBG_PRINT("MyNSOpenGLLayer::init (texture) %p, ctx %p, pfmt %p, opaque %d, tex[id %d, %dx%d], bounds: %lf/%lf %lfx%lf, displayLink %p (refcnt %d)\n",
- self, parentCtx, parentPixelFmt, opaque, (int)textureID, texWidth, texHeight,
+ DBG_PRINT("MyNSOpenGLLayer::init (texture) %p, pctx %p, pfmt %p, ctx %p, opaque %d, tex[id %d, %dx%d], bounds: %lf/%lf %lfx%lf, displayLink %p (refcnt %d)\n",
+ self, parentCtx, parentPixelFmt, glContext, opaque, (int)textureID, texWidth, texHeight,
lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, displayLink, (int)[self retainCount]);
}
#endif
@@ -493,11 +491,10 @@ static const GLfloat gl_verts[] = {
pthread_mutex_lock(&renderLock);
[self deallocPBuffer];
// [[self openGLContext] release];
- if( NULL != myCtx ) {
- [myCtx release];
- myCtx = NULL;
+ if( NULL != glContext ) {
+ [glContext release];
+ glContext = NULL;
}
- parentCtx = NULL;
if( NULL != parentPixelFmt ) {
[parentPixelFmt release];
parentPixelFmt = NULL;
@@ -632,22 +629,19 @@ static const GLfloat gl_verts[] = {
- (NSOpenGLContext *)openGLContextForPixelFormat:(NSOpenGLPixelFormat *)pixelFormat
{
- DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, parent %p, DisplayLink %p\n",
- self, (int)[self retainCount], pixelFormat, parentCtx, displayLink);
- // NSLog(@"MyNSOpenGLLayer::openGLContextForPixelFormat: %@",[NSThread callStackSymbols]);
- myCtx = [[MyNSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:parentCtx];
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.0: %p (refcnt %d) - pfmt %p, ctx %p, DisplayLink %p\n",
+ self, (int)[self retainCount], pixelFormat, glContext, displayLink);
#ifndef HAS_CADisplayLink
if(NULL != displayLink) {
CVReturn cvres;
DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.1: setup DisplayLink %p\n", displayLink);
- cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [myCtx CGLContextObj], [pixelFormat CGLPixelFormatObj]);
+ cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [glContext CGLContextObj], [pixelFormat CGLPixelFormatObj]);
if(kCVReturnSuccess != cvres) {
DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
}
}
#endif
- DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.X: new-ctx %p\n", myCtx);
- return myCtx;
+ return glContext;
}
- (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat