From ae7a2b9f02b4becdcc7cb96f79031c840198989f Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Wed, 17 Feb 2021 15:14:59 +0100 Subject: Change: allow video-drivers to miss deadlines slightly Before, every next frame was calculated from the current time. If for some reason the current frame was drifting a bit, the next would too, and the next more, etc etc. This meant we rarely hit the targets we would like, like 33.33fps. Instead, allow video-drivers to drift slightly, and schedule the next frame based on the time the last should have happened. Only if the drift gets too much, that deadlines are missed for longer period of times, schedule the next frame based on the current time. This makes the FPS a lot smoother, as sleeps aren't as exact as you might think. --- src/video/win32_v.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'src/video/win32_v.cpp') diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 8a80344c4..2fe5f67f0 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.cpp @@ -1207,7 +1207,13 @@ void VideoDriver_Win32::MainLoop() } if (cur_ticks >= next_game_tick || (_fast_forward && !_pause_mode)) { - next_game_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK); + if (_fast_forward && !_pause_mode) { + next_game_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK); + } else { + next_game_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK); + /* Avoid next_game_tick getting behind more and more if it cannot keep up. */ + if (next_game_tick < cur_ticks - std::chrono::milliseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_game_tick = cur_ticks; + } /* Flush GDI buffer to ensure we don't conflict with the drawing thread. */ GdiFlush(); @@ -1220,7 +1226,9 @@ void VideoDriver_Win32::MainLoop() } if (cur_ticks >= next_draw_tick) { - next_draw_tick = cur_ticks + std::chrono::milliseconds(MILLISECONDS_PER_TICK); + next_draw_tick += std::chrono::milliseconds(MILLISECONDS_PER_TICK); + /* Avoid next_draw_tick getting behind more and more if it cannot keep up. */ + if (next_draw_tick < cur_ticks - std::chrono::microseconds(ALLOWED_DRIFT * MILLISECONDS_PER_TICK)) next_draw_tick = cur_ticks; bool old_ctrl_pressed = _ctrl_pressed; -- cgit v1.2.3-54-g00ecf