summaryrefslogtreecommitdiffstats
path: root/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
diff options
context:
space:
mode:
authorSven Gothel <[email protected]>2013-03-15 19:08:22 +0100
committerSven Gothel <[email protected]>2013-03-15 19:08:22 +0100
commit28c6472335b924080d638b33a28f8f4eedb459b1 (patch)
treee41dc5fec789634b4e0cb1c286385a7a2a43adab /src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
parent538a41849192cc09da36eeaa5fa9ae10973d85b7 (diff)
Remodel OSX/CALayer Threading (commit 896e8b021b39e9415040a57a1d540d7d24b02db1): Run on main-thread w/o blocking ; Misc Changes
Commit 896e8b021b39e9415040a57a1d540d7d24b02db1 moved all native CALayer calls to the current thread to avoid deadlocks. Even though this seemed to be fine at least resource GC (release/dealloc calls) were issued very late in time, probably due to multithreading synchronization of JAWT and/or OSX API. Example: Our 'TestAddRemove01GLCanvasSwingAWT' test didn't freed CALayer resources incl. GL ctx when destroying the objects (AWT Frame, GLCanvas, ..), leading to resource starvation .. eventually. Remedy is a compromise of behavior before commit 896e8b021b39e9415040a57a1d540d7d24b02db1 and that commit, i.e. to run CALayer lifecycle methods on main-thread, but do not block! The careful part within MacOSXCGLContext.associateDrawable(..) performs the following block on main-thread: - lock the context - create NSOpenGLLayer (incl. it's own shared GL context and the DisplayLink) - attach NSOpenGLLayer to root CALayer - unlock the context Due to the GL ctx locking, this async offthread operation is safe within our course of operations. Details: - NSOpenGLContext - Context and CVDisplayLink creation at init - Call [ctx update] if texture/frame size changed - 'waitUntilRenderSignal' uses default TO value if given TO is 0 to avoid deadlocks +++ Misc Changes: - Fix object type detection: isMemberOfClass -> isKindOfClass - OSXUtil_isNSView0 OSXUtil_isNSWindow0, CGL_isNSOpenGLPixelBuffer - MacOSXCGLDrawable/MacOSXPbufferCGLDrawable: remove getNSViewHandle() method. MacOSXCGLContext uses common code to detect nature of the drawable handle. - MacOSXCGLContext/CALayer: Use safe screenVSyncTimeout values, never 0 to avoid deadlock! - JAWTWindow.invalidate: Call detachSurfaceLayer() if not done yet
Diffstat (limited to 'src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m')
-rw-r--r--src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m85
1 files changed, 41 insertions, 44 deletions
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
index 125ca8af8..96783c75d 100644
--- a/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
+++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface-calayer.m
@@ -117,6 +117,7 @@ extern GLboolean glIsVertexArray (GLuint array);
CGLContextObj cglCtx = [self CGLContextObj];
DBG_PRINT("MyNSOpenGLContext::dealloc.0 %p (refcnt %d) - CGL-Ctx %p\n", self, (int)[self retainCount], cglCtx);
+ // NSLog(@"MyNSOpenGLContext::dealloc: %@",[NSThread callStackSymbols]);
[self clearDrawable];
if( NULL != cglCtx ) {
CGLDestroyContext( cglCtx );
@@ -143,8 +144,8 @@ extern GLboolean glIsVertexArray (GLuint array);
NSOpenGLPixelFormat* parentPixelFmt;
int texWidth;
int texHeight;
- int dedicatedWidth;
- int dedicatedHeight;
+ volatile int dedicatedWidth;
+ volatile int dedicatedHeight;
volatile NSOpenGLPixelBuffer* pbuffer;
volatile GLuint textureID;
volatile NSOpenGLPixelBuffer* newPBuffer;
@@ -184,7 +185,6 @@ extern GLboolean glIsVertexArray (GLuint array);
- (void) setGLEnabled: (Bool) enable;
- (Bool) validateTexSizeWithDedicatedSize;
-- (Bool) validateTexSize: (int) _texWidth texHeight: (int) _texHeight;
- (void) setTextureID: (int) _texID;
- (Bool) isSamePBuffer: (NSOpenGLPixelBuffer*) p;
@@ -316,6 +316,14 @@ static const GLfloat gl_verts[] = {
}
}
if(NULL != displayLink) {
+ CVReturn cvres;
+ DBG_PRINT("MyNSOpenGLLayer::openGLContextForPixelFormat.1: setup DisplayLink %p\n", displayLink);
+ cvres = CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, [glContext CGLContextObj], [parentPixelFmt CGLPixelFormatObj]);
+ if(kCVReturnSuccess != cvres) {
+ DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
+ }
+ }
+ if(NULL != displayLink) {
cvres = CVDisplayLinkSetOutputCallback(displayLink, renderMyNSOpenGLLayer, self);
if(kCVReturnSuccess != cvres) {
DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetOutputCallback failed: %d\n", self, cvres);
@@ -354,14 +362,9 @@ static const GLfloat gl_verts[] = {
- (Bool) validateTexSizeWithDedicatedSize
{
- return [self validateTexSize: dedicatedWidth texHeight: dedicatedHeight];
-}
-
-- (Bool) validateTexSize: (int) _texWidth texHeight: (int) _texHeight
-{
- if(_texHeight != texHeight || _texWidth != texWidth) {
- texWidth = _texWidth;
- texHeight = _texHeight;
+ if( dedicatedHeight != texHeight || dedicatedWidth != texWidth ) {
+ texWidth = dedicatedWidth;
+ texHeight = dedicatedHeight;
GLfloat texCoordWidth, texCoordHeight;
if(NULL != pbuffer) {
@@ -477,10 +480,10 @@ static const GLfloat gl_verts[] = {
- (void)releaseLayer
{
DBG_PRINT("MyNSOpenGLLayer::releaseLayer.0: %p (refcnt %d)\n", self, (int)[self retainCount]);
+ [self setGLEnabled: NO];
[self disableAnimation];
pthread_mutex_lock(&renderLock);
[self deallocPBuffer];
- // [[self openGLContext] release];
if( NULL != glContext ) {
[glContext release];
glContext = NULL;
@@ -570,16 +573,6 @@ static const GLfloat gl_verts[] = {
{
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, [glContext CGLContextObj], [pixelFormat CGLPixelFormatObj]);
- if(kCVReturnSuccess != cvres) {
- DBG_PRINT("MyNSOpenGLLayer::init %p, CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext failed: %d\n", self, cvres);
- }
- }
-#endif
return glContext;
}
@@ -607,6 +600,9 @@ static const GLfloat gl_verts[] = {
GLenum textureTarget;
Bool texSizeChanged = [self validateTexSizeWithDedicatedSize];
+ if( texSizeChanged ) {
+ [context update];
+ }
if( NULL != pbuffer ) {
if( texSizeChanged && 0 != textureID ) {
@@ -812,29 +808,23 @@ static const GLfloat gl_verts[] = {
struct timespec t0, t1, td, td2;
timespec_now(&t0);
#endif
- if(0 < to_micros) {
- struct timespec to_abs = lastWaitTime;
- timespec_addmicros(&to_abs, to_micros);
- #ifdef DBG_SYNC
- timespec_subtract(&td, &to_abs, &t0);
- fprintf(stderr, ", (%ld) / ", timespec_milliseconds(&td));
- #endif
- wr = pthread_cond_timedwait(&renderSignal, &renderLock, &to_abs);
- #ifdef DBG_SYNC
- timespec_now(&t1);
- timespec_subtract(&td, &t1, &t0);
- timespec_subtract(&td2, &t1, &lastWaitTime);
- fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
- #endif
- } else {
- pthread_cond_wait (&renderSignal, &renderLock);
- #ifdef DBG_SYNC
- timespec_now(&t1);
- timespec_subtract(&td, &t1, &t0);
- timespec_subtract(&td2, &t1, &lastWaitTime);
- fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
- #endif
+ if( 0 >= to_micros ) {
+ to_micros = 16666 + 1000; // defaults to 1/60s + 1ms
+ NSLog(@"MyNSOpenGLContext::waitUntilRenderSignal: to_micros was zero, using defaults");
}
+ struct timespec to_abs = lastWaitTime;
+ timespec_addmicros(&to_abs, to_micros);
+ #ifdef DBG_SYNC
+ timespec_subtract(&td, &to_abs, &t0);
+ fprintf(stderr, ", (%ld) / ", timespec_milliseconds(&td));
+ #endif
+ wr = pthread_cond_timedwait(&renderSignal, &renderLock, &to_abs);
+ #ifdef DBG_SYNC
+ timespec_now(&t1);
+ timespec_subtract(&td, &t1, &t0);
+ timespec_subtract(&td2, &t1, &lastWaitTime);
+ fprintf(stderr, "(%ld) / (%ld) ms", timespec_milliseconds(&td), timespec_milliseconds(&td2));
+ #endif
ready = YES;
}
} while (NO == ready && 0 == wr) ;
@@ -923,9 +913,16 @@ void setNSOpenGLLayerNeedsDisplayPBuffer(NSOpenGLLayer* layer, NSOpenGLPixelBuff
void releaseNSOpenGLLayer(NSOpenGLLayer* layer) {
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
MyNSOpenGLLayer* l = (MyNSOpenGLLayer*) layer;
+
+ [CATransaction begin];
+ [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
+
DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.0: %p\n", l);
[l releaseLayer];
DBG_PRINT("MyNSOpenGLLayer::releaseNSOpenGLLayer.X: %p\n", l);
+
+ [CATransaction commit];
+
[pool release];
}