diff options
author | Sven Gothel <[email protected]> | 2023-01-31 07:35:58 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2023-01-31 07:35:58 +0100 |
commit | 97b79ad351e48e7d3c6f9c95bacdf4f9d5d158ef (patch) | |
tree | 0945989bcd6ffbe87f295f422002b3055a1e082d | |
parent | 6eb13066996e94b2fe40bf64e74ea43d8f4e9171 (diff) |
NEWT Soft-PixelScale (p6): Implement Soft-PixelScale for X11 and Windows ... (working state)
Both:
- Using Soft-PixelScale mode, i.e. converting all given window-units to pixel-units for native GDI/X11 ops
- Using scaled pixel-sized surface
- Adjusting NEWT's Monitor's window-unit viewport value to pixel-scale
For X11:
- Using global scale factor from environment variable, either: "GDK_SCALE", "QT_SCALE_FACTOR" or "SOFT_SCALE".
The latter is for testing only.
See https://wiki.archlinux.org/title/HiDPI
For Windows:
- Using actual monitor's pixel-scale via native SHC API (Shellscaling API, shcore.dll)
Misc:
- SurfaceScaleUtils.getGlobalPixelScaleEnv() reads a float value from given env names, first come, first serve
- MonitorModeProps.streamInMonitorDevice(..): Add `invscale_wuviewport` argument to scale wuvieport for soft-pixel-scale
- TestGearsNEWT: Enhance GL2 demo to be suitable for manual tests, this since my Windows KVM machine doesn't support ES2
- TestGLContextDrawableSwitch10NEWT: Add a few more test constraints .. working
Tested:
- Manually on a Windows virtual machine (KVM) using
- 2 virtualized 'Video QXL' cards and
- and 'remote-viewer' to see the 2 monitors
since `Virtual Machine Manager` build-in doesn't support
- remote-viewer spice://localhost:5917
- Manually on a Linux machine w/ SOFT_SCALE
- Both, X11 and Windows
- Place window on each monitor
- Move window across monitors w/ pixel-scale change (or not)
- TODO: Test and fix utilization with AWT, i.e. NewtCanvasAWT
23 files changed, 373 insertions, 65 deletions
diff --git a/make/scripts/tests-win.bat b/make/scripts/tests-win.bat index a03c40cc5..7e37a1e94 100755 --- a/make/scripts/tests-win.bat +++ b/make/scripts/tests-win.bat @@ -5,7 +5,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.acore.TestMainVersion REM scripts\java-win.bat com.jogamp.oculusvr.OVRVersion %* REM REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNewtAWTWrapper %* -REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT -time 30000 +scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es1.newt.TestGearsES1NEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.jogl.demos.es2.newt.TestGearsES2NEWT -vsync -time 4000 -x 10 -y 10 -width 100 -height 100 -screen 0 @@ -188,7 +188,7 @@ REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02aN REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.TestScreenMode02bNEWT %* REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.mm.ManualScreenMode03sNEWT %* -scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT +REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT REM scripts\java-win.bat com.jogamp.opengl.test.junit.newt.TestCloseNewtAWT REM scripts\java-win.bat testawt com.jogamp.opengl.test.junit.jogl.caps.TestMultisampleES1AWT %* diff --git a/make/scripts/tests-x64-dbg.bat b/make/scripts/tests-x64-dbg.bat index 4e19bddd8..827453871 100755 --- a/make/scripts/tests-x64-dbg.bat +++ b/make/scripts/tests-x64-dbg.bat @@ -72,7 +72,7 @@ REM set D_ARGS="-Djogl.debug.GLContext" "-Djogl.debug.GLJPanel" REM set D_ARGS="-Djogl.gljpanel.noverticalflip"
REM set D_ARGS="-Dnewt.debug=all"
REM set D_ARGS="-Dnewt.debug.Window"
-set D_ARGS="-Dnativewindow.debug.SWT" "-Dnewt.debug.Window" "-Djogl.debug.GLCanvas"
+REM set D_ARGS="-Dnativewindow.debug.SWT" "-Dnewt.debug.Window" "-Djogl.debug.GLCanvas"
REM set D_ARGS="-Dnativewindow.debug.JFX" "-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window.KeyEvent"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Window.KeyEvent" "-Dnewt.debug.EDT"
@@ -88,7 +88,7 @@ REM set D_ARGS="-Dnewt.debug.Display" "-Dnewt.debug.EDT" "-Dnewt.debug.Window" REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.debug.EDT" "-Djogl.debug.GLContext"
REM set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.EDT" "-Dnativewindow.debug=all"
REM set D_ARGS="-Dnewt.debug.Screen"
-REM set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.Window"
+set D_ARGS="-Dnewt.debug.Screen" "-Dnewt.debug.Window"
REM set D_ARGS="-Dnewt.debug.Window" "-Dnewt.debug.Display" "-Dnewt.test.Window.reparent.incompatible=true"
REM set D_ARGS="-Djogamp.debug.ReflectionUtil" "-Djogamp.debug.ReflectionUtil.forNameStats"
diff --git a/make/scripts/tests.sh b/make/scripts/tests.sh index d5f7a5a66..dfa9bbec2 100644 --- a/make/scripts/tests.sh +++ b/make/scripts/tests.sh @@ -70,7 +70,7 @@ fi #export LIBGL_DEBUG=verbose #export MESA_DEBUG=true -#export LIBGL_ALWAYS_SOFTWARE=true +export LIBGL_ALWAYS_SOFTWARE=true #export INTEL_DEBUG="buf bat" #export INTEL_STRICT_CONFORMANCE=1 @@ -242,7 +242,7 @@ function jrun() { #D_ARGS="-Djogl.1thread=true -Djogl.debug.Threading" #D_ARGS="-Djogl.debug.DebugGL -Djogl.debug.TraceGL -Djogl.debug.GLContext.TraceSwitch -Djogl.debug=all" #D_ARGS="-Djogl.debug.GLArrayData" - #D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window" + D_ARGS="-Dnewt.debug.Screen -Dnewt.debug.Window" #D_ARGS="-Dnewt.debug.Window" #D_ARGS="-Dnewt.debug.Screen" #D_ARGS="-Dnewt.window.icons=null,null" @@ -981,7 +981,11 @@ function testawtswt() { #testnoawt com.jogamp.opengl.test.junit.jogl.glsl.TestRulerNEWT01 $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2AWT $* #testawt com.jogamp.opengl.test.junit.jogl.demos.es2.awt.TestGearsES2GLJPanelAWT $* -testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT +#testnoawt com.jogamp.opengl.test.junit.newt.TestDisplayLifecycle01NEWT +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.TestSharedContextListNEWT2 $* +testnoawt com.jogamp.opengl.test.junit.jogl.demos.gl2.newt.TestGearsNEWT $* +#testnoawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch10NEWT $* +#testawt com.jogamp.opengl.test.junit.jogl.acore.glels.TestGLContextDrawableSwitch11NewtAWT $* # Linux DRM/GBM # diff --git a/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java b/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java index f5804cd12..c732151e5 100644 --- a/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java +++ b/src/nativewindow/classes/jogamp/nativewindow/SurfaceScaleUtils.java @@ -28,6 +28,10 @@ */ package jogamp.nativewindow; +import java.security.PrivilegedAction; +import java.util.Map; + +import com.jogamp.common.util.SecurityUtil; import com.jogamp.nativewindow.ScalableSurface; /** @@ -222,4 +226,46 @@ public class SurfaceScaleUtils { result[1] = resultY; return changed; } + + /** + * Get global pixel-scale values from environment variables, e.g.: + * - QT_SCALE_FACTOR + * - GDK_SCALE + * See https://wiki.archlinux.org/title/HiDPI + * @param env_var_names array of potential environment variable names, treated as float. + * @param pixel_scale_xy store for resulting scale factors + * @return index of first found variable name within env_var_names, otherwise -1 + */ + public static int getGlobalPixelScaleEnv(final String[] env_var_names, final float[] pixel_scale_xy) { + final Map<String, String> env = SecurityUtil.doPrivileged(new PrivilegedAction<Map<String, String>>() { + @Override + public Map<String, String> run() { + return System.getenv(); + } + }); + float value = -1.0f; + boolean done = false; + int var_idx = 0; + while( var_idx < env_var_names.length && !done ) { + final String env_var_name = env_var_names[var_idx]; + final String s_value = env.get(env_var_name); + if( null != s_value ) { + try { + value = Float.valueOf(s_value); + done = true; + } catch(final NumberFormatException nfe) { + ++var_idx; + } + } else { + ++var_idx; + } + } + if( done ) { + pixel_scale_xy[0] = value; + pixel_scale_xy[1] = value; + return var_idx; + } else { + return -1; + } + } } diff --git a/src/newt/classes/jogamp/newt/MonitorModeProps.java b/src/newt/classes/jogamp/newt/MonitorModeProps.java index 873ee3ed6..292551559 100644 --- a/src/newt/classes/jogamp/newt/MonitorModeProps.java +++ b/src/newt/classes/jogamp/newt/MonitorModeProps.java @@ -273,6 +273,7 @@ public class MonitorModeProps { * @param screen the associated {@link ScreenImpl} * @param monitor_handle unique monitor long handle, implementation specific * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. + * @param invscale_wuviewport if true, the viewport in window-units will be scaled by 1/pixelScale for soft-pixel-scale * @param monitorProperties the input data inclusive 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}. @@ -281,8 +282,8 @@ public class MonitorModeProps { */ public static MonitorDevice streamInMonitorDevice(final Cache cache, final ScreenImpl screen, final long monitor_handle, - final float[] pixelScale, final int[] monitorProperties, - int offset, final int[] monitor_idx) { + final float[] pixelScale, final boolean invscale_wuviewport, + 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) { @@ -303,6 +304,9 @@ 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++]); + if( invscale_wuviewport && null != pixelScale ) { + viewportWU.scaleInv(pixelScale[0], pixelScale[1]); + } final MonitorMode currentMode; { final int modeId = monitorProperties[offset++]; @@ -360,6 +364,7 @@ public class MonitorModeProps { * @param monitor_handle unique monitor long handle, implementation specific * @param currentMode pre-fetched current {@link MonitorMode}s from cache. * @param pixelScale pre-fetched current pixel-scale, maybe {@code null} for {@link ScalableSurface#IDENTITY_PIXELSCALE}. + * @param invscale_wuviewport if true, the viewport in window-units will be scaled by 1/pixelScale for soft-pixel-scale * @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 @@ -371,9 +376,9 @@ public class MonitorModeProps { final long monitor_handle, final MonitorMode currentMode, final float[] pixelScale, - final ArrayHashSet<MonitorMode> supportedModes, - final int[] monitorProperties, int offset, - final int[] monitor_idx) { + final boolean invscale_wuviewport, + 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) { @@ -392,6 +397,9 @@ 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++]); + if( invscale_wuviewport && null != pixelScale ) { + viewportWU.scaleInv(pixelScale[0], pixelScale[1]); + } MonitorDevice monitorDevice = new MonitorDeviceImpl(screen, monitor_handle, monitor_id, isClone, isPrimary, sizeMM, currentMode, pixelScale, viewportPU, viewportWU, supportedModes); diff --git a/src/newt/classes/jogamp/newt/ScreenImpl.java b/src/newt/classes/jogamp/newt/ScreenImpl.java index 1dba31d4f..d90ee73bb 100644 --- a/src/newt/classes/jogamp/newt/ScreenImpl.java +++ b/src/newt/classes/jogamp/newt/ScreenImpl.java @@ -360,8 +360,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(jogamp.newt.MonitorModeProps.Cache, ScreenImpl, long, double[], int[], int, int[])}</li> - * <li>{@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, long, ArrayHashSet, int[], int, ScreenImpl)}</li> + * <li>{@link MonitorModeProps#streamInMonitorDevice(jogamp.newt.MonitorModeProps.Cache, ScreenImpl, long, double[], boolean, int[], int, int[])}</li> + * <li>{@link MonitorModeProps#streamInMonitorDevice(int[], jogamp.newt.MonitorModeProps.Cache, long, ArrayHashSet, boolean, int[], int, ScreenImpl)}</li> * <li>{@link MonitorModeProps#streamInMonitorMode(int[], jogamp.newt.MonitorModeProps.Cache, int[], int)}</li> * </ul> * @param cache memory pool caching the result @@ -520,7 +520,7 @@ public abstract class ScreenImpl extends Screen implements MonitorModeListener { if( MonitorModeProps.MIN_MONITOR_DEVICE_PROPERTIES != i ) { throw new InternalError("XX"); } - return MonitorModeProps.streamInMonitorDevice(cache, this, monitorId, null, props, 0, null); + return MonitorModeProps.streamInMonitorDevice(cache, this, monitorId, null, false /* invscale_wuviewport */, props, 0, null); } /** diff --git a/src/newt/classes/jogamp/newt/WindowImpl.java b/src/newt/classes/jogamp/newt/WindowImpl.java index ef8c4916d..ae63c4539 100644 --- a/src/newt/classes/jogamp/newt/WindowImpl.java +++ b/src/newt/classes/jogamp/newt/WindowImpl.java @@ -2966,12 +2966,9 @@ public abstract class WindowImpl implements Window, NEWTEventConsumer boolean res = false; if( DEBUG_IMPLEMENTATION ) { System.err.println("Window.SoftPixelScale.0a: req "+reqPixelScale[0]+", has "+hasPixelScale[0]+", new "+newPixelScale[0]+" - "+getThreadName()); - Thread.dumpStack(); + // Thread.dumpStack(); } synchronized( scaleLock ) { - if( DEBUG_IMPLEMENTATION ) { - System.err.println("Window.SoftPixelScale.0b: req "+reqPixelScale[0]+", has "+hasPixelScale[0]+", new "+newPixelScale[0]+" - "+getThreadName()); - } try { res = applySoftPixelScaleImpl(move_diff, sendEvent, defer, newPixelScale); } finally { diff --git a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java index 3c0b1aef4..8d73592b5 100644 --- a/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/android/ScreenDriver.java @@ -116,7 +116,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(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null); + MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java index d577ed501..fc4bf03a4 100644 --- a/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/awt/ScreenDriver.java @@ -122,7 +122,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(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null); + MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null); } @Override 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 62dbd0c72..3cdb368f2 100644 --- a/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/bcm/egl/ScreenDriver.java @@ -97,7 +97,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(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null); + MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, 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 9e05e1002..1b3807a94 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 @@ -90,7 +90,7 @@ public class ScreenDriver extends ScreenImpl { props[i++] = 0; // rotated viewport y window-units props[i++] = cachedWidth; // rotated viewport width window-units props[i++] = cachedHeight; // rotated viewport height window-units - MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null); + MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java index 5281f0ddc..a08b5a445 100644 --- a/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/egl/gbm/ScreenDriver.java @@ -129,7 +129,7 @@ public class ScreenDriver extends ScreenImpl { props[i++] = 0; // rotated viewport y window-units props[i++] = mode[scridx].getHdisplay(); // rotated viewport width window-units props[i++] = mode[scridx].getVdisplay(); // rotated viewport height window-units - MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null); + MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null); crtc_ids = new int[] { encoder[scridx].getCrtc_id() }; 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 ceb2c4cc6..7eb6eea92 100644 --- a/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/intel/gdl/ScreenDriver.java @@ -99,7 +99,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(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null); + MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, cache.monitorModes, props, 0, null); } @Override diff --git a/src/newt/classes/jogamp/newt/driver/ios/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/ios/ScreenDriver.java index de5cdd239..4cf459699 100644 --- a/src/newt/classes/jogamp/newt/driver/ios/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/ios/ScreenDriver.java @@ -177,7 +177,8 @@ public class ScreenDriver extends ScreenImpl { // merge monitor-props + supported modes final float pixelScale = crtProps.pixelScaleArray[crtIdx]; MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, - new float[] { pixelScale, pixelScale }, supportedModes, crtProps.propsFixedArray[crtIdx], 0, null); + new float[] { pixelScale, pixelScale }, false /* invscale_wuviewport */, + supportedModes, crtProps.propsFixedArray[crtIdx], 0, null); } } diff --git a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java index 3112aa88f..ba28e161d 100644 --- a/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/kd/ScreenDriver.java @@ -95,7 +95,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(cache, this, crt_id, currentMode, null, cache.monitorModes, props, 0, null); + MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, null, false, 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 a4823034f..635fffc0b 100644 --- a/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/macosx/ScreenDriver.java @@ -183,7 +183,8 @@ public class ScreenDriver extends ScreenImpl { // merge monitor-props + supported modes final float pixelScale = crtProps.pixelScaleArray[crtIdx]; MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, currentMode, - new float[] { pixelScale, pixelScale }, supportedModes, crtProps.propsFixedArray[crtIdx], 0, null); + new float[] { pixelScale, pixelScale }, false /* invscale_wuviewport */, + supportedModes, crtProps.propsFixedArray[crtIdx], 0, null); } } diff --git a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java index 002836e0c..c3aa94648 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/ScreenDriver.java @@ -143,7 +143,8 @@ public class ScreenDriver extends ScreenImpl { monitor_handle = monitor_id; } // merge monitor-props + supported modes - MonitorModeProps.streamInMonitorDevice(cache, this, monitor_handle, currentMode, pixel_scale, supportedModes, monitorProps, 0, null); + MonitorModeProps.streamInMonitorDevice(cache, this, monitor_handle, currentMode, pixel_scale, true /* invscale_wuviewport */, + supportedModes, monitorProps, 0, null); // next monitor, 1st mode supportedModes = new ArrayHashSet<MonitorMode>(false, ArrayHashSet.DEFAULT_INITIAL_CAPACITY, ArrayHashSet.DEFAULT_LOAD_FACTOR); @@ -168,6 +169,7 @@ public class ScreenDriver extends ScreenImpl { int offset = MonitorModeProps.IDX_MONITOR_DEVICE_VIEWPORT; viewportPU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]); viewportWU.set(monitorProps[offset++], monitorProps[offset++], monitorProps[offset++], monitorProps[offset++]); + viewportWU.scaleInv(pixelScale[0], pixelScale[1]); return true; } } diff --git a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java index fb20265ce..1605d4126 100644 --- a/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/windows/WindowDriver.java @@ -36,6 +36,7 @@ package jogamp.newt.driver.windows; import java.nio.ByteBuffer; +import jogamp.nativewindow.SurfaceScaleUtils; import jogamp.nativewindow.windows.GDI; import jogamp.nativewindow.windows.GDIUtil; import jogamp.newt.PointerIconImpl; @@ -47,11 +48,12 @@ import com.jogamp.nativewindow.NativeWindowException; import com.jogamp.nativewindow.VisualIDHolder; import com.jogamp.nativewindow.util.InsetsImmutable; import com.jogamp.nativewindow.util.Point; - import com.jogamp.common.os.Platform; import com.jogamp.common.util.VersionNumber; +import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.event.MonitorEvent; import com.jogamp.newt.event.MouseEvent; import com.jogamp.newt.event.MouseEvent.PointerType; @@ -61,7 +63,7 @@ public class WindowDriver extends WindowImpl { DisplayDriver.initSingleton(); } - private long hmon; + private volatile long hmon; private long hdc; private long hdc_old; private long windowHandleClose; @@ -69,6 +71,20 @@ public class WindowDriver extends WindowImpl { public WindowDriver() { } + /** + * Essentially updates {@code hasPixelScale} + */ + private boolean updatePixelScaleByMonitor(final long crt_handle, final int[] move_diff, final boolean sendEvent, final boolean defer) { + boolean res = false; + if( 0 != crt_handle ) { + final float newPixelScaleRaw[] = { 0, 0 }; + if( GDIUtil.GetMonitorPixelScale(crt_handle, newPixelScaleRaw) ) { + res = applySoftPixelScale(move_diff, sendEvent, defer, newPixelScaleRaw); + } + } + return res; + } + @Override protected int lockSurfaceImpl() { if (0 != hdc) { @@ -81,7 +97,14 @@ public class WindowDriver extends WindowImpl { if( 0 == hdc ) { return LOCK_SURFACE_NOT_READY; } - hmon = MonitorFromWindow0(hWnd); + if(DEBUG_IMPLEMENTATION) { + final long _hmon = GDIUtil.GetMonitorFromWindow(hWnd); + if (hmon != _hmon) { + System.err.println("Info: Window Device Changed (L) "+getThreadName()+ + ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon)); + // Thread.dumpStack(); + } + } // Let's not trigger on HDC change, GLDrawableImpl.'s destroy/create is a nop here anyways. // FIXME: Validate against EGL surface creation: ANGLE uses HWND -> fine! @@ -113,20 +136,27 @@ public class WindowDriver extends WindowImpl { } @Override - public boolean hasDeviceChanged() { - if(0!=getWindowHandle()) { - final long _hmon = MonitorFromWindow0(getWindowHandle()); - if (hmon != _hmon) { - if(DEBUG_IMPLEMENTATION) { - System.err.println("Info: Window Device Changed "+Thread.currentThread().getName()+ - ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon)); - // Thread.dumpStack(); - } - hmon = _hmon; - return true; - } + protected void monitorModeChanged(final MonitorEvent me, final boolean success) { + if( hmon == me.getMonitor().getHandle() ) { + updatePixelScaleByMonitor(me.getMonitor().getHandle(), null, false /* sendEvent*/, false /* defer */); // send reshape event itself } - return false; + } + + @Override + public final boolean setSurfaceScale(final float[] pixelScale) { + super.setSurfaceScale(pixelScale); // pixelScale -> reqPixelScale + + boolean changed = false; + if( isNativeValid() ) { + changed = applySoftPixelScale(null, true /* sendEvent */, false /* defer */, reqPixelScale); + } + if( DEBUG_IMPLEMENTATION ) { + 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 @@ -150,10 +180,14 @@ public class WindowDriver extends WindowImpl { flags |= CHANGE_MASK_MAXIMIZED_VERT; maxCount++; } + final int[] xy_pix = getPixelPosI(); + final int[] sz_pix = getPixelSizeI(); + + // this.convertToWindowUnits(null) final long _windowHandle = CreateWindow0(DisplayDriver.getHInstance(), display.getWindowClassName(), display.getWindowClassName(), winVer.getMajor(), winVer.getMinor(), getParentWindowHandle(), - getX(), getY(), getWidth(), getHeight(), flags); + xy_pix[0], xy_pix[1], sz_pix[0], sz_pix[1], flags); if ( 0 == _windowHandle ) { throw new NativeWindowException("Error creating window"); } @@ -164,10 +198,17 @@ public class WindowDriver extends WindowImpl { setWindowHandle(_windowHandle); windowHandleClose = _windowHandle; - if( 0 == ( STATE_MASK_CHILDWIN & flags ) && 1 == maxCount ) { - reconfigureWindowImpl(getX(), getY(), getWidth(), getHeight(), flags); + if( 0 == ( STATE_MASK_CHILDWIN & flags ) && 1 <= maxCount ) { + reconfigureWindowImpl(xy_pix[0], xy_pix[1], sz_pix[0], sz_pix[1], flags); } + hmon = GDIUtil.GetMonitorFromWindow(_windowHandle); + boolean changedPixelScale = applySoftPixelScale(null, true /* sendEvent */, false /* defer */, reqPixelScale); + if( !changedPixelScale ) { + changedPixelScale = updatePixelScaleByMonitor(hmon, null, true /* sendEvent */, false /* defer */); + } + positionModified[0] = changedPixelScale; + if(DEBUG_IMPLEMENTATION) { final Exception e = new Exception("Info: Window new window handle "+Thread.currentThread().getName()+ " (Parent HWND "+toHexString(getParentWindowHandle())+ @@ -201,6 +242,7 @@ public class WindowDriver extends WindowImpl { windowHandleClose = 0; hdc = 0; hdc_old = 0; + hmon = 0; } @Override @@ -244,7 +286,11 @@ public class WindowDriver extends WindowImpl { if( changeDecoration && isTranslucent ) { GDIUtil.DwmSetupTranslucency(getWindowHandle(), false); } - reconfigureWindow0( getParentWindowHandle(), getWindowHandle(), x, y, width, height, flags); + final int xy_pix[] = SurfaceScaleUtils.scale(new int[2], x, y, hasPixelScale); + final int sz_pix[] = SurfaceScaleUtils.scale(new int[2], width, height, hasPixelScale); + reconfigureWindow0( getParentWindowHandle(), getWindowHandle(), + xy_pix[0], xy_pix[1], sz_pix[0], sz_pix[1], flags); + if( changeDecoration && isTranslucent ) { GDIUtil.DwmSetupTranslucency(getWindowHandle(), true); } @@ -259,6 +305,37 @@ public class WindowDriver extends WindowImpl { } @Override + protected boolean positionChanged(final boolean defer, final boolean windowUnits, final int newX, final int newY) { + final boolean res = super.positionChanged(defer, windowUnits, newX, newY); + + if ( res ) { + final long hWnd = getWindowHandle(); + if( 0 != hWnd ) { + final long _hmon = GDIUtil.GetMonitorFromWindow(hWnd); + if( hmon != _hmon ) { + final int[] move_diff = new int[] { 0, 0 }; + MonitorDevice.Orientation orientation = MonitorDevice.Orientation.clone; + // Move from md0 -> md1 + final MonitorDevice md0 = getScreen().getMonitorByHandle(hmon); + final MonitorDevice md1 = getScreen().getMonitorByHandle(_hmon); + if( null != md0 && null != md1 ) { + orientation = md1.getOrientationTo(md0, move_diff); + } + if(DEBUG_IMPLEMENTATION) { + System.err.println("Info: Window Device Changed (P: "+newX+"/"+newY+ + ", crt_move[orient "+orientation+", diff "+move_diff[0]+"/"+move_diff[1]+") "+ + ", HMON "+toHexString(hmon)+" -> "+toHexString(_hmon)+ + " - "+Thread.currentThread().getName()); + } + hmon = _hmon; + updatePixelScaleByMonitor(_hmon, move_diff, true /* sendEvent */, defer); + } + } + } + return res; + } + + @Override protected void requestFocusImpl(final boolean force) { requestFocus0(getWindowHandle(), force); } @@ -307,7 +384,8 @@ public class WindowDriver extends WindowImpl { this.runOnEDTIfAvail(true, new Runnable() { @Override public void run() { - final Point sPos = convertToPixelUnits( getLocationOnScreenImpl(x, y) ); + // shortcut from getLocationOnScreenImpl(..) while maintaining pixel-units + final Point sPos = GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y ); warpPointer0(getWindowHandle(), sPos.getX(), sPos.getY()); } }); @@ -316,7 +394,8 @@ public class WindowDriver extends WindowImpl { @Override protected Point getLocationOnScreenImpl(final int x, final int y) { - return GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, x, y); + final int xy_pix[] = SurfaceScaleUtils.scale(new int[2], x, y, hasPixelScale); + return convertToWindowUnits( GDIUtil.GetRelativeLocation( getWindowHandle(), 0 /*root win*/, xy_pix[0], xy_pix[1]) ); } // diff --git a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java index 7fb70cc32..c6b91cbf6 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/ScreenDriver.java @@ -37,9 +37,11 @@ import java.util.ArrayList; import java.util.List; import com.jogamp.nativewindow.AbstractGraphicsDevice; +import com.jogamp.nativewindow.ScalableSurface; import com.jogamp.nativewindow.util.Rectangle; import com.jogamp.nativewindow.util.RectangleImmutable; +import jogamp.nativewindow.SurfaceScaleUtils; import jogamp.nativewindow.x11.X11Util; import jogamp.newt.Debug; import jogamp.newt.DisplayImpl; @@ -57,11 +59,27 @@ import com.jogamp.newt.MonitorMode; public class ScreenDriver extends ScreenImpl { protected static final boolean DEBUG_TEST_RANDR13_DISABLED; + protected static final float[] global_pixel_scale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; + protected static final boolean global_pixel_scale_set; static { Debug.initSingleton(); DEBUG_TEST_RANDR13_DISABLED = PropertyAccess.isPropertyDefined("newt.test.Screen.disableRandR13", true); + final String[] env_var_names = new String[] { "GDK_SCALE", "QT_SCALE_FACTOR", "SOFT_SCALE" }; + int var_name_idx = -1; + try { + var_name_idx = SurfaceScaleUtils.getGlobalPixelScaleEnv(env_var_names, global_pixel_scale); + } catch (final Throwable t) { t.printStackTrace(); } + if( 0 <= var_name_idx && var_name_idx < env_var_names.length ) { + global_pixel_scale_set = true; + if( DEBUG ) { + System.err.println("X11Screen: Global PixelScale Set: "+env_var_names[var_name_idx]+": "+global_pixel_scale[0]+"/"+global_pixel_scale[1]); + } + } else { + global_pixel_scale_set = false; + } + DisplayDriver.initSingleton(); } @@ -120,6 +138,10 @@ public class ScreenDriver extends ScreenImpl { try { if( rAndR.beginInitialQuery(device.getHandle(), this) ) { try { + final float pixel_scale[] = { ScalableSurface.IDENTITY_PIXELSCALE, ScalableSurface.IDENTITY_PIXELSCALE }; + if( global_pixel_scale_set ) { + System.arraycopy(global_pixel_scale, 0, pixel_scale, 0, 2); + } final int[] crt_ids = rAndR.getMonitorDeviceIds(device.getHandle(), this); final int crtCount = null != crt_ids ? crt_ids.length : 0; @@ -155,7 +177,8 @@ 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(cache, this, crt_id, null, monitorProps, 0, null); + MonitorModeProps.streamInMonitorDevice(cache, this, crt_id, pixel_scale, true /* invscale_wuviewport */, + monitorProps, 0, null); } } } @@ -177,6 +200,7 @@ public class ScreenDriver extends ScreenImpl { if( null != viewportProps ) { viewportPU.set(viewportProps[0], viewportProps[1], viewportProps[2], viewportProps[3]); viewportWU.set(viewportProps[0], viewportProps[1], viewportProps[2], viewportProps[3]); // equal window-units and pixel-units + viewportWU.scaleInv(pixelScale[0], pixelScale[1]); return true; } else { return false; diff --git a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java index c1a24797b..38c463e7c 100644 --- a/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java +++ b/src/newt/classes/jogamp/newt/driver/x11/WindowDriver.java @@ -36,6 +36,8 @@ package jogamp.newt.driver.x11; import java.nio.Buffer; +import jogamp.nativewindow.SurfaceScaleUtils; +import jogamp.nativewindow.windows.GDIUtil; import jogamp.nativewindow.x11.X11Lib; import jogamp.nativewindow.x11.X11Util; import jogamp.newt.DisplayImpl; @@ -53,9 +55,11 @@ import com.jogamp.common.ExceptionUtils; import com.jogamp.common.nio.Buffers; import com.jogamp.nativewindow.x11.X11GraphicsDevice; import com.jogamp.nativewindow.x11.X11GraphicsScreen; +import com.jogamp.newt.MonitorDevice; import com.jogamp.newt.NewtFactory; import com.jogamp.newt.event.InputEvent; import com.jogamp.newt.event.KeyEvent; +import com.jogamp.newt.event.MonitorEvent; import com.jogamp.newt.event.MouseEvent; public class WindowDriver extends WindowImpl { @@ -68,6 +72,8 @@ public class WindowDriver extends WindowImpl { private static final int defaultIconDataSize; private static final Buffer defaultIconData; + private volatile MonitorDevice last_monitor; + static { ScreenDriver.initSingleton(); @@ -94,8 +100,45 @@ public class WindowDriver extends WindowImpl { public WindowDriver() { } + /** + * Essentially updates {@code hasPixelScale} + */ + private boolean updatePixelScaleByMonitor(final MonitorDevice md, final int[] move_diff, final boolean sendEvent, final boolean defer) { + boolean res = false; + if( null != md ) { + final float newPixelScale[] = { 0, 0 }; + md.getPixelScale(newPixelScale); + res = applySoftPixelScale(move_diff, sendEvent, defer, newPixelScale); + } + return res; + } + + @Override + protected void monitorModeChanged(final MonitorEvent me, final boolean success) { + if( last_monitor == me.getMonitor() ) { + updatePixelScaleByMonitor(me.getMonitor(), null, false /* sendEvent*/, false /* defer */); // send reshape event itself + } + } + @Override - protected void createNativeImpl(boolean[] positionModified) { + public final boolean setSurfaceScale(final float[] pixelScale) { + super.setSurfaceScale(pixelScale); // pixelScale -> reqPixelScale + + boolean changed = false; + if( isNativeValid() ) { + changed = applySoftPixelScale(null, true /* sendEvent */, false /* defer */, reqPixelScale); + } + if( DEBUG_IMPLEMENTATION ) { + 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 + protected void createNativeImpl(final boolean[] positionModified) { final ScreenDriver screen = (ScreenDriver) getScreen(); final DisplayDriver display = (DisplayDriver) screen.getDisplay(); final AbstractGraphicsDevice edtDevice = display.getGraphicsDevice(); @@ -124,11 +167,14 @@ public class WindowDriver extends WindowImpl { setGraphicsConfiguration(cfg); final int flags = getReconfigureMask(0, true) & STATE_MASK_CREATENATIVE; edtDevice.lock(); + + final int[] xy_pix = getPixelPosI(); + final int[] sz_pix = getPixelSizeI(); try { final long[] handles = CreateWindow(getParentWindowHandle(), edtDevice.getHandle(), screen.getIndex(), visualID, display.getJavaObjectAtom(), display.getWindowDeleteAtom(), display.getXiOpcode(), - getX(), getY(), getWidth(), getHeight(), flags, + xy_pix[0], xy_pix[1], sz_pix[0], sz_pix[1], flags, defaultIconDataSize, defaultIconData, DEBUG_IMPLEMENTATION); if (null == handles || 2 != handles.length || 0 == handles[0] || 0 == handles[1] ) { throw new NativeWindowException("Error creating window"); @@ -138,6 +184,14 @@ public class WindowDriver extends WindowImpl { } setWindowHandle(handles[0]); javaWindowHandle = handles[1]; + + last_monitor = getMainMonitor(); + boolean changedPixelScale = applySoftPixelScale(null, true /* sendEvent */, false /* defer */, reqPixelScale); + if( !changedPixelScale ) { + changedPixelScale = updatePixelScaleByMonitor(last_monitor, null, true /* sendEvent */, false /* defer */); + } + positionModified[0] = changedPixelScale; + } finally { edtDevice.unlock(); } @@ -160,6 +214,7 @@ public class WindowDriver extends WindowImpl { } finally { edtDevice.unlock(); javaWindowHandle = 0; + last_monitor = null; } } if(null != renderDevice) { @@ -200,9 +255,13 @@ public class WindowDriver extends WindowImpl { _x = x; _y = y; } + final int xy_pix[] = SurfaceScaleUtils.scale(new int[2], _x, _y, hasPixelScale); + final int sz_pix[] = SurfaceScaleUtils.scale(new int[2], width, height, hasPixelScale); + if(DEBUG_IMPLEMENTATION) { - System.err.println("X11Window reconfig.0: "+x+"/"+y+" -> "+_x+"/"+_y+" "+width+"x"+height+", insets "+_insets+ - ", "+getReconfigStateMaskString(flags)); + System.err.println("X11Window reconfig.0: "+x+"/"+y+" -> "+_x+"/"+_y+" "+width+"x"+height+ + " -> pixel["+xy_pix[0]+"/"+xy_pix[1]+" "+sz_pix[0]+"x"+sz_pix[1]+ + "], insets "+_insets+", "+getReconfigStateMaskString(flags)); } if( 0 != ( CHANGE_MASK_FULLSCREEN & flags ) ) { if( 0 != ( STATE_MASK_FULLSCREEN & flags) && @@ -222,7 +281,7 @@ public class WindowDriver extends WindowImpl { @Override public Object run(final long dpy) { reconfigureWindow0( dpy, getScreenIndex(), - getParentWindowHandle(), javaWindowHandle, _x, _y, width, height, fflags); + getParentWindowHandle(), javaWindowHandle, xy_pix[0], xy_pix[1], sz_pix[0], sz_pix[1], fflags); return null; } }); @@ -259,6 +318,32 @@ public class WindowDriver extends WindowImpl { super.focusChanged(defer, focusGained); } + @Override + protected boolean positionChanged(final boolean defer, final boolean windowUnits, final int newX, final int newY) { + final boolean res = super.positionChanged(defer, windowUnits, newX, newY); + + if ( res ) { + if( isNativeValid() ) { + final MonitorDevice new_monitor = getMainMonitor(); + if( null != last_monitor && !new_monitor.equals(last_monitor) ) { + final int[] move_diff = new int[] { 0, 0 }; + MonitorDevice.Orientation orientation = MonitorDevice.Orientation.clone; + // Move from last_monitor -> new_monitor + orientation = new_monitor.getOrientationTo(last_monitor, move_diff); + if(DEBUG_IMPLEMENTATION) { + System.err.println("Info: Window Device Changed (P: "+newX+"/"+newY+ + ", crt_move[orient "+orientation+", diff "+move_diff[0]+"/"+move_diff[1]+") "+ + ", monitor "+last_monitor.getId()+" -> "+new_monitor.getId()+ + " - "+Thread.currentThread().getName()); + } + last_monitor = new_monitor; + updatePixelScaleByMonitor(new_monitor, move_diff, true /* sendEvent */, defer); + } + } + } + return res; + } + protected void reparentNotify(final long newParentWindowHandle) { if(DEBUG_IMPLEMENTATION) { final long p0 = getParentWindowHandle(); @@ -344,12 +429,14 @@ public class WindowDriver extends WindowImpl { @Override protected Point getLocationOnScreenImpl(final int x, final int y) { - return runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Point>() { + final int xy_pix[] = SurfaceScaleUtils.scale(new int[2], x, y, hasPixelScale); + final Point res_pix = runWithLockedDisplayDevice( new DisplayImpl.DisplayRunnable<Point>() { @Override public Point run(final long dpy) { - return X11Lib.GetRelativeLocation(dpy, getScreenIndex(), getWindowHandle(), 0 /*root win*/, x, y); + return X11Lib.GetRelativeLocation(dpy, getScreenIndex(), getWindowHandle(), 0 /*root win*/, xy_pix[0], xy_pix[1]); } } ); + return convertToWindowUnits( res_pix ); } @Override diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java index cd9defd83..df712ee4e 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/acore/glels/TestGLContextDrawableSwitch10NEWT.java @@ -106,6 +106,7 @@ public class TestGLContextDrawableSwitch10NEWT extends UITestCase { window.setVisible(true); Assert.assertTrue(NewtTestUtil.waitForVisible(window, true, null)); Assert.assertTrue(NewtTestUtil.waitForRealized(window, true, null)); + Assert.assertTrue(NewtTestUtil.waitForSize(window, width, height, null)); final GLDrawableFactory factory = GLDrawableFactory.getFactory(caps.getGLProfile()); final GLDrawable drawable = factory.createGLDrawable(window); @@ -113,6 +114,8 @@ public class TestGLContextDrawableSwitch10NEWT extends UITestCase { drawable.setRealized(true); Assert.assertTrue(drawable.isRealized()); + Assert.assertEquals(drawable.getSurfaceWidth(), window.getSurfaceWidth()); + Assert.assertEquals(drawable.getSurfaceHeight(), window.getSurfaceHeight()); final GLAutoDrawableDelegate glad = new GLAutoDrawableDelegate(drawable, null, window, false, null) { @Override @@ -123,6 +126,7 @@ public class TestGLContextDrawableSwitch10NEWT extends UITestCase { }; window.setWindowDestroyNotifyAction( new Runnable() { + @Override public void run() { glad.windowDestroyNotifyOp(); } } ); diff --git a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java index 0ab9308c2..9b44da691 100644 --- a/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/jogl/demos/gl2/newt/TestGearsNEWT.java @@ -28,15 +28,20 @@ package com.jogamp.opengl.test.junit.jogl.demos.gl2.newt; +import com.jogamp.nativewindow.ScalableSurface; +import com.jogamp.nativewindow.util.Dimension; +import com.jogamp.nativewindow.util.DimensionImmutable; +import com.jogamp.nativewindow.util.Point; +import com.jogamp.nativewindow.util.PointImmutable; import com.jogamp.newt.opengl.GLWindow; import com.jogamp.newt.opengl.util.NEWTDemoListener; import com.jogamp.opengl.test.junit.util.UITestCase; +import com.jogamp.opengl.test.junit.util.MiscUtils; import com.jogamp.opengl.test.junit.util.QuitAdapter; import com.jogamp.opengl.util.Animator; import com.jogamp.opengl.test.junit.jogl.demos.gl2.Gears; -import com.jogamp.opengl.test.junit.newt.parenting.NewtReparentingKeyAdapter; import com.jogamp.opengl.GLCapabilities; import com.jogamp.opengl.GLProfile; @@ -58,15 +63,18 @@ import org.junit.runners.MethodSorters; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class TestGearsNEWT extends UITestCase { static GLProfile glp; - static int width, height; + static PointImmutable wpos; + static DimensionImmutable wsize; + static float[] reqSurfacePixelScale = new float[] { ScalableSurface.AUTOMAX_PIXELSCALE, ScalableSurface.AUTOMAX_PIXELSCALE }; @BeforeClass public static void initClass() { if(GLProfile.isAvailable(GLProfile.GL2)) { glp = GLProfile.get(GLProfile.GL2); Assert.assertNotNull(glp); - width = 640; - height = 480; + if(null == wsize) { + wsize = new Dimension(640, 480); + } } else { setTestSupported(false); } @@ -95,11 +103,30 @@ public class TestGearsNEWT extends UITestCase { glWindow.addKeyListener(newtDemoListener); glWindow.addMouseListener(newtDemoListener); - glWindow.setSize(width, height); + glWindow.setSize(wsize.getWidth(), wsize.getHeight()); + if(null != wpos) { + glWindow.setPosition(wpos.getX(), wpos.getY()); + } + glWindow.setSurfaceScale(reqSurfacePixelScale); + final float[] valReqSurfacePixelScale = glWindow.getRequestedSurfaceScale(new float[2]); + glWindow.setVisible(true); animator.setUpdateFPSFrames(1, null); animator.start(); + System.err.println("Window Current State : "+glWindow.getStateMaskString()); + System.err.println("Window Supported States: "+glWindow.getSupportedStateMaskString()); + System.err.println("NW chosen: "+glWindow.getDelegatedWindow().getChosenCapabilities()); + System.err.println("GL chosen: "+glWindow.getChosenCapabilities()); + System.err.println("window insets: "+glWindow.getInsets()); + System.err.println("window bounds (window): "+glWindow.getBounds()); + System.err.println("window bounds (pixels): "+glWindow.getSurfaceBounds()); + + final float[] hasSurfacePixelScale1 = glWindow.getCurrentSurfaceScale(new float[2]); + System.err.println("HiDPI PixelScale: "+reqSurfacePixelScale[0]+"x"+reqSurfacePixelScale[1]+" (req) -> "+ + valReqSurfacePixelScale[0]+"x"+valReqSurfacePixelScale[1]+" (val) -> "+ + hasSurfacePixelScale1[0]+"x"+hasSurfacePixelScale1[1]+" (has)"); + while(!quitAdapter.shouldQuit() && animator.isAnimating() && animator.getTotalFPSDuration()<duration) { Thread.sleep(100); } @@ -117,14 +144,42 @@ public class TestGearsNEWT extends UITestCase { static long duration = 500; // ms public static void main(final String args[]) { + int x=0, y=0, w=640, h=480; + boolean usePos = false; + for(int i=0; i<args.length; i++) { if(args[i].equals("-time")) { i++; try { duration = Integer.parseInt(args[i]); } catch (final Exception ex) { ex.printStackTrace(); } + } else if(args[i].equals("-width")) { + i++; + w = MiscUtils.atoi(args[i], w); + } else if(args[i].equals("-height")) { + i++; + h = MiscUtils.atoi(args[i], h); + } else if(args[i].equals("-x")) { + i++; + x = MiscUtils.atoi(args[i], x); + usePos = true; + } else if(args[i].equals("-y")) { + i++; + y = MiscUtils.atoi(args[i], y); + usePos = true; + } else if(args[i].equals("-pixelScale")) { + i++; + final float pS = MiscUtils.atof(args[i], reqSurfacePixelScale[0]); + reqSurfacePixelScale[0] = pS; + reqSurfacePixelScale[1] = pS; } } + wsize = new Dimension(w, h); + if(usePos) { + wpos = new Point(x, y); + } + System.err.println("position "+wpos); + System.err.println("size "+wsize); org.junit.runner.JUnitCore.main(TestGearsNEWT.class.getName()); } } diff --git a/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java b/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java index fbca2e614..78f59931a 100644 --- a/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java +++ b/src/test/com/jogamp/opengl/test/junit/newt/mm/TestScreenMode00aNEWT.java @@ -119,7 +119,7 @@ public class TestScreenMode00aNEWT extends UITestCase { cache.monitorDevices.add(monOut); { final int[] props = MonitorModeProps.streamOutMonitorDevice(monOut); - final MonitorDevice monIn = MonitorModeProps.streamInMonitorDevice(cache, null, monitor_handle, null, props, 0, null); + final MonitorDevice monIn = MonitorModeProps.streamInMonitorDevice(cache, null, monitor_handle, null, false /* invscale_wuviewport */, props, 0, null); System.err.println("01 in : "+monIn); Assert.assertEquals(monOut.getHandle(), monIn.getHandle()); |