diff options
author | Sven Gothel <[email protected]> | 2013-03-15 19:08:22 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2013-03-15 19:08:22 +0100 |
commit | 28c6472335b924080d638b33a28f8f4eedb459b1 (patch) | |
tree | e41dc5fec789634b4e0cb1c286385a7a2a43adab /src/jogl/native/macosx/MacOSXWindowSystemInterface.m | |
parent | 538a41849192cc09da36eeaa5fa9ae10973d85b7 (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.m')
-rw-r--r-- | src/jogl/native/macosx/MacOSXWindowSystemInterface.m | 83 |
1 files changed, 46 insertions, 37 deletions
diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m index f8faeb8d0..38f1789e3 100644 --- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m +++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m @@ -501,6 +501,28 @@ NSView* getNSView(NSOpenGLContext* ctx) { return view; } +static Bool lockViewIfReady(NSView *view) { + Bool viewReady = false; + + if (view != nil) { + if ([view lockFocusIfCanDraw] == NO) { + DBG_PRINT("lockViewIfReady.1 [view lockFocusIfCanDraw] failed\n"); + } else { + NSRect frame = [view frame]; + if ((frame.size.width == 0) || (frame.size.height == 0)) { + [view unlockFocus]; + DBG_PRINT("lockViewIfReady.2 view.frame size %dx%d\n", (int)frame.size.width, (int)frame.size.height); + } else { + DBG_PRINT("lockViewIfReady.X ready and locked\n"); + viewReady = true; + } + } + } else { + DBG_PRINT("lockViewIfReady.3 nil view\n"); + } + return viewReady; +} + NSOpenGLContext* createContext(NSOpenGLContext* share, NSView* view, Bool incompleteView, @@ -515,40 +537,18 @@ NSOpenGLContext* createContext(NSOpenGLContext* share, DBG_PRINT("createContext.0: share %p, view %p, incompleteView %d, pixfmt %p, opaque %d\n", share, view, (int)incompleteView, fmt, opaque); - if (view != nil) { - Bool viewReady = true; - - if(!incompleteView) { - if ([view lockFocusIfCanDraw] == NO) { - DBG_PRINT("createContext.1 [view lockFocusIfCanDraw] failed\n"); - viewReady = false; - } - } - if(viewReady) { - NSRect frame = [view frame]; - if ((frame.size.width == 0) || (frame.size.height == 0)) { - if(!incompleteView) { - [view unlockFocus]; - } - DBG_PRINT("createContext.2 view.frame size %dx%d\n", (int)frame.size.width, (int)frame.size.height); - viewReady = false; - } - } + Bool viewReadyAndLocked = incompleteView ? false : lockViewIfReady(view); - if (!viewReady) - { - if (viewNotReady != NULL) - { - *viewNotReady = 1; - } + if (nil != viewNotReady) { + *viewNotReady = 1; + } - // the view is not ready yet - DBG_PRINT("createContext.X: view not ready yet\n"); - [pool release]; - return NULL; - } + if (nil != view && !incompleteView && !viewReadyAndLocked) { + DBG_PRINT("createContext.X: Assumed complete view not ready yet\n"); + [pool release]; + return NULL; } - + NSOpenGLContext* ctx = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:share]; if ( nil != ctx && nil != view ) { @@ -556,10 +556,8 @@ NSOpenGLContext* createContext(NSOpenGLContext* share, GLint zeroOpacity = 0; [ctx setValues:&zeroOpacity forParameter:NSOpenGLCPSurfaceOpacity]; } - if(!incompleteView) { - DBG_PRINT("createContext.3.0: setView\n"); + if( viewReadyAndLocked ) { [ctx setView:view]; - DBG_PRINT("createContext.3.X: setView\n"); [view unlockFocus]; } } @@ -571,8 +569,19 @@ NSOpenGLContext* createContext(NSOpenGLContext* share, void setContextView(NSOpenGLContext* ctx, NSView* view) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - if ( nil != ctx && nil != view ) { - [ctx setView:view]; + if ( nil != ctx ) { + if ( nil != view ) { + Bool viewReadyAndLocked = lockViewIfReady(view); + DBG_PRINT("setContextView.0: ctx %p, view %p: setView: %d\n", ctx, view, viewReadyAndLocked); + if( viewReadyAndLocked ) { + [ctx setView:view]; + [view unlockFocus]; + } + } else { + DBG_PRINT("setContextView.1: ctx %p, view nil: clearDrawable\n", ctx); + [ctx clearDrawable]; + } + DBG_PRINT("setContextView.X\n"); } [pool release]; } @@ -725,7 +734,7 @@ void setContextTextureImageToPBuffer(NSOpenGLContext* ctx, NSOpenGLPixelBuffer* Bool isNSOpenGLPixelBuffer(uint64_t object) { NSObject *nsObj = (NSObject*) (intptr_t) object; DBG_PRINT("isNSOpenGLPixelBuffer.0: obj %p\n", object); - Bool res = [nsObj isMemberOfClass:[NSOpenGLPixelBuffer class]]; + Bool res = [nsObj isKindOfClass:[NSOpenGLPixelBuffer class]]; DBG_PRINT("isNSOpenGLPixelBuffer.X: res %d\n", (int)res); return res; } |