diff options
-rw-r--r-- | make/stub_includes/opengl/macosx-window-system.h | 1 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/GLContextImpl.java | 16 | ||||
-rw-r--r-- | src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java | 48 | ||||
-rw-r--r-- | src/jogl/native/macosx/ContextUpdater.h | 11 | ||||
-rw-r--r-- | src/jogl/native/macosx/ContextUpdater.m | 54 | ||||
-rw-r--r-- | src/jogl/native/macosx/MacOSXWindowSystemInterface.m | 23 |
6 files changed, 112 insertions, 41 deletions
diff --git a/make/stub_includes/opengl/macosx-window-system.h b/make/stub_includes/opengl/macosx-window-system.h index 18cf6c719..8e6d5ba2d 100644 --- a/make/stub_includes/opengl/macosx-window-system.h +++ b/make/stub_includes/opengl/macosx-window-system.h @@ -36,6 +36,7 @@ void updateContext(void* nsContext); void copyContext(void* destContext, void* srcContext, int mask); void* updateContextRegister(void* nsContext, void* nsView); +Bool updateContextNeedsUpdate(void* updater); void updateContextUnregister(void* updater); void* createPBuffer(int renderTarget, int internalFormat, int width, int height); diff --git a/src/jogl/classes/jogamp/opengl/GLContextImpl.java b/src/jogl/classes/jogamp/opengl/GLContextImpl.java index 99693aabe..283b0c751 100644 --- a/src/jogl/classes/jogamp/opengl/GLContextImpl.java +++ b/src/jogl/classes/jogamp/opengl/GLContextImpl.java @@ -196,8 +196,18 @@ public abstract class GLContextImpl extends GLContext { return gl; } - // This is only needed for Mac OS X on-screen contexts - protected void update() throws GLException { } + /** + * Call this method to notify the OpenGL context + * that the drawable has changed (size or position). + * + * <p> + * This is currently being used and overridden by Mac OSX, + * which issues the {@link jogamp.opengl.macosx.cgl.CGL#updateContext(long) NSOpenGLContext update()} call. + * </p> + * + * @throws GLException + */ + protected void drawableUpdatedNotify() throws GLException { } boolean lockFailFast = true; Object lockFailFastSync = new Object(); @@ -362,7 +372,7 @@ public abstract class GLContextImpl extends GLContext { if (current == this) { // Assume we don't need to make this context current again // For Mac OS X, however, we need to update the context to track resizes - update(); + drawableUpdatedNotify(); return CONTEXT_CURRENT; } else { current.release(); diff --git a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java index 55d3a0853..393bd398b 100644 --- a/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java +++ b/src/jogl/classes/jogamp/opengl/macosx/cgl/MacOSXOnscreenCGLContext.java @@ -49,41 +49,67 @@ public class MacOSXOnscreenCGLContext extends MacOSXCGLContext { super(drawable, shareWith); } - @Override + @Override protected void makeCurrentImpl(boolean newCreated) throws GLException { super.makeCurrentImpl(newCreated); - CGL.updateContext(contextHandle); + drawableUpdatedNotify(); } - @Override + @Override protected void releaseImpl() throws GLException { super.releaseImpl(); } - @Override + @Override protected void swapBuffers() { if (!CGL.flushBuffer(contextHandle)) { throw new GLException("Error swapping buffers"); } } - @Override - protected void update() throws GLException { - if (contextHandle == 0) { - throw new GLException("Context not created"); + @Override + protected void drawableUpdatedNotify() throws GLException { + if(0==updateHandle || CGL.updateContextNeedsUpdate(updateHandle)) { + if (contextHandle == 0) { + throw new GLException("Context not created"); + } + CGL.updateContext(contextHandle); } - CGL.updateContext(contextHandle); } - + + protected long updateHandle = 0; + + @Override protected boolean createImpl() { - return create(false, false); + boolean res = create(false, false); + if(res && isNSContext) { + if(0 != updateHandle) { + throw new InternalError("XXX1"); + } + updateHandle = CGL.updateContextRegister(contextHandle, drawable.getHandle()); + if(0 == updateHandle) { + throw new InternalError("XXX2"); + } + } + return res; } + @Override + protected void destroyImpl() throws GLException { + if ( 0 != updateHandle ) { + CGL.updateContextUnregister(updateHandle); + updateHandle = 0; + } + super.destroyImpl(); + } + + @Override public void setOpenGLMode(int mode) { if (mode != MacOSXCGLDrawable.NSOPENGL_MODE) throw new GLException("OpenGL mode switching not supported for on-screen GLContexts"); } + @Override public int getOpenGLMode() { return MacOSXCGLDrawable.NSOPENGL_MODE; } diff --git a/src/jogl/native/macosx/ContextUpdater.h b/src/jogl/native/macosx/ContextUpdater.h index f8ce93def..2483ec403 100644 --- a/src/jogl/native/macosx/ContextUpdater.h +++ b/src/jogl/native/macosx/ContextUpdater.h @@ -22,10 +22,13 @@ This notification is sent whenever an NSView that has an attached NSSurface chan #define UNLOCK_GL(func, line) [ContextUpdater unlock]; #endif -// gznote: OpenGL NOT thread safe - need to sync on update and paints - @interface ContextUpdater : NSObject { +@protected + NSView * view; + NSRect viewRect; + NSOpenGLContext *ctx; + BOOL viewUpdated; } + (void) lock; @@ -33,8 +36,10 @@ This notification is sent whenever an NSView that has an attached NSSurface chan + (void) unlock; + (void) unlockInFunction:(char *)func atLine:(int)line; -- (void) registerFor:(NSOpenGLContext *)context with: (NSView *)window; +- (id) initWithContext:(NSOpenGLContext *)context view: (NSView *)nsView; - (void) update:(NSNotification *)notification; +- (BOOL) needsUpdate; + @end diff --git a/src/jogl/native/macosx/ContextUpdater.m b/src/jogl/native/macosx/ContextUpdater.m index 859697722..64d5ef1f9 100644 --- a/src/jogl/native/macosx/ContextUpdater.m +++ b/src/jogl/native/macosx/ContextUpdater.m @@ -5,18 +5,17 @@ { } -static NSOpenGLContext *theContext; static pthread_mutex_t resourceLock = PTHREAD_MUTEX_INITIALIZER; static void printLockDebugInfo(char *message, char *func, int line) { fprintf(stderr, "%s in function: \"%s\" at line: %d\n", message, func, line); - fflush(stderr); + fflush(NULL); } + (void) lock { - if (theContext != NULL) + if (ctx != NULL) { pthread_mutex_lock(&resourceLock); } @@ -24,7 +23,7 @@ static void printLockDebugInfo(char *message, char *func, int line) + (void) lockInFunction:(char *)func atLine:(int)line { - if (theContext != NULL) + if (ctx != NULL) { printLockDebugInfo("locked ", func, line); [self lock]; @@ -33,7 +32,7 @@ static void printLockDebugInfo(char *message, char *func, int line) + (void) unlock { - if (theContext != NULL) + if (ctx != NULL) { pthread_mutex_unlock(&resourceLock); } @@ -41,43 +40,62 @@ static void printLockDebugInfo(char *message, char *func, int line) + (void) unlockInFunction:(char *)func atLine:(int)line { - if (theContext != NULL) + if (ctx != NULL) { printLockDebugInfo("unlocked", func, line); [self unlock]; } } -- (void) registerFor:(NSOpenGLContext *)context with: (NSView *)view +- (void) update:(NSNotification *)notification { - if (view != NULL) - { - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update:) name:NSViewGlobalFrameDidChangeNotification object: view]; - theContext = context; + [ContextUpdater lock]; + + NSRect r = [view frame]; + if(viewRect.origin.x != r.origin.x || + viewRect.origin.y != r.origin.y || + viewRect.size.width != r.size.width || + viewRect.size.height != r.size.height) { + viewUpdated = TRUE; + viewRect = r; } + + [ContextUpdater unlock]; } -- (void) update:(NSNotification *)notification +- (BOOL) needsUpdate { + BOOL r; [ContextUpdater lock]; - [theContext update]; + r = viewUpdated; + viewUpdated = FALSE; [ContextUpdater unlock]; + + return r; } -- (id) init -{ - theContext = NULL; - +- (id) initWithContext:(NSOpenGLContext *)context view: (NSView *)nsView +{ + ctx = context; + view = nsView; + [ctx retain]; + [view retain]; + viewRect = [view frame]; + viewUpdated = FALSE; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update:) name:NSViewGlobalFrameDidChangeNotification object: view]; + return [super init]; } - (void) dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; + [view release]; + [ctx release]; [super dealloc]; } -@end
\ No newline at end of file +@end diff --git a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m index 86d875502..aab70791c 100644 --- a/src/jogl/native/macosx/MacOSXWindowSystemInterface.m +++ b/src/jogl/native/macosx/MacOSXWindowSystemInterface.m @@ -590,7 +590,8 @@ Bool deleteContext(void* nsJContext) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; [nsContext clearDrawable]; - [nsContext release]; // freezes for a few seconds if ctx is shared + // [nsContext release]; // FIXME: JAU: freezes for a few seconds if ctx is shared + // [nsContext dealloc]; [pool release]; return true; } @@ -624,15 +625,25 @@ void copyContext(void* destContext, void* srcContext, int mask) { [dst copyAttributesFromContext: src withMask: mask]; } -void* updateContextRegister(void* nsJContext, void* view) { +void* updateContextRegister(void* nsJContext, void* nsJView) { NSOpenGLContext *nsContext = (NSOpenGLContext*)nsJContext; - NSView *nsView = (NSView*)view; + NSView *nsView = (NSView*)nsJView; NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - ContextUpdater *contextUpdater = [[ContextUpdater alloc] init]; - [contextUpdater registerFor:nsContext with:nsView]; + ContextUpdater *contextUpdater = [[ContextUpdater alloc] initWithContext: nsContext view: nsView]; [pool release]; - return NULL; + return contextUpdater; +} + +Bool updateContextNeedsUpdate(void* updater) { + ContextUpdater *contextUpdater = (ContextUpdater *)updater; + BOOL res; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + res = [contextUpdater needsUpdate]; + [pool release]; + + return ( res == TRUE ) ? true : false; } void updateContextUnregister(void* updater) { |