Summary: | Support High-DPI for JRE>8 AWT on Windows, MacOSX and Linux | ||
---|---|---|---|
Product: | [JogAmp] Jogl | Reporter: | Sven Gothel <sgothel> |
Component: | awt | Assignee: | Sven Gothel <sgothel> |
Status: | RESOLVED FIXED | ||
Severity: | major | CC: | GMoubarak, maheshkurmi2010, marcel.au, rami.santina, Rayan, wwalker3 |
Priority: | P4 | ||
Version: | 2.5.0 | ||
Hardware: | pc_all | ||
OS: | all | ||
Type: | DEFECT | SCM Refs: |
c7858dc766cb9f76ac8f543796b1587a0f8f9279
24b75b2e91ec5f101b19fa24aa3804adb3819ebf
7ec068e0c95a230101450cc80031f76770a0cd49
ba83a59363023ba0cc314746d7864ccf2cdd4d7a
|
Workaround: | --- | ||
Bug Depends on: | |||
Bug Blocks: | 1404, 1373 |
Description
Sven Gothel
2019-04-04 23:47:25 CEST
See long discussion: http://forum.jogamp.org/JOGL-broken-with-JRE-gt-8-and-Windows-window-scaling-td4039122.html c7858dc766cb9f76ac8f543796b1587a0f8f9279 Bug 1363: Java 11: Don't use GraphicsDevice.getScaleFactor() on Java9+ [illegal reflective access] Use non-reflective method to get the pixel scale on Java9+ It's now possible to use GraphicsConfiguration.getDefaultTransform() instead of using reflection to get the pixel scale, which eliminates an illegal reflective access warning. Orig patch by Wade Walker 24b75b2e91ec5f101b19fa24aa3804adb3819ebf Bug 1363: Java 11: Use getPixelScale standard method even on Mac under Java9+ Changed getPixelScale to use standard method, even on Mac Previously it used a Mac-specific method, but the new standard method of device.getDefaultConfiguration().getDefaultTransform() seems to work on Mac, so use it instead to avoid illegal reflective access warnings. Orig patch by Wade Walker. 7ec068e0c95a230101450cc80031f76770a0cd49 Bug 1363: Java 11: Resolve unsupported JAWTUtil.getMonitorDisplayID(..) Previous commits removed access to OSX's GraphicsDevice.getCGDisplayID() on Java9+, avoiding illegal reflective access. Here we JAWTUtil.getMonitorDisplayID(..) simply returns null if Java9 or !OSX, so the sole NewtFactory caller falls back to the alternative working solution. Orig patch Wade Walker: This was used on Mac OS only to create a MonitorDevice in NewtFactoryAWT. But there was a fallback method for creating MonitorDevice, and testing with TestGearsES2GLJPanelAWT shows that the fallback method seems to give identical results on Mac, so changed to just use the fallback method (which is now the only method) everywhere. This gets rid of an illegal reflective access. While working on the whole tree of Bug 674, in particular Bug 1421, Bug 1422, Bug 1423 and Bug 1424 - I finally 'gave in' to this group of issues. +++ NEWT itself does not utilize a low level API for 'High-DPI' on certain platforms, namely Windows (GDI) and X11 (Xlib) on GNU/Linux and others. Let's call these 'non native dpi scaling platforms', see Bug 1422. Currently only on OSX, NEWT does handle its low level pixelScale from window-units to pixel-units. +++ In case a higher API tookit imposes some sort of 'dpi scale' on said 'non native dpi scaling platforms', both units gets scaled up: - window units - pixel units (See Bug 1422) In such cases using NEWT, we keep the imposed 'dpi scale' agnostic to NEWT's native pixel-scale. Here the toolkit wrapper like NewtCanvasAWT/SWT etc simply scale both units (window- and pixel) while leaving NEWT's pixel-scale at 1f. +++ Therefor, we should not only handle such case for SWT (Bug 1422), but also for the AWT and Swing toolkit in concert with using NEWT or plain using our direct AWT/Swing components. +++ I made some annotations earlier: commit ba83a59363023ba0cc314746d7864ccf2cdd4d7a Bug 1374: NEWT/AWT: Annotation regarding general High-DPI for even non native DPI toolkit aware platforms (Linux, Windows) NEWT + NewtCanvasAWT: Maybe create "interface ScalableSurface.Upstream { void pixelScaleChangeNotify(final float[] curPixelScale, final float[] minPixelScale, final float[] maxPixelScale); }" to allow downstream to notify upstream ScalableSurface implementations like NEWT's Window to act accordingly. +++ AWT GLCanvas: Add remark where to add the potential pixel scale. (In reply to Sven Gothel from comment #3) In particular, the following finding by Wade allows us to react on AWT's detected 'dpi scale' on the non native dpi scaling platforms: 24b75b2e91ec5f101b19fa24aa3804adb3819ebf Bug 1363: Java 11: Use getPixelScale standard method even on Mac under Java9+ Changed getPixelScale to use standard method, even on Mac Previously it used a Mac-specific method, but the new standard method of device.getDefaultConfiguration().getDefaultTransform() seems to work on Mac, so use it instead to avoid illegal reflective access warnings. Orig patch by Wade Walker. NewtAwtCanvas does't honour the pixelScale factor with swing layout on hidpi screens. I added NewtAwtCanvas to JFrame with layout set to fill jframe on my surface pro 6(2k Resolution).But the canvas is taking quarter of space (that is because of pixelScaleFactor being 2). I have two workarounds which work fine with JDK9 and windows 10. 1. Set layout as null, and manually scale dimesions of canvas by pixelScaleFactor. 2. Override getPreferredSize() ,getWidth() and getHeight() of NewtAwtCanvas and returned scaled dimensions. Associated test snippet can be found here. https://gist.github.com/maheshkurmi/e984430d33236b6bfb7c3de0f8a1a0e5 I came to conclusion that there is some layout related bug (not taking pixelScale factor in account) in NewTAwtCanvas implementation. (In reply to maheshkurmi2010 from comment #5) Copying from my forum post: Great job Mahesh & Martin, Julien .. I will consider this for 2.4.0 and thx for putting it in bugzilla as well. One question, would you expect this pixel scale also being used 'naturally' by a NEWT window (w/o AWT)? In such case we would have seamless pixel scale in NEWT, AWT or not (Note: reparenting is possible). That probably means to read out the windowing system's pixel scale, potentially an environment variable or something. When I added the pixel scale API .. well, it was mostly for NEWT and a client request :) For NEWT, I was hoping ppl would use the monitor DPI info we provide to render the objects in the desired _size_. But who am I to judge and choose :) So status is pixel scale works - using GLCanvas + GLJPanel - using MacOS anyways (in NEWT too) - missing for NEWT alone and with NewtCanvasAWT ? - Our Bugzilla issue 1374 https://jogamp.org/bugzilla/show_bug.cgi?id=1374 - Martin's issue tracker https://github.com/jzy3d/jogl/issues/8 - This forum post https://forum.jogamp.org/GLcanvas-vs-NEWT-on-Hi-DPI-Screens-tp4041191p4042115.html - Harvey's kicking https://forum.jogamp.org/Release-2-4-0-Progress-tp4042061p4042114.html (In reply to Sven Gothel from comment #6) 'pixel scale', an arbitrary scaling factor, customized by the user, to please the eyes etc. This in contrast to actual DPI naturally scaled rendering. 'true to scale'. +++ Generic way to determine the OS's windowing system's so called 'pixel scale': Windows: 1a) GetDpiForMonitor(ddmon, MDT_EFFECTIVE_DPI, int *dpi_x, int *dpi_y) - NOTE: MDT_EFFECTIVE_DPI returns the custom user DPI setting according to user pixel scale setting (See above). This is not the true dpi, which NEWT already calculates per monitor by its size and resolution! (or attribute MDT_RAW_DPI here) or, if 1a is n/a 1b) { dpi_x, dpi_y } = GetDeviceCaps(hdc, {LOGPIXELSX, LOGPIXELSX}) - NOTE: Same for all monitors 2) pixel_scale_x = (float)dpi_x / (float)96 pixel_scale_y = (float)dpi_x / (float)96 Unix: 0) See https://wiki.archlinux.org/title/HiDPI 1) KDE Plasme: How to read the setup value? - System Settings > Display and Monitor > Display Configuration > Global Scale - range 100 - x00% in 25% steps, i.e. float 2) Qt5: QT_SCREEN_SCALE_FACTORS, QT_SCALE_FACTOR, ... 3) ... 9) GDK3+ GTK3/4: int GDK_SCALE, an environment variable - NOTE: just an int type, not pleasing - from GDK3 world Note: JDK-17 seems to use GDK_SCALE only .. Note: We might end up using an AWT Compatibility mode - and - a proper pixel scale mode (when and if available) Note: Needs more investigation. Debugging w/ AWT: X) float J2D_UISCALE, an environment variable - Windows: value is kept as float - Unix: valye is cut-off to int (duh!) .. to be continued .. (In reply to Sven Gothel from comment #7) Further re `AWT Compatibility mode`: - OpenJDK17 uses float on Windows and int on Unix/X11 - IF we are able to retrieve the fractional pixel scale on Unix/X11, such a compatibility mode might be required .. (In reply to Sven Gothel from comment #8) https://www.qt.io/blog/2016/01/26/high-dpi-support-in-qt-5-6 <quote> Q: Are non-integer scale factors supported? A: Qt uses qreal in the API, and will allow setting non-integer scale factors via QT_SCALE_FACTOR. However, Qt does not guarantee that graphics and styles will be glitch-free in that case. Styles may break first: the fusion style is generally most scalable. The Qt platform plugins round the reported scale factors to the nearest integer. Q: Could a scale factor of 0.5 allow me to work in device pixels on a 2x device? A: That’s uncharted waters, but a possibility. </quote> +++ https://doc.qt.io/qt-5/highdpi.html <quote> Note: Non-integer scale factors may cause significant scaling/painting artifacts. </quote> Hence fractional scaling is supported, but also limited to same scale factor for both axis. (In reply to Sven Gothel from comment #9) NEWT: On the MacOS and iOS, window units are used for the native UI component's position and size. Here the surface size in pixel units = window-units-size * pixelScale. This has been implemented already. On Windows-GDI and X11, pixel units are used for the native UI component's position and size. Here we need to convert NEWT's window position and size to and from the pixel-size, i.e. window units = pixel-units / pixelScale. Hence all NEWT window-unit position and size values must be appropriately converted from/to window-units on Windows and X11. WIP .. (In reply to Sven Gothel from comment #10) NEWT's Soft-PixelScale done, used for X11 and Windows. See <https://jogamp.org/cgit/jogl.git/commit/?id=97b79ad351e48e7d3c6f9c95bacdf4f9d5d158ef> TODO: Test and fix utilization with AWT, i.e. NewtCanvasAWT (In reply to Sven Gothel from comment #11) https://forum.jogamp.org/GLcanvas-vs-NEWT-on-Hi-DPI-Screens-tp4041191p4042145.html Soft PixelScale on X11/Windows ======================= .. we sort up end up with the requirement of mapping window-units <-> pixel-units taking the monitor viewport layout into account. X11/Windows: A simple scaling of the window-units position is not suitable due to multiple monitors, i.e. a window-units gap will be created and fullscreen/spanning coordinates will be wrong. TODO: Implement seamless conversion of units incl. monitor viewport mapping - X11, Windows: Recalculate monitor window-units viewport (native is pixels) - MacOS Recalculate monitor pixel-units viewport (native is 'points', aka window-units) Impact will be to have the ability to use either pixel- or window-units for positioning and size and hence be fully platform independent. Not sure how and when to complete this task and where to cut the line .. This work asks to be resolved to have a nice solution though. (Or it is 'Looking for a problem'? Discussion welcome) (In reply to Sven Gothel from comment #12) Mind notes in this forum thread https://forum.jogamp.org/template/NamlServlet.jtp?macro=reply&node=4042246 Bug 1373 comment 3 details NEWT Soft-PixelScale. |