-
-
Notifications
You must be signed in to change notification settings - Fork 26
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
App time variance #37
Comments
FWIW, this was actually the initial design of this plugin.
That was taken from my comments in the initial discussion that spawned this plugin: bevyengine/bevy#3317 However, in practice I had a lot of trouble getting good results from it. This may have predated my use of |
Yeah you'd essentially need to duplicate the framepace PID controller for the framerate limiter. You need very accurate sleep times. |
Yup, I did play around with writing a PID controller, but I may have been limited by platform sleep time accuracy/variance. Definitely worth revisiting this, I appreciate your deep-dive. |
Appreciate the investigation into this. Would be great to get this improved. I can replicate frequent stutters on my machine under Wayland. |
@MatthewScholefield a comprehensive rework of this crate is blocked by bevy's render code, which doesn't currently expose timing information for presenting frames. |
Unfortunately that is the case. I can take another look at the PID impl if I get the time, but it's low on my priority list as I expect improvements will be minor until we can properly measure vblanks. |
Framepacing adds a delay between the previous frame's presentation and the beginning of the current frame's update cycle. It calculates that delay based on the duration of the previous frame's update cycle.
If the current frame's update cycle takes longer than the previous frame, then the current frame's duration (from previous frame's presentation to current frame's presentation), will be longer than the target duration. This is a problem when vsync is enabled, because the current frame will miss the frame buffer refresh that comes after the previous frame's presentation step (the previous frame was 'just in time' for the buffer swap, but the current frame is 'just too late'). As a result, the previous frame will be presented twice. Depending on the vsync buffering strategy and how many frames are buffered, the current frame may be stuck on the frame presentation step all the way until the next buffer refresh.
Even very low variance in update cycle times can therefore lead to frequent frame drops on machines with unbuffered vsync. On machines with buffered vsync I think you will instead see occasional stutter based on desync between frame presentation and the time stamps of the beginning of update cycles.
Frame loss for unbuffered vsync can be solved by adding a 'buffer' to the framepace sleep based on the variance of app times (e.g. 2 standard deviations).
Since vsync is not always on, you'd need an additional framerate limiter just prior to the frame presentation step, which can absorb any remaining time to reach the target frametime. @aevyrie has observed that on machines with buffered vsync you get better results by targeting a slower framerate than the monitor refresh period -> a framerate limiter would allow compile-time configuration to achieve the best strategy for any given machine.
The text was updated successfully, but these errors were encountered: