diff options
Diffstat (limited to 'src/newt/classes')
20 files changed, 283 insertions, 139 deletions
diff --git a/src/newt/classes/com/jogamp/newt/MonitorDevice.java b/src/newt/classes/com/jogamp/newt/MonitorDevice.java index 126162006..1a3222c71 100644 --- a/src/newt/classes/com/jogamp/newt/MonitorDevice.java +++ b/src/newt/classes/com/jogamp/newt/MonitorDevice.java @@ -30,6 +30,7 @@ package com.jogamp.newt; import java.util.List; +import javax.media.nativewindow.ScalableSurface; import javax.media.nativewindow.util.DimensionImmutable; import javax.media.nativewindow.util.Rectangle; import javax.media.nativewindow.util.RectangleImmutable; @@ -51,6 +52,7 @@ import com.jogamp.common.util.ArrayHashSet; * <ul> * <li>{@link MonitorMode} current mode</li> * <li>{@link RectangleImmutable} viewport (rotated)</li> + * <li>pixel-scale (rotated)</li> * </ul></li> * </ul> * <p> @@ -65,16 +67,31 @@ public abstract class MonitorDevice { protected final ArrayHashSet<MonitorMode> supportedModes; // FIXME: May need to support mutable mode, i.e. adding modes on the fly! protected MonitorMode currentMode; protected boolean modeChanged; - protected Rectangle viewportPU; // in pixel units - protected Rectangle viewportWU; // in window units + protected final float[] pixelScale; + protected final Rectangle viewportPU; // in pixel units + protected final Rectangle viewportWU; // in window units - protected MonitorDevice(final Screen screen, final int nativeId, final DimensionImmutable sizeMM, final Rectangle viewportPU, final Rectangle viewportWU, final MonitorMode currentMode, final ArrayHashSet<MonitorMode> supportedModes) { + /** + * @param screen associated {@link Screen} + * @param nativeId unique monitor device ID + * @param sizeMM size in millimeters + * @param currentMode + * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. + * @param viewportPU viewport in pixel-units + * @param viewportWU viewport in window-units + * @param supportedModes all supported {@link MonitorMode}s + */ + protected MonitorDevice(final Screen screen, final int nativeId, final DimensionImmutable sizeMM, + final MonitorMode currentMode, + final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU, + final ArrayHashSet<MonitorMode> supportedModes) { this.screen = screen; this.nativeId = nativeId; this.sizeMM = sizeMM; this.originalMode = currentMode; this.supportedModes = supportedModes; this.currentMode = currentMode; + this.pixelScale = null != pixelScale ? pixelScale : new float[] { 1.0f, 1.0f }; this.viewportPU = viewportPU; this.viewportWU = viewportWU; this.modeChanged = false; @@ -180,26 +197,40 @@ public abstract class MonitorDevice { } /** - * Returns the {@link RectangleImmutable rectangular} portion + * Returns the current {@link RectangleImmutable rectangular} portion * of the <b>rotated</b> virtual {@link Screen} size in pixel units * represented by this monitor, i.e. top-left origin and size. - * @see Screen + * @see #getPixelScale() + * @see Screen#getViewport() */ public final RectangleImmutable getViewport() { return viewportPU; } /** - * Returns the {@link RectangleImmutable rectangular} portion + * Returns the current {@link RectangleImmutable rectangular} portion * of the <b>rotated</b> virtual {@link Screen} size in window units * represented by this monitor, i.e. top-left origin and size. - * @see Screen + * @see #getPixelScale() + * @see Screen#getViewportInWindowUnits() */ public final RectangleImmutable getViewportInWindowUnits() { return viewportWU; } /** + * Returns the current <b>rotated</b> pixel-scale + * of this monitor, i.e. horizontal and vertical. + * @see #getViewportInWindowUnits() + * @see #getViewport() + * @see ScalableSurface#getMaximumSurfaceScale(float[]) + */ + public float[] getPixelScale(final float[] result) { + System.arraycopy(pixelScale, 0, result, 0, 2); + return result; + } + + /** * Returns <code>true</code> if given screen coordinates in pixel units * are contained by this {@link #getViewport() viewport}, otherwise <code>false</code>. * @param x x-coord in pixel units @@ -292,7 +323,8 @@ public abstract class MonitorDevice { @Override public String toString() { - return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, viewport "+viewportPU+ " [pixels], "+viewportWU+" [window], orig "+originalMode+", curr "+currentMode+ + return "Monitor[Id "+Display.toHexString(nativeId)+", "+sizeMM+" mm, pixelScale ["+pixelScale[0]+", "+pixelScale[1]+ + "], viewport "+viewportPU+ " [pixels], "+viewportWU+" [window], orig "+originalMode+", curr "+currentMode+ ", modeChanged "+modeChanged+", modeCount "+supportedModes.size()+"]"; } } diff --git a/src/newt/classes/com/jogamp/newt/Window.java b/src/newt/classes/com/jogamp/newt/Window.java index c4ca9a554..7b7937c98 100644 --- a/src/newt/classes/com/jogamp/newt/Window.java +++ b/src/newt/classes/com/jogamp/newt/Window.java @@ -273,7 +273,7 @@ public interface Window extends NativeWindow, WindowClosingProtocol, ScalableSur * 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} + * Method takes the {@link #getCurrentSurfaceScale(float[]) current surface-scale} and {@link #getMaximumSurfaceScale(float[]) native surface-scale} * into account, i.e.: * <pre> * surfacePpMM = monitorPpMM * currentSurfaceScale / nativeSurfaceScale, diff --git a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java index e890bc640..b469492c8 100644 --- a/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java +++ b/src/newt/classes/com/jogamp/newt/awt/NewtCanvasAWT.java @@ -474,6 +474,13 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } jawtWindow = NewtFactoryAWT.getNativeWindow(NewtCanvasAWT.this, null != newtChild ? newtChild.getRequestedCapabilities() : null); jawtWindow.setShallUseOffscreenLayer(shallUseOffscreenLayer); + // enforce initial lock on AWT-EDT, allowing acquisition of pixel-scale + jawtWindow.lockSurface(); + try { + // attachNewtChild sets surface scale! + } finally { + jawtWindow.unlockSurface(); + } awtWindowClosingProtocol.addClosingListener(); componentAdded = true; // Bug 910 if(DEBUG) { @@ -486,6 +493,25 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } } } + private final boolean updatePixelScale() { + if( jawtWindow.updatePixelScale(true) ) { + final Window cWin = newtChild; + final Window dWin = cWin.getDelegatedWindow(); + if( dWin instanceof WindowImpl ) { + final float[] maxPixelScale = jawtWindow.getMaximumSurfaceScale(new float[2]); + final float[] minPixelScale = jawtWindow.getMinimumSurfaceScale(new float[2]); + ((WindowImpl)dWin).pixelScaleChangeNotify(minPixelScale, maxPixelScale, true); + // ((WindowImpl)dWin).sizeChangedNotify(true /* defer */, getWidth(), getHeight(), true /* force */); + } else { + final float[] reqPixelScale = jawtWindow.getRequestedSurfaceScale(new float[2]); + if( jawtWindow.setSurfaceScale(reqPixelScale) ) { + // jawtWindow.getRequestedSurfaceScale(reqPixelScale); + } + } + return true; + } + return false; + } @Override public void removeNotify() { @@ -588,7 +614,11 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto System.err.println("NewtCanvasAWT.reshape: "+x+"/"+y+" "+width+"x"+height); } if( validateComponent(true) ) { - // newtChild.setSize(width, height); + if( !printActive && updatePixelScale() ) { + // NOP + } else { + // newtChild.setSize(width, height); + } } } } @@ -877,18 +907,12 @@ public class NewtCanvasAWT extends java.awt.Canvas implements WindowClosingProto } final int w = getWidth(); final int h = getHeight(); - final boolean isNValid = newtChild.isNativeValid(); if(DEBUG) { - System.err.println("NewtCanvasAWT.attachNewtChild.2: size "+w+"x"+h+", isNValid "+isNValid); + System.err.println("NewtCanvasAWT.attachNewtChild.2: size "+w+"x"+h+", isNValid "+newtChild.isNativeValid()); } newtChild.setVisible(false); newtChild.setSize(w, h); - final int[] reqSurfaceScale = new int[2]; - if( isNValid ) { - newtChild.getCurrentSurfaceScale(reqSurfaceScale); - } else { - newtChild.getRequestedSurfaceScale(reqSurfaceScale); - } + final float[] reqSurfaceScale = newtChild.getRequestedSurfaceScale(new float[2]); jawtWindow.setSurfaceScale(reqSurfaceScale); newtChild.reparentWindow(jawtWindow, -1, -1, Window.REPARENT_HINT_BECOMES_VISIBLE); newtChild.addSurfaceUpdatedListener(jawtWindow); diff --git a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java index 2ba030f76..0d286f25a 100644 --- a/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java +++ b/src/newt/classes/com/jogamp/newt/opengl/GLWindow.java @@ -401,23 +401,28 @@ public class GLWindow extends GLAutoDrawableBase implements GLAutoDrawable, Wind } @Override - public final void setSurfaceScale(final int[] pixelScale) { - window.setSurfaceScale(pixelScale); + public final boolean setSurfaceScale(final float[] pixelScale) { + return window.setSurfaceScale(pixelScale); } @Override - public final int[] getRequestedSurfaceScale(final int[] result) { + public final float[] getRequestedSurfaceScale(final float[] result) { return window.getRequestedSurfaceScale(result); } @Override - public final int[] getCurrentSurfaceScale(final int[] result) { + public final float[] getCurrentSurfaceScale(final float[] result) { return window.getCurrentSurfaceScale(result); } @Override - public final int[] getNativeSurfaceScale(final int[] result) { - return window.getNativeSurfaceScale(result); + public final float[] getMinimumSurfaceScale(final float[] result) { + return window.getMinimumSurfaceScale(result); + } + + @Override + public final float[] getMaximumSurfaceScale(final float[] result) { + return window.getMaximumSurfaceScale(result); } @Override diff --git a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java index 72300740f..f1bd445ab 100644 --- a/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java +++ b/src/newt/classes/jogamp/newt/MonitorDeviceImpl.java @@ -28,6 +28,7 @@ package jogamp.newt; +import javax.media.nativewindow.ScalableSurface; import javax.media.nativewindow.util.DimensionImmutable; import javax.media.nativewindow.util.Rectangle; @@ -38,8 +39,21 @@ import com.jogamp.newt.Screen; public class MonitorDeviceImpl extends MonitorDevice { - public MonitorDeviceImpl(final ScreenImpl screen, final int nativeId, final DimensionImmutable sizeMM, final Rectangle viewportPU, final Rectangle viewportWU, final MonitorMode currentMode, final ArrayHashSet<MonitorMode> supportedModes) { - super(screen, nativeId, sizeMM, viewportPU, viewportWU, currentMode, supportedModes); + /** + * @param screen associated {@link Screen} + * @param nativeId unique monitor device ID + * @param sizeMM size in millimeters + * @param currentMode + * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. + * @param viewportPU viewport in pixel-units + * @param viewportWU viewport in window-units + * @param supportedModes all supported {@link MonitorMode}s + */ + public MonitorDeviceImpl(final ScreenImpl screen, final int nativeId, final DimensionImmutable sizeMM, + final MonitorMode currentMode, + final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU, + final ArrayHashSet<MonitorMode> supportedModes) { + super(screen, nativeId, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); } @Override diff --git a/src/newt/classes/jogamp/newt/MonitorModeProps.java b/src/newt/classes/jogamp/newt/MonitorModeProps.java index 6e376ce48..6ed3b2382 100644 --- a/src/newt/classes/jogamp/newt/MonitorModeProps.java +++ b/src/newt/classes/jogamp/newt/MonitorModeProps.java @@ -33,6 +33,7 @@ import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.MonitorMode; import java.util.List; +import javax.media.nativewindow.ScalableSurface; import javax.media.nativewindow.util.Dimension; import javax.media.nativewindow.util.DimensionImmutable; import javax.media.nativewindow.util.Rectangle; @@ -256,14 +257,19 @@ public class MonitorModeProps { * <p> * Note: This variant only works for impl. w/ a unique mode key pair <i>modeId, rotation</i>. * </p> - * @param mode_idx if not null, returns the index of resulting {@link MonitorDevice} within {@link Cache#monitorDevices}. * @param cache hash arrays of unique {@link MonitorMode} components and {@link MonitorDevice}s, allowing to avoid duplicates - * @param modeProperties the input data + * @param screen the associated {@link ScreenImpl} + * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. + * @param monitorProperties the input data minus supported modes! * @param offset the offset to the input data + * @param monitor_idx if not null, returns the index of resulting {@link MonitorDevice} within {@link Cache#monitorDevices}. * @return {@link MonitorDevice} of the identical (old or new) element in {@link Cache#monitorDevices}, * matching the input <code>modeProperties</code>, or null if input could not be processed. */ - public static MonitorDevice streamInMonitorDevice(final int[] monitor_idx, final Cache cache, final ScreenImpl screen, final int[] monitorProperties, int offset) { + public static MonitorDevice streamInMonitorDevice(final Cache cache, final ScreenImpl screen, + final float[] pixelScale, + final int[] monitorProperties, int offset, + final int[] monitor_idx) { // min 11: count, id, ScreenSizeMM[width, height], Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+ final int count = monitorProperties[offset]; if(MIN_MONITOR_DEVICE_PROPERTIES > count) { @@ -298,7 +304,7 @@ public class MonitorModeProps { } } } - MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, viewportPU, viewportWU, currentMode, supportedModes); + MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); if(null!=cache) { monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice); } @@ -329,17 +335,23 @@ public class MonitorModeProps { * This variant expects <code>count</code> to be <code>{@link MIN_MONITOR_DEVICE_PROPERTIES} - 1 - {@link NUM_MONITOR_MODE_PROPERTIES}</code>, * due to lack of supported mode and current mode. * </p> - * - * @param mode_idx if not null, returns the index of resulting {@link MonitorDevice} within {@link Cache#monitorDevices}. * @param cache hash arrays of unique {@link MonitorMode} components and {@link MonitorDevice}s, allowing to avoid duplicates - * @param supportedModes pre-assembled list of supported {@link MonitorMode}s from cache. + * @param screen the associated {@link ScreenImpl} * @param currentMode pre-fetched current {@link MonitorMode}s from cache. - * @param modeProperties the input data minus supported modes! + * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. + * @param supportedModes pre-assembled list of supported {@link MonitorMode}s from cache. + * @param monitorProperties the input data minus supported modes! * @param offset the offset to the input data + * @param monitor_idx if not null, returns the index of resulting {@link MonitorDevice} within {@link Cache#monitorDevices}. * @return {@link MonitorDevice} of the identical (old or new) element in {@link Cache#monitorDevices}, * matching the input <code>modeProperties</code>, or null if input could not be processed. */ - public static MonitorDevice streamInMonitorDevice(final int[] monitor_idx, final Cache cache, final ScreenImpl screen, final ArrayHashSet<MonitorMode> supportedModes, final MonitorMode currentMode, final int[] monitorProperties, int offset) { + public static MonitorDevice streamInMonitorDevice(final Cache cache, final ScreenImpl screen, + final MonitorMode currentMode, + final float[] pixelScale, + final ArrayHashSet<MonitorMode> supportedModes, + final int[] monitorProperties, int offset, + final int[] monitor_idx) { // min 11: count, id, ScreenSizeMM[width, height], Viewport[x, y, width, height], currentMonitorModeId, rotation, supportedModeId+ final int count = monitorProperties[offset]; if(MIN_MONITOR_DEVICE_PROPERTIES - 1 - NUM_MONITOR_MODE_PROPERTIES != count) { @@ -356,7 +368,7 @@ public class MonitorModeProps { final DimensionImmutable sizeMM = streamInResolution(monitorProperties, offset); offset+=NUM_RESOLUTION_PROPERTIES; final Rectangle viewportPU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); final Rectangle viewportWU = new Rectangle(monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++], monitorProperties[offset++]); - MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, viewportPU, viewportWU, currentMode, supportedModes); + MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, id, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); if(null!=cache) { monitorDevice = cache.monitorDevices.getOrAdd(monitorDevice); } diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index e73e153ad..c57f84528 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -364,8 +364,8 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { * <li>{@link MonitorModeProps#MIN_MONITOR_DEVICE_PROPERTIES}</li> * </ul>, i.e. * <ul> - * <li>{@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, ScreenImpl, int[], int)}</li> - * <li>{@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, ScreenImpl, ArrayHashSet, int[], int)}</li> + * <li>{@link MonitorModeProps#streamInMonitorDevice(jogamp.newt.MonitorModeProps.Cache, ScreenImpl, double[], int[], int, int[])}</li> + * <li>{@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, ArrayHashSet, int[], int, ScreenImpl)}</li> * <li>{@link MonitorModeProps#streamInMonitorMode(int[], jogamp.newt.MonitorModeProps.Cache, int[], int)}</li> * </ul> * @param cache memory pool caching the result @@ -373,6 +373,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { protected abstract void collectNativeMonitorModesAndDevicesImpl(MonitorModeProps.Cache cache); protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, + final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU) { return false; } @@ -428,9 +429,14 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { final List<MonitorDevice> monitors = getMonitorDevices(); for(int i=monitors.size()-1; i>=0; i--) { final MonitorDeviceImpl monitor = (MonitorDeviceImpl) monitors.get(i); - final boolean viewportUpdated = updateNativeMonitorDeviceViewportImpl(monitor, monitor.getMutuableViewportPU(), monitor.getMutuableViewportWU()); + final float[] pixelScale = monitor.getPixelScale(new float[2]); + final boolean viewportUpdated = updateNativeMonitorDeviceViewportImpl(monitor, pixelScale, + monitor.getMutuableViewportPU(), + monitor.getMutuableViewportWU()); if( DEBUG ) { - System.err.println("Screen.updateMonitorViewport["+i+"] @ "+Thread.currentThread().getName()+": updated: "+viewportUpdated+", PU "+monitor.getViewport()+", WU "+monitor.getViewportInWindowUnits()); + System.err.println("Screen.updateMonitorViewport["+i+"] @ "+Thread.currentThread().getName()+": updated: "+viewportUpdated+ + ", PU "+monitor.getViewport()+", WU "+monitor.getViewportInWindowUnits()+ + ", pixelScale ["+pixelScale[0]+", "+pixelScale[1]+"]"); } } } @@ -510,7 +516,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { if( MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES != i ) { throw new InternalError("XX"); } - return MonitorModeProps.streamInMonitorDevice(null, cache, this, props, 0); + return MonitorModeProps.streamInMonitorDevice(cache, this, null, props, 0, null); } /** diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index 0c4dcd192..2230acd67 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -154,9 +154,10 @@ 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 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 }; + protected final float[] minPixelScale = new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + protected final float[] maxPixelScale = new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + protected final float[] hasPixelScale = new float[] { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + protected final float[] reqPixelScale = new float[] { 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) @@ -1087,8 +1088,8 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } @Override public final void setSurfaceSize(final int pixelWidth, final int pixelHeight) { - // FIXME HiDPI: Shortcut, may need to adjust if we change scaling methodology - setSize(pixelWidth / getPixelScaleX(), pixelHeight / getPixelScaleY()); + setSize( SurfaceScaleUtils.scaleInv(pixelWidth, getPixelScaleX()), + SurfaceScaleUtils.scaleInv(pixelHeight, getPixelScaleY()) ); } @Override public final void setTopLevelSize(final int width, final int height) { @@ -1181,8 +1182,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer parentWindowHandle = 0; hasPixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE; hasPixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE; - nativePixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE; - nativePixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE; + minPixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE; + minPixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE; + maxPixelScale[0] = ScalableSurface.IDENTITY_PIXELSCALE; + maxPixelScale[1] = ScalableSurface.IDENTITY_PIXELSCALE; _lock.unlock(); } @@ -1926,16 +1929,12 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer @Override public final int[] convertToWindowUnits(final int[] pixelUnitsAndResult) { - pixelUnitsAndResult[0] /= getPixelScaleX(); - pixelUnitsAndResult[1] /= getPixelScaleY(); - return pixelUnitsAndResult; + return SurfaceScaleUtils.scaleInv(pixelUnitsAndResult, pixelUnitsAndResult, hasPixelScale); } @Override public final int[] convertToPixelUnits(final int[] windowUnitsAndResult) { - windowUnitsAndResult[0] *= getPixelScaleX(); - windowUnitsAndResult[1] *= getPixelScaleY(); - return windowUnitsAndResult; + return SurfaceScaleUtils.scale(windowUnitsAndResult, windowUnitsAndResult, hasPixelScale); } protected final Point convertToWindowUnits(final Point pixelUnitsAndResult) { @@ -1947,43 +1946,50 @@ 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 final int getPixelScaleX() { + protected final float getPixelScaleX() { return hasPixelScale[0]; } /** HiDPI: We currently base scaling of window units to pixel units on an integer scale factor per component. */ - protected final int getPixelScaleY() { + protected final float getPixelScaleY() { return hasPixelScale[1]; } @Override - public void setSurfaceScale(final int[] pixelScale) { - SurfaceScaleUtils.validateReqPixelScale(reqPixelScale, pixelScale, DEBUG_IMPLEMENTATION ? getClass().getSimpleName() : null); + public boolean setSurfaceScale(final float[] pixelScale) { + System.arraycopy(pixelScale, 0, reqPixelScale, 0, 2); + return false; } @Override - public final int[] getRequestedSurfaceScale(final int[] result) { + public final float[] getRequestedSurfaceScale(final float[] result) { System.arraycopy(reqPixelScale, 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) { - System.arraycopy(nativePixelScale, 0, result, 0, 2); + public final float[] getMinimumSurfaceScale(final float[] result) { + System.arraycopy(minPixelScale, 0, result, 0, 2); + return result; + } + + @Override + public final float[] getMaximumSurfaceScale(final float[] result) { + System.arraycopy(maxPixelScale, 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]; + ppmmStore[0] *= hasPixelScale[0] / maxPixelScale[0]; + ppmmStore[1] *= hasPixelScale[1] / maxPixelScale[1]; return ppmmStore; } @@ -2004,8 +2010,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer * and {@link #pixWidth} and {@link #pixHeight} in pixel units according to {@link #convertToPixelUnits(int[])}. */ protected final void defineSize(final int winWidth, final int winHeight) { - final int pixWidth = winWidth * getPixelScaleX(); // FIXME HiDPI: Shortcut, may need to adjust if we change scaling methodology - final int pixHeight = winHeight * getPixelScaleY(); + final int pixWidth = SurfaceScaleUtils.scale(winWidth, getPixelScaleX()); // FIXME HiDPI: Shortcut, may need to adjust if we change scaling methodology + final int pixHeight = SurfaceScaleUtils.scale(winHeight, getPixelScaleY()); + if(DEBUG_IMPLEMENTATION) { System.err.println("defineSize: win["+this.winWidth+"x"+this.winHeight+" -> "+winWidth+"x"+winHeight+ "], pixel["+this.pixWidth+"x"+this.pixHeight+" -> "+pixWidth+"x"+pixHeight+"]"); @@ -2631,13 +2638,13 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // special repaint treatment case WindowEvent.EVENT_WINDOW_REPAINT: // queue repaint event in case window is locked, ie in operation - if( null != windowLock.getOwner() ) { + if( windowLock.isLockedByOtherThread() ) { // make sure only one repaint event is queued if(!repaintQueued) { repaintQueued=true; final boolean discardTO = QUEUED_EVENT_TO <= System.currentTimeMillis()-e.getWhen(); if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.consumeEvent: REPAINT "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO); + System.err.println("Window.consumeEvent: REPAINT [me "+Thread.currentThread().getName()+", owner "+windowLock.getOwner()+"] - queued "+e+", discard-to "+discardTO); // ExceptionUtils.dumpStackTrace(System.err); } return discardTO; // discardTO:=true -> consumed @@ -2650,10 +2657,10 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer // common treatment case WindowEvent.EVENT_WINDOW_RESIZED: // queue event in case window is locked, ie in operation - if( null != windowLock.getOwner() ) { + if( windowLock.isLockedByOtherThread() ) { final boolean discardTO = QUEUED_EVENT_TO <= System.currentTimeMillis()-e.getWhen(); if(DEBUG_IMPLEMENTATION) { - System.err.println("Window.consumeEvent: RESIZED "+Thread.currentThread().getName()+" - queued "+e+", discard-to "+discardTO); + System.err.println("Window.consumeEvent: RESIZED [me "+Thread.currentThread().getName()+", owner "+windowLock.getOwner()+"] - queued "+e+", discard-to "+discardTO); // ExceptionUtils.dumpStackTrace(System.err); } return discardTO; // discardTO:=true -> consumed @@ -3756,6 +3763,21 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer } } + /** + * Notify to update the pixel-scale values. + * @param minPixelScale + * @param maxPixelScale + * @param reset if {@code true} {@link #setSurfaceScale(float[]) reset pixel-scale} w/ {@link #getRequestedSurfaceScale(float[]) requested values} + * value to reflect the new minimum and maximum values. + */ + public final void pixelScaleChangeNotify(final float[] minPixelScale, final float[] maxPixelScale, final boolean reset) { + System.arraycopy(minPixelScale, 0, this.minPixelScale, 0, 2); + System.arraycopy(maxPixelScale, 0, this.maxPixelScale, 0, 2); + if( reset ) { + setSurfaceScale(reqPixelScale); + } + } + /** Triggered by implementation's WM events to update the client-area size in window units w/o insets/decorations. */ protected void sizeChanged(final boolean defer, final int newWidth, final int newHeight, final boolean force) { if(force || getWidth() != newWidth || getHeight() != newHeight) { diff --git a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java index b28cdcbed..59688cd8d 100644 --- a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java @@ -113,7 +113,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { props[i++] = 0; // rotated viewport y window-units props[i++] = outMetrics.widthPixels; // rotated viewport width window-units props[i++] = outMetrics.heightPixels; // rotated viewport height window-units - MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0); + MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, cache.monitorModes, props, 0, null); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java index eccdd63cf..76ae26764 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java +++ b/src/newt/classes/jogamp/newt/driver/awt/AWTCanvas.java @@ -69,8 +69,8 @@ public class AWTCanvas extends Canvas { private final UpstreamScalable upstreamScale; public static interface UpstreamScalable { - int[] getReqPixelScale(); - void setHasPixelScale(final int[] pixelScale); + float[] getReqPixelScale(); + void setHasPixelScale(final float[] pixelScale); } private boolean displayConfigChanged=false; @@ -148,7 +148,7 @@ public class AWTCanvas extends Canvas { // trigger initialization cycle jawtWindow.setSurfaceScale(upstreamScale.getReqPixelScale() ); jawtWindow.lockSurface(); - upstreamScale.setHasPixelScale(jawtWindow.getCurrentSurfaceScale(new int[2])); + upstreamScale.setHasPixelScale(jawtWindow.getCurrentSurfaceScale(new float[2])); jawtWindow.unlockSurface(); } diff --git a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java index 57948cfc3..eb92e0d13 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java @@ -119,7 +119,7 @@ public class ScreenDriver extends ScreenImpl { props[i++] = 0; // rotated viewport y window-units props[i++] = currentMode.getRotatedWidth(); // rotated viewport width window-units props[i++] = currentMode.getRotatedHeight(); // rotated viewport height window-units - MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0); + MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, cache.monitorModes, props, 0, null); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java index 06dcb8ff5..2ccc8d763 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/WindowDriver.java @@ -100,12 +100,12 @@ public class WindowDriver extends WindowImpl { private final AWTCanvas.UpstreamScalable upstreamScalable = new AWTCanvas.UpstreamScalable() { @Override - public int[] getReqPixelScale() { + public float[] getReqPixelScale() { return WindowDriver.this.reqPixelScale; } @Override - public void setHasPixelScale(final int[] pixelScale) { + public void setHasPixelScale(final float[] pixelScale) { System.arraycopy(pixelScale, 0, WindowDriver.this.hasPixelScale, 0, 2); } }; diff --git a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java index 2cd47313a..f3ac3e851 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java @@ -94,7 +94,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { props[i++] = 0; // rotated viewport y window-units props[i++] = fixedWidth; // FIXME rotated viewport width window-units props[i++] = fixedHeight; // FIXME rotated viewport height window-units - MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0); + MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, cache.monitorModes, props, 0, null); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java index 64cae75f6..bc1c19fe4 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/vc/iv/ScreenDriver.java @@ -87,7 +87,7 @@ public class ScreenDriver extends ScreenImpl { props[i++] = 0; // rotated viewport y window-units props[i++] = cachedWidth; // rotated viewport width window-units props[i++] = cachedWidth; // rotated viewport height window-units - MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0); + MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, cache.monitorModes, props, 0, null); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java index 2ce835c52..36a95dca4 100644 --- a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java @@ -96,7 +96,7 @@ public class ScreenDriver extends jogamp.newt.ScreenImpl { props[i++] = 0; // rotated viewport y window-units props[i++] = cachedWidth; // rotated viewport width window-units props[i++] = cachedWidth; // rotated viewport height window-units - MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0); + MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, cache.monitorModes, props, 0, null); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java index d4113561a..42659b14e 100644 --- a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java @@ -92,7 +92,7 @@ public class ScreenDriver extends ScreenImpl { props[i++] = 0; // rotated viewport y window-units props[i++] = cachedWidth; // rotated viewport width window-units props[i++] = cachedWidth; // rotated viewport height window-units - MonitorModeProps.streamInMonitorDevice(null, cache, this, cache.monitorModes, currentMode, props, 0); + MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, cache.monitorModes, props, 0, null); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java index 5f458e2c9..7c4fa569a 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java @@ -77,7 +77,7 @@ public class ScreenDriver extends ScreenImpl { private class CrtProps { CrtProps() { count = getMonitorCount0(); - pixelScaleArray = new int[count]; + pixelScaleArray = new float[count]; propsOrigArray = new int[count][]; propsFixedArray = new int[count][]; @@ -85,8 +85,8 @@ public class ScreenDriver extends ScreenImpl { // Gather whole topology of monitors (NSScreens) // for(int crtIdx=0; crtIdx<count; crtIdx++) { - final float pixelScaleRaw = (float) OSXUtil.GetPixelScale(crtIdx); - pixelScaleArray[crtIdx] = FloatUtil.isZero(pixelScaleRaw, FloatUtil.EPSILON) ? 1 : (int)pixelScaleRaw; + final float pixelScaleRaw = (float)OSXUtil.GetPixelScaleByScreenIdx(crtIdx); + pixelScaleArray[crtIdx] = FloatUtil.isZero(pixelScaleRaw, FloatUtil.EPSILON) ? 1.0f : pixelScaleRaw; propsOrigArray[crtIdx] = getMonitorProps0(crtIdx); if ( null == propsOrigArray[crtIdx] ) { throw new InternalError("Could not gather device props "+crtIdx+"/"+count); @@ -105,7 +105,7 @@ public class ScreenDriver extends ScreenImpl { final int[] thisMonitorProps = propsFixedArray[crtIdx]; final int x = thisMonitorProps[MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+0]; final int y = thisMonitorProps[MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+1]; - final int thisPixelScale = pixelScaleArray[crtIdx]; + final float thisPixelScale = pixelScaleArray[crtIdx]; thisMonitorProps[MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+2] *= thisPixelScale; // fix width thisMonitorProps[MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT+3] *= thisPixelScale; // fix height if( 0 != x ) { @@ -129,7 +129,7 @@ public class ScreenDriver extends ScreenImpl { } } final int count; - final int[] pixelScaleArray; + final float[] pixelScaleArray; final int[][] propsOrigArray; final int[][] propsFixedArray; } @@ -167,12 +167,15 @@ public class ScreenDriver extends ScreenImpl { throw new InternalError("Could not gather current mode of device "+crtIdx+"/"+crtProps.count+", but gathered "+modeIdx+" modes"); } // merge monitor-props + supported modes - MonitorModeProps.streamInMonitorDevice(null, cache, this, supportedModes, currentMode, crtProps.propsFixedArray[crtIdx], 0); + final float pixelScale = crtProps.pixelScaleArray[crtIdx]; + MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, + new float[] { pixelScale, pixelScale }, + supportedModes, crtProps.propsFixedArray[crtIdx], 0, null); } } @Override - protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final Rectangle viewportPU, final Rectangle viewportWU) { + protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU) { final CrtProps crtProps = new CrtProps(); final int crtIdx = monitor.getId(); if( 0 > crtIdx || crtIdx >= crtProps.count ) { @@ -182,6 +185,9 @@ public class ScreenDriver extends ScreenImpl { int offset = MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT; viewportPU.set(fixedMonitorProps[offset++], fixedMonitorProps[offset++], fixedMonitorProps[offset++], fixedMonitorProps[offset++]); viewportWU.set(fixedMonitorProps[offset++], fixedMonitorProps[offset++], fixedMonitorProps[offset++], fixedMonitorProps[offset++]); + final float _pixelScale = crtProps.pixelScaleArray[crtIdx]; + pixelScale[0] = _pixelScale; + pixelScale[1] = _pixelScale; return true; } diff --git a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java index c0f7d3859..a57bb5ac6 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/WindowDriver.java @@ -67,20 +67,26 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl public WindowDriver() { } - private boolean updatePixelScale(final boolean sendEvent, final boolean defer, final float newPixelScaleRaw, final float nativePixelScaleRaw) { - final int[] newPixelScale = new int[2]; + private boolean updatePixelScale(final boolean sendEvent, final boolean defer, final boolean deferOffThread, + final float newPixelScaleRaw, final float maxPixelScaleRaw) { + final float[] newPixelScale = new float[2]; { - final int _newPixelScale = FloatUtil.isZero(newPixelScaleRaw, FloatUtil.EPSILON) ? ScalableSurface.IDENTITY_PIXELSCALE : (int) newPixelScaleRaw; + final float _newPixelScale = FloatUtil.isZero(newPixelScaleRaw, FloatUtil.EPSILON) ? ScalableSurface.IDENTITY_PIXELSCALE : 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; + final float _maxPixelScale = FloatUtil.isZero(maxPixelScaleRaw, FloatUtil.EPSILON) ? ScalableSurface.IDENTITY_PIXELSCALE : maxPixelScaleRaw; + maxPixelScale[0]= _maxPixelScale; + maxPixelScale[1]= _maxPixelScale; } + // We keep minPixelScale at [1f, 1f]! - if( SurfaceScaleUtils.computePixelScale(hasPixelScale, hasPixelScale, reqPixelScale, newPixelScale, DEBUG_IMPLEMENTATION ? getClass().getName() : null) ) { + if( SurfaceScaleUtils.setNewPixelScale(hasPixelScale, hasPixelScale, newPixelScale, minPixelScale, maxPixelScale, DEBUG_IMPLEMENTATION ? getClass().getName() : null) ) { if( sendEvent ) { - super.sizeChanged(defer, getWidth(), getHeight(), true); + if( deferOffThread ) { + superSizeChangedOffThread(defer, getWidth(), getHeight(), true); + } else { + super.sizeChanged(defer, getWidth(), getHeight(), true); + } } else { defineSize(getWidth(), getHeight()); } @@ -91,34 +97,34 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl } private boolean updatePixelScaleByScreenIdx(final boolean sendEvent) { - final float nativePixelScaleRaw = (float) OSXUtil.GetPixelScale(getScreen().getIndex()); + final float maxPixelScaleRaw = (float) OSXUtil.GetPixelScaleByScreenIdx(getScreen().getIndex()); if( DEBUG_IMPLEMENTATION ) { - System.err.println("WindowDriver.updatePixelScale.1: "+hasPixelScale[0]+", "+nativePixelScaleRaw+" (native)"); + System.err.println("WindowDriver.updatePixelScale.1: "+hasPixelScale[0]+", "+maxPixelScaleRaw+" (max)"); } - return updatePixelScale(sendEvent, true /* defer */, nativePixelScaleRaw, nativePixelScaleRaw); + return updatePixelScale(sendEvent, true /* defer */, false /*offthread */, maxPixelScaleRaw, maxPixelScaleRaw); } private boolean updatePixelScaleByWindowHandle(final boolean sendEvent) { final long handle = getWindowHandle(); if( 0 != handle ) { - final float nativePixelScaleRaw = (float)OSXUtil.GetPixelScale(handle); + final float maxPixelScaleRaw = (float)OSXUtil.GetPixelScale(handle); if( DEBUG_IMPLEMENTATION ) { - System.err.println("WindowDriver.updatePixelScale.2: "+hasPixelScale[0]+", "+nativePixelScaleRaw+" (native)"); + System.err.println("WindowDriver.updatePixelScale.2: "+hasPixelScale[0]+", "+maxPixelScaleRaw+" (max)"); } - return updatePixelScale(sendEvent, true /* defer */, nativePixelScaleRaw, nativePixelScaleRaw); + return updatePixelScale(sendEvent, true /* defer */, false /*offthread */, maxPixelScaleRaw, maxPixelScaleRaw); } else { return false; } } /** Called from native code */ - protected void updatePixelScale(final boolean defer, final float newPixelScaleRaw, final float nativePixelScaleRaw) { + protected void updatePixelScale(final boolean defer, final float newPixelScaleRaw, final float maxPixelScaleRaw) { final long handle = getWindowHandle(); if( DEBUG_IMPLEMENTATION ) { - System.err.println("WindowDriver.updatePixelScale.3: "+hasPixelScale[0]+" (has) -> "+newPixelScaleRaw+" (raw), "+nativePixelScaleRaw+" (native), drop "+(0==handle)); + System.err.println("WindowDriver.updatePixelScale.3: "+hasPixelScale[0]+" (has) -> "+newPixelScaleRaw+" (new), "+maxPixelScaleRaw+" (max), drop "+(0==handle)); } if( 0 != handle ) { - updatePixelScale(true /* sendEvent*/, defer, newPixelScaleRaw, nativePixelScaleRaw); + updatePixelScale(true /* sendEvent*/, defer, true /*offthread */, newPixelScaleRaw, maxPixelScaleRaw); } } @@ -139,44 +145,47 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl } @Override - public final void setSurfaceScale(final int[] pixelScale) { - SurfaceScaleUtils.validateReqPixelScale(reqPixelScale, pixelScale, DEBUG_IMPLEMENTATION ? getClass().getName() : null); + public final boolean setSurfaceScale(final float[] pixelScale) { + super.setSurfaceScale(pixelScale); - final int[] resPixelScale; + boolean changed = false; if( isNativeValid() ) { if( isOffscreenInstance ) { final NativeWindow pWin = getParent(); if( pWin instanceof ScalableSurface ) { final ScalableSurface sSurf = (ScalableSurface)pWin; sSurf.setSurfaceScale(reqPixelScale); - final int[] pPixelScale = sSurf.getCurrentSurfaceScale(new int[2]); - sSurf.getNativeSurfaceScale(nativePixelScale); - updatePixelScale(true /* sendEvent */, true /* defer */, pPixelScale[0], nativePixelScale[0]); // HiDPI: uniformPixelScale + sSurf.getMaximumSurfaceScale(maxPixelScale); + sSurf.getMinimumSurfaceScale(minPixelScale); + final float[] pPixelScale = sSurf.getCurrentSurfaceScale(new float[2]); + changed = updatePixelScale(true /* sendEvent */, true /* defer */, true /*offthread */, pPixelScale[0], maxPixelScale[0]); // HiDPI: uniformPixelScale } else { // just notify updated pixelScale if offscreen - SurfaceScaleUtils.replaceAutoMaxWithPlatformMax(reqPixelScale); - updatePixelScale(true /* sendEvent */, true /* defer */, reqPixelScale[0], nativePixelScale[0]); // HiDPI: uniformPixelScale + changed = updatePixelScale(true /* sendEvent */, true /* defer */, true /*offthread */, reqPixelScale[0], maxPixelScale[0]); // HiDPI: uniformPixelScale } } else { - // set pixelScale in native code, will issue an update PixelScale - OSXUtil.RunOnMainThread(true, false, new Runnable() { - @Override - public void run() { - setPixelScale0(getWindowHandle(), surfaceHandle, reqPixelScale[0]); // HiDPI: uniformPixelScale - } - } ); + // set pixelScale in native code, will issue an update updatePixelScale(..) + // hence we pre-query whether pixel-scale will change, without affecting current state 'hasPixelScale'! + final float[] _hasPixelScale = new float[2]; + System.arraycopy(hasPixelScale, 0, _hasPixelScale, 0, 2); + if( SurfaceScaleUtils.setNewPixelScale(_hasPixelScale, _hasPixelScale, reqPixelScale, minPixelScale, maxPixelScale, DEBUG_IMPLEMENTATION ? getClass().getName() : null) ) { + OSXUtil.RunOnMainThread(true, false, new Runnable() { + @Override + public void run() { + setPixelScale0(getWindowHandle(), surfaceHandle, _hasPixelScale[0]); // HiDPI: uniformPixelScale + } + } ); + changed = true; + } } - 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()); + System.err.println("WindowDriver.setPixelScale: min["+minPixelScale[0]+", "+minPixelScale[1]+"], max["+ + maxPixelScale[0]+", "+maxPixelScale[1]+"], req["+ + reqPixelScale[0]+", "+reqPixelScale[1]+"] -> result["+ + hasPixelScale[0]+", "+hasPixelScale[1]+"] - changed "+changed+", realized "+isNativeValid()); } + return changed; } @Override @@ -360,13 +369,23 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl System.err.println("MacWindow: sizeChanged() parent["+useParent+" "+x+"/"+y+"] "+getX()+"/"+getY()+" "+newWidth+"x"+newHeight+" -> "+p0S+" screen-client-pos"); } OSXUtil.RunOnMainThread(false, false, new Runnable() { - @Override - public void run() { - setWindowClientTopLeftPoint0(getWindowHandle(), p0S.getX(), p0S.getY(), isVisible()); - } } ); + @Override + public void run() { + setWindowClientTopLeftPoint0(getWindowHandle(), p0S.getX(), p0S.getY(), isVisible()); + } } ); } } - super.sizeChanged(defer, newWidth, newHeight, force); + superSizeChangedOffThread(defer, newWidth, newHeight, force); + } + private void superSizeChangedOffThread(final boolean defer, final int newWidth, final int newHeight, final boolean force) { + if( defer ) { + new Thread() { + public void run() { + WindowDriver.super.sizeChanged(false /* defer */, newWidth, newHeight, force); + } }.start(); + } else { + WindowDriver.super.sizeChanged(false /* defer */, newWidth, newHeight, force); + } } @Override @@ -556,14 +575,18 @@ public class WindowDriver extends WindowImpl implements MutableSurface, DriverCl @Override protected void warpPointerImpl(final int x, final int y) { if( !isOffscreenInstance ) { - warpPointer0(getWindowHandle(), x / getPixelScaleX(), y / getPixelScaleY()); + warpPointer0(getWindowHandle(), + SurfaceScaleUtils.scaleInv(x, getPixelScaleX()), + SurfaceScaleUtils.scaleInv(y, getPixelScaleY())); } // else may need offscreen solution ? FIXME } @Override protected final void doMouseEvent(final boolean enqueue, final boolean wait, final short eventType, final int modifiers, final int x, final int y, final short button, final float[] rotationXYZ, final float rotationScale) { - super.doMouseEvent(enqueue, wait, eventType, modifiers, x * getPixelScaleX(), y * getPixelScaleY(), button, rotationXYZ, rotationScale); + super.doMouseEvent(enqueue, wait, eventType, modifiers, + SurfaceScaleUtils.scale(x, getPixelScaleX()), + SurfaceScaleUtils.scale(y, getPixelScaleY()), button, rotationXYZ, rotationScale); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java index 38acd03ae..79ba623f8 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java @@ -106,7 +106,7 @@ public class ScreenDriver extends ScreenImpl { if ( null != currentMode ) { // enabled final int[] monitorProps = getMonitorDevice0(adapterName, crtIdx); // merge monitor-props + supported modes - MonitorModeProps.streamInMonitorDevice(null, cache, this, supportedModes, currentMode, monitorProps, 0); + MonitorModeProps.streamInMonitorDevice(cache, this, currentMode, null, supportedModes, monitorProps, 0, null); // next monitor, 1st mode supportedModes= new ArrayHashSet<MonitorMode>(); @@ -118,7 +118,7 @@ public class ScreenDriver extends ScreenImpl { } @Override - protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final Rectangle viewportPU, final Rectangle viewportWU) { + protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU) { final String adapterName = getAdapterName(monitor.getId()); if( null != adapterName ) { final String activeMonitorName = getActiveMonitorName(adapterName, 0); diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java index f7361740e..1ec91dce2 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java @@ -152,7 +152,7 @@ public class ScreenDriver extends ScreenImpl { if( null != monitorProps && MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES <= monitorProps[0] && // Enabled ? I.e. contains active modes ? MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES <= monitorProps.length ) { - MonitorModeProps.streamInMonitorDevice(null, cache, this, monitorProps, 0); + MonitorModeProps.streamInMonitorDevice(cache, this, null, monitorProps, 0, null); } } } @@ -166,7 +166,7 @@ public class ScreenDriver extends ScreenImpl { } @Override - protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final Rectangle viewportPU, final Rectangle viewportWU) { + protected boolean updateNativeMonitorDeviceViewportImpl(final MonitorDevice monitor, final float[] pixelScale, final Rectangle viewportPU, final Rectangle viewportWU) { final AbstractGraphicsDevice device = getDisplay().getGraphicsDevice(); device.lock(); try { |