diff options
Diffstat (limited to 'src/native')
-rw-r--r-- | src/native/jogl/ContextUpdater.h | 40 | ||||
-rw-r--r-- | src/native/jogl/ContextUpdater.m | 83 | ||||
-rw-r--r-- | src/native/jogl/MacOSXWindowSystemInterface.m | 306 |
3 files changed, 342 insertions, 87 deletions
diff --git a/src/native/jogl/ContextUpdater.h b/src/native/jogl/ContextUpdater.h new file mode 100644 index 000000000..e8b757fac --- /dev/null +++ b/src/native/jogl/ContextUpdater.h @@ -0,0 +1,40 @@ +/* + +Listens to NSViewGlobalFrameDidChangeNotification + +This notification is sent whenever an NSView that has an attached NSSurface changes size or changes screens (thus potentially changing graphics hardware drivers.) + +*/ + +#import <Cocoa/Cocoa.h> +#import <Foundation/Foundation.h> +#import <AppKit/NSView.h> +#import <OpenGL/OpenGL.h> +#import <OpenGL/gl.h> + +//#define DEBUG_GL_LOCKS + +#ifdef DEBUG_GL_LOCKS + #define LOCK_GL(func, line) [ContextUpdater lockInFunction:func atLine:line]; + #define UNLOCK_GL(func, line) [ContextUpdater unlockInFunction:func atLine:line]; +#else + #define LOCK_GL(func, line) [ContextUpdater lock]; + #define UNLOCK_GL(func, line) [ContextUpdater unlock]; +#endif + +// gznote: OpenGL NOT thread safe - need to sync on update and paints + +@interface ContextUpdater : NSObject +{ +} + ++ (void) lock; ++ (void) lockInFunction:(char *)func atLine:(int)line; ++ (void) unlock; ++ (void) unlockInFunction:(char *)func atLine:(int)line; + +- (void) registerFor:(NSOpenGLContext *)context with: (NSView *)window; + +- (void) update:(NSNotification *)notification; + +@end diff --git a/src/native/jogl/ContextUpdater.m b/src/native/jogl/ContextUpdater.m new file mode 100644 index 000000000..587782c98 --- /dev/null +++ b/src/native/jogl/ContextUpdater.m @@ -0,0 +1,83 @@ +#import "ContextUpdater.h" +#import <pthread.h> + +@implementation ContextUpdater +{ +} + +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); +} + ++ (void) lock +{ + if (theContext != NULL) + { + pthread_mutex_lock(&resourceLock); + } +} + ++ (void) lockInFunction:(char *)func atLine:(int)line +{ + if (theContext != NULL) + { + printLockDebugInfo("locked ", func, line); + [self lock]; + } +} + ++ (void) unlock +{ + if (theContext != NULL) + { + pthread_mutex_unlock(&resourceLock); + } +} + ++ (void) unlockInFunction:(char *)func atLine:(int)line +{ + if (theContext != NULL) + { + printLockDebugInfo("unlocked", func, line); + [self unlock]; + } +} + +- (void) registerFor:(NSOpenGLContext *)context with: (NSView *)view +{ + if (view != NULL) + { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(update:) name:NSViewGlobalFrameDidChangeNotification object: view]; + theContext = context; + } +} + +- (void) update:(NSNotification *)notification +{ + [ContextUpdater lock]; + + [theContext update]; + + [ContextUpdater unlock]; +} + +- (id) init +{ + theContext = NULL; + + return [super init]; +} + +- (void) dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [super dealloc]; +} + +@end
\ No newline at end of file diff --git a/src/native/jogl/MacOSXWindowSystemInterface.m b/src/native/jogl/MacOSXWindowSystemInterface.m index 0499984c3..ceb07a63d 100644 --- a/src/native/jogl/MacOSXWindowSystemInterface.m +++ b/src/native/jogl/MacOSXWindowSystemInterface.m @@ -1,83 +1,210 @@ #import <Cocoa/Cocoa.h> #import <OpenGL/gl.h> +#import "ContextUpdater.h" + +#ifndef GL_TEXTURE_RECTANGLE_EXT + #define GL_TEXTURE_RECTANGLE_EXT 0x84F5 +#endif typedef int Bool; -void* createContext(void* nsView, void* shareContext) { - NSView *view = nsView; - NSOpenGLContext *share = shareContext; - - // FIXME: hardcoded pixel format. Instead pass these attributes down - // as arguments. There is really no way to enumerate the possible - // pixel formats for a given window on Mac OS X, so we will assume - // that we can match the requested capabilities and leave the - // selection up to the built-in pixel format selection algorithm. - GLuint attribs[] = { - NSOpenGLPFANoRecovery, - NSOpenGLPFAWindow, - NSOpenGLPFAAccelerated, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAColorSize, 32, - NSOpenGLPFAAlphaSize, 8, - NSOpenGLPFADepthSize, 24, - NSOpenGLPFAStencilSize, 8, - NSOpenGLPFAAccumSize, 0, - 0 - }; - - NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes: (NSOpenGLPixelFormatAttribute*) attribs]; - - NSOpenGLContext* context = [[NSOpenGLContext alloc] initWithFormat: [fmt autorelease] shareContext: share]; - - if (view != nil) { - [context setView: view]; - - [context makeCurrentContext]; - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - [context update]; - [context flushBuffer]; - } - - return context; +NSAutoreleasePool* gAutoreleasePool = NULL; + +void* createContext(void* shareContext, void* view) +{ +//fprintf(stderr, "createContext shareContext=%p view=%p\n", shareContext, view); + NSOpenGLContext *nsChareCtx = (NSOpenGLContext*)shareContext; + NSView *nsView = (NSView*)view; + + if (gAutoreleasePool == NULL) + { + gAutoreleasePool = [[NSAutoreleasePool alloc] init]; + } + + // FIXME: hardcoded pixel format. Instead pass these attributes down + // as arguments. There is really no way to enumerate the possible + // pixel formats for a given window on Mac OS X, so we will assume + // that we can match the requested capabilities and leave the + // selection up to the built-in pixel format selection algorithm. + NSOpenGLPixelFormatAttribute attribs[] = + { + NSOpenGLPFANoRecovery, YES, + NSOpenGLPFAAccelerated, YES, + NSOpenGLPFADoubleBuffer, YES, + NSOpenGLPFAColorSize, 32, + NSOpenGLPFAAlphaSize, 8, + NSOpenGLPFADepthSize, 8, + NSOpenGLPFAStencilSize, 8, + NSOpenGLPFAAccumSize, 0, + 0 + }; + + if (nsView == NULL) + { + attribs[12] = 0; // no stencil, no accums fo pBuffers + } + + NSOpenGLPixelFormat* fmt = [[NSOpenGLPixelFormat alloc] initWithAttributes:attribs]; + + NSOpenGLContext* nsContext = [[NSOpenGLContext alloc] initWithFormat:fmt shareContext:nsChareCtx]; + + [fmt release]; + + if (nsView != nil) + { + [nsContext setView: nsView]; + } + + [nsContext retain]; + +//fprintf(stderr, " nsContext=%p\n", nsContext); + return nsContext; } -Bool makeCurrentContext(void* nsView, void* nsContext) { - NSOpenGLContext *context = nsContext; +Bool makeCurrentContext(void* context, void* view) +{ +//fprintf(stderr, "makeCurrentContext context=%p, view=%p\n", context, view); + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + + [nsContext makeCurrentContext]; + return true; +} - [context makeCurrentContext]; - return true; +Bool clearCurrentContext(void* context, void* view) +{ +//fprintf(stderr, "clearCurrentContext context=%p, view=%p\n", context, view); + [NSOpenGLContext clearCurrentContext]; + return true; } -Bool clearCurrentContext(void* nsView, void* nsContext) { - NSView *view = nsView; - NSOpenGLContext *context = nsContext; +Bool deleteContext(void* context, void* view) +{ +//fprintf(stderr, "deleteContext context=%p, view=%p\n", context, view); + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + + [nsContext setView: nil]; + [nsContext release]; + return true; +} - [NSOpenGLContext clearCurrentContext]; - return true; +Bool flushBuffer(void* context, void* view) +{ +//fprintf(stderr, "flushBuffer context=%p, view=%p\n", context, view); + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + + [nsContext flushBuffer]; + return true; } -void updateContext(void* nsView, void* nsContext) { - NSView *view = nsView; - NSOpenGLContext *context = nsContext; +void* updateContextRegister(void* context, void* view) +{ +//fprintf(stderr, "updateContextRegister context=%p, view=%p\n", context, view); + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + NSView *nsView = (NSView*)view; + + ContextUpdater *contextUpdater = [[ContextUpdater alloc] init]; + [contextUpdater registerFor:nsContext with:nsView]; +} - [context update]; +void updateContextUnregister(void* context, void* view, void* updater) +{ +//fprintf(stderr, "updateContextUnregister context=%p, view=%p\n", context, view); + ContextUpdater *contextUpdater = (ContextUpdater *)updater; + + [contextUpdater release]; } -Bool deleteContext(void* nsView, void* nsContext) { - NSOpenGLContext *context = nsContext; +static int getNextPowerOf2(int number) +{ + if (((number-1) & number) == 0) + { + //ex: 8 -> 0b1000; 8-1=7 -> 0b0111; 0b1000&0b0111 == 0 + return number; + } + int power = 0; + while (number > 0) + { + number = number>>1; + power++; + } + return (1<<power); +} - [context setView: nil]; - [context release]; - return true; +void* createPBuffer(void* context, int width, int height) +{ +//fprintf(stderr, "createPBuffer context=%p width=%d height=%d\n", context, width, height); +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER) + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + + //unsigned long taget = GL_TEXTURE_RECTANGLE_EXT; + unsigned long taget = GL_TEXTURE_2D; // texture size must be a multiple of power of 2 + + width = getNextPowerOf2(width); + height = getNextPowerOf2(height); + + NSOpenGLPixelBuffer* pBuffer = [[NSOpenGLPixelBuffer alloc] initWithTextureTarget:taget textureInternalFormat:GL_RGBA textureMaxMipMapLevel:0 pixelsWide:width pixelsHigh:height]; + + [nsContext setPixelBuffer:pBuffer cubeMapFace:0 mipMapLevel:0 currentVirtualScreen:0]; + + return pBuffer; +#else + return NULL; +#endif } -Bool flushBuffer(void* nsView, void* nsContext) { - NSOpenGLContext *context = nsContext; +Bool destroyPBuffer(void* context, void* buffer) +{ +//fprintf(stderr, "destroyPBuffer context=%p, buffer=%p\n", context, buffer); +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER) + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; + + [nsContext setPixelBuffer:NULL cubeMapFace:0 mipMapLevel:0 currentVirtualScreen:0]; + [pBuffer release]; + + return true; +#else + return false; +#endif +} - [context flushBuffer]; - return true; +int bindPBuffer(void* context, void* buffer) +{ +//fprintf(stderr, "bindPBuffer context=%p, buffer=%p\n", context, buffer); +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER) + NSOpenGLContext *nsContext = (NSOpenGLContext*)context; + NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; + + GLuint pBufferTextureName; + glGenTextures(1, &pBufferTextureName); + + glBindTexture([pBuffer textureTarget], pBufferTextureName); + + glTexParameteri([pBuffer textureTarget], GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri([pBuffer textureTarget], GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + [nsContext setTextureImageToPixelBuffer:pBuffer colorBuffer:GL_FRONT_LEFT]; + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glEnable([pBuffer textureTarget]); + + return pBufferTextureName; +#else + return 0; +#endif } +void unbindPBuffer(void* context, void* buffer, int texture) +{ +//fprintf(stderr, "unbindPBuffer context=%p, buffer=%p\n", context, buffer); +#ifdef AVAILABLE_MAC_OS_X_VERSION_10_3_AND_LATER) + NSOpenGLPixelBuffer *pBuffer = (NSOpenGLPixelBuffer*)buffer; + GLuint pBufferTextureName = (GLuint)texture; + + //glDisable([pBuffer textureTarget]); + glDeleteTextures(1, &pBufferTextureName); +#endif +} #include <mach-o/dyld.h> Bool imagesInitialized = false; @@ -85,32 +212,37 @@ static char libGLStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/ static char libGLUStr[] = "/System/Library/Frameworks/OpenGL.framework/Libraries/libGLU.dylib"; static const struct mach_header *libGLImage; static const struct mach_header *libGLUImage; -void* getProcAddress(const char *procname) { - if (imagesInitialized == false) { - imagesInitialized = true; - unsigned long options = NSADDIMAGE_OPTION_RETURN_ON_ERROR; - libGLImage = NSAddImage(libGLStr, options); - libGLUImage = NSAddImage(libGLUStr, options); - } - - unsigned long options = NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR; - char underscoreName[512] = "_"; - strcat(underscoreName, procname); - - if (NSIsSymbolNameDefinedInImage(libGLImage, underscoreName) == YES) { - NSSymbol sym = NSLookupSymbolInImage(libGLImage, underscoreName, options); - return NSAddressOfSymbol(sym); - } - - if (NSIsSymbolNameDefinedInImage(libGLUImage, underscoreName) == YES) { - NSSymbol sym = NSLookupSymbolInImage(libGLUImage, underscoreName, options); - return NSAddressOfSymbol(sym); - } - - if (NSIsSymbolNameDefinedWithHint(underscoreName, "GL")) { - NSSymbol sym = NSLookupAndBindSymbol(underscoreName); - return NSAddressOfSymbol(sym); - } - - return NULL; -} +void* getProcAddress(const char *procname) +{ + if (imagesInitialized == false) + { + imagesInitialized = true; + unsigned long options = NSADDIMAGE_OPTION_RETURN_ON_ERROR; + libGLImage = NSAddImage(libGLStr, options); + libGLUImage = NSAddImage(libGLUStr, options); + } + + unsigned long options = NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR; + char underscoreName[512] = "_"; + strcat(underscoreName, procname); + + if (NSIsSymbolNameDefinedInImage(libGLImage, underscoreName) == YES) + { + NSSymbol sym = NSLookupSymbolInImage(libGLImage, underscoreName, options); + return NSAddressOfSymbol(sym); + } + + if (NSIsSymbolNameDefinedInImage(libGLUImage, underscoreName) == YES) + { + NSSymbol sym = NSLookupSymbolInImage(libGLUImage, underscoreName, options); + return NSAddressOfSymbol(sym); + } + + if (NSIsSymbolNameDefinedWithHint(underscoreName, "GL")) + { + NSSymbol sym = NSLookupAndBindSymbol(underscoreName); + return NSAddressOfSymbol(sym); + } + + return NULL; +}
\ No newline at end of file |