floooh / sokol

minimal cross-platform standalone C headers
https://floooh.github.io/sokol-html5
zlib License
6.99k stars 490 forks source link

Get screen refresh rate (max fps) #866

Open edubart opened 1 year ago

edubart commented 1 year ago

I'm using Sokol App and I'm in a situation where I need to know the screen refresh rate (max fps) in advance. Can Sokol App expose this functionality? Or can we assume this is 60 for all platforms it supports?

floooh commented 1 year ago

I had started looking into this when I wrote the code behind sapp_frame_duration(), and unfortunately at least on browsers it's impossible to query the display refresh rate, and that's basically where I stopped researching (or even the rate at which request animation frame will be called).

You can't assume 60Hz unfortunately either (for instance on M1 Macs the frame callback will be called at 120Hz).

The other thing is that the refresh rate may change when the window is moved from one screen to another.

TL;DR: there's currently no proper solution to get a predictable rate at which the frame callback will be called. The only thing I have in mind is to replace the current swap_interval value with a 'target frame rate hint', and sokol_app.h would try to do it's best to call the frame callback at this rate (but without any guarantees that this actually happens on a specific platform).

ArtemkaKun commented 1 year ago

+1 for that feature

edubart commented 1 year ago

The only thing I have in mind is to replace the current swap_interval value with a 'target frame rate hint'

This would also be nice, even more so if it becomes something I can change at runtime, and perhaps the function could return an unsupported status for some platforms.

Unfortunately at least on browsers it's impossible to query the display refresh rate

The query display refresh rate function could also do the same and return an unsupported error in case of browser. So this would be available at least for some platforms.

The other thing is that the refresh rate may change when the window is moved from one screen to another.

Oh that is tricky, maybe an event could help on that? Or we just check every frame the display refresh rate, to not assume it is always constant.

You can't assume 60Hz unfortunately either (for instance on M1 Macs the frame callback will be called at 120Hz)

In the case of a 120Hz monitor and the 'target frame rate hint' is 60, Sokol could skip every other frame behind the scenes to make it 60. Actually I am doing that, I am using Sokol to draw some games that use unusual refresh rates like 35, 24 .. But without knowing the refresh rate in advance I have to do some timing computations that are not straightforward nor stable, whereas if I knew the display refresh rate I could know exactly which frames I should skip.