From d20d5546a389e75440fc522bdff6488873b0b22d Mon Sep 17 00:00:00 2001 From: kappaOne Date: Tue, 12 Nov 2013 01:25:06 +0000 Subject: [PATCH] Finalise implementation of HiDPI mode for OS X --- doc/lwjgl_hidden_switches.text | 5 +++- src/java/org/lwjgl/opengl/Display.java | 5 ++-- src/java/org/lwjgl/opengl/MacOSXDisplay.java | 14 +++++++-- src/native/macosx/org_lwjgl_opengl_Display.m | 30 ++++++++++++++++++-- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/doc/lwjgl_hidden_switches.text b/doc/lwjgl_hidden_switches.text index 175a798c..22cbc659 100644 --- a/doc/lwjgl_hidden_switches.text +++ b/doc/lwjgl_hidden_switches.text @@ -22,4 +22,7 @@ org.lwjgl.opengl.Window.undecorated Whether to create an undecorated window (no title bar) org.lwjgl.input.Mouse.allowNegativeMouseCoords -Usually mouse is clamped to 0,0 - setting this to true will cause you to get negative values if dragging outside and below or left of window \ No newline at end of file +Usually mouse is clamped to 0,0 - setting this to true will cause you to get negative values if dragging outside and below or left of window + +org.lwjgl.opengl.Display.enableHighDPI +Enable high DPI mode where available \ No newline at end of file diff --git a/src/java/org/lwjgl/opengl/Display.java b/src/java/org/lwjgl/opengl/Display.java index 42aa4496..066f4f14 100644 --- a/src/java/org/lwjgl/opengl/Display.java +++ b/src/java/org/lwjgl/opengl/Display.java @@ -1358,8 +1358,9 @@ public final class Display { * not be scaled to match the Display window size. * * OpenGL methods that require pixel dependent values e.g. glViewport, glTexImage2D, - * glReadPixels, etc can convert the scaled Display and Mouse coordinates to the - * correct high resolution value by multiplying them by the pixel scale factor. + * glReadPixels, glScissor, glLineWidth, glRenderbufferStorage, etc can convert the + * scaled Display and Mouse coordinates to the correct high resolution value by + * multiplying them by the pixel scale factor. * * e.g. Display.getWidth() * Display.getPixelScaleFactor() will return the high DPI * width of the OpenGL frame buffer. Whereas Display.getWidth() will be the same as diff --git a/src/java/org/lwjgl/opengl/MacOSXDisplay.java b/src/java/org/lwjgl/opengl/MacOSXDisplay.java index 831099b8..6d4a3f2e 100644 --- a/src/java/org/lwjgl/opengl/MacOSXDisplay.java +++ b/src/java/org/lwjgl/opengl/MacOSXDisplay.java @@ -91,6 +91,10 @@ final class MacOSXDisplay implements DisplayImplementation { private boolean updateNativeCursor = false; private long currentNativeCursor = 0; + + private boolean enableHighDPI = false; + + private float scaleFactor = 1.0f; MacOSXDisplay() { @@ -136,7 +140,7 @@ final class MacOSXDisplay implements DisplayImplementation { !Display.getPrivilegedBoolean("org.lwjgl.opengl.Display.disableOSXFullscreenModeAPI"); // OS X high DPI mode is only available on OS X 10.7+ - boolean enableHighDPI = LWJGLUtil.isMacOSXEqualsOrBetterThan(10, 7) && parent == null && + enableHighDPI = LWJGLUtil.isMacOSXEqualsOrBetterThan(10, 7) && parent == null && Display.getPrivilegedBoolean("org.lwjgl.opengl.Display.enableHighDPI"); if (parented) this.canvas = parent; @@ -191,6 +195,12 @@ final class MacOSXDisplay implements DisplayImplementation { } updateNativeCursor = true; } + + public void setScaleFactor(float scale) { + synchronized (this) { + scaleFactor = scale; + } + } public native void nDestroyCALayer(ByteBuffer peer_info_handle); @@ -624,7 +634,7 @@ final class MacOSXDisplay implements DisplayImplementation { } public float getPixelScaleFactor() { - return 1f; + return (enableHighDPI && !Display.isFullscreen()) ? scaleFactor : 1f; } } diff --git a/src/native/macosx/org_lwjgl_opengl_Display.m b/src/native/macosx/org_lwjgl_opengl_Display.m index 21f41d76..35d0afd6 100644 --- a/src/native/macosx/org_lwjgl_opengl_Display.m +++ b/src/native/macosx/org_lwjgl_opengl_Display.m @@ -74,6 +74,9 @@ static NSUInteger lastModifierFlags = 0; window_info->view = [[MacOSXOpenGLView alloc] initWithFrame:view_rect pixelFormat:peer_info->pixel_format]; [window_info->view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + // Inform the view of its parent window info; + [window_info->view setParent:window_info]; + if (window_info->enableHighDPI) { // call method using runtime selector as its a 10.7+ api and allows compiling on older SDK's [window_info->view performSelector:NSSelectorFromString(@"setWantsBestResolutionOpenGLSurface:") withObject:YES]; @@ -134,9 +137,6 @@ static NSUInteger lastModifierFlags = 0; [window_info->view setBoundsSize:newBounds]; } - // Inform the view of its parent window info; - [window_info->view setParent:window_info]; - if (window_info->enableFullscreenModeAPI && window_info->resizable) { // manually create OS X 10.7+ mask to allow compilation on previous OS X versions NSUInteger NSWindowCollectionBehaviorFullScreenPrimary = 1 << 7; @@ -499,6 +499,30 @@ static NSUInteger lastModifierFlags = 0; } } +- (void)viewDidChangeBackingProperties { + JNIEnv *env = attachCurrentThread(); + if (env == nil || _parent == nil || _parent->jdisplay == nil) { + return; + } + + jclass display_class = (*env)->GetObjectClass(env, _parent->jdisplay); + jmethodID setScaleFactor_callback = (*env)->GetMethodID(env, display_class, "setScaleFactor", "(F)V"); + + CGFloat scaleFactor; + + // call method using runtime selector as its a 10.7+ api and allows compiling on older SDK's + SEL selector = NSSelectorFromString(@"backingScaleFactor"); + + // as we are using a runtime selector, we need to use NSInvocations to get a CGFloat value back from it + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[[[self window] class] instanceMethodSignatureForSelector:selector]]; + [invocation setSelector:selector]; + [invocation setTarget:[self window]]; + [invocation invoke]; + [invocation getReturnValue:&scaleFactor]; + + (*env)->CallVoidMethod(env, _parent->jdisplay, setScaleFactor_callback, scaleFactor); +} + -(void)updateTrackingAreas { if(_trackingArea != nil) { [self removeTrackingArea:_trackingArea];