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

Fix GLUT thread to redraw at an accurate 60 FPS. #474

Merged
merged 2 commits into from
Apr 19, 2024

Conversation

mkilgore
Copy link
Contributor

Currently the GLUT thread draws the screen too slowly, it is supposed to
default to 60 FPS but you'll always get a bit less than that. This is because
the current logic simply inserts delays for the entire length of a frame, not
taking into account how long it took us to render the last frame. Any time
spent rendering thus results in a slowed down FPS.

The new code uses GetTicks() to measure how much time has passed since
the last render, which then lets us calculate the exact amount of time
until the next frame so we can sleep for that amount. We additionally
then measure how long the sleep lasted vs. what we asked for (since any
sleep we do only has a minimum guarantee, it will occasionally last a bit
longer) and adjust based on that as well. The result is a perfect 60 FPS
as long as rendering is quick enough.

If the rendering falls behind (Ex. a slow _GL SUB is in the program)
then we'll start skipping frames to get back on track. This is behavior
may want to be talk about or perhaps make configurable, I went with
basically having it drop back to 30 FPS (and then 20/15/etc.) if the rendering
is too slow. The alternative would be that we just set the deltaTick back to zero
and render as fast as possible.

The undocumented _FPS command can be used to change the speed from
60 FPS to whatever is desired (with a cap of 200 FPS). This was always
true, but now it should be accurate to whatever you request.

Fixes: #408

Copy link
Contributor

@a740g a740g left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mkilgore Do you think we should document the _FPS command?

@mkilgore
Copy link
Contributor Author

@a740g Maybe, but the _Auto flag is not implemented so that might be a bit of a problem. Based on it's description of "make QB64 auto-adjust fps based on load" I'd rather just get rid of it, functionally we already do that - if the CPU is too slow then the FPS goes down 🤣

What would probably be a good idea is replacing _Auto with a setting to toggle between preferring a stable FPS vs. preferring as many frames as possible under the requested FPS, but I don't really want to mess with implementing that at the moment.

Since the GetTicks() is visible in the logging, it's useful
to have it start from zero rather than an arbitrary number.
Currently the GLUT thread draws the screen too slowly, Ex. The default
is supposed to be 60 FPS, but it will always draw a bit slower than 60
FPS. This is because the current logic simply inserts delays for the
entire length of a frame, not taking into account how long it took us to
render the last frame.

The new code uses GetTicks() to measure how much time has passed since
the last render, which then lets us calculate the exact amount of delay
until the next frame. We additionally then measure how long the delay
lasted vs. what we asked for (since any delay we do only has a minimum
guarentee, it will ocassionally last a bit longer) and adjust based on
that as well. The result is a perfect 60 FPS as long as rendering is
quick enough.

If the rendering falls behind (Ex. a slow _GL SUB is in the program)
then we'll start skipping frames to get back on track.

Fixes: QB64-Phoenix-Edition#408
@grymmjack
Copy link
Contributor

@mkilgore will this fix the stuttering that I shared here:
https://app.screencast.com/7XGWZY42TJJcE

Thank you for this contribution regardless! <3

@a740g
Copy link
Contributor

a740g commented Apr 17, 2024

@mkilgore will this fix the stuttering that I shared here: https://app.screencast.com/7XGWZY42TJJcE

Thank you for this contribution regardless! <3

I think it should.

Thank you @mkilgore for fixing this! You should really push the merge button now. 😁

@mkilgore mkilgore merged commit cc382d4 into QB64-Phoenix-Edition:main Apr 19, 2024
4 checks passed
@mkilgore
Copy link
Contributor Author

@mkilgore will this fix the stuttering that I shared here: https://app.screencast.com/7XGWZY42TJJcE

Thank you for this contribution regardless! <3

Like @a740g said I think it should probably fix some of it, you should see it move at 60 FPS after this. Some of the stutter will be due to syncing between the QB64 thread and the rendering thread and that's not addressed by this. #409 would be a complete fix for that but will also require some level of code modification to use.

@a740g a740g mentioned this pull request May 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

The GLUT thread does not accurately redraw at 60 FPS
4 participants