Tweak frame timing to avoid overloading the main thread

This commit is contained in:
Brad Davis 2017-07-07 13:56:28 -07:00
parent 7e9ea596a0
commit 148eece065

View file

@ -2729,56 +2729,41 @@ bool Application::importSVOFromURL(const QString& urlString) {
return true; return true;
} }
bool _renderRequested { false };
bool Application::event(QEvent* event) { bool Application::event(QEvent* event) {
if (!Menu::getInstance()) { if (!Menu::getInstance()) {
return false; return false;
} }
// Presentation/painting logic int type = event->type();
// TODO: Decouple presentation and painting loops switch (type) {
static bool isPaintingThrottled = false; case Event::Lambda:
if ((int)event->type() == (int)Present) { static_cast<LambdaEvent*>(event)->call();
if (isPaintingThrottled) {
// If painting (triggered by presentation) is hogging the main thread,
// repost as low priority to avoid hanging the GUI.
// This has the effect of allowing presentation to exceed the paint budget by X times and
// only dropping every (1/X) frames, instead of every ceil(X) frames
// (e.g. at a 60FPS target, painting for 17us would fall to 58.82FPS instead of 30FPS).
removePostedEvents(this, Present);
postEvent(this, new QEvent(static_cast<QEvent::Type>(Present)), Qt::LowEventPriority);
isPaintingThrottled = false;
return true; return true;
}
float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed(); case Event::Present:
if (shouldPaint(nsecsElapsed)) { if (!_renderRequested) {
_lastTimeUpdated.start(); float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed();
idle(nsecsElapsed); if (shouldPaint(nsecsElapsed)) {
postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority); _renderRequested = true;
} _lastTimeUpdated.start();
isPaintingThrottled = true; idle(nsecsElapsed);
postEvent(this, new QEvent(static_cast<QEvent::Type>(Paint)), Qt::HighEventPriority);
}
}
return true;
return true; case Event::Paint:
} else if ((int)event->type() == (int)Paint) { // NOTE: This must be updated as close to painting as possible,
// NOTE: This must be updated as close to painting as possible, // or AvatarInputs will mysteriously move to the bottom-right
// or AvatarInputs will mysteriously move to the bottom-right AvatarInputs::getInstance()->update();
AvatarInputs::getInstance()->update(); paintGL();
_renderRequested = false;
return true;
paintGL(); default:
break;
isPaintingThrottled = false;
return true;
} else if ((int)event->type() == (int)Idle) {
float nsecsElapsed = (float)_lastTimeUpdated.nsecsElapsed();
idle(nsecsElapsed);
return true;
}
if ((int)event->type() == (int)Lambda) {
static_cast<LambdaEvent*>(event)->call();
return true;
} }
{ {