diff --git a/platform_build/macosx_ant/build.xml b/platform_build/macosx_ant/build.xml
index e801223e..7d27cebe 100644
--- a/platform_build/macosx_ant/build.xml
+++ b/platform_build/macosx_ant/build.xml
@@ -7,7 +7,7 @@
-
+
@@ -20,22 +20,19 @@
-
+
-
-
-
-
+
-
+
-
+
@@ -43,7 +40,7 @@
-
+
@@ -52,19 +49,19 @@
-
+
-
+
-
+
@@ -75,19 +72,19 @@
-
+
-
+
-
+
diff --git a/src/java/org/lwjgl/opengl/AWTSurfaceLock.java b/src/java/org/lwjgl/opengl/AWTSurfaceLock.java
index d2450ce9..0308c893 100644
--- a/src/java/org/lwjgl/opengl/AWTSurfaceLock.java
+++ b/src/java/org/lwjgl/opengl/AWTSurfaceLock.java
@@ -78,14 +78,15 @@ final class AWTSurfaceLock {
// We need to elevate privileges because of an AWT bug. Please see
// http://192.18.37.44/forums/index.php?topic=10572 for a discussion.
// It is only needed on first call, so we avoid it on all subsequent calls
- // due to performance.
+ // due to performance..
+ final Canvas parent = component instanceof AWTGLCanvas ? component : Display.getParent();
if (firstLockSucceeded)
- return lockAndInitHandle(lock_buffer, component);
+ return lockAndInitHandle(lock_buffer, component, parent);
else
try {
firstLockSucceeded = AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Boolean run() throws LWJGLException {
- return lockAndInitHandle(lock_buffer, component);
+ return lockAndInitHandle(lock_buffer, component, parent);
}
});
return firstLockSucceeded;
@@ -94,7 +95,7 @@ final class AWTSurfaceLock {
}
}
- private static native boolean lockAndInitHandle(ByteBuffer lock_buffer, Canvas component) throws LWJGLException;
+ private static native boolean lockAndInitHandle(ByteBuffer lock_buffer, Canvas component, Canvas display_parent) throws LWJGLException;
void unlock() throws LWJGLException {
nUnlock(lock_buffer);
diff --git a/src/native/common/org_lwjgl_opengl_AWTSurfaceLock.c b/src/native/common/org_lwjgl_opengl_AWTSurfaceLock.c
index 62446f2c..5c4868df 100644
--- a/src/native/common/org_lwjgl_opengl_AWTSurfaceLock.c
+++ b/src/native/common/org_lwjgl_opengl_AWTSurfaceLock.c
@@ -49,15 +49,29 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_AWTSurfaceLock_createHandle
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_opengl_AWTSurfaceLock_lockAndInitHandle
- (JNIEnv *env, jclass clazz, jobject lock_buffer_handle, jobject canvas) {
+ (JNIEnv *env, jclass clazz, jobject lock_buffer_handle, jobject canvas, jobject display_parent) {
JAWT awt;
JAWT_DrawingSurface* ds;
JAWT_DrawingSurfaceInfo *dsi;
AWTSurfaceLock *awt_lock = (AWTSurfaceLock *)(*env)->GetDirectBufferAddress(env, lock_buffer_handle);
- awt.version = JAWT_VERSION_1_4;
- if (JAWT_GetAWT(env, &awt) == JNI_FALSE) {
- throwException(env, "Could not get the JAWT interface");
- return JNI_FALSE;
+
+ jboolean result = JNI_FALSE;
+
+ #ifdef __MACH__
+ if (display_parent) {
+ //first try CALAYER
+ awt.version = JAWT_VERSION_1_4 | JAWT_MACOSX_USE_CALAYER;
+ result = JAWT_GetAWT(env, &awt);
+ }
+ #endif
+
+ if (result == JNI_FALSE) {
+ // now try without CALAYER
+ awt.version = JAWT_VERSION_1_4;
+ if (JAWT_GetAWT(env, &awt) == JNI_FALSE) {
+ throwException(env, "Could not get the JAWT interface");
+ return JNI_FALSE;
+ }
}
ds = awt.GetDrawingSurface(env, canvas);
diff --git a/src/native/macosx/context.h b/src/native/macosx/context.h
index 0942b6ec..4012c4ba 100644
--- a/src/native/macosx/context.h
+++ b/src/native/macosx/context.h
@@ -50,6 +50,7 @@
typedef struct {
NSOpenGLPixelFormat *pixel_format;
bool window;
+ bool canDrawGL;
union {
NSView *nsview;
NSOpenGLPixelBuffer *pbuffer;
diff --git a/src/native/macosx/org_lwjgl_opengl_MacOSXCanvasPeerInfo.m b/src/native/macosx/org_lwjgl_opengl_MacOSXCanvasPeerInfo.m
index 10e67485..3cf57264 100644
--- a/src/native/macosx/org_lwjgl_opengl_MacOSXCanvasPeerInfo.m
+++ b/src/native/macosx/org_lwjgl_opengl_MacOSXCanvasPeerInfo.m
@@ -37,6 +37,9 @@
* @version $Revision$
*/
+#import
+#import
+
#include
#include
#include "awt_tools.h"
@@ -44,13 +47,147 @@
#include "context.h"
#include "common_tools.h"
+// forward declaration
+@interface PBufferGLLayer : NSOpenGLLayer {
+ MacOSXPeerInfo *peer_info;
+ GLuint textureID;
+ BOOL canDraw;
+}
+
+@property (nonatomic) MacOSXPeerInfo *peer_info;
+@property (nonatomic) GLuint textureID;
+@end
+
+
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
- (JNIEnv *env, jclass clazz, jobject lock_buffer_handle, jobject peer_info_handle) {
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+(JNIEnv *env, jclass clazz, jobject lock_buffer_handle, jobject peer_info_handle) {
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+
MacOSXPeerInfo *peer_info = (MacOSXPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle);
AWTSurfaceLock *surface = (AWTSurfaceLock *)(*env)->GetDirectBufferAddress(env, lock_buffer_handle);
JAWT_MacOSXDrawingSurfaceInfo *macosx_dsi = (JAWT_MacOSXDrawingSurfaceInfo *)surface->dsi->platformInfo;
- peer_info->nsview = macosx_dsi->cocoaViewRef;
- peer_info->window = true;
+
+ // check for CALayer support
+ if(surface->awt.version & JAWT_MACOSX_USE_CALAYER) {
+ jint width = surface->dsi->bounds.width;
+ jint height = surface->dsi->bounds.height;
+
+ if(peer_info->pbuffer == NULL ||
+ width != [peer_info->pbuffer pixelsWide] || height != [peer_info->pbuffer pixelsHigh]) {
+ if(peer_info->pbuffer != NULL) {
+ [peer_info->pbuffer release];
+ }
+
+ // make pbuffer
+ NSOpenGLPixelBuffer *pbuffer = nil;
+ NSLog(@"Make pbuffer: %d x %d", width, height);
+ pbuffer = [[NSOpenGLPixelBuffer alloc] initWithTextureTarget:GL_TEXTURE_RECTANGLE_EXT
+ textureInternalFormat:GL_RGBA
+ textureMaxMipMapLevel:0
+ pixelsWide:width
+ pixelsHigh:height];
+
+ peer_info->pbuffer = pbuffer;
+ peer_info->window = false;
+ peer_info->canDrawGL = true;
+ }
+
+ if (macosx_dsi != NULL) {
+ [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+ // attach the "root layer" to the AWT Canvas surface layers
+ id surfaceLayers = (id )macosx_dsi;//dsi->platformInfo;
+ if(surfaceLayers.layer == NULL) {
+ PBufferGLLayer *caGLLayer = [[PBufferGLLayer new] autorelease];
+ caGLLayer.peer_info = peer_info;
+ caGLLayer.asynchronous = YES;
+ caGLLayer.needsDisplayOnBoundsChange = YES;
+ caGLLayer.opaque = YES;
+ surfaceLayers.layer = caGLLayer;
+ }
+ }];
+ }
+ } else {
+ peer_info->nsview = macosx_dsi->cocoaViewRef;
+ peer_info->window = true;
+ }
+
[pool release];
}
+
+// rotates a red square when asked to draw
+@implementation PBufferGLLayer
+
+@synthesize peer_info;
+@synthesize textureID;
+
+// override to draw custom GL content
+-(void)drawInCGLContext:(CGLContextObj)glContext
+ pixelFormat:(CGLPixelFormatObj)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval
+ displayTime:(const CVTimeStamp *)timeStamp {
+
+ if(!peer_info || !peer_info->pbuffer) {
+ return;
+ }
+
+ peer_info->canDrawGL = false;
+
+ NSOpenGLPixelBuffer *pbuffer = self.peer_info->pbuffer;
+
+ // set the current context
+ CGLSetCurrentContext(glContext);
+
+ GLsizei width = [pbuffer pixelsWide];
+ GLsizei height = [pbuffer pixelsHigh];
+
+ if(textureID == 0) {
+ glGenTextures(1, &textureID);
+ }
+ glBindTexture(GL_TEXTURE_RECTANGLE_EXT, self.textureID);
+ CGLTexImagePBuffer(glContext,[pbuffer CGLPBufferObj], GL_FRONT);
+
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+
+ glEnable(GL_TEXTURE_RECTANGLE_EXT);
+
+ static GLfloat verts[] = {
+ -1.0, -1.0,
+ -1.0, 1.0,
+ 1.0, 1.0,
+ 1.0, -1.0
+ };
+
+ GLfloat tex[] = {
+ 0.0, 0.0,
+ 0.0, height,
+ width, height,
+ width, 0.0
+ };
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(2, GL_FLOAT, 0, verts);
+ glTexCoordPointer(2, GL_FLOAT, 0, tex);
+
+ glDrawArrays(GL_QUADS, 0, 4);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glDisable(GL_TEXTURE_RECTANGLE_EXT);
+
+ // call super to finalize the drawing - by default all it does is call glFlush()
+ [super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
+}
+
+-(BOOL)canDrawInCGLContext:(CGLContextObj)glContext
+ pixelFormat:(CGLPixelFormatObj)pixelFormat
+ forLayerTime:(CFTimeInterval)timeInterval
+ displayTime:(const CVTimeStamp *)timeStamp {
+ return peer_info->canDrawGL ? YES : NO;
+}
+
+@end
\ No newline at end of file
diff --git a/src/native/macosx/org_lwjgl_opengl_MacOSXContextImplementation.m b/src/native/macosx/org_lwjgl_opengl_MacOSXContextImplementation.m
index aab4ec41..b8be99a9 100644
--- a/src/native/macosx/org_lwjgl_opengl_MacOSXContextImplementation.m
+++ b/src/native/macosx/org_lwjgl_opengl_MacOSXContextImplementation.m
@@ -45,6 +45,7 @@
typedef struct {
NSOpenGLContext *context;
+ MacOSXPeerInfo *peer_info;
} MacOSXContext;
JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nCreate
@@ -72,6 +73,7 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nCre
}
context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle);
context_info->context = context;
+ context_info->peer_info = peer_info;
[pool release];
return context_handle;
}
@@ -79,8 +81,9 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nCre
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nSwapBuffers
(JNIEnv *env, jclass clazz, jobject context_handle) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- MacOSXContext *peer_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle);
- [peer_info->context flushBuffer];
+ MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle);
+ [context_info->context flushBuffer];
+ context_info->peer_info->canDrawGL = true;
[pool release];
}
@@ -90,6 +93,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nUpdate
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle);
[context_info->context update];
+ context_info->peer_info->canDrawGL = true;
[pool release];
}
@@ -118,6 +122,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_setView
} else {
[context_info->context setPixelBuffer:peer_info->pbuffer cubeMapFace:0 mipMapLevel:0 currentVirtualScreen:0];
}
+ peer_info->canDrawGL = true;
[pool release];
}