Merge pull request #15499 from samcake/coco

BUGZ-92: Refresh rate Throttling refinements
This commit is contained in:
Sam Gateau 2019-05-02 17:24:34 -07:00 committed by GitHub
commit 46f4b13f2f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 80 additions and 68 deletions

View file

@ -4072,9 +4072,6 @@ bool Application::event(QEvent* event) {
case QEvent::KeyRelease: case QEvent::KeyRelease:
keyReleaseEvent(static_cast<QKeyEvent*>(event)); keyReleaseEvent(static_cast<QKeyEvent*>(event));
return true; return true;
case QEvent::FocusIn:
focusInEvent(static_cast<QFocusEvent*>(event));
return true;
case QEvent::FocusOut: case QEvent::FocusOut:
focusOutEvent(static_cast<QFocusEvent*>(event)); focusOutEvent(static_cast<QFocusEvent*>(event));
return true; return true;
@ -4117,6 +4114,11 @@ bool Application::eventFilter(QObject* object, QEvent* event) {
return true; return true;
} }
auto eventType = event->type();
if (eventType == QEvent::KeyPress || eventType == QEvent::KeyRelease || eventType == QEvent::MouseMove) {
getRefreshRateManager().resetInactiveTimer();
}
if (event->type() == QEvent::Leave) { if (event->type() == QEvent::Leave) {
getApplicationCompositor().handleLeaveEvent(); getApplicationCompositor().handleLeaveEvent();
} }
@ -4428,13 +4430,6 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
} }
void Application::focusInEvent(QFocusEvent* event) {
if (!_aboutToQuit && _startUpFinished) {
getRefreshRateManager().setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::RUNNING);
}
}
void Application::focusOutEvent(QFocusEvent* event) { void Application::focusOutEvent(QFocusEvent* event) {
auto inputPlugins = PluginManager::getInstance()->getInputPlugins(); auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
foreach(auto inputPlugin, inputPlugins) { foreach(auto inputPlugin, inputPlugins) {
@ -4442,10 +4437,6 @@ void Application::focusOutEvent(QFocusEvent* event) {
inputPlugin->pluginFocusOutEvent(); inputPlugin->pluginFocusOutEvent();
} }
} }
if (!_aboutToQuit && _startUpFinished) {
getRefreshRateManager().setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::UNFOCUS);
}
// FIXME spacemouse code still needs cleanup // FIXME spacemouse code still needs cleanup
#if 0 #if 0
//SpacemouseDevice::getInstance().focusOutEvent(); //SpacemouseDevice::getInstance().focusOutEvent();
@ -5614,7 +5605,7 @@ void Application::resumeAfterLoginDialogActionTaken() {
_myCamera.setMode(_previousCameraMode); _myCamera.setMode(_previousCameraMode);
cameraModeChanged(); cameraModeChanged();
_startUpFinished = true; _startUpFinished = true;
getRefreshRateManager().setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::RUNNING); getRefreshRateManager().setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::FOCUS_ACTIVE);
} }
void Application::loadAvatarScripts(const QVector<QString>& urls) { void Application::loadAvatarScripts(const QVector<QString>& urls) {
@ -8559,11 +8550,20 @@ void Application::activeChanged(Qt::ApplicationState state) {
switch (state) { switch (state) {
case Qt::ApplicationActive: case Qt::ApplicationActive:
_isForeground = true; _isForeground = true;
if (!_aboutToQuit && _startUpFinished) {
getRefreshRateManager().setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::FOCUS_ACTIVE);
}
break; break;
case Qt::ApplicationSuspended: case Qt::ApplicationSuspended:
break;
case Qt::ApplicationHidden: case Qt::ApplicationHidden:
break;
case Qt::ApplicationInactive: case Qt::ApplicationInactive:
if (!_aboutToQuit && _startUpFinished) {
getRefreshRateManager().setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::UNFOCUS);
}
break;
default: default:
_isForeground = false; _isForeground = false;
break; break;
@ -8894,7 +8894,7 @@ void Application::setDisplayPlugin(DisplayPluginPointer newDisplayPlugin) {
RefreshRateManager& refreshRateManager = getRefreshRateManager(); RefreshRateManager& refreshRateManager = getRefreshRateManager();
refreshRateManager.setRefreshRateOperator(OpenGLDisplayPlugin::getRefreshRateOperator()); refreshRateManager.setRefreshRateOperator(OpenGLDisplayPlugin::getRefreshRateOperator());
bool isHmd = newDisplayPlugin->isHmd(); bool isHmd = newDisplayPlugin->isHmd();
RefreshRateManager::UXMode uxMode = isHmd ? RefreshRateManager::UXMode::HMD : RefreshRateManager::UXMode uxMode = isHmd ? RefreshRateManager::UXMode::VR :
RefreshRateManager::UXMode::DESKTOP; RefreshRateManager::UXMode::DESKTOP;
refreshRateManager.setUXMode(uxMode); refreshRateManager.setUXMode(uxMode);

View file

@ -20,37 +20,40 @@
#include <display-plugins/hmd/HmdDisplayPlugin.h> #include <display-plugins/hmd/HmdDisplayPlugin.h>
static const int HMD_TARGET_RATE = 90; static const int VR_TARGET_RATE = 90;
static const std::array<std::string, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> REFRESH_RATE_PROFILE_TO_STRING = static const std::array<std::string, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> REFRESH_RATE_PROFILE_TO_STRING =
{ { "Eco", "Interactive", "Realtime" } }; { { "Eco", "Interactive", "Realtime" } };
static const std::array<std::string, RefreshRateManager::RefreshRateRegime::REGIME_NUM> REFRESH_RATE_REGIME_TO_STRING = static const std::array<std::string, RefreshRateManager::RefreshRateRegime::REGIME_NUM> REFRESH_RATE_REGIME_TO_STRING =
{ { "Running", "Unfocus", "Minimized", "StartUp", "ShutDown" } }; { { "FocusActive", "FocusInactive", "Unfocus", "Minimized", "StartUp", "ShutDown" } };
static const std::array<std::string, RefreshRateManager::UXMode::UX_NUM> UX_MODE_TO_STRING = static const std::array<std::string, RefreshRateManager::UXMode::UX_NUM> UX_MODE_TO_STRING =
{ { "Desktop", "HMD" } }; { { "Desktop", "VR" } };
static const std::map<std::string, RefreshRateManager::RefreshRateProfile> REFRESH_RATE_PROFILE_FROM_STRING = static const std::map<std::string, RefreshRateManager::RefreshRateProfile> REFRESH_RATE_PROFILE_FROM_STRING =
{ { "Eco", RefreshRateManager::RefreshRateProfile::ECO }, { { "Eco", RefreshRateManager::RefreshRateProfile::ECO },
{ "Interactive", RefreshRateManager::RefreshRateProfile::INTERACTIVE }, { "Interactive", RefreshRateManager::RefreshRateProfile::INTERACTIVE },
{ "Realtime", RefreshRateManager::RefreshRateProfile::REALTIME } }; { "Realtime", RefreshRateManager::RefreshRateProfile::REALTIME } };
static const std::array<int, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> RUNNING_REGIME_PROFILES =
{ { 5, 20, 60 } };
static const std::array<int, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> UNFOCUS_REGIME_PROFILES = // Porfile regimes are:
{ { 5, 5, 10 } }; // { { "FocusActive", "FocusInactive", "Unfocus", "Minimized", "StartUp", "ShutDown" } }
static const std::array<int, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> MINIMIZED_REGIME_PROFILE = static const std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM> ECO_PROFILE =
{ { 2, 2, 2 } }; { { 20, 10, 5, 2, 30, 30 } };
static const std::array<int, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> START_AND_SHUTDOWN_REGIME_PROFILES = static const std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM> INTERACTIVE_PROFILE =
{ { 30, 30, 30 } }; { { 30, 20, 10, 2, 30, 30 } };
static const std::array<std::array<int, RefreshRateManager::RefreshRateProfile::PROFILE_NUM>, RefreshRateManager::RefreshRateRegime::REGIME_NUM> REFRESH_RATE_REGIMES = static const std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM> REALTIME_PROFILE =
{ { RUNNING_REGIME_PROFILES, UNFOCUS_REGIME_PROFILES, MINIMIZED_REGIME_PROFILE, { { 60, 60, 10, 2, 30, 30} };
START_AND_SHUTDOWN_REGIME_PROFILES, START_AND_SHUTDOWN_REGIME_PROFILES } };
static const std::array<std::array<int, RefreshRateManager::RefreshRateRegime::REGIME_NUM>, RefreshRateManager::RefreshRateProfile::PROFILE_NUM> REFRESH_RATE_PROFILES =
{ { ECO_PROFILE, INTERACTIVE_PROFILE, REALTIME_PROFILE } };
static const int INACTIVE_TIMER_LIMIT = 3000;
std::string RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile refreshRateProfile) { std::string RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile refreshRateProfile) {
@ -70,14 +73,36 @@ std::string RefreshRateManager::uxModeToString(RefreshRateManager::RefreshRateMa
} }
RefreshRateManager::RefreshRateManager() { RefreshRateManager::RefreshRateManager() {
_refreshRateProfile = (RefreshRateManager::RefreshRateProfile) _refreshRateMode.get(); _refreshRateProfile = (RefreshRateManager::RefreshRateProfile) _refreshRateProfileSetting.get();
_inactiveTimer->setInterval(INACTIVE_TIMER_LIMIT);
_inactiveTimer->setSingleShot(true);
QObject::connect(_inactiveTimer.get(), &QTimer::timeout, [&] {
toggleInactive();
});
}
void RefreshRateManager::resetInactiveTimer() {
if (_uxMode == RefreshRateManager::UXMode::DESKTOP) {
auto regime = getRefreshRateRegime();
if (regime == RefreshRateRegime::FOCUS_ACTIVE || regime == RefreshRateRegime::FOCUS_INACTIVE) {
_inactiveTimer->start();
setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::FOCUS_ACTIVE);
}
}
}
void RefreshRateManager::toggleInactive() {
if (_uxMode == RefreshRateManager::UXMode::DESKTOP &&
getRefreshRateRegime() == RefreshRateManager::RefreshRateRegime::FOCUS_ACTIVE) {
setRefreshRateRegime(RefreshRateManager::RefreshRateRegime::FOCUS_INACTIVE);
}
} }
void RefreshRateManager::setRefreshRateProfile(RefreshRateManager::RefreshRateProfile refreshRateProfile) { void RefreshRateManager::setRefreshRateProfile(RefreshRateManager::RefreshRateProfile refreshRateProfile) {
if (_refreshRateProfile != refreshRateProfile) { if (_refreshRateProfile != refreshRateProfile) {
_refreshRateModeLock.withWriteLock([&] { _refreshRateProfileSettingLock.withWriteLock([&] {
_refreshRateProfile = refreshRateProfile; _refreshRateProfile = refreshRateProfile;
_refreshRateMode.set((int) refreshRateProfile); _refreshRateProfileSetting.set((int) refreshRateProfile);
}); });
updateRefreshRateController(); updateRefreshRateController();
} }
@ -86,9 +111,9 @@ void RefreshRateManager::setRefreshRateProfile(RefreshRateManager::RefreshRatePr
RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile() const { RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile() const {
RefreshRateManager::RefreshRateProfile profile = RefreshRateManager::RefreshRateProfile::REALTIME; RefreshRateManager::RefreshRateProfile profile = RefreshRateManager::RefreshRateProfile::REALTIME;
if (getUXMode() != RefreshRateManager::UXMode::HMD) { if (getUXMode() != RefreshRateManager::UXMode::VR) {
profile =(RefreshRateManager::RefreshRateProfile) _refreshRateModeLock.resultWithReadLock<int>([&] { profile =(RefreshRateManager::RefreshRateProfile) _refreshRateProfileSettingLock.resultWithReadLock<int>([&] {
return _refreshRateMode.get(); return _refreshRateProfileSetting.get();
}); });
} }
@ -96,8 +121,11 @@ RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile
} }
RefreshRateManager::RefreshRateRegime RefreshRateManager::getRefreshRateRegime() const { RefreshRateManager::RefreshRateRegime RefreshRateManager::getRefreshRateRegime() const {
return getUXMode() == RefreshRateManager::UXMode::HMD ? RefreshRateManager::RefreshRateRegime::RUNNING : if (getUXMode() == RefreshRateManager::UXMode::VR) {
_refreshRateRegime; return RefreshRateManager::RefreshRateRegime::FOCUS_ACTIVE;
} else {
return _refreshRateRegime;
}
} }
void RefreshRateManager::setRefreshRateRegime(RefreshRateManager::RefreshRateRegime refreshRateRegime) { void RefreshRateManager::setRefreshRateRegime(RefreshRateManager::RefreshRateRegime refreshRateRegime) {
@ -119,31 +147,12 @@ void RefreshRateManager::updateRefreshRateController() const {
if (_refreshRateOperator) { if (_refreshRateOperator) {
int targetRefreshRate; int targetRefreshRate;
if (_uxMode == RefreshRateManager::UXMode::DESKTOP) { if (_uxMode == RefreshRateManager::UXMode::DESKTOP) {
if (_refreshRateRegime == RefreshRateManager::RefreshRateRegime::RUNNING && targetRefreshRate = REFRESH_RATE_PROFILES[_refreshRateProfile][_refreshRateRegime];
_refreshRateProfile == RefreshRateManager::RefreshRateProfile::INTERACTIVE) {
targetRefreshRate = getInteractiveRefreshRate();
} else {
targetRefreshRate = REFRESH_RATE_REGIMES[_refreshRateRegime][_refreshRateProfile];
}
} else { } else {
targetRefreshRate = HMD_TARGET_RATE; targetRefreshRate = VR_TARGET_RATE;
} }
_refreshRateOperator(targetRefreshRate); _refreshRateOperator(targetRefreshRate);
_activeRefreshRate = targetRefreshRate; _activeRefreshRate = targetRefreshRate;
} }
} }
void RefreshRateManager::setInteractiveRefreshRate(int refreshRate) {
_refreshRateLock.withWriteLock([&] {
_interactiveRefreshRate.set(refreshRate);
});
updateRefreshRateController();
}
int RefreshRateManager::getInteractiveRefreshRate() const {
return _refreshRateLock.resultWithReadLock<int>([&] {
return _interactiveRefreshRate.get();
});
}

View file

@ -15,6 +15,8 @@
#include <map> #include <map>
#include <string> #include <string>
#include <QTimer>
#include <SettingHandle.h> #include <SettingHandle.h>
#include <shared/ReadWriteLockable.h> #include <shared/ReadWriteLockable.h>
@ -28,7 +30,8 @@ public:
}; };
enum RefreshRateRegime { enum RefreshRateRegime {
RUNNING = 0, FOCUS_ACTIVE = 0,
FOCUS_INACTIVE,
UNFOCUS, UNFOCUS,
MINIMIZED, MINIMIZED,
STARTUP, STARTUP,
@ -38,7 +41,7 @@ public:
enum UXMode { enum UXMode {
DESKTOP = 0, DESKTOP = 0,
HMD, VR,
UX_NUM UX_NUM
}; };
@ -57,8 +60,9 @@ public:
void setRefreshRateOperator(std::function<void(int)> refreshRateOperator) { _refreshRateOperator = refreshRateOperator; } void setRefreshRateOperator(std::function<void(int)> refreshRateOperator) { _refreshRateOperator = refreshRateOperator; }
int getActiveRefreshRate() const { return _activeRefreshRate; } int getActiveRefreshRate() const { return _activeRefreshRate; }
void updateRefreshRateController() const; void updateRefreshRateController() const;
void setInteractiveRefreshRate(int refreshRate);
int getInteractiveRefreshRate() const; void resetInactiveTimer();
void toggleInactive();
static std::string refreshRateProfileToString(RefreshRateProfile refreshRateProfile); static std::string refreshRateProfileToString(RefreshRateProfile refreshRateProfile);
static RefreshRateProfile refreshRateProfileFromString(std::string refreshRateProfile); static RefreshRateProfile refreshRateProfileFromString(std::string refreshRateProfile);
@ -66,18 +70,17 @@ public:
static std::string refreshRateRegimeToString(RefreshRateRegime refreshRateRegime); static std::string refreshRateRegimeToString(RefreshRateRegime refreshRateRegime);
private: private:
mutable ReadWriteLockable _refreshRateLock;
mutable ReadWriteLockable _refreshRateModeLock;
mutable int _activeRefreshRate { 20 }; mutable int _activeRefreshRate { 20 };
RefreshRateProfile _refreshRateProfile { RefreshRateProfile::INTERACTIVE}; RefreshRateProfile _refreshRateProfile { RefreshRateProfile::INTERACTIVE};
RefreshRateRegime _refreshRateRegime { RefreshRateRegime::STARTUP }; RefreshRateRegime _refreshRateRegime { RefreshRateRegime::STARTUP };
UXMode _uxMode; UXMode _uxMode;
Setting::Handle<int> _interactiveRefreshRate { "interactiveRefreshRate", 20}; mutable ReadWriteLockable _refreshRateProfileSettingLock;
Setting::Handle<int> _refreshRateMode { "refreshRateProfile", INTERACTIVE }; Setting::Handle<int> _refreshRateProfileSetting { "refreshRateProfile", RefreshRateProfile::INTERACTIVE };
std::function<void(int)> _refreshRateOperator { nullptr }; std::function<void(int)> _refreshRateOperator { nullptr };
std::shared_ptr<QTimer> _inactiveTimer { std::make_shared<QTimer>() };
}; };
#endif #endif