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.
This commit is contained in:
parent
d5d1229ae3
commit
3b50b57f54
1 changed files with 11 additions and 19 deletions
|
@ -299,10 +299,11 @@ void GuiManager::runLoop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Common::EventManager *eventMan = _system->getEventManager();
|
Common::EventManager *eventMan = _system->getEventManager();
|
||||||
uint32 lastRedraw = 0;
|
const uint32 targetFrameDuration = 1000 / 60;
|
||||||
const uint32 waitTime = 1000 / 60;
|
|
||||||
|
|
||||||
while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) {
|
while (!_dialogStack.empty() && activeDialog == getTopDialog() && !eventMan->shouldQuit()) {
|
||||||
|
uint32 frameStartTime = _system->getMillis(true);
|
||||||
|
|
||||||
redraw();
|
redraw();
|
||||||
|
|
||||||
// Don't "tickle" the dialog until the theme has had a chance
|
// Don't "tickle" the dialog until the theme has had a chance
|
||||||
|
@ -312,14 +313,6 @@ void GuiManager::runLoop() {
|
||||||
|
|
||||||
if (_useStdCursor)
|
if (_useStdCursor)
|
||||||
animateCursor();
|
animateCursor();
|
||||||
// _theme->updateScreen();
|
|
||||||
// _system->updateScreen();
|
|
||||||
|
|
||||||
if (lastRedraw + waitTime < _system->getMillis(true)) {
|
|
||||||
lastRedraw = _system->getMillis(true);
|
|
||||||
_theme->updateScreen();
|
|
||||||
_system->updateScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
Common::Event event;
|
Common::Event event;
|
||||||
|
|
||||||
|
@ -349,13 +342,6 @@ void GuiManager::runLoop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
processEvent(event, activeDialog);
|
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
|
// Delete GuiObject that have been added to the trash for a delayed deletion
|
||||||
|
@ -379,8 +365,14 @@ void GuiManager::runLoop() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delay for a moment
|
_theme->updateScreen();
|
||||||
_system->delayMillis(10);
|
|
||||||
|
// 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
|
// WORKAROUND: When quitting we might not properly close the dialogs on
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue