summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerard Ziemski <[email protected]>2003-10-12 06:31:59 +0000
committerGerard Ziemski <[email protected]>2003-10-12 06:31:59 +0000
commitfbdf8c337805b02385bf43b65aad93c20a2e3ad2 (patch)
treeae1575e8291ee93c85a1c00e6cbb5e00a0c59255
parent30664570919282ddef3d0496251a3bfb8558b298 (diff)
Implemented PBuffers (available in >= Panther). Reimplemented window resizing using update listener
git-svn-id: file:///usr/local/projects/SUN/JOGL/git-svn/svn-server-sync/jogl/trunk@67 232f8b59-042b-4e1e-8c03-345bb8c30851
-rw-r--r--make/cgl-macosx.cfg20
-rw-r--r--make/stub_includes/macosx/window-system.c19
-rw-r--r--src/native/jogl/ContextUpdater.h40
-rw-r--r--src/native/jogl/ContextUpdater.m83
-rw-r--r--src/native/jogl/MacOSXWindowSystemInterface.m306
-rw-r--r--src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java57
-rw-r--r--src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java31
-rw-r--r--src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java84
-rw-r--r--src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java113
9 files changed, 570 insertions, 183 deletions
diff --git a/make/cgl-macosx.cfg b/make/cgl-macosx.cfg
index f3824f703..649fc7e30 100644
--- a/make/cgl-macosx.cfg
+++ b/make/cgl-macosx.cfg
@@ -12,11 +12,21 @@ Opaque long void *
# FIXME: rather than put in a header file somewhere in the source tree,
# this was the easiest way of sharing the prototypes between these files
CustomCCode typedef int Bool;
-CustomCCode extern void* createContext(void* nsView, void* shareContext);
-CustomCCode extern Bool makeCurrentContext(void* nsView , void* nsContext);
-CustomCCode extern Bool clearCurrentContext (void* nsView , void* nsContext);
-CustomCCode extern Bool deleteContext (void* nsView , void* nsContext);
-CustomCCode extern Bool flushBuffer (void* nsView , void* nsContext);
+
+CustomCCode extern void* createContext(void* shareContext, void* nsView);
+CustomCCode extern Bool makeCurrentContext(void* nsContext, void* nsView);
+CustomCCode extern Bool clearCurrentContext(void* nsContext, void* nsView);
+CustomCCode extern Bool deleteContext(void* nsContext, void* nsView);
+CustomCCode extern Bool flushBuffer(void* nsContext, void* nsView);
+
+CustomCCode extern void* updateContextRegister(void* nsContext, void* nsView);
+CustomCCode extern void updateContextUnregister(void* nsContext, void* nsView, void* updater);
+
+CustomCCode extern void* createPBuffer(void* nsContext, int width, int height);
+CustomCCode extern Bool destroyPBuffer(void* nsContext, void* pBuffer);
+CustomCCode extern int bindPBuffer(void* nsContext, void* pBuffer);
+CustomCCode extern void unbindPBuffer(void* nsContext, void* pBuffer, int pBufferTextureName);
+
CustomCCode extern void* getProcAddress(const char *procName);
# Implement the first argument to getProcAddress as String instead
diff --git a/make/stub_includes/macosx/window-system.c b/make/stub_includes/macosx/window-system.c
index f49fd3d11..15506299b 100644
--- a/make/stub_includes/macosx/window-system.c
+++ b/make/stub_includes/macosx/window-system.c
@@ -3,11 +3,18 @@
typedef int Bool;
-void* createContext(void* nsView, void* shareContext);
-Bool makeCurrentContext(void* nsView, void* nsContext);
-Bool clearCurrentContext(void* nsView, void* nsContext);
-void updateContext(void* nsView, void* nsContext);
-Bool deleteContext(void* nsView, void* nsContext);
-Bool flushBuffer(void* nsView, void* nsContext);
+void* createContext(void* shareContext, void* nsView);
+Bool makeCurrentContext(void* nsContext, void* nsView);
+Bool clearCurrentContext(void* nsContext, void* nsView);
+Bool deleteContext(void* nsContext, void* nsView);
+Bool flushBuffer(void* nsContext, void* nsView);
+
+void* updateContextRegister(void* nsContext, void* nsView);
+void updateContextUnregister(void* nsContext, void* nsView, void* updater);
+
+void* createPBuffer(void* nsContext, int width, int height);
+Bool destroyPBuffer(void* nsContext, void* pBuffer);
+int bindPBuffer(void* nsContext, void* pBuffer);
+void unbindPBuffer(void* nsContext, void* pBuffer, int pBufferTextureName);
void* getProcAddress(const char *procName);
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
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
index 53e5986ec..e6169a4b9 100644
--- a/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXGLContext.java
@@ -49,6 +49,8 @@ public abstract class MacOSXGLContext extends GLContext
{
private static JAWT jawt;
protected long nsContext; // NSOpenGLContext
+ protected long nsView; // NSView
+ protected long updater; // ContextUpdater
// Table that holds the addresses of the native C-language entry points for
// OpenGL functions.
private GLProcAddressTable glProcAddressTable;
@@ -61,6 +63,11 @@ public abstract class MacOSXGLContext extends GLContext
super(component, capabilities, chooser, shareWith);
}
+ protected GL createGL()
+ {
+ return new MacOSXGLImpl(this);
+ }
+
protected String mapToRealGLFunctionName(String glFunctionName)
{
return glFunctionName;
@@ -88,11 +95,51 @@ public abstract class MacOSXGLContext extends GLContext
* Creates and initializes an appropriate OpenGl nsContext. Should only be
* called by {@link makeCurrent(Runnable)}.
*/
- protected abstract void create();
+ protected void create() {
+ MacOSXGLContext other = (MacOSXGLContext) GLContextShareSet.getShareContext(this);
+ long share = 0;
+ if (other != null) {
+ share = other.getNSContext();
+ if (share == 0) {
+ throw new GLException("GLContextShareSet returned an invalid OpenGL context");
+ }
+ }
+ nsContext = CGL.createContext(share, nsView);
+ if (nsContext == 0) {
+ throw new GLException("Error creating nsContext");
+ }
+ updater = CGL.updateContextRegister(nsContext, nsView);
+ GLContextShareSet.contextCreated(this);
+ }
- protected abstract boolean makeCurrent(Runnable initAction) throws GLException;
+ protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
+ boolean created = false;
+ if (nsContext == 0) {
+ create();
+ if (DEBUG) {
+ System.err.println("!!! Created GL nsContext for " + getClass().getName());
+ }
+ created = true;
+ }
+
+ if (!CGL.makeCurrentContext(nsContext, nsView)) {
+ throw new GLException("Error making nsContext current");
+ }
+
+ if (created) {
+ resetGLFunctionAvailability();
+ if (initAction != null) {
+ initAction.run();
+ }
+ }
+ return true;
+ }
- protected abstract void free() throws GLException;
+ protected synchronized void free() throws GLException {
+ if (!CGL.clearCurrentContext(nsContext, nsView)) {
+ throw new GLException("Error freeing OpenGL nsContext");
+ }
+ }
protected abstract void swapBuffers() throws GLException;
@@ -136,6 +183,10 @@ public abstract class MacOSXGLContext extends GLContext
return nsContext;
}
+ protected long getNSView() {
+ return nsView;
+ }
+
protected JAWT getJAWT()
{
if (jawt == null)
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java
index e9f3bed24..431710a7c 100644
--- a/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXOffscreenGLContext.java
@@ -48,12 +48,11 @@ public class MacOSXOffscreenGLContext extends MacOSXGLContext
// Width and height of the underlying bitmap
private int width;
private int height;
-
+
public MacOSXOffscreenGLContext(GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
GLContext shareWith) {
super(null, capabilities, chooser, shareWith);
- System.err.println("MacOSXOffscreenGLContext not implemented yet");
}
protected GL createGL() {
@@ -65,15 +64,10 @@ public class MacOSXOffscreenGLContext extends MacOSXGLContext
}
public int getOffscreenContextBufferedImageType() {
- if (capabilities.getAlphaBits() > 0) {
return BufferedImage.TYPE_INT_ARGB;
- } else {
- return BufferedImage.TYPE_INT_RGB;
- }
}
public int getOffscreenContextReadBuffer() {
- // On Windows these nsContexts are always single-buffered
return GL.GL_FRONT;
}
@@ -100,22 +94,23 @@ public class MacOSXOffscreenGLContext extends MacOSXGLContext
}
protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
- return false;
+ if (pendingOffscreenResize) {
+ if (pendingOffscreenWidth != width || pendingOffscreenHeight != height) {
+ if (nsContext != 0) {
+ destroy();
+ }
+ width = pendingOffscreenWidth;
+ height = pendingOffscreenHeight;
+ pendingOffscreenResize = false;
+ }
+ }
+ return super.makeCurrent(initAction);
}
protected synchronized void swapBuffers() throws GLException {
- throw new GLException("Not yet implemented");
- }
-
- protected synchronized void free() throws GLException {
- throw new GLException("Not yet implemented");
- }
-
- protected void create() {
- throw new GLException("Not yet implemented");
}
private void destroy() {
- throw new GLException("Not yet implemented");
+ free();
}
}
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java
index 8f75fd561..ec46de0d8 100644
--- a/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXOnscreenGLContext.java
@@ -50,33 +50,17 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
private JAWT_DrawingSurface ds;
private JAWT_DrawingSurfaceInfo dsi;
private JAWT_MacOSXDrawingSurfaceInfo macosxdsi;
- private long nsView; // NSView
- private Runnable myDeferredReshapeAction;
+ // Variables for pbuffer support
+ List pbuffersToInstantiate = new ArrayList();
+
public MacOSXOnscreenGLContext(Component component,
GLCapabilities capabilities,
GLCapabilitiesChooser chooser,
GLContext shareWith) {
super(component, capabilities, chooser, shareWith);
}
-
- public synchronized void invokeGL(final Runnable runnable, boolean isReshape, Runnable initAction) throws GLException {
- if (isReshape) {
- myDeferredReshapeAction = new Runnable() {
- public void run() {
- CGL.updateContext(nsView, nsContext);
- runnable.run();
- }
- };
- } else {
- if (myDeferredReshapeAction != null) {
- super.invokeGL(myDeferredReshapeAction, true, initAction);
- myDeferredReshapeAction = null;
- }
- super.invokeGL(runnable, isReshape, initAction);
- }
- }
-
+
protected GL createGL() {
return new MacOSXGLImpl(this);
}
@@ -98,12 +82,13 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
}
public boolean canCreatePbufferContext() {
- // For now say no
- return false;
+ return true;
}
public synchronized GLContext createPbufferContext(GLCapabilities capabilities, int initialWidth, int initialHeight) {
- throw new GLException("Not supported");
+ MacOSXPbufferGLContext ctx = new MacOSXPbufferGLContext(capabilities, initialWidth, initialHeight);
+ pbuffersToInstantiate.add(ctx);
+ return ctx;
}
public void bindPbufferToTexture() {
@@ -122,72 +107,42 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
// yet on this platform. This method can be deleted once
// the update for that release ships.
}
-
- protected void create() {
- MacOSXGLContext other = (MacOSXGLContext) GLContextShareSet.getShareContext(this);
- long share = 0;
- if (other != null) {
- share = other.getNSContext();
- if (share == 0) {
- throw new GLException("GLContextShareSet returned an invalid OpenGL context");
- }
- }
- nsContext = CGL.createContext(nsView, share);
- if (nsContext == 0) {
- throw new GLException("Error creating nsContext");
- }
- GLContextShareSet.contextCreated(this);
- }
protected synchronized boolean makeCurrent(Runnable initAction) throws GLException {
try {
if (!lockSurface()) {
return false;
}
-
- boolean created = false;
- if (nsContext == 0) {
- create();
- if (DEBUG) {
- System.err.println("!!! Created GL nsContext for " + getClass().getName());
- }
- created = true;
- }
-
- if (!CGL.makeCurrentContext(nsView, nsContext)) {
- throw new GLException("Error making nsContext current");
- }
-
- if (created) {
- resetGLFunctionAvailability();
- if (initAction != null) {
- initAction.run();
+ boolean ret = super.makeCurrent(initAction);
+ if (ret) {
+ // Instantiate any pending pbuffers
+ while (!pbuffersToInstantiate.isEmpty()) {
+ MacOSXPbufferGLContext ctx =
+ (MacOSXPbufferGLContext) pbuffersToInstantiate.remove(pbuffersToInstantiate.size() - 1);
+ ctx.createPbuffer(nsView, nsContext);
}
}
- return true;
+ return ret;
} catch (RuntimeException e) {
try {
unlockSurface();
} catch (Exception e2) {
// do nothing if unlockSurface throws
}
-
throw(e);
}
}
protected synchronized void free() throws GLException {
try {
- if (!CGL.clearCurrentContext(nsView, nsContext)) {
- throw new GLException("Error freeing OpenGL nsContext");
- }
+ super.free();
} finally {
unlockSurface();
}
}
protected synchronized void swapBuffers() throws GLException {
- if (!CGL.flushBuffer(nsView, nsContext)) {
+ if (!CGL.flushBuffer(nsContext, nsView)) {
throw new GLException("Error swapping buffers");
}
}
@@ -212,7 +167,8 @@ public class MacOSXOnscreenGLContext extends MacOSXGLContext {
// OpenGL nsContext so it will be recreated
if ((res & JAWTFactory.JAWT_LOCK_SURFACE_CHANGED) != 0) {
if (nsContext != 0) {
- if (!CGL.deleteContext(nsView, nsContext)) {
+ CGL.updateContextUnregister(nsContext, nsView, updater);
+ if (!CGL.deleteContext(nsContext, nsView)) {
throw new GLException("Unable to delete old GL nsContext after surface changed");
}
}
diff --git a/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java b/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java
new file mode 100644
index 000000000..70068ce63
--- /dev/null
+++ b/src/net/java/games/jogl/impl/macosx/MacOSXPbufferGLContext.java
@@ -0,0 +1,113 @@
+package net.java.games.jogl.impl.macosx;
+
+import net.java.games.jogl.*;
+import net.java.games.jogl.impl.*;
+
+public class MacOSXPbufferGLContext extends MacOSXGLContext {
+ private static final boolean DEBUG = false;
+
+ private int initWidth;
+ private int initHeight;
+
+ private long pBuffer;
+ private int pBufferTextureName;
+
+ private int width;
+ private int height;
+
+ // FIXME: kept around because we create the OpenGL context lazily to
+ // better integrate with the MacOSXGLContext framework
+ private long nsContextOfParent;
+
+ public MacOSXPbufferGLContext(GLCapabilities capabilities, int initialWidth, int initialHeight) {
+ super(null, capabilities, null, null);
+ this.initWidth = initialWidth;
+ this.initHeight = initialHeight;
+ if (initWidth <= 0 || initHeight <= 0) {
+ throw new GLException("Initial width and height of pbuffer must be positive (were (" +
+ initWidth + ", " + initHeight + "))");
+ }
+ }
+
+ public boolean canCreatePbufferContext() {
+ return false;
+ }
+
+ public GLContext createPbufferContext(GLCapabilities capabilities,
+ int initialWidth,
+ int initialHeight) {
+ throw new GLException("Not supported");
+ }
+
+ public void bindPbufferToTexture() {
+ pBufferTextureName = CGL.bindPBuffer(nsContextOfParent, pBuffer);
+ }
+
+ public void releasePbufferFromTexture() {
+ CGL.unbindPBuffer(nsContextOfParent, pBuffer, pBufferTextureName);
+ }
+
+ public void createPbuffer(long parentView, long parentContext) {
+ GL gl = getGL();
+ // Must initally grab OpenGL function pointers while parent's
+ // context is current because otherwise we don't have the cgl
+ // extensions available to us
+ resetGLFunctionAvailability();
+
+ this.pBuffer = CGL.createPBuffer(nsContext, initWidth, initHeight);
+ if (this.pBuffer == 0) {
+ throw new GLException("pbuffer creation error: CGL.createPBuffer() failed");
+ }
+
+ nsContextOfParent = parentContext;
+
+ width = getNextPowerOf2(initWidth);
+ height = getNextPowerOf2(initHeight);
+
+ if (DEBUG) {
+ System.err.println("Created pbuffer " + width + " x " + height);
+ }
+ }
+
+ public void handleModeSwitch(long parentView, long parentContext) {
+ throw new GLException("Not yet implemented");
+ }
+
+ protected boolean isOffscreen() {
+ // FIXME: currently the only caller of this won't cause proper
+ // resizing of the pbuffer anyway.
+ return false;
+ }
+
+ public int getOffscreenContextBufferedImageType() {
+ throw new GLException("Should not call this");
+ }
+
+ public int getOffscreenContextReadBuffer() {
+ throw new GLException("Should not call this");
+ }
+
+ public boolean offscreenImageNeedsVerticalFlip() {
+ throw new GLException("Should not call this");
+ }
+
+ protected void swapBuffers() throws GLException {
+ // FIXME: do we need to do anything if the pbuffer is double-buffered?
+ }
+
+ 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);
+ }
+}