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

Exposing the refresh rate of displays #47

Open
jespertheend opened this issue Jan 13, 2021 · 5 comments
Open

Exposing the refresh rate of displays #47

jespertheend opened this issue Jan 13, 2021 · 5 comments
Labels
enhancement New feature or request

Comments

@jespertheend
Copy link

It is sort of possible to figure out the refresh rate of a display by timing the requestAnimationFrame() events. But I think this api could be a nice place to expose this information in a much more stable way.

My main use case would be figuring out how much time is left to render a frame and making optimisations to make sure a frame can be rendered in time.

@michaelwasserman michaelwasserman added the enhancement New feature or request label Oct 30, 2021
@michaelwasserman
Copy link
Member

This seems like a reasonable enhancement request that may merit future consideration.

@michaelwasserman
Copy link
Member

I'd like to understand more about use cases for exposing this information.

  • Does exposing the current refresh rate alleviate the need to call requestAnimationFrame()?
    • In what practical scenarios is that true? (selecting a video source? animating content without explicitly calling rAF()?
    • Does that reduce power usage and save battery life?
  • Is the current refresh rate the most valuable information here? Or the set of possible refresh rates, etc.?
  • How would variable refresh rates be represented in a web-facing API? (ever-changing Hz? a bool? a bool+max?)
    • If we exposed volatile raw rates, firing Screen.change events would have a negative performance impact, right?

I invite anyone with knowledge about pertinent compositing and graphics performance issues to weigh in.

@jespertheend
Copy link
Author

jespertheend commented Aug 18, 2022

Does exposing the current refresh rate alleviate the need to call requestAnimationFrame()?

Not in most cases I think, the point of rAF() is not only to be fired at the same rate of the refresh rate of the display, the point is also to fire it at an appropriate time where calls to graphics apis are expected to stay in sync with the display. Simply replacing rAF() with setTimeout where the selected timeout is the current refresh rate will almost certainly result in either skipped frames or frames being rendered twice but only displayed once.

In what practical scenarios is that true?

I can't think of many, selecting a video source maybe, but I reckon that's a super niche use case. Animating without calling rAF() will almost certainly give suboptimal results as described above.

Does that reduce power usage and save battery life?

I don't think there will be a significant difference between rAF() or calling setTimeout with the given refresh rate.

Is the current refresh rate the most valuable information here? Or the set of possible refresh rates, etc.?

I'm not exactly sure. For my specific use case I want to dynamically adjust the resolution of a rendered image in order to ensure that the highest possible framerate would be achieved. Such an algorithm would need two variables:

  • The current time it takes to render a frame.
  • The target frame rate.

The current time can be measured by looking at how often the render code is called, which is usually directly linked to requestAnimationFrame(). The target framerate is not so easy to figure out, it can only be estimated.

So the goal here is to look at the current framerate, and if it is lower than the target framerate then adjust the resolution to make sure that the framerate goes up. The problem is that if the current framerate is low, then requestAnimationFrame() is also fired less frequently. So at that point the current framerate and the target framerate are exactly equal.

A system might be running at 60fps because it is using 100% of its resources, but the display might be capable of displaying 144fps. At that point rAF() is called 60 times a second and so there is no way to know if the display might be able to show more frames. In this case being able to see that the screen is, in fact, able to display at 144hz would be useful information. We can automatically lower the resolution in order to reach this target.

While the refresh rate is valuable information, it would be more valuable to have a timing api available that allows you to measure gpu usage accurately. But considering the security implications of that, I think a refresh rate is more reasonable and would allow you to reach the same goal.

How would variable refresh rates be represented in a web-facing API?

To be honest I'm not too familiar with variable refresh rates to be able to really answer this. But I think either null or some kind of flag indicating that the refresh rate is variable would suffice here.
Ever-changing Hz could be nice, considering that the rate at which rAF() fires might be lower when the system is under high load, whereas the refresh rate of the screen might not.

If we exposed volatile raw rates, firing Screen.change events would have a negative performance impact, right?

Firing Screen.change seems less than ideal because many applications don't expect this. And variable refresh rates are not very common so this likely won't get tested by developers either.

@michaelwasserman
Copy link
Member

Thank you for this detailed and prompt response!

I'd also like input from anyone using requestAnimationFrame() without animating (e.g. solely to infer refresh rate).
Some sites reportedly might do that, and understanding their use cases would be valuable here. +CC @rrwinterton

@jespertheend
Copy link
Author

CC @mdrejhon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants