summaryrefslogtreecommitdiffstats
path: root/src/native
diff options
context:
space:
mode:
Diffstat (limited to 'src/native')
-rw-r--r--src/native/jogl/ContextUpdater.h40
-rw-r--r--src/native/jogl/ContextUpdater.m83
-rw-r--r--src/native/jogl/MacOSXWindowSystemInterface.m306
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