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

DisplayServer.screen_get_refresh_rate() may be possible on Web on some browsers/systems #65747

Open
nathanfranke opened this issue Sep 13, 2022 · 6 comments

Comments

@nathanfranke
Copy link
Contributor

nathanfranke commented Sep 13, 2022

Godot version

v3.5.stable.arch_linux

System information

Arch on 5.19.7-arch1-1

Issue description

Link to documentation (master): https://docs.godotengine.org/en/latest/classes/class_displayserver.html#class-displayserver-method-screen-get-refresh-rate

Note: Returns -1.0 if the DisplayServer fails to find the refresh rate for the specified screen. On Web, screen_get_refresh_rate will always return -1.0 as there is no way to retrieve the refresh rate on that platform.

Semi-scientific tests:

Steps to reproduce

Assuming N/A, since I am assuming get_screen_refresh_rate is not implemented at all on Web

Minimal reproduction project

No response

@Calinou
Copy link
Member

Calinou commented Sep 13, 2022

TestUFO likely detects the refresh rate by checking the maximum achieved rendered FPS during the session. This only works in situations where the maximum framerate can be reached, and only when V-Sync is not forcibly disabled in the graphics driver. Another downside is that you don't know the refresh rate immediately – you need to wait a few seconds to be able to know it. In a sense, this is like what #52314 is doing.

Either way, on Linux + NVIDIA + Firefox, I get this on a 144 Hz monitor. V-Sync is not forcibly disabled in the driver settings, as there is no way to do so on Linux:

image

And on Chromium:

image

@lawnjelly
Copy link
Member

Yes, as @Calinou says, if delta smoothing finds a refresh rate, that could be easily be returned if that would be useful.

The caveat is it only works if the app is consistently hitting the refresh rate (usually vsync), and by design won't lock on if there is variable frame rate.

@nathanfranke
Copy link
Contributor Author

I think it's worth adding the discussion label, as it might not be worth it to implement something like this until web standards have caught up.

The caveat is it only works if the app is consistently hitting the refresh rate (usually vsync), and by design won't lock on if there is variable frame rate.

What if we run a "fake" process "thread?" that doesn't have much to do, and have it run vsynced. If there is a target framerate, it should be obvious at that point, right?

Just in case that doesn't make sense, let me put it this way. What if you put all your game logic in _physics_process, so now _process will run at a really high frame rate (If it's vsynced, it would be 144fps on a 144Hz monitor) and once we see delta has capped, we have a very good guess on what the refresh rate is.

@Calinou
Copy link
Member

Calinou commented Sep 13, 2022

What if we run a "fake" process "thread?" that doesn't have much to do, and have it run vsynced. If there is a target framerate, it should be obvious at that point, right?

The easiest way to work around the issue is to resize the main viewport to a very small size, hide everything, wait 2 seconds or so, then get the refresh rate after that. You can cache this value across restarts to prevent delaying game startup if desired, or only make it run once a day or so at most.

Detecting whether V-Sync is forcibly disabled in the graphics driver might be doable in another way, but it's not a common option nowadays, and it doesn't work on Vulkan applications anyway.

@nathanfranke
Copy link
Contributor Author

nathanfranke commented Sep 13, 2022

The easiest way to work around the issue is to resize the main viewport to a very small size, hide everything, wait 2 seconds or so, then get the refresh rate after that.

I know this is my issue 😆 but I am just very against this, I'm sure 99.9% of people don't even know about how this method works on the web, it's not worth running a 2 second task, even if it's only the first startup, for something so rarely used.

Unless you propose only running this 2 second task after the method is called, but I feel like that would also raise other issues potentially.

@Calinou
Copy link
Member

Calinou commented Sep 13, 2022

I wasn't saying DisplayServer.screen_get_refresh_rate() should perform the above automatically. This is something you should do in your own game logic to guess the refresh rate.

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

3 participants