From 2571ed0b5ef14155d204540d38b564a7d4cd47b6 Mon Sep 17 00:00:00 2001 From: Sven Gothel Date: Sun, 8 Jun 2014 08:11:57 +0200 Subject: Bug 741 HiDPI: Add ScalableSurface interface to get/set pixelScale w/ full OSX impl. Add ScalableSurface interface - To set pixelScale before and after realization - To get pixelScale - Implemented on: - NEWT Window - Generic impl. in WindowImpl - OSX WindowDriver impl. - Also propagetes pixelScale to parent JAWTWindow if offscreen (NewtCanvasAWT) - AWT WindowDriver impl. - JAWTWindow / OSXCalayer - AWT GLCanvas - AWT GLJPanel - NEWTCanvasAWT: - Propagates NEWT Window's pixelScale to underlying JAWTWindow - WrappedSurface for pixelScale propagation using offscreen drawables, i.e. GLJPanel - Generic helper in SurfaceScaleUtils (nativewindow package) - Fully implemented on OSX - Capable to switch pixelScale before realization, i.e. native-creation, as well as on-the-fly. - Impl. uses int[2] for pixelScale to support non-uniform scale. Test cases: - com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT - com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT - com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT - com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NewtCanvasAWT - Press 'x' to toggle HiDPI - Commandline '-pixelScale ' - Added basic auto unit test (setting pre-realization) --- src/newt/classes/com/jogamp/newt/Window.java | 3 +- .../classes/com/jogamp/newt/awt/NewtCanvasAWT.java | 1 + .../classes/com/jogamp/newt/opengl/GLWindow.java | 10 ++ src/newt/classes/jogamp/newt/WindowImpl.java | 25 ++++- .../classes/jogamp/newt/driver/awt/AWTCanvas.java | 15 ++- .../jogamp/newt/driver/awt/WindowDriver.java | 21 +++-- .../jogamp/newt/driver/macosx/WindowDriver.java | 102 ++++++++++++++------- src/newt/native/MacWindow.m | 72 ++++++++++++--- src/newt/native/NewtMacWindow.m | 10 +- 9 files changed, 190 insertions(+), 69 deletions(-) (limited to 'src/newt') diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 82199e9b5..88134f3ef 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -45,6 +45,7 @@ import jogamp.newt.WindowImpl; import javax.media.nativewindow.CapabilitiesChooser; import javax.media.nativewindow.CapabilitiesImmutable; import javax.media.nativewindow.NativeWindow; +import javax.media.nativewindow.ScalableSurface; import javax.media.nativewindow.WindowClosingProtocol; import javax.media.nativewindow.util.Rectangle; import javax.media.nativewindow.util.RectangleImmutable; @@ -94,7 +95,7 @@ import javax.media.nativewindow.util.RectangleImmutable; * *

*/ -public interface Window extends NativeWindow, WindowClosingProtocol { +public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSurface { public static final boolean DEBUG_MOUSE_EVENT = Debug.debug("Window.MouseEvent"); public static final boolean DEBUG_KEY_EVENT = Debug.debug("Window.KeyEvent"); public static final boolean DEBUG_IMPLEMENTATION = Debug.debug("Window"); diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index 37e9f9813..baaa69e8e 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -865,6 +865,7 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } newtChild.setVisible(false); newtChild.setSize(w, h); + jawtWindow.setSurfaceScale(newtChild.getSurfaceScale(new int[2])); newtChild.reparentWindow(jawtWindow, -1, -1, Window.REPARENT_HINT_BECOMES_VISIBLE); newtChild.addSurfaceUpdatedListener(jawtWindow); if( jawtWindow.isOffscreenLayerSurfaceEnabled() && diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index a61085fb0..6610bd74f 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -403,6 +403,16 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind return window.convertToPixelUnits(windowUnitsAndResult); } + @Override + public final void setSurfaceScale(final int[] pixelScale) { + window.setSurfaceScale(pixelScale); + } + + @Override + public final int[] getSurfaceScale(final int[] result) { + return window.getSurfaceScale(result); + } + @Override public final void setPosition(int x, int y) { window.setPosition(x, y); diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 5288bfcc5..f02b9740d 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -48,6 +48,7 @@ import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.OffscreenLayerSurface; +import javax.media.nativewindow.ScalableSurface; import javax.media.nativewindow.SurfaceUpdatedListener; import javax.media.nativewindow.WindowClosingProtocol; import javax.media.nativewindow.util.DimensionImmutable; @@ -59,6 +60,7 @@ import javax.media.nativewindow.util.PointImmutable; import javax.media.nativewindow.util.Rectangle; import javax.media.nativewindow.util.RectangleImmutable; +import jogamp.nativewindow.SurfaceScaleUtils; import jogamp.nativewindow.SurfaceUpdatedHelper; import com.jogamp.common.util.ArrayHashSet; @@ -150,6 +152,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer private volatile boolean hasFocus = false; private volatile int pixWidth = 128, pixHeight = 128; // client-area size w/o insets in pixel units, default: may be overwritten by user private volatile int winWidth = 128, winHeight = 128; // client-area size w/o insets in window units, default: may be overwritten by user + protected int[] hasPixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + protected int[] reqPixelScale = new int[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; + private volatile int x = 64, y = 64; // client-area pos w/o insets in window units private volatile Insets insets = new Insets(); // insets of decoration (if top-level && decorated) private boolean blockInsetsChange = false; // block insets change (from same thread) @@ -1953,9 +1958,25 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } /** HiDPI: We currently base scaling of window units to pixel units on an integer scale factor per component. */ - protected int getPixelScaleX() { return 1; } + protected final int getPixelScaleX() { + return hasPixelScale[0]; + } + /** HiDPI: We currently base scaling of window units to pixel units on an integer scale factor per component. */ - protected int getPixelScaleY() { return 1; } + protected final int getPixelScaleY() { + return hasPixelScale[1]; + } + + @Override + public void setSurfaceScale(final int[] pixelScale) { + SurfaceScaleUtils.validateReqPixelScale(reqPixelScale, pixelScale, DEBUG_IMPLEMENTATION ? getClass().getSimpleName() : null); + } + + @Override + public final int[] getSurfaceScale(final int[] result) { + System.arraycopy(isNativeValid() ? hasPixelScale : reqPixelScale, 0, result, 0, 2); + return result; + } protected final boolean autoPosition() { return autoPosition; } diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java index 5dab64e39..d01a2f21f 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java +++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java @@ -66,10 +66,16 @@ public class AWTCanvas extends Canvas { private volatile JAWTWindow jawtWindow=null; // the JAWTWindow presentation of this AWT Canvas, bound to the 'drawable' lifecycle private CapabilitiesChooser chooser=null; private final CapabilitiesImmutable capabilities; + private final UpstreamScalable upstreamScale; + + public static interface UpstreamScalable { + int[] getReqPixelScale(); + void setHasPixelScale(final int[] pixelScale); + } private boolean displayConfigChanged=false; - public AWTCanvas(CapabilitiesImmutable capabilities, CapabilitiesChooser chooser) { + public AWTCanvas(CapabilitiesImmutable capabilities, CapabilitiesChooser chooser, UpstreamScalable upstreamScale) { super(); if(null==capabilities) { @@ -77,6 +83,7 @@ public class AWTCanvas extends Canvas { } this.capabilities=capabilities; this.chooser=chooser; + this.upstreamScale = upstreamScale; } public AWTGraphicsConfiguration getAWTGraphicsConfiguration() { @@ -139,7 +146,9 @@ public class AWTCanvas extends Canvas { { jawtWindow = (JAWTWindow) NativeWindowFactory.getNativeWindow(this, awtConfig); // trigger initialization cycle + jawtWindow.setSurfaceScale( upstreamScale.getReqPixelScale() ); jawtWindow.lockSurface(); + upstreamScale.setHasPixelScale(jawtWindow.getSurfaceScale(new int[2])); jawtWindow.unlockSurface(); } @@ -152,10 +161,6 @@ public class AWTCanvas extends Canvas { } } - public int getPixelScale() { - final JAWTWindow _jawtWindow = jawtWindow; - return (null != _jawtWindow) ? _jawtWindow.getPixelScale() : 1; - } public NativeWindow getNativeWindow() { final JAWTWindow _jawtWindow = jawtWindow; return (null != _jawtWindow) ? _jawtWindow : null; diff --git a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java index cc92c4963..4064fdb05 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java @@ -98,16 +98,17 @@ public class WindowDriver extends WindowImpl { } } - @Override - protected final int getPixelScaleX() { - final AWTCanvas _awtCanvas = awtCanvas; - return null != _awtCanvas ? _awtCanvas.getPixelScale() : 1; - } + private final AWTCanvas.UpstreamScalable upstreamScalable = new AWTCanvas.UpstreamScalable() { + @Override + public int[] getReqPixelScale() { + return WindowDriver.this.reqPixelScale; + } - @Override - protected final int getPixelScaleY() { - return getPixelScaleX(); - } + @Override + public void setHasPixelScale(final int[] pixelScale) { + System.arraycopy(pixelScale, 0, WindowDriver.this.hasPixelScale, 0, 2); + } + }; @Override protected void createNativeImpl() { @@ -130,7 +131,7 @@ public class WindowDriver extends WindowImpl { awtContainer.setLayout(new BorderLayout()); if( null == awtCanvas ) { - awtCanvas = new AWTCanvas(capsRequested, WindowDriver.this.capabilitiesChooser); + awtCanvas = new AWTCanvas(capsRequested, WindowDriver.this.capabilitiesChooser, upstreamScalable); // canvas.addComponentListener(listener); awtContainer.add(awtCanvas, BorderLayout.CENTER); diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index cd852bb09..0fa4739a3 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -39,11 +39,13 @@ import javax.media.nativewindow.GraphicsConfigurationFactory; import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.MutableSurface; +import javax.media.nativewindow.ScalableSurface; import javax.media.nativewindow.VisualIDHolder; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; import javax.media.nativewindow.util.PointImmutable; +import jogamp.nativewindow.SurfaceScaleUtils; import jogamp.nativewindow.macosx.OSXUtil; import jogamp.newt.PointerIconImpl; import jogamp.newt.ScreenImpl; @@ -62,43 +64,42 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl DisplayDriver.initSingleton(); } - private int pixelScale; - public WindowDriver() { - pixelScale = 1; } - private boolean updatePixelScale(final boolean sendEvent, final boolean defer, final float newPixelScaleRaw) { - final int newPixelScaleSafe = FloatUtil.isZero(newPixelScaleRaw, FloatUtil.EPSILON) ? 1 : (int) newPixelScaleRaw; - final boolean changed = pixelScale != newPixelScaleSafe; - if( DEBUG_IMPLEMENTATION ) { - System.err.println("WindowDriver.updatePixelScale.X: "+pixelScale+" -> "+newPixelScaleSafe+" (raw "+newPixelScaleRaw+") - changed "+changed); + private boolean updatePixelScale(final boolean sendEvent, final boolean defer, final float pixelScaleRaw) { + final int[] pixelScaleInt; + { + final int ps = FloatUtil.isZero(pixelScaleRaw, FloatUtil.EPSILON) ? 1 : (int) pixelScaleRaw; + pixelScaleInt = new int[] { ps, ps }; } - if( changed ) { - pixelScale = newPixelScaleSafe; + + if( SurfaceScaleUtils.computePixelScale(hasPixelScale, hasPixelScale, reqPixelScale, pixelScaleInt, DEBUG_IMPLEMENTATION ? getClass().getName() : null) ) { if( sendEvent ) { super.sizeChanged(defer, getWidth(), getHeight(), true); } else { defineSize(getWidth(), getHeight()); } + return true; + } else { + return false; } - return changed; } private boolean updatePixelScaleByScreenIdx(final boolean sendEvent) { final float newPixelScaleRaw = (float) OSXUtil.GetPixelScale(getScreen().getIndex()); if( DEBUG_IMPLEMENTATION ) { - System.err.println("WindowDriver.updatePixelScale.1: "+pixelScale+" -> "+newPixelScaleRaw); + System.err.println("WindowDriver.updatePixelScale.1: "+hasPixelScale[0]+" -> "+newPixelScaleRaw); } return updatePixelScale(sendEvent, true /* defer */, newPixelScaleRaw); } private boolean updatePixelScaleByWindowHandle(final boolean sendEvent) { - final long wh = getWindowHandle(); - if( 0 != wh ) { - final float newPixelScaleRaw = (float)OSXUtil.GetPixelScale(wh); + final long handle = getWindowHandle(); + if( 0 != handle ) { + final float newPixelScaleRaw = (float)OSXUtil.GetPixelScale(handle); if( DEBUG_IMPLEMENTATION ) { - System.err.println("WindowDriver.updatePixelScale.2: "+pixelScale+" -> "+newPixelScaleRaw); + System.err.println("WindowDriver.updatePixelScale.2: "+hasPixelScale[0]+" -> "+newPixelScaleRaw); } return updatePixelScale(sendEvent, true /* defer */, newPixelScaleRaw); } else { @@ -109,10 +110,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl /** Called from native code */ protected void updatePixelScale(final boolean defer, final float newPixelScaleRaw) { final long handle = getWindowHandle(); + if( DEBUG_IMPLEMENTATION ) { + System.err.println("WindowDriver.updatePixelScale.3: "+hasPixelScale[0]+" (has) -> "+newPixelScaleRaw+" (raw), drop "+(0==handle)); + } if( 0 != handle ) { - if( DEBUG_IMPLEMENTATION ) { - System.err.println("WindowDriver.updatePixelScale.3: "+pixelScale+" -> "+newPixelScaleRaw); - } updatePixelScale(true /* sendEvent*/, defer, newPixelScaleRaw); } } @@ -134,13 +135,43 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl } @Override - protected final int getPixelScaleX() { - return pixelScale; - } - - @Override - protected final int getPixelScaleY() { - return pixelScale; + public final void setSurfaceScale(final int[] pixelScale) { + SurfaceScaleUtils.validateReqPixelScale(reqPixelScale, pixelScale, DEBUG_IMPLEMENTATION ? getClass().getName() : null); + + final int[] resPixelScale; + if( isNativeValid() ) { + if( isOffscreenInstance ) { + final NativeWindow pWin = getParent(); + if( pWin instanceof ScalableSurface ) { + final ScalableSurface sSurf = (ScalableSurface)pWin; + sSurf.setSurfaceScale(reqPixelScale); + final int[] pPixelScale = sSurf.getSurfaceScale(new int[2]); + updatePixelScale(true /* sendEvent */, true /* defer */, pPixelScale[0]); // HiDPI: uniformPixelScale + } else { + // just notify updated pixelScale if offscreen + SurfaceScaleUtils.replaceAutoMaxWithPlatformMax(reqPixelScale); + updatePixelScale(true /* sendEvent */, true /* defer */, reqPixelScale[0]); // HiDPI: uniformPixelScale + } + } else { + // set pixelScale in native code, will issue an update PixelScale + OSXUtil.RunOnMainThread(true, new Runnable() { + @Override + public void run() { + setPixelScale0(getWindowHandle(), surfaceHandle, reqPixelScale[0]); // HiDPI: uniformPixelScale + } + } ); + } + resPixelScale = hasPixelScale; + } else { + hasPixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE; + hasPixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE; + resPixelScale = reqPixelScale; + } + if( DEBUG_IMPLEMENTATION ) { + System.err.println("WindowDriver.setPixelScale: "+pixelScale[0]+"x"+pixelScale[1]+" (req) -> "+ + reqPixelScale[0]+"x"+reqPixelScale[1]+" (validated) -> "+ + resPixelScale[0]+"x"+resPixelScale[1]+" (result) - realized "+isNativeValid()); + } } @Override @@ -351,6 +382,9 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl } } + final boolean setVisible = 0 != ( FLAG_IS_VISIBLE & flags); + final boolean hasFocus = hasFocus(); + if(DEBUG_IMPLEMENTATION) { final AbstractGraphicsConfiguration cWinCfg = this.getGraphicsConfiguration(); final NativeWindow pWin = getParent(); @@ -362,12 +396,10 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl ", isOffscreenInstance(sscSurfaceHandle "+toHexString(sscSurfaceHandle)+ ", ioi: "+_isOffscreenInstance+ ") -> "+isOffscreenInstance+ - "\n\t, "+getReconfigureFlagsAsString(null, flags)); + "\n\t, "+getReconfigureFlagsAsString(null, flags)+", setVisible "+setVisible+", hasFocus "+hasFocus); // Thread.dumpStack(); } - final boolean setVisible = 0 != ( FLAG_IS_VISIBLE & flags); - if( 0 != ( FLAG_CHANGE_VISIBILITY & flags) && !setVisible ) { if ( !isOffscreenInstance ) { OSXUtil.RunOnMainThread(false, new Runnable() { @@ -395,6 +427,9 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl updatePixelScaleByWindowHandle(false /* sendEvent */); super.sizeChanged(false, width, height, true); visibleChanged(false, setVisible); + if( hasFocus ) { + requestFocusImpl(true); + } } else { if( width>0 && height>0 ) { if( !isOffscreenInstance ) { @@ -613,7 +648,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl if( 0 != surfaceHandle ) { throw new NativeWindowException("Internal Error - create w/o window, but has Newt NSView"); } - surfaceHandle = createView0(pS.getX(), pS.getY(), width, height, fullscreen); + surfaceHandle = createView0(pS.getX(), pS.getY(), width, height); if( 0 == surfaceHandle ) { throw new NativeWindowException("Could not create native view "+Thread.currentThread().getName()+" "+this); } @@ -633,7 +668,7 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl OSXUtil.RunOnMainThread(true, new Runnable() { @Override public void run() { - initWindow0( parentWinHandle, newWin, pS.getX(), pS.getY(), width, height, + initWindow0( parentWinHandle, newWin, pS.getX(), pS.getY(), width, height, reqPixelScale[0] /* HiDPI uniformPixelScale */, isOpaque, visible && !offscreenInstance, surfaceHandle); if( offscreenInstance ) { orderOut0(0!=parentWinHandle ? parentWinHandle : newWin); @@ -648,11 +683,12 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl } protected static native boolean initIDs0(); - private native long createView0(int x, int y, int w, int h, boolean fullscreen); + private native long createView0(int x, int y, int w, int h); private native long createWindow0(int x, int y, int w, int h, boolean fullscreen, int windowStyle, int backingStoreType, long view); /** Must be called on Main-Thread */ - private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h, + private native void initWindow0(long parentWindow, long window, int x, int y, int w, int h, float reqPixelScale, boolean opaque, boolean visible, long view); + private native void setPixelScale0(long window, long view, float reqPixelScale); private native boolean lockSurface0(long window, long view); private native boolean unlockSurface0(long window, long view); /** Must be called on Main-Thread */ diff --git a/src/newt/native/MacWindow.m b/src/newt/native/MacWindow.m index 80e70216e..2bd11da3c 100644 --- a/src/newt/native/MacWindow.m +++ b/src/newt/native/MacWindow.m @@ -747,24 +747,18 @@ JNIEXPORT jboolean JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initIDs0 /** * Class: jogamp_newt_driver_macosx_WindowDriver * Method: createView0 - * Signature: (IIIIZ)J + * Signature: (IIII)J */ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createView0 - (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, - jboolean fullscreen) + (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; - DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d, fs %d (START)\n", - (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h, (int)fullscreen); + DBG_PRINT( "createView0 - %p (this), %d/%d %dx%d (START)\n", + (void*)(intptr_t)jthis, (int)x, (int)y, (int)w, (int)h); NSRect rectView = NSMakeRect(0, 0, w, h); NewtView *myView = [[NewtView alloc] initWithFrame: rectView] ; -NS_DURING - // Available >= 10.7 - [myView setWantsBestResolutionOpenGLSurface: YES]; // HiDPI scaling: Always desired -NS_HANDLER -NS_ENDHANDLER DBG_PRINT( "createView0.X - new view: %p\n", myView); [pool release]; @@ -780,7 +774,7 @@ NS_ENDHANDLER * Signature: (IIIIZIIJ)J */ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow0 - (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, + (JNIEnv *env, jobject jthis, jint x, jint y, jint w, jint h, jboolean fullscreen, jint styleMask, jint bufferingType, jlong jview) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -816,10 +810,10 @@ JNIEXPORT jlong JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_createWindow * * Class: jogamp_newt_driver_macosx_WindowDriver * Method: initWindow0 - * Signature: (JJIIIIZZZJ)V + * Signature: (JJIIIIFZZZJ)V */ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0 - (JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h, + (JNIEnv *env, jobject jthis, jlong parent, jlong window, jint x, jint y, jint w, jint h, jfloat reqPixelScale, jboolean opaque, jboolean visible, jlong jview) { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; @@ -827,10 +821,20 @@ JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_initWindow0 NewtView* myView = (NewtView*) (intptr_t) jview ; BOOL fullscreen = myWindow->isFullscreenWindow; - DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, opaque %d, fs %d, visible %d, view %p (START)\n", - (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, + DBG_PRINT( "initWindow0 - %p (this), %p (parent), %p (window), %d/%d %dx%d, reqPixScale %f, opaque %d, fs %d, visible %d, view %p (START)\n", + (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, (int)x, (int)y, (int)w, (int)h, (float)reqPixelScale, (int) opaque, (int)fullscreen, (int)visible, myView); +NS_DURING + // HiDPI scaling: Setup - Available >= 10.7 + if( 1.0 == reqPixelScale ) { + [myView setWantsBestResolutionOpenGLSurface: NO]; + } else { + [myView setWantsBestResolutionOpenGLSurface: YES]; + } +NS_HANDLER +NS_ENDHANDLER + [myWindow setReleasedWhenClosed: NO]; // We control NSWindow destruction! [myWindow setPreservesContentDuringLiveResize: NO]; NS_DURING @@ -983,6 +987,44 @@ NS_ENDHANDLER (void*)(intptr_t)jthis, (void*)(intptr_t)parent, myWindow, myView); } +/** + * Method is called on Main-Thread, hence no special invocation required inside method. + * + * Class: jogamp_newt_driver_macosx_WindowDriver + * Method: setPixelScale0 + * Signature: (JJF)V + */ +JNIEXPORT void JNICALL Java_jogamp_newt_driver_macosx_WindowDriver_setPixelScale0 + (JNIEnv *env, jobject jthis, jlong window, jlong view, jfloat reqPixelScale) +{ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NewtMacWindow* myWindow = (NewtMacWindow*) ((intptr_t) window); + NewtView* myView = (NewtView*) (intptr_t) view ; +#ifdef VERBOSE_ON + int dbgIdx = 1; +#endif + + DBG_PRINT( "setPixelScale0 - %p (this), %p (window), view %p, reqPixScale %f (START)\n", + (void*)(intptr_t)jthis, myWindow, myView, (float)reqPixelScale); + +NS_DURING + // HiDPI scaling: Setup - Available >= 10.7 + if( 1.0 == reqPixelScale ) { + [myView setWantsBestResolutionOpenGLSurface: NO]; + } else { + [myView setWantsBestResolutionOpenGLSurface: YES]; + } +NS_HANDLER +NS_ENDHANDLER + + DBG_PRINT( "setPixelScale0.%d - %p (this), window: %p, view %p\n", + dbgIdx++, (void*)(intptr_t)jthis, myWindow, myView); + + [pool release]; + DBG_PRINT( "setPixelScale0.X - %p (this), window: %p, view %p\n", + (void*)(intptr_t)jthis, myWindow, myView); +} + /** * Method is called on Main-Thread, hence no special invocation required inside method. * diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index c4800bd26..fe761833d 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -778,8 +778,12 @@ static jmethodID windowRepaintID = NULL; { [super viewDidChangeBackingProperties]; - CGFloat pixelScale = [[self window] backingScaleFactor]; - [[self layer] setContentsScale: pixelScale]; + // HiDPI scaling + BOOL useHiDPI = [self wantsBestResolutionOpenGLSurface]; + CGFloat pixelScaleRaw = [[self window] backingScaleFactor]; + CGFloat pixelScaleUse = useHiDPI ? pixelScaleRaw : 1.0; + DBG_PRINT("viewDidChangeBackingProperties: PixelScale: HiDPI %d, raw %f -> use %f\n", useHiDPI, (float)pixelScaleRaw, (float)pixelScaleUse); + [[self layer] setContentsScale: pixelScaleUse]; if (javaWindowObject == NULL) { DBG_PRINT("viewDidChangeBackingProperties: null javaWindowObject\n"); @@ -792,7 +796,7 @@ static jmethodID windowRepaintID = NULL; return; } - (*env)->CallVoidMethod(env, javaWindowObject, updatePixelScaleID, JNI_TRUE, (jfloat)pixelScale); // defer + (*env)->CallVoidMethod(env, javaWindowObject, updatePixelScaleID, JNI_TRUE, (jfloat)pixelScaleUse); // defer // detaching thread not required - daemon // NewtCommon_ReleaseJNIEnv(shallBeDetached); -- cgit v1.2.3