1
\$\begingroup\$

I'm working on a very simple game, and one of the project goals is to minimise the use of libraries.

I'm drawing every frame into a buffer, which is then displayed using XPutImage (see the code of the main loop). This simple code is used to limit FPS:

// Limit FPS
{
  u64 current_timestamp = LinuxGetWallClock();
  u64 ns_elapsed = LinuxGetWallClock() - last_timestamp;

  if (ns_elapsed < target_nspf) {
    struct timespec ts;
    ts.tv_sec = 0;
    ts.tv_nsec = target_nspf - ns_elapsed;  // time to sleep
    clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);

    while (ns_elapsed < target_nspf) {
      ns_elapsed = LinuxGetWallClock() - last_timestamp;
    }
  } else {
    // printf("Frame missed\n");
  }

  last_timestamp = LinuxGetWallClock();
}

Everything works fine and as expected, but every now and then the image stutters, as if the X server has buffered up a few frames' worth of images and then flushed them all in a single go. This happens irrespective of frame misses.

Note: I'm not talking about image tearing here.

I realise that the code above is not supposed to provide a stable frame rate, and occasionally one frame might be displayed for too long, and another frame might get lost and never displayed, but I don't see how that thing alone can cause the terrible occasional stuttering.

My only guess would be that clock_nanosleep may sleep for longer than I asked for.

Questions:

  • Is my guess above correct?
  • If not, what might be the reason?
  • Are there any ways to address this problem without having to use OpenGL to wait on vblank?

Thanks.

\$\endgroup\$
  • \$\begingroup\$ Hi there. I'm pretty sure this isn't a solution to your issue, but have you tried using CLOCK_MONOTONIC_RAW in your clock_gettime() call? If you look at the manpage for clock_gettime(), it states the following for CLOCK_MONOTONIC_RAW: Similar to CLOCK_MONOTONIC, but provides access to a raw hardware-based time that is not subject to NTP adjustments or the incremental adjustments performed by adjtime(3). So it could cause slight issues with your times, but it's probably very unlikely. But it would be nice to try in order to rule that out. \$\endgroup\$ – Faison Zutavern Aug 20 '17 at 8:08
  • \$\begingroup\$ Hi. Thanks for your comment. Just tried that, it didn't help, as you expected \$\endgroup\$ – Ivan Ivanov Aug 20 '17 at 17:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.