Advertisement

60fps framelock done properly - without duplicated or skipped frames

Started by December 06, 2019 12:27 PM
11 comments, last by frob 4 years, 10 months ago

This may help: https://medium.com/@tglaiel/how-to-make-your-game-run-at-60fps-24c61210fe75

I would actually try using vsync if the monitor is 60Hz or a multiple thereof, and a timer-based approach if it isn't. You can ask the OS about the monitor refresh rate, or you can measure it if you don't trust the OS. If the monitor is at 75Hz, you're going to get irregular frame duplication no matter what you do, and if the monitor has a variable refresh rate, then using a timer is how you fix the refresh rate to 60Hz.

Advertisement

Thanks for the suggestions and ideas, everyone. That medium.com article really hit the nail on the head!

I have just converted my game loop to busy wait, like this:

constexpr auto frameTime = chrono::duration<int64_t, ratio<1, 60>>(1);
auto nextFrame = chrono::steady_clock::now() + frameTime;
while (true)
{
  if (std::chrono::steady_clock::now() < nextFrame)
  {
    continue;
  }

  // process frame here

  nextFrame += frameTime;
}

Now I only get a very rare single stutter, pretty much what is described in the article. I will modify my solution and try to get rid of that as well. Maybe I could also sleep for, say, half the frame time, knowing that processing my frames is going to be very fast...

d h k said:
Maybe I could also sleep for, say, half the frame time

That puts you right back at the mercy of the OS task scheduler, which was part of the problem to begin with. The default scheduler in Windows is about a full frame in duration. Any sleep at all, even those based on higher resolution timers, will still suffer from the task scheduler's resolution.

Blocking for hardware is the best reliable way to do it, and even that is filled with issues and gotchas.

This topic is closed to new replies.

Advertisement