Page 1 of 1
Framerate Limiting
Posted: Mon Feb 03, 2025 10:12 pm
by dart_theg
I've tried my hand at limiting the frame rate of my application like so:
u32 then = device->getTimer()->getTime();
f32 const frameDur = 1000.f / m_frameLimit;
^ runs before the update loop, m_frameLimit is the framerate limit (for example, 60 or 144)
f32 frameTime = device->getTimer()->getTime() - now;
if (frameTime < frameDur)
device->sleep((frameDur - frameTime) / 2.0);
^ runs at the end of each update
This results in pretty inconsistent results. What am I doing wrong and are there better approaches I should be using?
Re: Framerate Limiting
Posted: Mon Feb 03, 2025 10:42 pm
by Noiecity
For consistency above 60 frames it is difficult, using vertical sync should be enough (I have not experimented with above 60 hz), but using timers it is difficult to get an accurate time if each frame is rendered in less than 16 ms, from here on the inconsistency is permanent if you rely on frame by frame due to the time it takes for the timer to do the calculation, but it is possible if you rely on more than one frame, for example, use a counter inside the loop and when it reaches an amount that is not 1, for example 4 (4 frames) get the elapsed time and limit.
The other way is to use a timer based on cpu cycles, but it is still quite cumbersome in these cases.
cutealien has been experiencing this problem for a lot of time lmao
Re: Framerate Limiting
Posted: Tue Feb 04, 2025 11:27 am
by CuteAlien
Yeah in short - sleep always sleeps until the next "tick" on Windows. Which happen by default every 16.625ms. And while that tick-time can be changed, there are some complications, see
https://randomascii.wordpress.com/2020/ ... ule-change if you want to dig deep.
With current Irrlicht svn you can try working with repeated calls to yield() and a timer-check instead, but as I learned from the same guy I just linked above that is also bad:
https://randomascii.wordpress.com/2012/ ... f-idleness
So ... Irrlicht sleep() on Windows should really be rewritten once more. In the meantime check those links and then decide what you want to do *sigh*
Maybe you'll even end up producing a nice patch for Irrlicht.
Re: Framerate Limiting
Posted: Tue Feb 04, 2025 2:49 pm
by Brainsaw
I am limiting the framerate using the C++ 11 function std::sleep_until (
https://en.cppreference.com/w/cpp/thread/sleep_until), like this
Calculate the time the frame after the current should be drawn
Render current frame
Sleep until the time calculated above
Seems to work fine for me, but I am only using this on Windows. But as it's standard C++ it should be available everywhere. Works fine I think
Re: Framerate Limiting
Posted: Tue Feb 04, 2025 11:30 pm
by CuteAlien
Try to go beyond 65fps. Unless you speed up the timer even adding 1ms with sleep_until will mean it will sleep until the next Windows tick (the 16.625ms). Wasn't so bad in the past when all screens where limited to 60 fps anyway, but with 144Hz screens it's no longer working well.
Re: Framerate Limiting
Posted: Wed Feb 05, 2025 5:14 am
by dart_theg
Interesting notes, I'll be sure to take a look. Hopefully you're right that I find out a magical patch for this! I'll return if I have any findings.