Implement AWTGLCanvas, fix initial glViewport size when using

Display.setParent
This commit is contained in:
kappaOne 2013-03-13 00:51:32 +00:00
parent 0cbe94d9e3
commit d462208c4c
6 changed files with 95 additions and 49 deletions

View File

@ -45,6 +45,7 @@ import org.lwjgl.LWJGLUtil;
*/
abstract class MacOSXCanvasPeerInfo extends MacOSXPeerInfo {
private final AWTSurfaceLock awt_surface = new AWTSurfaceLock();
public ByteBuffer window_handle;
protected MacOSXCanvasPeerInfo(PixelFormat pixel_format, ContextAttribs attribs, boolean support_pbuffer) throws LWJGLException {
super(pixel_format, attribs, true, true, support_pbuffer, true);
@ -61,9 +62,9 @@ abstract class MacOSXCanvasPeerInfo extends MacOSXPeerInfo {
forceCALayer = false;
}
nInitHandle(awt_surface.lockAndGetHandle(component), getHandle(), forceCALayer);
window_handle = nInitHandle(awt_surface.lockAndGetHandle(component), getHandle(), window_handle, forceCALayer);
}
private static native void nInitHandle(ByteBuffer surface_buffer, ByteBuffer peer_info_handle, boolean forceCALayer) throws LWJGLException;
private static native ByteBuffer nInitHandle(ByteBuffer surface_buffer, ByteBuffer peer_info_handle, ByteBuffer window_handle, boolean forceCALayer) throws LWJGLException;
protected void doUnlock() throws LWJGLException {
awt_surface.unlock();

View File

@ -134,11 +134,13 @@ final class MacOSXDisplay implements DisplayImplementation {
DrawableGL gl_drawable = (DrawableGL)Display.getDrawable();
PeerInfo peer_info = gl_drawable.peer_info;
ByteBuffer peer_handle = peer_info.lockAndGetHandle();
ByteBuffer window_handle = parented ? ((MacOSXCanvasPeerInfo)peer_info).window_handle : window;
try {
window = nCreateWindow(x, y, mode.getWidth(), mode.getHeight(),
fullscreen, isUndecorated(), resizable,
parented, peer_handle, window);
fullscreen, isUndecorated(), resizable,
parented, peer_handle, window_handle);
if (fullscreen) {
// when going to fullscreen viewport is set to screen size by Cocoa, ignore this value

View File

@ -103,6 +103,7 @@ typedef struct {
@public
JAWT_MacOSXDrawingSurfaceInfo *macosx_dsi;
MacOSXWindowInfo *window_info;
bool setViewport;
@private
CGLContextObj contextObject;
@ -117,6 +118,8 @@ typedef struct {
- (void) removeLayer;
- (void) blitFrameBuffer;
- (int) getWidth;
- (int) getHeight;
@end
typedef struct {

View File

@ -77,14 +77,8 @@ static MacOSXPeerInfo *peer_info;
if (!window_info->fullscreen) {
if (window_info->parented) {
if (peer_info->isCALayer) {
window_info->window = [[MacOSXKeyableWindow alloc] initWithContentRect:[[NSScreen mainScreen] frame] styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
[window_info->window setContentView:window_info->view];
}
else {
window_info->window = [peer_info->parent window];
[peer_info->parent addSubview:window_info->view];
}
window_info->window = [peer_info->parent window];
[peer_info->parent addSubview:window_info->view];
}
else {
@ -131,31 +125,30 @@ static MacOSXPeerInfo *peer_info;
// Inform the view of its parent window info;
[window_info->view setParent:window_info];
if (!window_info->fullscreen && peer_info->isCALayer) {
// hidden window when using CALayer
[window_info->window orderOut:nil];
}
else {
[window_info->window makeFirstResponder:window_info->view];
[window_info->window setInitialFirstResponder:window_info->view];
[window_info->window makeKeyAndOrderFront:[NSApplication sharedApplication]];
}
[window_info->window makeFirstResponder:window_info->view];
[window_info->window setInitialFirstResponder:window_info->view];
[window_info->window makeKeyAndOrderFront:[NSApplication sharedApplication]];
}
+ (void) destroyWindow {
MacOSXWindowInfo *window_info = peer_info->window_info;
if (window_info->fullscreen) {
[window_info->view exitFullScreenModeWithOptions: nil];
window_info->window = nil;
}
else {
if (peer_info->isCALayer) {
[peer_info->glLayer removeLayer];
}
if (window_info->window != nil) {
// if the nsview has no parent then close window
if ([window_info->window contentView] == window_info->view) {
// release the nsview and remove it from any parent nsview
[window_info->view removeFromSuperviewWithoutNeedingDisplay];
[window_info->window close];
window_info->window = nil;
}
else {
// release the nsview and remove it from any parent nsview
@ -575,7 +568,20 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_nSetTitle(JNIEnv *env
}
JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_nCreateWindow(JNIEnv *env, jobject this, jint x, jint y, jint width, jint height, jboolean fullscreen, jboolean undecorated, jboolean resizable, jboolean parented, jobject peer_info_handle, jobject window_handle) {
pool = [[NSAutoreleasePool alloc] init];
peer_info = (MacOSXPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle);
if (peer_info->isCALayer && !fullscreen) {
MacOSXWindowInfo *window_info = (MacOSXWindowInfo *)(*env)->GetDirectBufferAddress(env, window_handle);
window_info->fullscreen = fullscreen;
window_info->undecorated = undecorated;
window_info->parented = parented;
return window_handle;
}
if (window_handle == NULL) {
window_handle = newJavaManagedByteBuffer(env, sizeof(MacOSXWindowInfo));
if (window_handle == NULL) {
@ -584,7 +590,6 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_nCreateWindow(JNIE
}
}
peer_info = (MacOSXPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle);
MacOSXWindowInfo *window_info = (MacOSXWindowInfo *)(*env)->GetDirectBufferAddress(env, window_handle);
window_info->fullscreen = fullscreen;
@ -598,12 +603,10 @@ JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXDisplay_nCreateWindow(JNIE
window_info->display_rect = NSMakeRect(x, y, width, height);
// Cache the necessary info for window-close callbacks into the JVM
if (!peer_info->isCALayer && window_info->jdisplay == NULL) {
if (window_info->jdisplay == NULL) {
window_info->jdisplay = (*env)->NewGlobalRef(env, this);
}
pool = [[NSAutoreleasePool alloc] init];
// create window on main thread
[MacOSXKeyableWindow performSelectorOnMainThread:@selector(createWindow) withObject:nil waitUntilDone:YES];

View File

@ -46,8 +46,8 @@
#include "context.h"
#include "common_tools.h"
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
(JNIEnv *env, jclass clazz, jobject lock_buffer_handle, jobject peer_info_handle, jboolean forceCALayer) {
JNIEXPORT jobject JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
(JNIEnv *env, jclass clazz, jobject lock_buffer_handle, jobject peer_info_handle, jobject window_handle, jboolean forceCALayer) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
MacOSXPeerInfo *peer_info = (MacOSXPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle);
@ -58,20 +58,35 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
if(forceCALayer || (surface->awt.version & 0x80000000)) { //JAWT_MACOSX_USE_CALAYER) {
if (macosx_dsi != NULL) {
if (window_handle == NULL) {
window_handle = newJavaManagedByteBuffer(env, sizeof(MacOSXWindowInfo));
if (window_handle == NULL) {
throwException(env, "Could not create handle buffer");
}
} else if (peer_info->window_info->window != nil) {
return window_handle;
}
if (peer_info->isCALayer) {
[peer_info->glLayer release];
}
peer_info->glLayer = [GLLayer new];
peer_info->glLayer->macosx_dsi = macosx_dsi;
peer_info->window_info = (MacOSXWindowInfo *)(*env)->GetDirectBufferAddress(env, window_handle);
peer_info->glLayer->window_info = peer_info->window_info;
[peer_info->glLayer performSelectorOnMainThread:@selector(createWindow:) withObject:peer_info->pixel_format waitUntilDone:YES];
peer_info->isCALayer = true;
peer_info->isWindowed = true;
peer_info->parent = nil;
[pool release];
return window_handle;
}
peer_info->isCALayer = true;
peer_info->isWindowed = true;
peer_info->parent = nil;
[pool release];
return;
}
// no CALayer support, fallback to using legacy method of getting the NSView of an AWT Canvas
@ -80,6 +95,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
peer_info->isWindowed = true;
[pool release];
return NULL;
}
@implementation GLLayer
@ -104,6 +120,29 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
surfaceLayers.layer = nil;
}
- (int) getWidth {
return self.bounds.size.width;
}
- (int) getHeight {
return self.bounds.size.height;
}
- (void) createWindow:(NSOpenGLPixelFormat*)pixel_format {
if (window_info->window != nil) {
[window_info->window close];
}
window_info->display_rect = [[NSScreen mainScreen] frame];
window_info->view = [[MacOSXOpenGLView alloc] initWithFrame:window_info->display_rect pixelFormat:pixel_format];
window_info->window = [[MacOSXKeyableWindow alloc] initWithContentRect:window_info->display_rect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
[window_info->window setContentView:window_info->view];
[window_info->window orderOut:nil];
}
- (void) blitFrameBuffer {
// get the size of the CALayer/AWT Canvas
@ -198,11 +237,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
glClear(GL_COLOR_BUFFER_BIT);
}
GLint originalReadFBO;
// get and save the current fbo values
//glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING_EXT, &originalReadFBO);
// read the LWJGL FBO and blit it into this CALayers FBO
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, fboID);
glBlitFramebufferEXT(0, 0, width, height,
@ -210,9 +244,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXCanvasPeerInfo_nInitHandle
GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT,
GL_NEAREST);
// restore original fbo read value
//glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, originalReadFBO);
// call super to finalize the drawing - by default all it does is call glFlush()
[super drawInCGLContext:glContext pixelFormat:pixelFormat forLayerTime:timeInterval displayTime:timeStamp];
}

View File

@ -151,8 +151,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nReleas
}
JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_setView
//(JNIEnv *env, jclass clazz, jobject peer_info_handle) {
(JNIEnv *env, jclass clazz, jobject peer_info_handle, jobject context_handle) {
(JNIEnv *env, jclass clazz, jobject peer_info_handle, jobject context_handle) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle);
MacOSXPeerInfo *peer_info = (MacOSXPeerInfo *)(*env)->GetDirectBufferAddress(env, peer_info_handle);
@ -165,7 +164,8 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_setView
}
if (peer_info->isCALayer) {
// if using a CALayer, attach it to AWT Canvas and create a shared opengl context with current context
peer_info->glLayer->setViewport = YES;
// if using a CALayer, attach it to AWT Canvas and create a shared opengl context with current context
[peer_info->glLayer performSelectorOnMainThread:@selector(attachLayer) withObject:nil waitUntilDone:NO];
}
@ -177,6 +177,12 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nMakeCu
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
MacOSXContext *context_info = (MacOSXContext *)(*env)->GetDirectBufferAddress(env, context_handle);
[context_info->context makeCurrentContext];
if (context_info->peer_info->isCALayer && context_info->peer_info->glLayer->setViewport) {
context_info->peer_info->glLayer->setViewport = NO;
glViewport(0, 0, [context_info->peer_info->glLayer getWidth], [context_info->peer_info->glLayer getHeight]);
}
[pool release];
}
@ -208,6 +214,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nDestro
context_info->peer_info->isCALayer = false;
[context_info->peer_info->glLayer performSelectorOnMainThread:@selector(removeLayer) withObject:nil waitUntilDone:YES];
[context_info->peer_info->glLayer release];
context_info->peer_info->glLayer = nil;
}
// clearDrawable on main thread to ensure its not in use
@ -218,7 +225,6 @@ JNIEXPORT void JNICALL Java_org_lwjgl_opengl_MacOSXContextImplementation_nDestro
context_info->context = nil;
context_info->peer_info->window_info->context = nil;
}
else [context_info->context release];
[pool release];
}