diff options
author | Bastien Bouclet | 2018-01-01 05:40:41 +0100 |
---|---|---|
committer | Bastien Bouclet | 2018-01-27 18:12:34 +0100 |
commit | 3b50b57f544cb7c719a5f02f061853e10885ae6c (patch) | |
tree | 12a1aed649f42b4b45f16389577e403f9b67daef | |
parent | d5d1229ae303030c4a478504f86e4eefad2ccc11 (diff) | |
download | scummvm-rg350-3b50b57f544cb7c719a5f02f061853e10885ae6c.tar.gz scummvm-rg350-3b50b57f544cb7c719a5f02f061853e10885ae6c.tar.bz2 scummvm-rg350-3b50b57f544cb7c719a5f02f061853e10885ae6c.zip |
GUI: Rework the frame limiter to actually reach the target framerate
The previous combination of a fixed 10 milliseconds delay and time since
last update checks meant that in most cases 20 milliseconds elapsed
between two calls to updateScreen resulting in a 50 fps framerate. On
systems with wait for vsync enabled that meant that some frames were
missed.
The new frame limiter waits for a variable delay equal to the non
consumed time in the slot allocated to the frame.
-rw-r--r-- | gui/gui-manager.cpp | 30 |
1 files changed, 11 insertions, 19 deletions
diff --git a/gui/gui-manager.cpp b/gui/gui-manager.cpp index 76f557711d..2e947c6f32 100644 --- a/gui/gui-manager.cpp +++ b/gui/gui-manager.cpp @@ -299,10 +299,11 @@ void GuiManager::runLoop() { } Common::EventManager *eventMan = _system->getEventManager(); - uint32 lastRedraw = 0; - const uint32 waitTime = 1000 / 60; + const uint32 targetFrameDuration = 1000 / 60; while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) { + uint32 frameStartTime = _system->getMillis(true); + redraw(); // Don't "tickle" the dialog until the theme has had a chance @@ -312,14 +313,6 @@ void GuiManager::runLoop() { if (_useStdCursor) animateCursor(); -// _theme->updateScreen(); -// _system->updateScreen(); - - if (lastRedraw + waitTime < _system->getMillis(true)) { - lastRedraw = _system->getMillis(true); - _theme->updateScreen(); - _system->updateScreen(); - } Common::Event event; @@ -349,13 +342,6 @@ void GuiManager::runLoop() { } processEvent(event, activeDialog); - - - if (lastRedraw + waitTime < _system->getMillis(true)) { - lastRedraw = _system->getMillis(true); - _theme->updateScreen(); - _system->updateScreen(); - } } // Delete GuiObject that have been added to the trash for a delayed deletion @@ -379,8 +365,14 @@ void GuiManager::runLoop() { } } - // Delay for a moment - _system->delayMillis(10); + _theme->updateScreen(); + + // Delay until the allocated frame time is elapsed to match the target frame rate + uint32 actualFrameDuration = _system->getMillis(true) - frameStartTime; + if (actualFrameDuration < targetFrameDuration) { + _system->delayMillis(targetFrameDuration - actualFrameDuration); + } + _system->updateScreen(); } // WORKAROUND: When quitting we might not properly close the dialogs on |