diff options
author | Sven Gothel <[email protected]> | 2014-06-09 03:58:37 +0200 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-06-09 03:58:37 +0200 |
commit | 4686a652d821efe04045333026be79270bc19bfd (patch) | |
tree | 240ac4df0ae58c7461e7bfdfb3b438917041a3af /src/newt | |
parent | 14ff638b63fc7adaa59f351891f6a38806d7fa5d (diff) |
Bug 741 HiDPI: Add ScalableSurface.getNativeSurfaceScale(..) to compute surface DPI ; Add NEWT Window.getPixelsPerMM(..) to query surface DPI
With HiDPI and surface scale, we need knowledge of the native surface's pixel-scale
matching the monitor's pixel-per-millimeter value.
Preserving the queried native pixel-scale and exposing it via
ScalableSurface.getNativeSurfaceScale(..) to compute surface DPI.
Add NEWT Window.getPixelsPerMM(..) to query surface DPI.
Surface DPI is demonstrated in GraphUI's GPUUISceneGLListener0A .. and TestRulerNEWT01, etc ..
Diffstat (limited to 'src/newt')
-rw-r--r-- | src/newt/classes/com/jogamp/newt/MonitorDevice.java | 22 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/Window.java | 21 | ||||
-rw-r--r-- | src/newt/classes/com/jogamp/newt/opengl/GLWindow.java | 10 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/WindowImpl.java | 35 | ||||
-rw-r--r-- | src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java | 37 | ||||
-rw-r--r-- | src/newt/native/NewtMacWindow.m | 10 |
6 files changed, 96 insertions, 39 deletions
diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java index 8e5d305dd..a65675204 100644 --- a/src/newt/classes/com/jogamp/newt/MonitorDevice.java +++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java @@ -34,6 +34,7 @@ import javax.media.nativewindow.util.DimensionImmutable; import javax.media.nativewindow.util.Rectangle; import javax.media.nativewindow.util.RectangleImmutable; import javax.media.nativewindow.util.SurfaceSize; + import com.jogamp.common.util.ArrayHashSet; /** @@ -124,29 +125,34 @@ public abstract class MonitorDevice { } /** - * Stores the <i>pixels per millimeter</i> value according to <i>current</i> {@link MonitorMode} - * {@link SurfaceSize#getResolution() SurfaceSize's resolution} in the given storage <code>ppmmStore</code>. + * Returns the <i>pixels per millimeter</i> value according to the <i>current</i> {@link MonitorMode mode}'s + * {@link SurfaceSize#getResolution() surface resolution}. * <p> * To convert the result to <i>dpi</i>, i.e. dots-per-inch, multiply both components with <code>25.4f</code>. * </p> + * @param ppmmStore float[2] storage for the ppmm result + * @return the passed storage containing the ppmm for chaining */ - public final void getPixelsPerMM(final float[] ppmmStore) { - final MonitorMode mode = getCurrentMode(); - getPixelsPerMM(mode, ppmmStore); + public final float[] getPixelsPerMM(final float[] ppmmStore) { + return getPixelsPerMM(getCurrentMode(), ppmmStore); } /** - * Stores the <i>pixels per millimeter</i> value according to the given {@link MonitorMode} - * {@link SurfaceSize#getResolution() SurfaceSize's resolution} in the given storage <code>ppmmStore</code>. + * Returns the <i>pixels per millimeter</i> value according to the given {@link MonitorMode mode}'s + * {@link SurfaceSize#getResolution() surface resolution}. * <p> * To convert the result to <i>dpi</i>, i.e. dots-per-inch, multiply both components with <code>25.4f</code>. * </p> + * @param mode + * @param ppmmStore float[2] storage for the ppmm result + * @return the passed storage containing the ppmm for chaining */ - public final void getPixelsPerMM(final MonitorMode mode, final float[] ppmmStore) { + public final float[] getPixelsPerMM(final MonitorMode mode, final float[] ppmmStore) { final DimensionImmutable sdim = getSizeMM(); final DimensionImmutable spix = mode.getSurfaceSize().getResolution(); ppmmStore[0] = (float)spix.getWidth() / (float)sdim.getWidth(); ppmmStore[1] = (float)spix.getHeight() / (float)sdim.getHeight(); + return ppmmStore; } /** diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index 08236ae67..600ecee52 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -49,6 +49,7 @@ import javax.media.nativewindow.ScalableSurface; import javax.media.nativewindow.WindowClosingProtocol; import javax.media.nativewindow.util.Rectangle; import javax.media.nativewindow.util.RectangleImmutable; +import javax.media.nativewindow.util.SurfaceSize; /** * Specifying NEWT's Window functionality: @@ -254,6 +255,26 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur Rectangle getBounds(); /** + * Returns the <i>pixels per millimeter</i> of this window's {@link NativeSurface} + * according to the {@link #getMainMonitor() main monitor}'s <i>current</i> {@link MonitorMode mode}'s + * {@link SurfaceSize#getResolution() surface resolution}. + * <p> + * Method takes the {@link #getCurrentSurfaceScale(int[]) current surface-scale} and {@link #getNativeSurfaceScale(int[]) native surface-scale} + * into account, i.e.: + * <pre> + * surfacePpMM = monitorPpMM * currentSurfaceScale / nativeSurfaceScale, + * with PpMM == pixel per millimeter + * </pre> + * </p> + * <p> + * To convert the result to <i>dpi</i>, i.e. dots-per-inch, multiply both components with <code>25.4f</code>. + * </p> + * @param ppmmStore float[2] storage for the ppmm result + * @return the passed storage containing the ppmm for chaining + */ + float[] getPixelsPerMM(final float[] ppmmStore); + + /** * Sets the size of the window's client area in window units, excluding decorations. * * <p> diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 2991bb98a..cdc4f1217 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -404,6 +404,16 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind } @Override + public final int[] getNativeSurfaceScale(final int[] result) { + return window.getNativeSurfaceScale(result); + } + + @Override + public final float[] getPixelsPerMM(final float[] ppmmStore) { + return window.getPixelsPerMM(ppmmStore); + } + + @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 0501f6ad6..61fa7af6b 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -152,8 +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 }; + protected final int[] nativePixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + protected final int[] hasPixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + protected final 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) @@ -1092,7 +1093,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer setSize(width - getInsets().getTotalWidth(), height - getInsets().getTotalHeight()); } - private class DestroyAction implements Runnable { + private final Runnable destroyAction = new Runnable() { @Override public final void run() { boolean animatorPaused = false; @@ -1164,6 +1165,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer fullscreenUseMainMonitor = true; hasFocus = false; parentWindowHandle = 0; + hasPixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE; + hasPixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE; + nativePixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE; + nativePixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE; _lock.unlock(); } @@ -1187,9 +1192,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer windowListeners = null; parentWindow = null; */ - } - } - private final DestroyAction destroyAction = new DestroyAction(); + } }; @Override public void destroy() { @@ -1567,7 +1570,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } - private class ReparentActionRecreate implements Runnable { + private final Runnable reparentActionRecreate = new Runnable() { @Override public final void run() { final RecursiveLock _lock = windowLock; @@ -1581,9 +1584,7 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } finally { _lock.unlock(); } - } - } - private final ReparentActionRecreate reparentActionRecreate = new ReparentActionRecreate(); + } }; @Override public final ReparentOperation reparentWindow(NativeWindow newParent, int x, int y, int hints) { @@ -1958,6 +1959,20 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer return result; } + @Override + public final int[] getNativeSurfaceScale(final int[] result) { + System.arraycopy(nativePixelScale, 0, result, 0, 2); + return result; + } + + @Override + public final float[] getPixelsPerMM(final float[] ppmmStore) { + getMainMonitor().getPixelsPerMM(ppmmStore); + ppmmStore[0] *= (float)hasPixelScale[0] / (float)nativePixelScale[0]; + ppmmStore[1] *= (float)hasPixelScale[1] / (float)nativePixelScale[1]; + return ppmmStore; + } + protected final boolean autoPosition() { return autoPosition; } /** Sets the position fields {@link #x} and {@link #y} in window units to the given values and {@link #autoPosition} to false. */ diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index 498556630..b44c2a3cc 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -67,14 +67,18 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl public WindowDriver() { } - private boolean updatePixelScale(final boolean sendEvent, final boolean defer, final float pixelScaleRaw) { - final int[] pixelScaleInt; + private boolean updatePixelScale(final boolean sendEvent, final boolean defer, final float newPixelScaleRaw, final float nativePixelScaleRaw) { + final int[] newPixelScale = new int[2]; { - final int ps = FloatUtil.isZero(pixelScaleRaw, FloatUtil.EPSILON) ? 1 : (int) pixelScaleRaw; - pixelScaleInt = new int[] { ps, ps }; + final int _newPixelScale = FloatUtil.isZero(newPixelScaleRaw, FloatUtil.EPSILON) ? ScalableSurface.IDENTITY_PIXELSCALE : (int) newPixelScaleRaw; + newPixelScale[0]= _newPixelScale; + newPixelScale[1]= _newPixelScale; + final int _nativePixelScale = FloatUtil.isZero(nativePixelScaleRaw, FloatUtil.EPSILON) ? ScalableSurface.IDENTITY_PIXELSCALE : (int) nativePixelScaleRaw; + nativePixelScale[0]= _nativePixelScale; + nativePixelScale[1]= _nativePixelScale; } - if( SurfaceScaleUtils.computePixelScale(hasPixelScale, hasPixelScale, reqPixelScale, pixelScaleInt, DEBUG_IMPLEMENTATION ? getClass().getName() : null) ) { + if( SurfaceScaleUtils.computePixelScale(hasPixelScale, hasPixelScale, reqPixelScale, newPixelScale, DEBUG_IMPLEMENTATION ? getClass().getName() : null) ) { if( sendEvent ) { super.sizeChanged(defer, getWidth(), getHeight(), true); } else { @@ -87,34 +91,34 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl } private boolean updatePixelScaleByScreenIdx(final boolean sendEvent) { - final float newPixelScaleRaw = (float) OSXUtil.GetPixelScale(getScreen().getIndex()); + final float nativePixelScaleRaw = (float) OSXUtil.GetPixelScale(getScreen().getIndex()); if( DEBUG_IMPLEMENTATION ) { - System.err.println("WindowDriver.updatePixelScale.1: "+hasPixelScale[0]+" -> "+newPixelScaleRaw); + System.err.println("WindowDriver.updatePixelScale.1: "+hasPixelScale[0]+", "+nativePixelScaleRaw+" (native)"); } - return updatePixelScale(sendEvent, true /* defer */, newPixelScaleRaw); + return updatePixelScale(sendEvent, true /* defer */, nativePixelScaleRaw, nativePixelScaleRaw); } private boolean updatePixelScaleByWindowHandle(final boolean sendEvent) { final long handle = getWindowHandle(); if( 0 != handle ) { - final float newPixelScaleRaw = (float)OSXUtil.GetPixelScale(handle); + final float nativePixelScaleRaw = (float)OSXUtil.GetPixelScale(handle); if( DEBUG_IMPLEMENTATION ) { - System.err.println("WindowDriver.updatePixelScale.2: "+hasPixelScale[0]+" -> "+newPixelScaleRaw); + System.err.println("WindowDriver.updatePixelScale.2: "+hasPixelScale[0]+", "+nativePixelScaleRaw+" (native)"); } - return updatePixelScale(sendEvent, true /* defer */, newPixelScaleRaw); + return updatePixelScale(sendEvent, true /* defer */, nativePixelScaleRaw, nativePixelScaleRaw); } else { return false; } } /** Called from native code */ - protected void updatePixelScale(final boolean defer, final float newPixelScaleRaw) { + protected void updatePixelScale(final boolean defer, final float newPixelScaleRaw, final float nativePixelScaleRaw) { final long handle = getWindowHandle(); if( DEBUG_IMPLEMENTATION ) { - System.err.println("WindowDriver.updatePixelScale.3: "+hasPixelScale[0]+" (has) -> "+newPixelScaleRaw+" (raw), drop "+(0==handle)); + System.err.println("WindowDriver.updatePixelScale.3: "+hasPixelScale[0]+" (has) -> "+newPixelScaleRaw+" (raw), "+nativePixelScaleRaw+" (native), drop "+(0==handle)); } if( 0 != handle ) { - updatePixelScale(true /* sendEvent*/, defer, newPixelScaleRaw); + updatePixelScale(true /* sendEvent*/, defer, newPixelScaleRaw, nativePixelScaleRaw); } } @@ -146,11 +150,12 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl final ScalableSurface sSurf = (ScalableSurface)pWin; sSurf.setSurfaceScale(reqPixelScale); final int[] pPixelScale = sSurf.getCurrentSurfaceScale(new int[2]); - updatePixelScale(true /* sendEvent */, true /* defer */, pPixelScale[0]); // HiDPI: uniformPixelScale + sSurf.getNativeSurfaceScale(nativePixelScale); + updatePixelScale(true /* sendEvent */, true /* defer */, pPixelScale[0], nativePixelScale[0]); // HiDPI: uniformPixelScale } else { // just notify updated pixelScale if offscreen SurfaceScaleUtils.replaceAutoMaxWithPlatformMax(reqPixelScale); - updatePixelScale(true /* sendEvent */, true /* defer */, reqPixelScale[0]); // HiDPI: uniformPixelScale + updatePixelScale(true /* sendEvent */, true /* defer */, reqPixelScale[0], nativePixelScale[0]); // HiDPI: uniformPixelScale } } else { // set pixelScale in native code, will issue an update PixelScale diff --git a/src/newt/native/NewtMacWindow.m b/src/newt/native/NewtMacWindow.m index fe761833d..5a1963155 100644 --- a/src/newt/native/NewtMacWindow.m +++ b/src/newt/native/NewtMacWindow.m @@ -780,9 +780,9 @@ static jmethodID windowRepaintID = NULL; // 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); + CGFloat pixelScaleNative = [[self window] backingScaleFactor]; + CGFloat pixelScaleUse = useHiDPI ? pixelScaleNative : 1.0; + DBG_PRINT("viewDidChangeBackingProperties: PixelScale: HiDPI %d, native %f -> use %f\n", useHiDPI, (float)pixelScaleNative, (float)pixelScaleUse); [[self layer] setContentsScale: pixelScaleUse]; if (javaWindowObject == NULL) { @@ -796,7 +796,7 @@ static jmethodID windowRepaintID = NULL; return; } - (*env)->CallVoidMethod(env, javaWindowObject, updatePixelScaleID, JNI_TRUE, (jfloat)pixelScaleUse); // defer + (*env)->CallVoidMethod(env, javaWindowObject, updatePixelScaleID, JNI_TRUE, (jfloat)pixelScaleUse, (jfloat)pixelScaleNative); // defer // detaching thread not required - daemon // NewtCommon_ReleaseJNIEnv(shallBeDetached); @@ -812,7 +812,7 @@ static jmethodID windowRepaintID = NULL; enqueueMouseEventID = (*env)->GetMethodID(env, clazz, "enqueueMouseEvent", "(ZSIIISF)V"); enqueueKeyEventID = (*env)->GetMethodID(env, clazz, "enqueueKeyEvent", "(ZSISCC)V"); sizeChangedID = (*env)->GetMethodID(env, clazz, "sizeChanged", "(ZIIZ)V"); - updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZF)V"); + updatePixelScaleID = (*env)->GetMethodID(env, clazz, "updatePixelScale", "(ZFF)V"); visibleChangedID = (*env)->GetMethodID(env, clazz, "visibleChanged", "(ZZ)V"); insetsChangedID = (*env)->GetMethodID(env, clazz, "insetsChanged", "(ZIIII)V"); positionChangedID = (*env)->GetMethodID(env, clazz, "screenPositionChanged", "(ZII)V"); |