From 0120a81c36ffc7455d196960048fe935f82fc9a6 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Thu, 10 Nov 2011 17:14:51 +0100 Subject: OS X Layered View: Part6 (native) Using a root CALayer where we attach/detach our GL one - it seems to be more stable, having one root CALayer attached to the JAWT_SurfaceView forever - tackles crach at GL layer destruction - proper release of all GL layer resources - now final [gl-layer dealloc] happens at very destruction of JAWT object, even though it was removed from root-layer earlier (and all other references) - see comment in MacOSXWindowSystemInterface-pbuffer.m :: createNSOpenGLLayer(..) - at least no more crash .. and resource release ASAP, but the GL-layer itself (see above) --- .../jogamp/opengl/macosx/cgl/MacOSXCGLContext.java | 6 +- .../macosx/MacOSXWindowSystemInterface-pbuffer.m | 92 ++++++++++++++++------ 2 files changed, 73 insertions(+), 25 deletions(-) (limited to 'src/jogl') diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java index 8e845e847..b75d2f927 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXCGLContext.java @@ -477,11 +477,11 @@ public abstract class MacOSXCGLContext extends GLContextImpl } else { texWidth = drawable.getWidth(); texHeight = drawable.getHeight(); - } + } nsOpenGLLayer = CGL.createNSOpenGLLayer(ctx, nsOpenGLLayerPFmt, drawable.getHandle(), fixedCaps.isBackgroundOpaque(), texWidth, texHeight); if (DEBUG) { System.err.println("NS create nsOpenGLLayer "+toHexString(nsOpenGLLayer)); - } + } lsh.attachSurfaceLayer(nsOpenGLLayer); } } finally { @@ -499,8 +499,8 @@ public abstract class MacOSXCGLContext extends GLContextImpl if (DEBUG) { System.err.println("NS destroy nsOpenGLLayer "+toHexString(nsOpenGLLayer)); } - lsh.attachSurfaceLayer(0); CGL.releaseNSOpenGLLayer(nsOpenGLLayer); + lsh.detachSurfaceLayer(nsOpenGLLayer); CGL.deletePixelFormat(nsOpenGLLayerPFmt); nsOpenGLLayerPFmt = 0; nsOpenGLLayer = 0; diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m index ef6d11419..f261e95b2 100644 --- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m +++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-pbuffer.m @@ -46,13 +46,15 @@ BOOL shallDraw; } -- (id) initWithContext: (NSOpenGLContext*) ctx +- (id) setupWithContext: (NSOpenGLContext*) ctx pixelFormat: (NSOpenGLPixelFormat*) pfmt pbuffer: (NSOpenGLPixelBuffer*) p opaque: (Bool) opaque texWidth: (int) texWidth texHeight: (int) texHeight; +- (void)deallocTex; +- (void)disableAnimation; - (int)getSwapInterval; - (void)setSwapInterval:(int)interval; - (void)tick; @@ -85,15 +87,13 @@ static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink, @implementation MyNSOpenGLLayer -- (id) initWithContext: (NSOpenGLContext*) _ctx +- (id) setupWithContext: (NSOpenGLContext*) _ctx pixelFormat: (NSOpenGLPixelFormat*) _fmt pbuffer: (NSOpenGLPixelBuffer*) p opaque: (Bool) opaque texWidth: (int) _texWidth texHeight: (int) _texHeight; { - self = [super init]; - pthread_mutex_init(&renderLock, NULL); // fast non-recursive pthread_cond_init(&renderSignal, NULL); // no attribute @@ -152,29 +152,61 @@ static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink, CGRect lRect = [self frame]; - DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, frame: %lf/%lf %lfx%lf\n", + DBG_PRINT("MyNSOpenGLLayer::init %p, ctx %p, pfmt %p, pbuffer %p, opaque %d, pbuffer %dx%d -> tex %dx%d, frame: %lf/%lf %lfx%lf (refcnt %d)\n", self, _ctx, _fmt, pbuffer, opaque, [pbuffer pixelsWide], [pbuffer pixelsHigh], texWidth, texHeight, - lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height); + lRect.origin.x, lRect.origin.y, lRect.size.width, lRect.size.height, (int)[self retainCount]); return self; } -- (void)dealloc +- (void)disableAnimation { + DBG_PRINT("MyNSOpenGLLayer::disableAnimation: %p (refcnt %d) - displayLink %p\n", self, (int)[self retainCount], displayLink); + pthread_mutex_lock(&renderLock); [self setAsynchronous: NO]; + if(NULL != displayLink) { #ifdef HAS_CADisplayLink - [displayLink setPaused: YES]; - [displayLink release]; + [displayLink setPaused: YES]; + [displayLink release]; #else - if(NULL!=displayLink) { - CVDisplayLinkStop(displayLink); - CVDisplayLinkRelease(displayLink); - } + if(NULL!=displayLink) { + CVDisplayLinkStop(displayLink); + CVDisplayLinkRelease(displayLink); + } #endif - [pbuffer release]; + displayLink = NULL; + } + pthread_mutex_unlock(&renderLock); +} + +- (void)deallocTex +{ + pthread_mutex_lock(&renderLock); + NSOpenGLContext* context = [self openGLContext]; + DBG_PRINT("MyNSOpenGLLayer::deallocTex %p (refcnt %d) - context %p, pbuffer %p\n", self, (int)[self retainCount], context, pbuffer); + if(NULL != pbuffer) { + if(NULL!=context) { + [context makeCurrentContext]; + if(0 != textureID) { + glDeleteTextures(1, &textureID); + textureID = 0; + } + [context clearDrawable]; + } + [pbuffer release]; + pbuffer = NULL; + } + pthread_mutex_unlock(&renderLock); +} + +- (void)dealloc +{ + DBG_PRINT("MyNSOpenGLLayer::dealloc.0 %p (refcnt %d)\n", self, (int)[self retainCount]); + [self disableAnimation]; + [self deallocTex]; pthread_cond_destroy(&renderSignal); pthread_mutex_destroy(&renderLock); - DBG_PRINT("MyNSOpenGLLayer::dealloc %p\n", self); [super dealloc]; + DBG_PRINT("MyNSOpenGLLayer::dealloc.X %p\n", self); } - (BOOL)canDrawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat @@ -183,13 +215,14 @@ static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink, // assume both methods 'canDrawInOpenGLContext' and 'drawInOpenGLContext' // are called from the same thread subsequently pthread_mutex_lock(&renderLock); - if(NO == shallDraw) { + Bool res = NULL != pbuffer && YES == shallDraw; + if(!res) { SYNC_PRINT("<0>"); pthread_mutex_unlock(&renderLock); } else { SYNC_PRINT("<"); } - return shallDraw; + return res; } - (void)drawInOpenGLContext:(NSOpenGLContext *)context pixelFormat:(NSOpenGLPixelFormat *)pixelFormat @@ -279,6 +312,7 @@ static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink, glDisableClientState(GL_TEXTURE_COORD_ARRAY); glDisable(textureTarget); + glBindTexture(textureTarget, 0); [super drawInOpenGLContext: context pixelFormat: pixelFormat forLayerTime: timeInterval displayTime: timeStamp]; shallDraw = NO; @@ -342,7 +376,11 @@ static CVReturn renderMyNSOpenGLLayer(CVDisplayLinkRef displayLink, @end NSOpenGLLayer* createNSOpenGLLayer(NSOpenGLContext* ctx, NSOpenGLPixelFormat* fmt, NSOpenGLPixelBuffer* p, Bool opaque, int texWidth, int texHeight) { - return [[MyNSOpenGLLayer alloc] initWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight]; + // This simply crashes after dealloc() has been called .. ie. ref-count -> 0 too early ? + // However using alloc/init, actual dealloc happens at JAWT destruction, hence too later IMHO. + // return [[MyNSOpenGLLayer layer] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight]; + + return [[[MyNSOpenGLLayer alloc] init] setupWithContext:ctx pixelFormat: fmt pbuffer: p opaque: opaque texWidth: texWidth texHeight: texHeight]; } void setNSOpenGLLayerSwapInterval(NSOpenGLLayer* layer, int interval) { @@ -403,9 +441,19 @@ void setNSOpenGLLayerNeedsDisplay(NSOpenGLLayer* layer) { } } -void releaseNSOpenGLLayer(NSOpenGLLayer* l) { - NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - [l release]; - [pool release]; +void releaseNSOpenGLLayer(NSOpenGLLayer* layer) { + MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p (refcnt %d)\n", l, (int)[l retainCount]); + + [l performSelectorOnMainThread:@selector(disableAnimation) withObject:nil waitUntilDone:YES]; + // [l disableAnimation]; + + [l performSelectorOnMainThread:@selector(deallocTex) withObject:nil waitUntilDone:YES]; + // [l deallocTex]; + + [l release]; + DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p (refcnt %d)\n", l, (int)[l retainCount]); + [pool release]; } -- cgit v1.2.3