Add legacy NSView support

NSView is used in preference to CALayer if available, as we avoid all the
framebuffer blitting overhead.
pull/48/head
Graham 5 years ago
parent ae0baeb271
commit e1d24ec065
  1. 122
      gl-natives/src/main/c/jaggl.c

@ -27,14 +27,18 @@
#include <stdlib.h> #include <stdlib.h>
#if defined(__APPLE__) && defined(__MACH__) #if defined(__APPLE__) && defined(__MACH__)
#define _JAGGL_JAWT_VERSION (JAWT_VERSION_1_4 | JAWT_MACOSX_USE_CALAYER) #define _JAGGL_GET(env) \
JAWT awt = { .version = JAWT_VERSION_1_4 }; \
bool awt_valid = JAWT_GetAWT(env, &awt); \
if (!awt_valid) { \
awt.version |= JAWT_MACOSX_USE_CALAYER; \
awt_valid = JAWT_GetAWT(env, &awt); \
}
#else #else
#define _JAGGL_JAWT_VERSION JAWT_VERSION_1_4
#endif
#define _JAGGL_GET(env) \ #define _JAGGL_GET(env) \
JAWT awt = { .version = (jint) _JAGGL_JAWT_VERSION }; \ JAWT awt = { .version = JAWT_VERSION_1_4 }; \
bool awt_valid = JAWT_GetAWT(env, &awt); bool awt_valid = JAWT_GetAWT(env, &awt);
#endif
#define _JAGGL_GET_AND_LOCK(env) \ #define _JAGGL_GET_AND_LOCK(env) \
_JAGGL_GET(env); \ _JAGGL_GET(env); \
@ -126,6 +130,11 @@ static HWND jaggl_window;
static HDC jaggl_device; static HDC jaggl_device;
static HGLRC jaggl_context; static HGLRC jaggl_context;
#elif defined(__APPLE__) && defined(__MACH__) #elif defined(__APPLE__) && defined(__MACH__)
/* copy of JAWT_MacOSXDrawingSurfaceInfo from Java 6's jawt_md.h */
struct jaggl_legacy_dsi {
NSView *view;
};
@interface JagGLLayer : CAOpenGLLayer @interface JagGLLayer : CAOpenGLLayer
{ {
@private @private
@ -136,6 +145,7 @@ static HGLRC jaggl_context;
} }
@end @end
static bool jaggl_calayer;
static CGLContextObj jaggl_onscreen_context; static CGLContextObj jaggl_onscreen_context;
static CGLContextObj jaggl_context; static CGLContextObj jaggl_context;
static CGLPixelFormatObj jaggl_pix; static CGLPixelFormatObj jaggl_pix;
@ -697,24 +707,26 @@ JNIEXPORT jboolean JNICALL Java_jaggl_context_destroy(JNIEnv *env, jclass cls) {
jaggl_context_appkit = NULL; jaggl_context_appkit = NULL;
} }
if (jaggl_view) { if (jaggl_calayer) {
[jaggl_view release]; if (jaggl_view) {
jaggl_view = NULL; [jaggl_view release];
} jaggl_view = NULL;
}
if (jaggl_window) { if (jaggl_window) {
[jaggl_window release]; [jaggl_window release];
jaggl_window = NULL; jaggl_window = NULL;
} }
if (jaggl_layer) { if (jaggl_layer) {
[jaggl_layer removeFromSuperlayer]; [jaggl_layer removeFromSuperlayer];
[jaggl_layer release]; [jaggl_layer release];
jaggl_layer = NULL; jaggl_layer = NULL;
}
} }
}); });
if (jaggl_onscreen_context) { if (jaggl_calayer && jaggl_onscreen_context) {
CGLDestroyContext(jaggl_onscreen_context); CGLDestroyContext(jaggl_onscreen_context);
jaggl_onscreen_context = NULL; jaggl_onscreen_context = NULL;
} }
@ -750,7 +762,9 @@ JNIEXPORT jboolean JNICALL Java_jaggl_context_swapBuffers(JNIEnv *env, jclass cl
#elif defined(_WIN32) #elif defined(_WIN32)
result = (jboolean) SwapBuffers(jaggl_device); result = (jboolean) SwapBuffers(jaggl_device);
#elif defined(__APPLE__) && defined(__MACH__) #elif defined(__APPLE__) && defined(__MACH__)
[jaggl_layer blit]; if (jaggl_calayer) {
[jaggl_layer blit];
}
/* /*
* This buffer swap isn't strictly necessary (in fact, I'm not sure if we * This buffer swap isn't strictly necessary (in fact, I'm not sure if we
@ -796,7 +810,9 @@ JNIEXPORT void JNICALL Java_jaggl_context_setSwapInterval(JNIEnv *env, jclass cl
#elif defined(__APPLE__) && defined(__MACH__) #elif defined(__APPLE__) && defined(__MACH__)
GLint param = (GLint) interval; GLint param = (GLint) interval;
CGLSetParameter(jaggl_context, kCGLCPSwapInterval, &param); CGLSetParameter(jaggl_context, kCGLCPSwapInterval, &param);
CGLSetParameter(jaggl_onscreen_context, kCGLCPSwapInterval, &param); if (jaggl_calayer) {
CGLSetParameter(jaggl_onscreen_context, kCGLCPSwapInterval, &param);
}
#else #else
#error Unsupported platform #error Unsupported platform
#endif #endif
@ -1066,11 +1082,12 @@ JNIEXPORT jboolean JNICALL Java_jaggl_context_choosePixelFormat1(JNIEnv *env, jc
result = JNI_TRUE; result = JNI_TRUE;
#elif defined(__APPLE__) && defined(__MACH__) #elif defined(__APPLE__) && defined(__MACH__)
id<JAWT_SurfaceLayers> platformInfo = (id<JAWT_SurfaceLayers>) dsi->platformInfo; if (!dsi->platformInfo) {
if (!platformInfo) {
goto dsi_free; goto dsi_free;
} }
jaggl_calayer = awt.version & (jint) JAWT_MACOSX_USE_CALAYER;
for (int i = 0; i < 2; i++) { for (int i = 0; i < 2; i++) {
bool double_buffered = i == 0; bool double_buffered = i == 0;
@ -1109,34 +1126,41 @@ JNIEXPORT jboolean JNICALL Java_jaggl_context_choosePixelFormat1(JNIEnv *env, jc
jaggl_double_buffered = double_buffered; jaggl_double_buffered = double_buffered;
jaggl_alpha_bits = alpha_bits; jaggl_alpha_bits = alpha_bits;
CGLCreateContext(jaggl_pix, NULL, &jaggl_onscreen_context); if (jaggl_calayer) {
if (!jaggl_onscreen_context) { id<JAWT_SurfaceLayers> platformInfo = (id<JAWT_SurfaceLayers>) dsi->platformInfo;
CGLDestroyPixelFormat(jaggl_pix);
goto dsi_free;
}
dispatch_sync(dispatch_get_main_queue(), ^{ CGLCreateContext(jaggl_pix, NULL, &jaggl_onscreen_context);
NSRect frame = NSMakeRect(0, 0, dsi->bounds.width, dsi->bounds.height); if (!jaggl_onscreen_context) {
jaggl_view = [[NSView alloc] initWithFrame:frame]; CGLDestroyPixelFormat(jaggl_pix);
goto dsi_free;
jaggl_window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:NO]; }
jaggl_window.contentView = jaggl_view;
dispatch_sync(dispatch_get_main_queue(), ^{
jaggl_layer = [[JagGLLayer alloc] init]; NSRect frame = NSMakeRect(0, 0, dsi->bounds.width, dsi->bounds.height);
platformInfo.layer = jaggl_layer; jaggl_view = [[NSView alloc] initWithFrame:frame];
/* jaggl_window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:NO];
* XXX(gpe): the DSI bounds include the top/left insets, which we jaggl_window.contentView = jaggl_view;
* need to subtract here. Unfortunately, we can't access them here
* easily. Ignoring the left inset and hard-coding y to zero work, jaggl_layer = [[JagGLLayer alloc] init];
* but only because windows don't have left borders and there is platformInfo.layer = jaggl_layer;
* nothing above the Canvas in the Frame.
*/ /*
jint x = dsi->bounds.x; /* should be dsi->bounds.x - insets.left */ * XXX(gpe): the DSI bounds include the top/left insets, which we
jint y = 0; /* should be dsi->bounds.y - insets.top */ * need to subtract here. Unfortunately, we can't access them here
jaggl_layer.frame = NSMakeRect(x, platformInfo.windowLayer.bounds.size.height - y - dsi->bounds.height, dsi->bounds.width, dsi->bounds.height); * easily. Ignoring the left inset and hard-coding y to zero work,
[jaggl_layer setNeedsDisplay]; * but only because windows don't have left borders and there is
}); * nothing above the Canvas in the Frame.
*/
jint x = dsi->bounds.x; /* should be dsi->bounds.x - insets.left */
jint y = 0; /* should be dsi->bounds.y - insets.top */
jaggl_layer.frame = NSMakeRect(x, platformInfo.windowLayer.bounds.size.height - y - dsi->bounds.height, dsi->bounds.width, dsi->bounds.height);
[jaggl_layer setNeedsDisplay];
});
} else {
struct jaggl_legacy_dsi *platformInfo = (struct jaggl_legacy_dsi *) dsi->platformInfo;
jaggl_view = platformInfo->view;
}
result = JNI_TRUE; result = JNI_TRUE;
goto dsi_free; goto dsi_free;

Loading…
Cancel
Save