From a6646d8dffdd40ace5db7268761048fc535a553e Mon Sep 17 00:00:00 2001 From: latex Date: Wed, 29 Nov 2023 22:29:02 +0100 Subject: [PATCH] Custom refresh rate profile WIP This adds a Custom refresh rate profile with configurable refresh rate regimes. Unfortunately this commit does not work yet. The SpinBoxes inside GraphicsSettings are on top of each other, and changing the values for the Custom profile through e.g. the JS API does not actually affect the refresh rate cap at all for some reason. --- .../dialogs/graphics/GraphicsSettings.qml | 134 +++++++++++++++++- interface/src/RefreshRateManager.cpp | 22 ++- interface/src/RefreshRateManager.h | 7 + .../PerformanceScriptingInterface.cpp | 12 +- .../scripting/PerformanceScriptingInterface.h | 16 +++ interface/src/ui/PreferencesDialog.cpp | 3 +- 6 files changed, 190 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml b/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml index 06894d9576..feb42f59a4 100644 --- a/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml +++ b/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml @@ -347,6 +347,10 @@ Flickable { text: "Real-Time" refreshRatePreset: 2 // RefreshRateProfile::REALTIME } + ListElement { + text: "Custom" + refreshRatePreset: 3 // RefreshRateProfile::CUSTOM + } } HifiControlsUit.ComboBox { @@ -366,8 +370,10 @@ Flickable { refreshRateDropdown.currentIndex = 0; } else if (Performance.getRefreshRateProfile() === 1) { refreshRateDropdown.currentIndex = 1; - } else { + } else if (Performance.getRefreshRateProfile() === 2) { refreshRateDropdown.currentIndex = 2; + } else { + refreshRateDropdown.currentIndex = 3; } } @@ -380,6 +386,132 @@ Flickable { refreshRateDropdown.displayText = model.get(currentIndex).text; } } + + HifiControlsUit.SpinBox { + id: refreshRateCustomFocusActive + decimals: 0 + width: 160 + height: parent.height + suffix: " FPS" + label: "Focus Active" + minimumValue: 1.0 + realStepSize: 1.0 + realValue: 60.0 + colorScheme: hifi.colorSchemes.dark + + Component.onCompleted: { + realValue = Performance.getCustomRefreshRate(0) + } + + onRealValueChanged: { + Performance.setCustomRefreshRate(0, realValue); + } + } + + HifiControlsUit.SpinBox { + id: refreshRateCustomFocusInactive + decimals: 0 + width: 160 + height: parent.height + suffix: " FPS" + label: "Focus Inactive" + minimumValue: 1.0 + realStepSize: 1.0 + realValue: 60.0 + colorScheme: hifi.colorSchemes.dark + + Component.onCompleted: { + realValue = Performance.getCustomRefreshRate(1) + } + + onRealValueChanged: { + Performance.setCustomRefreshRate(1, realValue); + } + } + + HifiControlsUit.SpinBox { + id: refreshRateCustomUnfocus + decimals: 0 + width: 160 + height: parent.height + suffix: " FPS" + label: "Unfocus" + minimumValue: 1.0 + realStepSize: 1.0 + realValue: 60.0 + colorScheme: hifi.colorSchemes.dark + + Component.onCompleted: { + realValue = Performance.getCustomRefreshRate(2) + } + + onRealValueChanged: { + Performance.setCustomRefreshRate(2, realValue); + } + } + + HifiControlsUit.SpinBox { + id: refreshRateCustomMinimized + decimals: 0 + width: 160 + height: parent.height + suffix: " FPS" + label: "Minimized" + minimumValue: 1.0 + realStepSize: 1.0 + realValue: 60.0 + colorScheme: hifi.colorSchemes.dark + + Component.onCompleted: { + realValue = Performance.getCustomRefreshRate(3) + } + + onRealValueChanged: { + Performance.setCustomRefreshRate(3, realValue); + } + } + + HifiControlsUit.SpinBox { + id: refreshRateCustomStartup + decimals: 0 + width: 160 + height: parent.height + suffix: " FPS" + label: "Startup" + minimumValue: 1.0 + realStepSize: 1.0 + realValue: 60.0 + colorScheme: hifi.colorSchemes.dark + + Component.onCompleted: { + realValue = Performance.getCustomRefreshRate(4) + } + + onRealValueChanged: { + Performance.setCustomRefreshRate(4, realValue); + } + } + + HifiControlsUit.SpinBox { + id: refreshRateCustomShutdown + decimals: 0 + width: 160 + height: parent.height + suffix: " FPS" + label: "Shutdown" + minimumValue: 1.0 + realStepSize: 1.0 + realValue: 60.0 + colorScheme: hifi.colorSchemes.dark + + Component.onCompleted: { + realValue = Performance.getCustomRefreshRate(5) + } + + onRealValueChanged: { + Performance.setCustomRefreshRate(5, realValue); + } + } } Item { diff --git a/interface/src/RefreshRateManager.cpp b/interface/src/RefreshRateManager.cpp index 09428da5ea..0238267180 100644 --- a/interface/src/RefreshRateManager.cpp +++ b/interface/src/RefreshRateManager.cpp @@ -94,7 +94,8 @@ static const std::array UX_MODE static const std::map REFRESH_RATE_PROFILE_FROM_STRING = { { "Eco", RefreshRateManager::RefreshRateProfile::ECO }, { "Interactive", RefreshRateManager::RefreshRateProfile::INTERACTIVE }, - { "Realtime", RefreshRateManager::RefreshRateProfile::REALTIME } }; + { "Realtime", RefreshRateManager::RefreshRateProfile::REALTIME }, + { "Custom", RefreshRateManager::RefreshRateProfile::CUSTOM } }; // Porfile regimes are: @@ -168,6 +169,25 @@ void RefreshRateManager::setRefreshRateProfile(RefreshRateManager::RefreshRatePr } } +int RefreshRateManager::getCustomRefreshRate(RefreshRateRegime regime) +{ + Q_ASSERT(regime >= 0 && regime < RefreshRateRegime::REGIME_NUM); + if (regime < 0 && regime >= RefreshRateRegime::REGIME_NUM) + return -1; + + return _customProfile[regime]; +} + +int RefreshRateManager::setCustomRefreshRate(RefreshRateRegime regime, int value) +{ + Q_ASSERT(regime >= 0 && regime < RefreshRateRegime::REGIME_NUM); + if (regime < 0 && regime >= RefreshRateRegime::REGIME_NUM) + return -1; + + _customProfile[regime] = value; + return 0; +} + RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile() const { RefreshRateManager::RefreshRateProfile profile = RefreshRateManager::RefreshRateProfile::REALTIME; diff --git a/interface/src/RefreshRateManager.h b/interface/src/RefreshRateManager.h index 4b91f0c45e..27c615d2e0 100644 --- a/interface/src/RefreshRateManager.h +++ b/interface/src/RefreshRateManager.h @@ -32,6 +32,7 @@ public: ECO = 0, INTERACTIVE, REALTIME, + CUSTOM, PROFILE_NUM }; Q_ENUM(RefreshRateProfile) @@ -106,6 +107,9 @@ public: // query the refresh rate target at the specified combination int queryRefreshRateTarget(RefreshRateProfile profile, RefreshRateRegime regime, UXMode uxMode) const; + int getCustomRefreshRate(RefreshRateRegime regime); + int setCustomRefreshRate(RefreshRateRegime regime, int value); + void resetInactiveTimer(); void toggleInactive(); @@ -115,6 +119,9 @@ public: static std::string refreshRateRegimeToString(RefreshRateRegime refreshRateRegime); private: + std::array _customProfile = + { { 0, 0, 0, 0, 0, 0 } }; + mutable int _activeRefreshRate { 20 }; RefreshRateProfile _refreshRateProfile { RefreshRateProfile::INTERACTIVE}; RefreshRateRegime _refreshRateRegime { RefreshRateRegime::STARTUP }; diff --git a/interface/src/scripting/PerformanceScriptingInterface.cpp b/interface/src/scripting/PerformanceScriptingInterface.cpp index 9f3534b3e8..f619729eff 100644 --- a/interface/src/scripting/PerformanceScriptingInterface.cpp +++ b/interface/src/scripting/PerformanceScriptingInterface.cpp @@ -56,12 +56,22 @@ void PerformanceScriptingInterface::setRefreshRateProfile(RefreshRateProfile ref emit settingsChanged(); } +void PerformanceScriptingInterface::setCustomRefreshRate(RefreshRateManager::RefreshRateRegime refreshRateRegime, int value) +{ + qApp->getRefreshRateManager().setCustomRefreshRate(refreshRateRegime, value); + emit settingsChanged(); +} + +int PerformanceScriptingInterface::getCustomRefreshRate(RefreshRateManager::RefreshRateRegime refreshRateRegime) const { + return qApp->getRefreshRateManager().getCustomRefreshRate(refreshRateRegime); +} + PerformanceScriptingInterface::RefreshRateProfile PerformanceScriptingInterface::getRefreshRateProfile() const { return (PerformanceScriptingInterface::RefreshRateProfile)qApp->getRefreshRateManager().getRefreshRateProfile(); } QStringList PerformanceScriptingInterface::getRefreshRateProfileNames() const { - static const QStringList refreshRateProfileNames = { "ECO", "INTERACTIVE", "REALTIME" }; + static const QStringList refreshRateProfileNames = { "ECO", "INTERACTIVE", "REALTIME", "CUSTOM" }; return refreshRateProfileNames; } diff --git a/interface/src/scripting/PerformanceScriptingInterface.h b/interface/src/scripting/PerformanceScriptingInterface.h index 86350c8a1f..05e2c1d7bc 100644 --- a/interface/src/scripting/PerformanceScriptingInterface.h +++ b/interface/src/scripting/PerformanceScriptingInterface.h @@ -127,6 +127,22 @@ public slots: */ void setRefreshRateProfile(RefreshRateProfile refreshRateProfile); + /*@jsdoc + * Sets a custom refresh rate. + * @function Performance.setCustomRefreshRate + * @param {RefreshRateRegime} refreshRateRegime - The refresh rate regime + * @param {int} value - The value for the regime + */ + void setCustomRefreshRate(RefreshRateManager::RefreshRateRegime refreshRateRegime, int value); + + /*@jsdoc + * Gets the value for a specific RefreshRateRegime. + * @function Performance.getCustomRefreshRate + * @param {RefreshRateRegime} - The regime to get the value from + * @returns {int} - The value from the specified regime + */ + int getCustomRefreshRate(RefreshRateManager::RefreshRateRegime regime) const; + /*@jsdoc * Gets the current refresh rate profile in use. * @function Performance.getRefreshRateProfile diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index 8597cb5717..ce5a588776 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -100,7 +100,8 @@ void setupPreferences() { QStringList refreshRateProfiles { QString::fromStdString(RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile::ECO)), QString::fromStdString(RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile::INTERACTIVE)), - QString::fromStdString(RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile::REALTIME)) }; + QString::fromStdString(RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile::REALTIME)), + QString::fromStdString(RefreshRateManager::refreshRateProfileToString(RefreshRateManager::RefreshRateProfile::CUSTOM)) }; preference->setItems(refreshRateProfiles); preferences->addPreference(preference);