Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow Hidpi leads to wrong window scale #42085

Open
okapii opened this issue Sep 15, 2020 · 22 comments
Open

Allow Hidpi leads to wrong window scale #42085

okapii opened this issue Sep 15, 2020 · 22 comments

Comments

@okapii
Copy link

okapii commented Sep 15, 2020

Godot version:
3.2.3 RC 6 Official, MacOS

OS/device including version:

  • MacBook Pro (13", 2020)
  • 2,3 GHz Quad-Core Intel Core i7
  • 16 GB 3733 MHz LPDDR4X
  • Intel Iris Plus Graphics 1536 MB

Issue description:
Checking "Allow Hidpi" in the project settings (Display > Window > Dpi) scales down the window size to half (?) its intended size.
It happens with newly created vanilla 3D-projects, too. So this seems not to be about some other conflicting setting.
This appears to be a regression as the current stable build does not have this problem. It has been around for a number of release candidates already.

Steps to reproduce:
Check "Allow Hidpi" in project settings (Display > Window > Dpi).

Minimal reproduction project:
Happy to provide the fresh test-project I just created but since this is a one click operation for a newly created project, I refrained from uploading anything at this point for now.

@okapii okapii changed the title Display > Window > Dpi: Allow Hidpi Allow Hidpi scales leads to wrong window scale Sep 15, 2020
@okapii okapii changed the title Allow Hidpi scales leads to wrong window scale Allow Hidpi leads to wrong window scale Sep 15, 2020
@Calinou
Copy link
Member

Calinou commented Sep 15, 2020

Can you reproduce this in older 3.2.3 RCs and betas? You can download them here.

@okapii
Copy link
Author

okapii commented Sep 15, 2020

Just checked RC1. The issue was in that one already.

@Calinou
Copy link
Member

Calinou commented Sep 15, 2020

@okapii Thanks! If you can build Godot from source, can you bisect the regression? For the bisection, the "good" commit to use is 3.2.2-stable and the bad commit is a24e30abd7b1bc226dc1231ef2b8eb5a9ee50df6.

I don't have a macOS machine with an hiDPI display to test here.

@okapii
Copy link
Author

okapii commented Sep 15, 2020

Sorry, not really equipped with infrastructure / knowledge on how to do that … :(
Could try finding the time to figure this out next weekend.

@okapii
Copy link
Author

okapii commented Sep 17, 2020

I just updated to the new Godot 3.2.3 and the issue exists in that one, too.

@pk-nb
Copy link

pk-nb commented Sep 20, 2020

Hi there! I ran into this issue as well after updating a basic project to 3.2.3 and bisected the two commits above. I believe I've found the specific change:

commit e9ab41b71d59f5555d1171c75b2aa5a72b6e801b
Author: bruvzg <7645683+bruvzg@users.noreply.github.com>
Date:   Tue Jul 7 21:37:05 2020 +0300

    [macOS, 3.2] Implement seamless display scaling.

 core/bind/core_bind.cpp    |  10 ++++
 core/bind/core_bind.h      |   2 +
 core/os/os.h               |   2 +
 doc/classes/OS.xml         |  20 +++++++
 editor/editor_node.cpp     |   4 ++
 editor/editor_run.cpp      |  29 ++++++----
 editor/project_manager.cpp |   7 ++-
 platform/osx/os_osx.h      |  12 +---
 platform/osx/os_osx.mm     | 138 ++++++++++++++++++++++++++-------------------
 9 files changed, 143 insertions(+), 81 deletions(-)

Specific commit: e9ab41b

While I am new to the codebase, I would suspect the code change in editor/editor_run.cpp for window size and scale is what causes this. Not sure if intentional, but does seem surprising to see a halved window size (actual pixels) compared to points that match the rest of the OS windowing.

(Aside: It does appear to properly fix window position centering on a dual monitor setup when starting up the game compared to 3.2.2 which is great!)

@Calinou
Copy link
Member

Calinou commented Sep 20, 2020

cc @bruvzg

@bruvzg
Copy link
Member

bruvzg commented Sep 20, 2020

What's "wrong window scale"? When hiDPI is enabled real screen resolution is used and the window with the same pixel size will appear smaller, it's done for handling multiple displays with different DPI.

Before #40201 scaled resolution was used for both hiDPI and loDPI and multi monitor setups were completely unusable.

For example if you have 1024x768 window in loDPI mode, Godot will create and render 1024x768 window and OS will upscale it to double size on retina screen and keep as is on normal screen.
In hiDPI mode OS will downscale it on normal screen and keep as is on retina.

@pk-nb
Copy link

pk-nb commented Sep 20, 2020

Hey @bruvzg, thanks for the response. The sizing behavior seems to be much improved! Hoping to check my understanding now the behavior has changed a bit. Are the following statements correct?

  • When "Allow HiDPI = false", size units (Width, Height, Test Width, Test Height) are effectively in the unit of points.
  • When "Allow HiDPI = true", size units (Width, Height, Test Width, Test Height) are effectively in the unit of pixels of the highest DPI screen.

The only thing I'm worried about this change is that I'd like to use `Allow HiDPI = true" (for better font oversampling/rasterization) yet have a predictable window size. That seems impossible to do as we can't assume the device density (could be 1x, 2x, 3x, etc) but Test Width and Test Height are interpreted in pixels (effectively baking in a single density assumption).

If my understanding is correct, could I suggest the following?

  • "Test Width" and "Test Height" are always interpreted in the unit of points and scaled by the screen density.
  • (Width and Height are still always in pixels)
  • When Test Width and Test Height are 0, the engine defaults to using the native size as points.
    • That way the default settings yield 1 game pixel = 1 screen point = 1/2/3 actual pixels depending on the display.
    • Example: a game setup with width=480, height=270, testWidth=0, testHeight=0 would yield a screen size of 480x270 points (rendering as 960x540pixels on a typical retina screen).

My feeling is that this would be more intuitive as it more closely matches how macOS handles window units. It seems it would make it easier for developers to setup the same window sizing across monitors in hiDPI mode too, without resorting to scripting.

I am new to this and there may be other solutions or thinking I'm unaware of—so forgive me if this suggestion seems like a bad idea. Thanks so much for your thoughts!


(aside, wanted to share the current behavior for reference)

Example of behavior in 3.2.3 for reference

Screenshots of a game with a native size of 480x270 on a HiDPI screen.

Starting window size when "Allow HiDPI = false"

Window is 480x270 points (960x540 pixels on my HiDPI display).

Screen Shot 2020-09-20 at 2 51 49 PM
Starting window size when "Allow HiDPI = true"

Window is 240x135 points (480x270 pixels on my HiDPI display).

Screen Shot 2020-09-20 at 2 51 36 PM

@bruvzg
Copy link
Member

bruvzg commented Sep 20, 2020

Godot do not have any dynamic UI scaling support (#21446) and all window management is designed to use pixels, so it's always using pixels, we can't use points unless DPI independent rendering is implemented in the renderer.
In loDPI mode it's still using pixels but reports to OS that it does not support hiDPI.

Current solution was done to make editor usable on dual hiDPI + loDPI monitor setup (which is probably the most common mac setup, retina MacBook + external display). I agree, this approach is not most intuitive for macOS users, but it's consistent with other OSes.
And 3.2.2 behavior was my previous attempt to solve the issue (which was faulty, because I was implementing it without hiDPI monitor to test).

Using points is the best solution, but it will require much bigger changes to the renderer to make everything function properly (and outside of mine expertise).
And it's also the way to go on Windows 10, some Linux DEs (AFAIK only latest version of GNOME) seems to have DPI independent mode, but I'm sure how exactly it's implemented.

@Calinou
Copy link
Member

Calinou commented Sep 20, 2020

some Linux DEs (AFAIK only latest version of GNOME) seems to have DPI independent mode, but I'm sure how exactly it's implemented.

As far as I know, loDPI fallbacks on Linux are only available in some Wayland-based desktop environments, not X11. This is because X11 is too limited to provide proper mouse input for windows scaled by the display server.

@DoctorWhoof
Copy link

DoctorWhoof commented Oct 2, 2020

For what it's worth, I like the current behavior in 3.2.3, i.e. turning on HiDPI causes the window to be smaller, since it's displaying the true size in pixels.

This allows me the design a UI with hiDPI that looks identical, albeit smaller, to its non-hiDPI counterpart until I maximize it or go full screen.

What the OP is asking actually makes sense and is more in line with Apple's Retina screen guidelines (I think), but I find less practical. Maybe both can be an option?

Now if Godot's controls had automatic dynamic resizing that preserved the apparent size of everything when changing pixel density, then yes, I think it would make a lot more sense to preserve the dimensions in relation to the monitor size, not in pixels, but with higher/lower pixel count. Is there a request for that already?

@Calinou
Copy link
Member

Calinou commented Oct 2, 2020

@DoctorWhoof We would really prefer to encourage best practices out of the box. Supporting hiDPI displays correctly is a best practice 🙂

Gotta get those WSGF labels somehow…

Now if Godot's controls had automatic dynamic resizing that preserved the apparent size of everything when changing pixel density, then yes, I think it would make a lot more sense to preserve the dimensions in relation to the monitor size, not in pixels, but with higher/lower pixel count. Is there a request for that already?

This already exists in the form of the 2d stretch mode. See Multiple resolutions in the documentation. As for applying a manual scale factor on top of that (or independently of the 2d stretch mode), see #21446.

@DoctorWhoof
Copy link

DoctorWhoof commented Oct 2, 2020

This already exists in the form of the 2d stretch mode

That works well for games, not for applications, which is what I'm focusing on now. For instance, when using 2D stretch mode all text is resized when resizing the window, which is not what you want in an application. Just resize Godot itself to see what I mean.

I feel that to satisfy the original request with Godot applications, Godot's Controls would need to behave in a resolution independent way - i.e. not use pixels as the unit, so that layout can be preserved while increasing pixel density. The effect can actually be achieved via code (I have it working, including resizing the UI on the fly with "zoom" controls), but implementing it is a pain, especially if you didn't start the project like that from the get go.

Supporting hiDPI displays correctly is a best practice

I strongly feel that to support HiDPI switching correctly with applications Godot would need resolution independent controls for GUIs, which is probably a full redesign not in the horizon (unless I'm mistaken!). In the absence of that, the way it handles hiDPI switching now is Ok for applications (layout is preserved, despite the size change), bad for games (window size relative to display size changes, as described in the original request).

Thanks!

@Calinou
Copy link
Member

Calinou commented Oct 2, 2020

@DoctorWhoof As I said, we need to expose a way to manually change the scale factor independently of the window size. This is what #21446 provides.

The editor is already designed in DPI-indepedent pixels for the most part, although it's a manual process – all values have to be multiplied by the EDSCALE macro.

@DoctorWhoof
Copy link

DoctorWhoof commented Oct 2, 2020

Yes @Calinou! Sorry I missed that point, I believe proper hiDPI (like the original request) + a global scale factor like that would work for applications.

Thanks!

@okapii
Copy link
Author

okapii commented Dec 26, 2020

Has there been made any progress regarding this issue? I am pretty much stuck on 3.2.2 for utilising 2D-nodes in my 3D game for the GUI which are all displayed substantially too small in newer versions because of how things are handled now.
This seems like a fairly common combination so I would assume that I am probably not the only one having trouble here?

@Calinou
Copy link
Member

Calinou commented Dec 26, 2020

Has there been made any progress regarding this issue?

Use the 2d stretch mode and expand stretch aspect to ensure that 2D elements are readable on any screen resolution. See Multiple resolutions in the documentation for more information.

For games, the 2d (or viewport) stretch mode are almost always what you want. Pretty much all games released since the late 90s use a variant of this stretch mode. disabled should be reserved to non-game applications.

You can check the godot-demo-projects repository for examples of projects that scale correctly to multiple resolutions and aspect ratios. (Not all demos are suitable for this, but most demos should be.)

@okapii
Copy link
Author

okapii commented Dec 27, 2020

@Calinou Thanks for the feedback! Gonna give that a try!

@akien-mga
Copy link
Member

As I understand it things are working as intended, but it's maybe not the most self explanatory behavior? Does it behave the same on macOS and on other OSes? Should we just document this better?

@pseidemann
Copy link

pseidemann commented Nov 21, 2022

hi everyone :)

issue confirmed with v3.5.1.stable.official [6fed1ff].

@akien-mga,
I think it's not intended once you are trying to create a gui application (like the godot editor itself).

imho there are multiple aspects which need to be considered.

what is allow hidpi currently doing?
it disables scaling of the viewport by the os. it also enables rendering it at the native resolution. this implies that when e.g. a system has 2x scaling (example: display is 4k but user wants desktop size to be logical 1080p), the project will be rendered 2x too small when not doing anything special about that.

what are gui applications?
a gui application is usually a project which uses mostly only control nodes. examples would be the godot editor itself or your favorite browser.

how should gui applications behave regarding scaling?
gui applications should have a proper control element size when starting the app and this size must stay the same regardless of the window size (different from games where fullscreen is often desired so the window size can be "predicted").

what is the behavior with default settings?
gui applications are properly scaled, though it could be argued that they don't render at native resolution, which MIGHT look blurry on some systems.
also I was told that there is some windows bug which is not fixable by godot which breaks window scaling (especially on multi monitor setups?).

gui application: allow hidpi + fix scaling?
I was told to enable stretch mode 2d but this is however NOT a solution because this breaks a fundamental principle how gui applications work. this would make control sizes dependent of the window size. see how should gui applications behave regarding scaling?.

I also ran into that issue while doing an unrelated fix for a godot demo but I couldn't get a good answer to that problem yet: godotengine/godot-demo-projects#791

my conclusion is that currently "allow hidpi" is broken for gui applications. in fact that is also what the guide "multiple resolutions" is stating: https://docs.godotengine.org/en/stable/tutorials/rendering/multiple_resolutions.html

imho a fix might be worth here. maybe implementing dynamic scaling like the godot editor does.

another source: this person on q&a also explains the issue very well but the given answer doesn't fix the issues I mentioned here:
https://godotengine.org/qa/89180/whats-the-right-way-to-support-hidpi

@pseidemann
Copy link

still a problem in godot 4

@KoBeWi KoBeWi modified the milestones: 3.5, 3.x Apr 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants