DPI scaling not working

classic Classic list List threaded Threaded
22 messages Options
12
Reply | Threaded
Open this post in threaded view
|

DPI scaling not working

gbburkhardt
JOGL specification version 2.4
JOGL implementation version 2.4.0-rc-20221130
JOGL implementation vendor JogAmp Community

I'm working with NASA WorldWind's "InstallImagery" example.  On a Windows 11 platform with Java 11, when I set the text scaling to something other that 125%, the GLCanvas doesn't fill the entire application pane, e.g.,



It looks like the scaling updates are not working properly.  I turned on jogl.debug.GLCanvas=true, and I don't see the scaling change in the log output:

Changing to 125%:

AWT-EventQueue-0: GLCanvas.reshape.0 canvas0 resize [ this 994x765, pixelScale [1.0, 1.0]] -> 994x765 * [1.0, 1.0] -> 994x765 - surfaceHandle 0x0
AWT-EventQueue-0: GLCanvas.reshape.0 canvas0 resize [ this 998x775, pixelScale [1.0, 1.0]] -> 998x775 * [1.0, 1.0] -> 998x775 - surfaceHandle 0x0
AWT-EventQueue-0: Reshape: 998x775


Changing to 100%:
AWT-EventQueue-0: GLCanvas.reshape.0 canvas0 resize [ this 996x773, pixelScale [1.0, 1.0]] -> 996x773 * [1.0, 1.0] -> 996x773 - surfaceHandle 0x0
AWT-EventQueue-0: Reshape: 996x773

The initial size of the canvas is set to 1000x800, but that doesn't seem to change even though the frame containing resizes when the text size changes.  The display is the same if the text scaling is set to 125% before starting the application.

It looks like GLCanvas.updatePixelScale is being called before JAWTWindow.updatePixelScale, and the jawtWindow.hasPixelScaleChanged() return is false when called in GLCanvas.
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

Sven Gothel
Administrator
I did some work regarding the fake-97DPI scaling for Windows and even Linux/X11 within NEWT itself.
I have a thread here somewhere .. and its marked NEWT Soft-PixelScale in the git commits.
While it works on using NEWT windows, it also needs some update on the NEWT multi-monitor management.

I have not tested this with pure AWT, as I assumed that this code-path is already working.

I may remind all parties, that I am desperately seeking funding to continue to work on this project
in a proper and healthy way forward.
So far - my limited outreach wasn't successful, see
- https://forum.jogamp.org/JogAmp-Management-Kick-Off-Meeting-td4042042.html

What might be also interesting in this regard is a vision of Java on Desktop
and bare metal embedded devices w/o Windowing System using Graph UI (which I am currently working on)
https://forum.jogamp.org/Graph-Type-Rendering-Updates-Graph-UI-td4042173.html#a4042200
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

gouessej
Administrator
In reply to this post by gbburkhardt
Hello

By the way, I advise you to use the very latest version of JOGL 2.4.0 instead of an obsolete release candidate even though it won't solve this particular problem.

I agree with Sven, work must pay, it's difficult to spend a lot of time on changes that require such an effort without proper funding.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

gbburkhardt
This post was updated on .
I appreciate the problem of funding.  Sorry, but I don't have a solution.  

I've created a simpler example to work with.  OneTriangleSwingGLCanvas.java  OneTriangle.java

It looks like this at 100% and 125% scaling.




It almost seems like the scaling is going in the wrong direction.  Or the OpenGL code is drawing in physical size pixels, when it should be drawing in logical size pixels.  Or the coordinates should be scaled before passing them to the OpenGL code.

Apparently this problem exists with LWJGL as well.  Here are two posts.  I haven't been able to get the solution proposed to work yet, nor do I especially like it.

https://hub.jmonkeyengine.org/t/solved-jme-only-renders-within-two-thirds-of-the-swing-canvas/46059/4

https://github.com/jMonkeyEngine/jmonkeyengine/issues/1393
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

Sven Gothel
Administrator
Looks like this is related to the integer-limited scaling in AWT?

When I was digging into OpenJDK17 (guess it was 17)
while elaborating about the scaling in bugzilla ..
https://jogamp.org/bugzilla//show_bug.cgi?id=1374#c7
.. I thought on Windows its a float, while on Linux an integer scale.

1.25 would suffer if int scaling is used in AWT,
obvious on MacOS .. yup.

We can fix that at some stage, added a note in the bugzilla report.

Note to all: Please at least state Java version/vendor and OS.
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

gbburkhardt
I've been working on Windows 10 and 11, using OpenJDK jdk-11.0.17.8-hotspot.  I'm working with a recently cloned copy of the gluegen/jogl repos.  Native libraries were built with gcc 12.2.0 under Msys2/MinGW.

When I run with OpenJDK jdk-17.0.6.10-hotspot

Exception in thread "main" com.jogamp.opengl.GLException: Unable to determine GraphicsConfiguration: WindowsWGLGraphicsConfiguration[DefaultGraphicsScreen[WindowsGraphicsDevice[type .windows, connection decon, unitID 0, handle 0x0, owner false, NullToolkitLock[obj 0x4aafad9d]], idx 0], pfdID 8, ARB-Choosen true,
        requested GLCaps[rgba 8/8/8/0, opaque, accum-rgba 0/0/0/0, dp/st/ms 16/0/0, dbl, mono  , hw, GLProfile[GL4bc/GL4bc.hw], on-scr[.]],
        chosen    GLCaps[wgl vid 8 arb: rgba 10/10/10/2, opaque, accum-rgba 0/0/0/0, dp/st/ms 24/8/0, dbl, mono  , hw, GLProfile[GL4bc/GL4bc.hw], on-scr[.]]]
        at jogamp.opengl.windows.wgl.awt.WindowsAWTWGLGraphicsConfigurationFactory.chooseGraphicsConfigurationImpl(WindowsAWTWGLGraphicsConfigurationFactory.java:182)
        at com.jogamp.nativewindow.GraphicsConfigurationFactory.chooseGraphicsConfiguration(GraphicsConfigurationFactory.java:424)
        at com.jogamp.opengl.awt.GLCanvas.chooseGraphicsConfiguration(GLCanvas.java:1513)
        at com.jogamp.opengl.awt.GLCanvas.addNotify(GLCanvas.java:609)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4839)
        at java.desktop/javax.swing.JRootPane.addNotify(JRootPane.java:729)
        at java.desktop/java.awt.Container.addNotify(Container.java:2804)
        at java.desktop/java.awt.Window.addNotify(Window.java:791)
        at java.desktop/java.awt.Frame.addNotify(Frame.java:495)
        at java.desktop/java.awt.Window.show(Window.java:1053)
        at java.desktop/java.awt.Component.show(Component.java:1728)
        at java.desktop/java.awt.Component.setVisible(Component.java:1675)
        at java.desktop/java.awt.Window.setVisible(Window.java:1036)
        at demo.OneTriangleSwingGLCanvas.main(OneTriangleSwingGLCanvas.java:88)
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

Sven Gothel
Administrator
Don't forget to add the following for OpenJDK17, we run all tests with this java cmdline options:

--add-opens java.desktop/sun.awt=ALL-UNNAMED --add-opens java.desktop/sun.java2d=ALL-UNNAMED
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

gbburkhardt
Ah.  Thanks.  With Java 17, I get the same result w.r.t. scaling.
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

Sven Gothel
Administrator
OK .. so at least consistent.

Yeah, when fixing this I will use our way of determining the actual scale to 'size-up' out drawable surface.
A PIA so to speak but doable having all behavioral data in :)
So same bug with Windows and MacOS here on fractional scale.
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

gbburkhardt
I have time to work on this, and plan to.  So any guidance will be appreciated.
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

Sven Gothel
Administrator
Great, but warning .. this may become a deep dive :)

The last related git commits include NEWT Soft-PixelScale in the subject.
Bugs related and new commented are in Bug 1374.

In NEWT, we have different means to pull the pixel-scale from the system
- Windows: GDI, see GDIUtil.GetMonitorPixelScale()
- OSX: OSXUtil.getScreenPixelScaleByDisplayID()
  - Note: NEWT also considers the specific native view/window configuration.
- Linux: Environment variable, see SurfaceScaleUtil.getPixelScaleEnv()

Currently, in our AWT GLCanvas, we use:
- JAWTUtil.getPixelScale()
and this might be an issue or something, despite the fact that we use floats.
This method sort of does the very same path as all other are using for a workaround.

However, it uses one method for Java < 9
and one method for Java >= 9.
The latter (Java >= 9) simply uses the generic GraphicsConfiguration's AffineTransform's x/y scale factor
which is a double, so float compatible if you want.

This JAWTUtil method is currently used in
- GLJPanel
- JAWTWindow
  - used in GLCanvas

When I would start this journey, I would first hack-in code to show me
the actual pixel-scale (using the mentioned NEWT methods)
and the JAWTUtil scales used.

Assuming full integer scales work, but we got a 'float bug',
probably AWT using just integer.
In the latter case, we would need to use the ceiling of rounded float, done :)

Hope it helps a little.

Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

gbburkhardt
Well, I've found the sweet spot, if nothing else.  Please see attached patch.scale.patch

I've made modest modifications to the test program that makes it easier to see the problem.  
OneTriangleSwingGLCanvas1.java

The picture using the patch now looks like


But, I wonder what else this will break.  It's not entirely clear to me how the variables 'hasPixelScale' and 'reqPixelScale' are supposed to be used in GLCanvas and JAWTWindow.

The debug output with -Dnativewindow.debug.JAWT is

JAWTUtil initialization (JAWT/JNI/...); SKIP_AWT_HIDPI false
JAWTUtil.getJAWT(tryOffscreenLayer false, tryOnscreen true)
JAWTUtil: Has sun.awt.SunToolkit: awtLock/awtUnlock true, disableBackgroundErase true
JAWTUtil: Has Java2D true
JAWTUtil: Is headless false
JAWTUtil: AWT Desktop hints 2
JAWTUtil: OffscreenLayer Supported: false - Required false
JAWTWindow[0x48aaecc3].invalidate @ Thread main - visible[isShowing false],
    ** THIS 0x1f3f4916: GLCanvas[visible true, showing false, valid false, displayable true, 0/0 640x480]
    ** THREAD main
JAWTWindow[0x48aaecc3].ctor @ Thread main
JAWTUtil.getJAWT(tryOffscreenLayer false, tryOnscreen true)
JAWTWindow.updateBounds: [ 0 / 0  0 x 0 ] -> [ 0 / 0  640 x 480 ]
JAWTWindow.updatePixelScale: updated req[0.0, 0.0], min[1.0, 1.0], max[1.25, 1.25], has[1.25, 1.25]
JAWTWindow[0x48aaecc3].attach @ Thread AWT-EventQueue-0: visible[isShowing true],
    ** THIS 0x1f3f4916: GLCanvas[visible true, showing true, valid true, displayable true, 5/5 640x480]
    ** THREAD AWT-EventQueue-0
JAWTWindow.updateBounds: [ 0 / 0  640 x 480 ] -> [ 5 / 5  640 x 480 ]
JAWTWindow: surface change 0x3b01187b -> 0xffffffffb7012b77
GLCanvas.setSurfaceScaleImpl reqPixelScale 0.00 0.00, hasPixelScale 1.25 1.25
reshape canvas 800 x 600
display drawable 800 x 600
display canvas bnds 640 x 480 at 5, 5
display panel 650 x 490
display frame 664 x 527

Without the patch, the only difference is

JAWTWindow.updatePixelScale: updated req[0.0, 0.0], min[1.0, 1.0], max[1.25, 1.25], has[1.0, 1.0]
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

Sven Gothel
Administrator
Nice! Thank you!

Yeah, I will review this later on and dive in my memories :)
- has - current pixelScale
- req - requested pixelScale
That's to keep track of the transition etc, trigger a reshape and so forth.

The 'max'  value usually is determined by the system (mostly MacOS).
The whole API started with MacOS .. perhaps it was a bit overdesigned thus.

Now we need to check same for GLJPanel, SWT, ..

Can you make a git commit to merge?
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

Sven Gothel
Administrator
In reply to this post by gbburkhardt
I revised HiDPI a little (simplification for AWT),
see https://jogamp.org/cgit/jogl.git/commit/?id=900c35c6a49e0d53e38dd07da709bf81e28abd3e
HiDPI: Revise AWT GLCanvas/GLJPanel ScalableSurface: No setSurfaceScale(), have AWT toolkit define pixelScale only (simplification)HEADmaster
This aligns with Glenn's initial AWT patch commit e5e7514d649cd7dd28bbb8e04b72338dc09c2c83, i.e. removing redundancies...

Tested on Linux, Windows and MacOS w/ GLCanvas, GLJPanel and GLWindow using pixelScale values:
- Linux: 1, 2
- Windows: 1, 1.25, 2
- MacOS: 1, 2
.. and then perhaps

- HiDPI AWT/NEWT: Propagate AWT enforced pixelScale via setSurfaceScale() blocking native change by monitor-pixelScale (Windows, X11)
  https://jogamp.org/cgit/jogl.git/commit/?id=9d1e7c9adca97780a5b45b135c5693cffee218fc

- HiDPI: NEWT/MacOS: WindowDriver.sizeScreenPosInsetsChanged() is called w/ client-area in windowUnits (*fix regression*)
  https://jogamp.org/cgit/jogl.git/commit/?id=cfe56e9e6bda15873fefce6f03d343ccdfc51f9b

I consider it fixed now .. and will make another RC.

Please test as well, thank you!
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

gbburkhardt
I've run all my tests, and they all work with DPI scaling > 100%.  Thanks for the update.
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

Sven Gothel
Administrator
gbburkhardt wrote
I've run all my tests, and they all work with DPI scaling > 100%.  Thanks for the update.
Great. Yup, ran a bunch of mine (HiDPI section in scripts/tests.sh and the tests-win.bat).
Tedious but .. necessary it was.

Thank you for the review and 1st patch, resulting in the final simplification :)
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

mahesh
This post was updated on .
Is there any way, I can disable automatic scaling as per DPI in GLCanvas?

I have introduced several fixes internally to account for high DPI in my application itself.
left screenshot old jogl jars and right one is with latest jars.
using jogl with and without DPI fix

The text seems to be scaled twice. I am using com.jogamp.opengl.util.awt.TextRenderer to render texts. Does latest jogl includes Dpi fix for textrenderer as well?

One more thing does DPI fix in GLCanvas work for Linux as well?
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

gouessej
Administrator
Hello

You can call setSurfaceScale​() on a GLCanvas.
Julien Gouesse | Personal blog | Website
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

gbburkhardt
This post was updated on .
That won't work for com.jogamp.opengl.awt.GLCanvas.setSurfaceScale, which does nothing except for returning 'false'.  Note that 'canSetSurfaceScale' returns false.  

See commit 900c35c6a.  Mr. Gothel decided not to support this feature for AWT.

'setSurfaceScale' does work for the NEWT implementation of GLCanvas, as it does for some others.  Better to switch to NEWT.  And it shouldn't be too hard to change your application to use the changes for DPI scaling for AWT in the current code base.
Reply | Threaded
Open this post in threaded view
|

Re: DPI scaling not working

gouessej
Administrator
Thank you for the reminder.

What about NewtCanvasAWT in this case?
Julien Gouesse | Personal blog | Website
12