diff options
author | Sven Gothel <[email protected]> | 2015-01-27 00:49:51 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2015-01-27 00:49:51 +0100 |
commit | 6516a52d3da5cced924db63b64af911d55355325 (patch) | |
tree | fe4404bbd72d4db624722459c76a520019cfb4ca /src/nativewindow/classes/jogamp | |
parent | 26f965bbe7b40968158901c3f4ef2f54e821ac70 (diff) |
Bug 1120 - Refine HiDPI Support ( Part-2 ) (API CHANGE)
- Use float[2] for pixel-scale.
Utilize simple integer rounding:
int-pixel-units = (int) ( int-window-units * pixel-scale + 0.5f )
- Provide minimum and maximum allowed pixel-scale values
to be set by platform, supporting generic pixel-scale validation.
- Remove 'OSXUtil.GetPixelScale(final RectangleImmutable r, final int[] screenIndexOut)',
implementation for all platforms would cause huge redundancy of
Screen and MonitorDevice code (duplication of NEWT).
- instead, add 'float[2] pixelScale' to NEWT's MonitorDevice
- Detect change of pixel-scale and propagate accordingly.
This allows GLCanvas, GLJPanel and NewtCanvasAWT instances
to be dragged between monitor devices w/ different pixel-scale.
- OSX: Handle native triggered reshape events off-thread to avoid EDT congestion
due to locked window when consuming deferred events on EDT.
Diffstat (limited to 'src/nativewindow/classes/jogamp')
5 files changed, 212 insertions, 200 deletions
diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java index 73413cf59..70eec7b24 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java +++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java @@ -27,7 +27,6 @@ */ package jogamp.nativewindow; -import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.ScalableSurface; /** @@ -35,138 +34,162 @@ import javax.media.nativewindow.ScalableSurface; */ public class SurfaceScaleUtils { - private static final int[] PlatformMaxPixelScale; - private static final boolean PlatformUniformPixelScale; - private static final boolean PlatformPixelScaleSupported; + private static final float EPSILON = 1.1920929E-7f; // Float.MIN_VALUE == 1.4e-45f ; double EPSILON 2.220446049250313E-16d - static { - if( NativeWindowFactory.TYPE_MACOSX == NativeWindowFactory.getNativeWindowType(true) ) { - PlatformMaxPixelScale = new int[] { jogamp.nativewindow.macosx.OSXUtil.MAX_PIXELSCALE, jogamp.nativewindow.macosx.OSXUtil.MAX_PIXELSCALE }; - PlatformUniformPixelScale = true; - PlatformPixelScaleSupported = true; - } else { - PlatformMaxPixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; - PlatformUniformPixelScale = false; - PlatformPixelScaleSupported = false; - } + private static boolean isZero(final float a) { + return Math.abs(a) < EPSILON; } /** - * Compute a new valid pixelScale to be used by {@link NativeSurface} implementations, - * based on the given request and surface's pixelScale + * Returns integer rounded product, i.e. {@code (int) ( a * pixelScale + 0.5f )} * - * @param result int[2] storage for result, maybe same as <code>prePixelScale</code> for in-place - * @param prePixelScale previous pixelScale - * @param reqPixelScale requested pixelScale, validated via {@link #validateReqPixelScale(int[], int, String)}. - * @param newPixelScaleRaw new raw surface pixelScale - * @param DEBUG_PREFIX if set, dumps debug info on stderr using this prefix - * @return true if pixelScale has changed, otherwise false + * @param a the int value + * @param pixelScale the float scale factor + * @return the integer rounded product */ - public static boolean computePixelScale(final int[] result, final int[] prePixelScale, final int[] reqPixelScale, final int[] newPixelScaleRaw, final String DEBUG_PREFIX) { - final int newPixelScaleSafeX = 0 < newPixelScaleRaw[0] ? newPixelScaleRaw[0] : ScalableSurface.IDENTITY_PIXELSCALE; - final int newPixelScaleSafeY = 0 < newPixelScaleRaw[1] ? newPixelScaleRaw[1] : ScalableSurface.IDENTITY_PIXELSCALE; - final boolean useHiDPI = ScalableSurface.IDENTITY_PIXELSCALE != reqPixelScale[0] || ScalableSurface.IDENTITY_PIXELSCALE != reqPixelScale[1]; - final int prePixelScaleX = prePixelScale[0]; - final int prePixelScaleY = prePixelScale[1]; - - if( useHiDPI ) { - result[0] = newPixelScaleSafeX; - result[1] = newPixelScaleSafeY; - } else { - result[0] = ScalableSurface.IDENTITY_PIXELSCALE; - result[1] = ScalableSurface.IDENTITY_PIXELSCALE; - } - - final boolean changed = result[0] != prePixelScaleX || result[1] != prePixelScaleY; - if( null != DEBUG_PREFIX ) { - System.err.println(DEBUG_PREFIX+".computePixelScale: useHiDPI "+useHiDPI+", ["+prePixelScaleX+"x"+prePixelScaleY+" (pre), "+ - reqPixelScale[0]+"x"+reqPixelScale[1]+" (req)] -> "+ - newPixelScaleRaw[0]+"x"+newPixelScaleRaw[1]+" (raw) -> "+ - newPixelScaleSafeX+"x"+newPixelScaleSafeY+" (safe) -> "+ - result[0]+"x"+result[1]+" (use), changed "+changed); - } - return changed; + public static int scale(final int a, final float pixelScale) { + return (int) ( a * pixelScale + 0.5f ); } /** - * Validate the given requested pixelScale value pair, i.e. clip it to the - * limits of {@link ScalableSurface#AUTOMAX_PIXELSCALE} and {@link #getPlatformMaxPixelScale(int[])} - * <p> - * To be used by {@link ScalableSurface#setSurfaceScale(int[])} implementations. - * </p> + * Returns integer rounded product, i.e. {@code (int) ( a / pixelScale + 0.5f )} * - * @param result int[2] storage for result - * @param reqPixelScale requested pixelScale - * @param DEBUG_PREFIX if set, dumps debug info on stderr using this prefix + * @param a the int value + * @param pixelScale the float scale factor + * @return the integer rounded product */ - public static void validateReqPixelScale(final int[] result, final int[] reqPixelScale, final String DEBUG_PREFIX) { - final int minPS = Math.min(reqPixelScale[0], reqPixelScale[1]); - if( ScalableSurface.AUTOMAX_PIXELSCALE >= minPS ) { - result[0] = ScalableSurface.AUTOMAX_PIXELSCALE; - result[1] = ScalableSurface.AUTOMAX_PIXELSCALE; - } else if( PlatformUniformPixelScale ) { - final int maxPS = Math.max(reqPixelScale[0], reqPixelScale[1]); - if( maxPS >= PlatformMaxPixelScale[0] ) { - result[0] = PlatformMaxPixelScale[0]; - result[1] = PlatformMaxPixelScale[1]; - } else { - result[0] = maxPS; - result[1] = maxPS; - } - } else { - if( reqPixelScale[0] >= PlatformMaxPixelScale[0] ) { - result[0] = PlatformMaxPixelScale[0]; - } else { - result[0] = reqPixelScale[0]; - } - if( reqPixelScale[1] >= PlatformMaxPixelScale[1] ) { - result[1] = PlatformMaxPixelScale[1]; - } else { - result[1] = reqPixelScale[1]; - } - } - if( null != DEBUG_PREFIX ) { - System.err.println(DEBUG_PREFIX+".validateReqPixelScale: ["+reqPixelScale[0]+"x"+reqPixelScale[1]+" (req), "+ - PlatformMaxPixelScale[0]+"x"+PlatformMaxPixelScale[1]+" (max)] -> "+ - result[0]+"x"+result[1]+" (valid)"); - } + public static int scaleInv(final int a, final float pixelScale) { + return (int) ( a / pixelScale + 0.5f ); } /** - * Replaces {@link ScalableSurface#AUTOMAX_PIXELSCALE} with {@link #getPlatformMaxPixelScale(int[])}, - * for each component. + * Returns integer rounded product, i.e. {@code (int) ( a * pixelScale + 0.5f )} * - * @param pixelScale int[2] value array to be tested and replaced + * @param result the int[2] result, may be {@code a} for in-place operation + * @param a the int[2] values + * @param pixelScale the float[2] scale factors + * @return the result for chaining */ - public static void replaceAutoMaxWithPlatformMax(final int[] pixelScale) { - if( ScalableSurface.AUTOMAX_PIXELSCALE == pixelScale[0] ) { - pixelScale[0] = PlatformMaxPixelScale[0]; - } - if( ScalableSurface.AUTOMAX_PIXELSCALE == pixelScale[1] ) { - pixelScale[1] = PlatformMaxPixelScale[1]; - } + public static int[] scale(final int[] result, final int[] a, final float[] pixelScale) { + result[0] = (int) ( a[0] * pixelScale[0] + 0.5f ); + result[1] = (int) ( a[1] * pixelScale[1] + 0.5f ); + return result; } - /** - * Returns the maximum platform pixelScale + * Returns integer rounded product, i.e. {@code (int) ( a / pixelScale + 0.5f )} + * + * @param result the int[2] result, may be {@code a} for in-place operation + * @param a the int[2] values + * @param pixelScale the float[2] scale factors + * @return the result for chaining */ - public static int[] getPlatformMaxPixelScale(final int[] result) { - System.arraycopy(PlatformMaxPixelScale, 0, result, 0, 2); + public static int[] scaleInv(final int[] result, final int[] a, final float[] pixelScale) { + result[0] = (int) ( a[0] / pixelScale[0] + 0.5f ); + result[1] = (int) ( a[1] / pixelScale[1] + 0.5f ); return result; } /** - * Returns true if platform pixelScale is uniform, i.e. same scale factor for x- and y-direction, otherwise false. + * Method constrains the given pixel-scale within ]0..{@code maxPixelScale}], as described below. + * <p> + * Method returns {@link ScalableSurface#IDENTITY_PIXELSCALE IDENTITY_PIXELSCALE} if: + * <ul> + * <li>{@code pixelScale} ~= {@link ScalableSurface#IDENTITY_PIXELSCALE IDENTITY_PIXELSCALE}</li> + * </ul> + * </p> + * <p> + * Method returns {@code maxPixelScale} if + * <ul> + * <li>{@code pixelScale} ~= {@link ScalableSurface#AUTOMAX_PIXELSCALE AUTOMAX_PIXELSCALE}</li> + * <li>{@code pixelScale} > {@code maxPixelScale}</li> + * <li>{@code pixelScale} ~= {@code maxPixelScale}</li> + * </ul> + * </p> + * <p> + * Method returns {@code minPixelScale} if + * <ul> + * <li>{@code pixelScale} < {@code minPixelScale}</li> + * <li>{@code pixelScale} ~= {@code minPixelScale}</li> + * </ul> + * </p> + * <p> + * Otherwise method returns the given {@code pixelScale}. + * </p> + * <p> + * <i>~=</i> denominates a delta ≤ {@link FloatUtil#EPSILON}. + * </p> + * @param pixelScale pixel-scale to be constrained + * @param minPixelScale minimum pixel-scale + * @param maxPixelScale maximum pixel-scale + * @return the constrained pixel-scale */ - public static boolean isPlatformPixelScaleUniform() { - return PlatformUniformPixelScale; + public static float clampPixelScale(final float pixelScale, final float minPixelScale, final float maxPixelScale) { + if( isZero(pixelScale-ScalableSurface.IDENTITY_PIXELSCALE) ) { + return ScalableSurface.IDENTITY_PIXELSCALE; + } else if( isZero(pixelScale-ScalableSurface.AUTOMAX_PIXELSCALE) || + pixelScale > maxPixelScale || + isZero(pixelScale-maxPixelScale) + ) + { + return maxPixelScale; + } else if( pixelScale < minPixelScale || isZero(pixelScale-minPixelScale) ) + { + return minPixelScale; + } else { + return pixelScale; + } } /** - * Returns whether the platform supports pixelScale + * Method {@link #clampPixelScale(float, float, float) constrains} the given float[2] pixel-scale + * within ]0..{@code maxPixelScale}], as described in {@link #clampPixelScale(float, float, float)}. + * + * @param result float[2] storage for result, maybe same as <code>s</code> for in-place + * @param pixelScale float[2] pixelScale to be constrained + * @param minPixelScale float[2] minimum pixel-scale + * @param maxPixelScale float[2] maximum pixel-scale + * @return the constrained result for chaining */ - public static boolean isPlatformPixelScaleSupported() { - return PlatformPixelScaleSupported; + public static float[] clampPixelScale(final float[] result, final float[] pixelScale, + final float[] minPixelScale, final float[] maxPixelScale) { + result[0] = clampPixelScale(pixelScale[0], minPixelScale[0], maxPixelScale[0]); + result[1] = clampPixelScale(pixelScale[1], minPixelScale[1], maxPixelScale[1]); + return result; } + /** + * Method writes the given float[2] requested pixel-scale {@code reqPixelScale} + * into {@code result} within its constraints ]0..{@code maxPixelScale}], as described in {@link #clampPixelScale(float, float, float)}. + * <p> + * Method only differs from {@link #clampPixelScale(float[], float[], float[], float[])} + * by returning the whether the value has changed, i.e. different from the given {@code prePixelScale}. + * </p> + * + * @param result int[2] storage for result, maybe same as <code>prePixelScale</code> for in-place + * @param prePixelScale float[2] previous pixel-scale + * @param reqPixelScale float[2] requested pixel-scale, validated via {@link #validateReqPixelScale(float[], float[], String)}. + * @param minPixelScale float[2] minimum pixel-scale + * @param maxPixelScale float[2] maximum pixel-scale + * @param DEBUG_PREFIX if set, dumps debug info on stderr using this prefix + * @param newPixelScaleRaw new raw surface pixel-scale + * @return {@code true} if pixel-scale has changed, otherwise {@code false}. + */ + public static boolean setNewPixelScale(final float[] result, + final float[] prePixelScale, final float[] reqPixelScale, + final float[] minPixelScale, final float[] maxPixelScale, + final String DEBUG_PREFIX) { + final float resultX = clampPixelScale(reqPixelScale[0], minPixelScale[0], maxPixelScale[0]); + final float resultY = clampPixelScale(reqPixelScale[1], minPixelScale[1], maxPixelScale[1]); + final boolean changed = resultX != prePixelScale[0] || resultY != prePixelScale[1]; + if( null != DEBUG_PREFIX ) { + System.err.println(DEBUG_PREFIX+".setNewPixelScale: pre["+prePixelScale[0]+", "+prePixelScale[1]+"], req["+ + reqPixelScale[0]+", "+reqPixelScale[1]+"], min["+ + minPixelScale[0]+", "+minPixelScale[1]+"], max["+ + maxPixelScale[0]+", "+maxPixelScale[1]+"] -> result["+ + resultX+", "+resultY+"], changed "+changed); + } + result[0] = resultX; + result[1] = resultY; + return changed; + } } diff --git a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java index d3439b53f..cfcca7d05 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java +++ b/src/nativewindow/classes/jogamp/nativewindow/WrappedSurface.java @@ -42,7 +42,7 @@ import com.jogamp.nativewindow.UpstreamSurfaceHookMutableSize; * @see ProxySurface */ public class WrappedSurface extends ProxySurfaceImpl implements ScalableSurface { - private final int[] hasPixelScale = new int[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + private final float[] hasPixelScale = new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; private long surfaceHandle; /** @@ -104,27 +104,23 @@ public class WrappedSurface extends ProxySurfaceImpl implements ScalableSurface /** * {@inheritDoc} * <p> - * {@link WrappedSurface}'s implementation uses the {@link #setSurfaceScale(int[]) given pixelScale} directly. + * {@link WrappedSurface}'s implementation uses the {@link #setSurfaceScale(float[]) given pixelScale} directly. * </p> */ @Override public final int[] convertToWindowUnits(final int[] pixelUnitsAndResult) { - pixelUnitsAndResult[0] /= hasPixelScale[0]; - pixelUnitsAndResult[1] /= hasPixelScale[1]; - return pixelUnitsAndResult; + return SurfaceScaleUtils.scaleInv(pixelUnitsAndResult, pixelUnitsAndResult, hasPixelScale); } /** * {@inheritDoc} * <p> - * {@link WrappedSurface}'s implementation uses the {@link #setSurfaceScale(int[]) given pixelScale} directly. + * {@link WrappedSurface}'s implementation uses the {@link #setSurfaceScale(float[]) given pixelScale} directly. * </p> */ @Override public final int[] convertToPixelUnits(final int[] windowUnitsAndResult) { - windowUnitsAndResult[0] *= hasPixelScale[0]; - windowUnitsAndResult[1] *= hasPixelScale[1]; - return windowUnitsAndResult; + return SurfaceScaleUtils.scale(windowUnitsAndResult, windowUnitsAndResult, hasPixelScale); } /** @@ -147,25 +143,32 @@ public class WrappedSurface extends ProxySurfaceImpl implements ScalableSurface * </p> */ @Override - public final void setSurfaceScale(final int[] pixelScale) { - hasPixelScale[0] = pixelScale[0]; - hasPixelScale[1] = pixelScale[1]; + public final boolean setSurfaceScale(final float[] pixelScale) { + final boolean changed = hasPixelScale[0] != pixelScale[0] || hasPixelScale[1] != pixelScale[1]; + System.arraycopy(pixelScale, 0, hasPixelScale, 0, 2); + return changed; } @Override - public final int[] getRequestedSurfaceScale(final int[] result) { + public final float[] getRequestedSurfaceScale(final float[] result) { System.arraycopy(hasPixelScale, 0, result, 0, 2); return result; } @Override - public final int[] getCurrentSurfaceScale(final int[] result) { + public final float[] getCurrentSurfaceScale(final float[] result) { System.arraycopy(hasPixelScale, 0, result, 0, 2); return result; } @Override - public final int[] getNativeSurfaceScale(final int[] result) { + public float[] getMinimumSurfaceScale(final float[] result) { + System.arraycopy(hasPixelScale, 0, result, 0, 2); + return result; + } + + @Override + public final float[] getMaximumSurfaceScale(final float[] result) { System.arraycopy(hasPixelScale, 0, result, 0, 2); return result; } diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java index 231a89c26..4fd2b0dca 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/JAWTUtil.java @@ -56,6 +56,7 @@ import javax.media.nativewindow.ToolkitLock; import jogamp.common.os.PlatformPropsImpl; import jogamp.nativewindow.Debug; import jogamp.nativewindow.NWJNILibLoader; +import jogamp.nativewindow.macosx.OSXUtil; import com.jogamp.common.os.Platform; import com.jogamp.common.util.PropertyAccess; @@ -93,6 +94,7 @@ public class JAWTUtil { private static final ToolkitLock jawtToolkitLock; private static final Method getScaleFactorMethod; + private static final Method getCGDisplayIDMethodOnOSX; private static class PrivilegedDataBlob1 { PrivilegedDataBlob1() { @@ -101,6 +103,7 @@ public class JAWTUtil { Method sunToolkitAWTLockMethod; Method sunToolkitAWTUnlockMethod; Method getScaleFactorMethod; + Method getCGDisplayIDMethodOnOSX; boolean ok; } @@ -321,6 +324,7 @@ public class JAWTUtil { hasSunToolkitAWTLock = false; // hasSunToolkitAWTLock = false; getScaleFactorMethod = null; + getCGDisplayIDMethodOnOSX = null; } else { // Non-headless case JAWTJNILibLoader.initSingleton(); // load libjawt.so @@ -357,8 +361,13 @@ public class JAWTUtil { } try { final GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); - d.getScaleFactorMethod = gd.getClass().getDeclaredMethod("getScaleFactor"); + final Class<?> gdClass = gd.getClass(); + d.getScaleFactorMethod = gdClass.getDeclaredMethod("getScaleFactor"); d.getScaleFactorMethod.setAccessible(true); + if( Platform.OSType.MACOS == PlatformPropsImpl.OS_TYPE ) { + d.getCGDisplayIDMethodOnOSX = gdClass.getDeclaredMethod("getCGDisplayID"); + d.getCGDisplayIDMethodOnOSX.setAccessible(true); + } } catch (final Throwable t) {} return d; } @@ -366,6 +375,7 @@ public class JAWTUtil { sunToolkitAWTLockMethod = pdb1.sunToolkitAWTLockMethod; sunToolkitAWTUnlockMethod = pdb1.sunToolkitAWTUnlockMethod; getScaleFactorMethod = pdb1.getScaleFactorMethod; + getCGDisplayIDMethodOnOSX = pdb1.getCGDisplayIDMethodOnOSX; boolean _hasSunToolkitAWTLock = false; if ( pdb1.ok ) { @@ -545,20 +555,46 @@ public class JAWTUtil { * Note: Currently only supported on OSX since 1.7.0_40 for HiDPI retina displays * </p> * @param device the {@link GraphicsDevice} instance used to query the pixel scale - * @return the pixel scale factor + * @param minScale current and output min scale values + * @param maxScale current and output max scale values + * @return {@code true} if the given min and max scale values have changed, otherwise {@code false}. */ - public static final int getPixelScale(final GraphicsDevice device) { + public static final boolean getPixelScale(final GraphicsDevice device, final float[] minScale, final float[] maxScale) { + // Shall we allow ]0..1[ minimum scale? + boolean changed = minScale[0] != 1f || minScale[1] != 1f; + minScale[0] = 1f; + minScale[1] = 1f; + float sx = 1f; + float sy = 1f; if( !SKIP_AWT_HIDPI ) { + if( null != getCGDisplayIDMethodOnOSX ) { + // OSX specific, preserving double type + try { + final Object res = getCGDisplayIDMethodOnOSX.invoke(device); + if (res instanceof Integer) { + final int displayID = ((Integer)res).intValue(); + sx = (float) OSXUtil.GetPixelScaleByDisplayID(displayID); + sy = sx; + } + } catch (final Throwable t) {} + } if( null != getScaleFactorMethod ) { + // Generic (?) try { final Object res = getScaleFactorMethod.invoke(device); if (res instanceof Integer) { - return ((Integer)res).intValue(); + sx = ((Integer)res).floatValue(); + } else if ( res instanceof Double) { + sx = ((Double)res).floatValue(); } + sy = sx; } catch (final Throwable t) {} } } - return 1; + changed = maxScale[0] != sx || maxScale[1] != sy; + maxScale[0] = sx; + maxScale[1] = sy; + return changed; } /** @@ -574,20 +610,23 @@ public class JAWTUtil { * Note: Currently only supported on OSX since 1.7.0_40 for HiDPI retina displays * </p> * @param gc the {@link GraphicsConfiguration} instance used to query the pixel scale - * @return the pixel scale factor + * @param minScale current and output min scale values + * @param maxScale current and output max scale values + * @return {@code true} if the given min and max scale values have changed, otherwise {@code false}. */ - public static final int getPixelScale(final GraphicsConfiguration gc) { + public static final boolean getPixelScale(final GraphicsConfiguration gc, final float[] minScale, final float[] maxScale) { final GraphicsDevice device = null != gc ? gc.getDevice() : null; - final int ps; + boolean changed; if( null == device ) { - ps = 0; + changed = minScale[0] != 1f || minScale[1] != 1f || maxScale[0] != 1f || maxScale[1] != 1f; + minScale[0] = 1f; + minScale[1] = 1f; + maxScale[0] = 1f; + maxScale[1] = 1f; } else { - ps = JAWTUtil.getPixelScale(device); - } - if( DEBUG ) { - System.err.println("JAWTUtil.updatePixelScale: Fetched "+ps); + changed = JAWTUtil.getPixelScale(device, minScale, maxScale); } - return ps; + return changed; } } diff --git a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java index fae8db52a..1c6c41262 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java +++ b/src/nativewindow/classes/jogamp/nativewindow/jawt/macosx/MacOSXJAWTWindow.java @@ -48,7 +48,6 @@ import java.security.PrivilegedAction; import javax.media.nativewindow.AbstractGraphicsConfiguration; import javax.media.nativewindow.Capabilities; import javax.media.nativewindow.NativeSurface; -import javax.media.nativewindow.NativeWindow; import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.MutableSurface; import javax.media.nativewindow.util.Point; @@ -116,13 +115,10 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { } @Override - public void setSurfaceScale(final int[] pixelScale) { + public boolean setSurfaceScale(final float[] pixelScale) { super.setSurfaceScale(pixelScale); - if( 0 != getWindowHandle() ) { // locked at least once ! - final int hadPixelScaleX = getPixelScaleX(); - updatePixelScale(); - - if( hadPixelScaleX != getPixelScaleX() && 0 != getAttachedSurfaceLayer() ) { + if( 0 != getWindowHandle() && setReqPixelScale() ) { // locked at least once _and_ updated pixel-scale + if( 0 != getAttachedSurfaceLayer() ) { OSXUtil.RunOnMainThread(false, false, new Runnable() { @Override public void run() { @@ -133,6 +129,9 @@ public class MacOSXJAWTWindow extends JAWTWindow implements MutableSurface { } }); } + return true; + } else { + return false; } } diff --git a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java index 9af74d9f5..7cd0439b7 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java +++ b/src/nativewindow/classes/jogamp/nativewindow/macosx/OSXUtil.java @@ -31,8 +31,6 @@ import javax.media.nativewindow.NativeWindowException; import javax.media.nativewindow.NativeWindowFactory; import javax.media.nativewindow.util.Insets; import javax.media.nativewindow.util.Point; -import javax.media.nativewindow.util.Rectangle; -import javax.media.nativewindow.util.RectangleImmutable; import com.jogamp.common.util.Function; import com.jogamp.common.util.FunctionTask; @@ -109,64 +107,14 @@ public class OSXUtil implements ToolkitProperties { return (Insets) GetInsets0(windowOrView); } - /** - * Returns the pixel-scale of the NSScreen, with the highest - * {@link RectangleImmutable#coverage(RectangleImmutable) coverage} of the given rectangle in window units. - * <p> - * If no coverage is detected the pixel-scale of the first NSScreen is returned. - * </p> - * @param r arbitrary rectangle in window units - * @param screenIndexOut storage returning the native screen index containing the given rectangle - */ - public static double GetPixelScale(final RectangleImmutable r, final int[] screenIndexOut) { - if( DEBUG ) { - System.err.printf("GetPixelScale covering %s%n", r.toString()); - } - final int screenCount; - final RectangleImmutable[] screenBounds; - final double[] pixelScales; - { - final double[] sd = GetScreenData0(); - if( 0 != sd.length % 5 ) { - throw new InternalError("GetScreenData0 didn't return multiple of 5 but "+sd.length); - } - screenCount = sd.length / 5; - screenBounds = new RectangleImmutable[screenCount]; - pixelScales = new double[screenCount] ; - for(int i=0; i<screenCount; i++) { - final int j = i*5; - pixelScales[i] = sd[j+0]; - screenBounds[i] = new Rectangle((int)sd[j+1], (int)sd[j+2], (int)sd[j+3], (int)sd[j+4]); - if( DEBUG ) { - System.err.printf("GetPixelScale.Screen[%d]: scale %f, bounds[%f / %f %f x %f]%n", - i, pixelScales[i], sd[j+1], sd[j+2], sd[j+3], sd[j+4]); - } - } - } - double pixelScale = pixelScales[0]; - screenIndexOut[0] = 0; - float maxCoverage = Float.MIN_VALUE; - for(int i=screenCount-1; i>=0; i--) { - final RectangleImmutable sb = screenBounds[i]; - final float coverage = sb.coverage(r); - if( coverage > maxCoverage ) { - maxCoverage = coverage; - screenIndexOut[0] = i; - pixelScale = pixelScales[i]; - } - } - if( DEBUG ) { - System.err.printf("GetPixelScale Result: screen %d, scale %f%n%n", screenIndexOut[0], pixelScale); - } - return pixelScale; - } - - public static double GetPixelScale(final int screenIndex) { + public static double GetPixelScaleByScreenIdx(final int screenIndex) { return GetPixelScale0(screenIndex); } - + public static double GetPixelScaleByDisplayID(final int displayID) { + return GetPixelScale1(displayID); + } public static double GetPixelScale(final long windowOrView) { - return GetPixelScale1(windowOrView); + return GetPixelScale2(windowOrView); } public static long CreateNSWindow(final int x, final int y, final int width, final int height) { @@ -447,9 +395,9 @@ public class OSXUtil implements ToolkitProperties { private static native boolean isNSWindow0(long object); private static native Object GetLocationOnScreen0(long windowOrView, int src_x, int src_y); private static native Object GetInsets0(long windowOrView); - private static native double[] GetScreenData0(); private static native double GetPixelScale0(int screenIndex); - private static native double GetPixelScale1(long windowOrView); + private static native double GetPixelScale1(int displayID); + private static native double GetPixelScale2(long windowOrView); private static native long CreateNSWindow0(int x, int y, int width, int height); private static native void DestroyNSWindow0(long nsWindow); private static native long GetNSView0(long nsWindow); |