From 3bcb305f70b0ec3fd1ad4fa58da5ef56e96d32f3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 18 Oct 2019 11:51:51 +1300 Subject: [PATCH 1/4] Santize LODManager.setWorldQualityDetail() parameter value --- interface/src/LODManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 3e47d88f3c..9fd7b0851a 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -397,7 +397,7 @@ void LODManager::setWorldDetailQuality(float quality) { static const float MIN_FPS = 10; static const float LOW = 0.25f; - bool isLowestValue = quality == LOW; + bool isLowestValue = quality <= LOW; bool isHMDMode = qApp->isHMDMode(); float maxFPS = isHMDMode ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS; From 378c47d16cb953d465a167ff7fcad910dd87cfdf Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 22 Oct 2019 19:18:11 +1300 Subject: [PATCH 2/4] Replace world detail quality float with enum --- .../dialogs/graphics/GraphicsSettings.qml | 14 +--- interface/src/Application.cpp | 1 + interface/src/LODManager.cpp | 78 +++++++------------ interface/src/LODManager.h | 57 ++++++++++---- interface/src/PerformanceManager.cpp | 6 +- interface/src/ui/PreferencesDialog.cpp | 17 ++-- 6 files changed, 88 insertions(+), 85 deletions(-) diff --git a/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml b/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml index 8634648d17..3b6502cc98 100644 --- a/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml +++ b/interface/resources/qml/hifi/dialogs/graphics/GraphicsSettings.qml @@ -133,15 +133,12 @@ Item { ListElement { text: "Low World Detail" - worldDetailQualityValue: 0.25 } ListElement { text: "Medium World Detail" - worldDetailQualityValue: 0.5 } ListElement { text: "Full World Detail" - worldDetailQualityValue: 0.75 } } @@ -158,14 +155,7 @@ Item { currentIndex: -1 function refreshWorldDetailDropdown() { - var currentWorldDetailQuality = LODManager.worldDetailQuality; - if (currentWorldDetailQuality <= 0.25) { - worldDetailDropdown.currentIndex = 0; - } else if (currentWorldDetailQuality <= 0.5) { - worldDetailDropdown.currentIndex = 1; - } else { - worldDetailDropdown.currentIndex = 2; - } + worldDetailDropdown.currentIndex = LODManager.worldDetailQuality; } Component.onCompleted: { @@ -173,7 +163,7 @@ Item { } onCurrentIndexChanged: { - LODManager.worldDetailQuality = model.get(currentIndex).worldDetailQualityValue; + LODManager.worldDetailQuality = currentIndex; worldDetailDropdown.displayText = model.get(currentIndex).text; } } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a10e17c010..257808c683 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -7508,6 +7508,7 @@ void Application::registerScriptEngineWithApplicationServices(const ScriptEngine scriptEngine->registerGlobalObject("AvatarManager", DependencyManager::get().data()); scriptEngine->registerGlobalObject("LODManager", DependencyManager::get().data()); + qScriptRegisterMetaType(scriptEngine.data(), worldDetailQualityToScriptValue, worldDetailQualityFromScriptValue); scriptEngine->registerGlobalObject("Keyboard", DependencyManager::get().data()); scriptEngine->registerGlobalObject("Performance", new PerformanceScriptingInterface()); diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 9fd7b0851a..1a72dffe20 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -19,11 +19,8 @@ #include "ui/DialogsManager.h" #include "InterfaceLogging.h" -const float LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS = LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS; -const float LODManager::DEFAULT_HMD_LOD_DOWN_FPS = LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS; - -Setting::Handle desktopLODDecreaseFPS("desktopLODDecreaseFPS", LODManager::DEFAULT_DESKTOP_LOD_DOWN_FPS); -Setting::Handle hmdLODDecreaseFPS("hmdLODDecreaseFPS", LODManager::DEFAULT_HMD_LOD_DOWN_FPS); +Setting::Handle desktopWorldDetailQuality("desktopWorldDetailQuality", (int)DEFAULT_WORLD_DETAIL_QUALITY); +Setting::Handle hmdWorldDetailQuality("hmdWorldDetailQuality", (int)DEFAULT_WORLD_DETAIL_QUALITY); LODManager::LODManager() { } @@ -326,19 +323,21 @@ QString LODManager::getLODFeedbackText() { } void LODManager::loadSettings() { - setDesktopLODTargetFPS(desktopLODDecreaseFPS.get()); - Setting::Handle firstRun { Settings::firstRun, true }; + auto desktopQuality = static_cast(desktopWorldDetailQuality.get()); + auto hmdQuality = static_cast(hmdWorldDetailQuality.get()); + + Setting::Handle firstRun{ Settings::firstRun, true }; if (qApp->property(hifi::properties::OCULUS_STORE).toBool() && firstRun.get()) { - const float LOD_HIGH_QUALITY_LEVEL = 0.75f; - setHMDLODTargetFPS(LOD_HIGH_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS); - } else { - setHMDLODTargetFPS(hmdLODDecreaseFPS.get()); + hmdQuality = WORLD_DETAIL_HIGH; } + + setWorldDetailQuality(desktopQuality, false); + setWorldDetailQuality(hmdQuality, true); } void LODManager::saveSettings() { - desktopLODDecreaseFPS.set(getDesktopLODTargetFPS()); - hmdLODDecreaseFPS.set(getHMDLODTargetFPS()); + desktopWorldDetailQuality.set((int)_desktopWorldDetailQuality); + hmdWorldDetailQuality.set((int)_hmdWorldDetailQuality); } const float MIN_DECREASE_FPS = 0.5f; @@ -393,54 +392,35 @@ float LODManager::getLODTargetFPS() const { } } -void LODManager::setWorldDetailQuality(float quality) { +void LODManager::setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode) { static const float MIN_FPS = 10; - static const float LOW = 0.25f; - - bool isLowestValue = quality <= LOW; - bool isHMDMode = qApp->isHMDMode(); - - float maxFPS = isHMDMode ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS; - float desiredFPS = maxFPS; - - if (!isLowestValue) { - float calculatedFPS = (maxFPS - (maxFPS * quality)); - desiredFPS = calculatedFPS < MIN_FPS ? MIN_FPS : calculatedFPS; - } + float desiredFPS = isHMDMode ? QUALITY_TO_FPS_HMD[quality] : QUALITY_TO_FPS_DESKTOP[quality]; if (isHMDMode) { + _hmdWorldDetailQuality = quality; setHMDLODTargetFPS(desiredFPS); } else { + _desktopWorldDetailQuality = quality; setDesktopLODTargetFPS(desiredFPS); } - +} + +void LODManager::setWorldDetailQuality(WorldDetailQuality quality) { + setWorldDetailQuality(quality, qApp->isHMDMode()); emit worldDetailQualityChanged(); } -float LODManager::getWorldDetailQuality() const { +WorldDetailQuality LODManager::getWorldDetailQuality() const { + return qApp->isHMDMode() ? _hmdWorldDetailQuality : _desktopWorldDetailQuality; +} - static const float LOW = 0.25f; - static const float MEDIUM = 0.5f; - static const float HIGH = 0.75f; +QScriptValue worldDetailQualityToScriptValue(QScriptEngine* engine, const WorldDetailQuality& worldDetailQuality) { + return worldDetailQuality; +} - bool inHMD = qApp->isHMDMode(); - - float targetFPS = 0.0f; - if (inHMD) { - targetFPS = getHMDLODTargetFPS(); - } else { - targetFPS = getDesktopLODTargetFPS(); - } - float maxFPS = inHMD ? LOD_MAX_LIKELY_HMD_FPS : LOD_MAX_LIKELY_DESKTOP_FPS; - float percentage = 1.0f - targetFPS / maxFPS; - - if (percentage <= LOW) { - return LOW; - } else if (percentage <= MEDIUM) { - return MEDIUM; - } - - return HIGH; +void worldDetailQualityFromScriptValue(const QScriptValue& object, WorldDetailQuality& worldDetailQuality) { + worldDetailQuality = + static_cast(std::min(std::max(object.toInt32(), (int)WORLD_DETAIL_LOW), (int)WORLD_DETAIL_HIGH)); } void LODManager::setLODQualityLevel(float quality) { diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 3dafa8c800..1a516e0410 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -23,26 +23,52 @@ #include +/**jsdoc + *

The world detail quality rendered.

+ * + * + * + * + * + * + * + * + * + *
ValueDescription
0Low world detail quality.
1Medium world detail quality.
2High world detail quality.
+ * @typedef {number} LODManager.WorldDetailQuality + */ +enum WorldDetailQuality { + WORLD_DETAIL_LOW = 0, + WORLD_DETAIL_MEDIUM, + WORLD_DETAIL_HIGH +}; +Q_DECLARE_METATYPE(WorldDetailQuality); + #ifdef Q_OS_ANDROID const float LOD_DEFAULT_QUALITY_LEVEL = 0.2f; // default quality level setting is High (lower framerate) #else const float LOD_DEFAULT_QUALITY_LEVEL = 0.5f; // default quality level setting is Mid #endif -const float LOD_MAX_LIKELY_DESKTOP_FPS = 60.0f; // this is essentially, V-synch fps + #ifdef Q_OS_ANDROID -const float LOD_MAX_LIKELY_HMD_FPS = 36.0f; // this is essentially, V-synch fps +const WorldDetailQuality DEFAULT_WORLD_DETAIL_QUALITY = WORLD_DETAIL_LOW; +const std::vector QUALITY_TO_FPS_DESKTOP = { 60.0f, 30.0f, 15.0f }; +const std::vector QUALITY_TO_FPS_HMD = { 25.0f, 16.0f, 10.0f }; #else -const float LOD_MAX_LIKELY_HMD_FPS = 90.0f; // this is essentially, V-synch fps +const WorldDetailQuality DEFAULT_WORLD_DETAIL_QUALITY = WORLD_DETAIL_MEDIUM; +const std::vector QUALITY_TO_FPS_DESKTOP = { 60.0f, 30.0f, 15.0f }; +const std::vector QUALITY_TO_FPS_HMD = { 90.0f, 45.0f, 22.5f }; #endif const float LOD_OFFSET_FPS = 5.0f; // offset of FPS to add for computing the target framerate class AABox; + /**jsdoc * The LOD class manages your Level of Detail functions within Interface. * @namespace LODManager - * + * * @hifi-interface * @hifi-client-entity * @hifi-avatar @@ -51,12 +77,12 @@ class AABox; * @property {number} engineRunTime Read-only. * @property {number} gpuTime Read-only. */ - class LODManager : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY - Q_PROPERTY(float worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality NOTIFY worldDetailQualityChanged) + Q_PROPERTY(WorldDetailQuality worldDetailQuality READ getWorldDetailQuality WRITE setWorldDetailQuality + NOTIFY worldDetailQualityChanged) Q_PROPERTY(float lodQualityLevel READ getLODQualityLevel WRITE setLODQualityLevel NOTIFY lodQualityLevelChanged) @@ -193,8 +219,8 @@ public: float getSmoothRenderTime() const { return _smoothRenderTime; }; float getSmoothRenderFPS() const { return (_smoothRenderTime > 0.0f ? (float)MSECS_PER_SECOND / _smoothRenderTime : 0.0f); }; - void setWorldDetailQuality(float quality); - float getWorldDetailQuality() const; + void setWorldDetailQuality(WorldDetailQuality quality); + WorldDetailQuality getWorldDetailQuality() const; void setLODQualityLevel(float quality); float getLODQualityLevel() const; @@ -220,9 +246,6 @@ public: float getPidOd() const; float getPidO() const; - static const float DEFAULT_DESKTOP_LOD_DOWN_FPS; - static const float DEFAULT_HMD_LOD_DOWN_FPS; - signals: /**jsdoc @@ -244,6 +267,8 @@ signals: private: LODManager(); + void LODManager::setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode); + std::mutex _automaticLODLock; bool _automaticLODAdjust = true; @@ -258,8 +283,11 @@ private: float _lodQualityLevel{ LOD_DEFAULT_QUALITY_LEVEL }; - float _desktopTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_DESKTOP_FPS }; - float _hmdTargetFPS { LOD_OFFSET_FPS + LOD_DEFAULT_QUALITY_LEVEL * LOD_MAX_LIKELY_HMD_FPS }; + WorldDetailQuality _desktopWorldDetailQuality { DEFAULT_WORLD_DETAIL_QUALITY }; + WorldDetailQuality _hmdWorldDetailQuality { DEFAULT_WORLD_DETAIL_QUALITY }; + + float _desktopTargetFPS { QUALITY_TO_FPS_DESKTOP[_desktopWorldDetailQuality] }; + float _hmdTargetFPS { QUALITY_TO_FPS_HMD[_hmdWorldDetailQuality] }; float _lodHalfAngle = getHalfAngleFromVisibilityDistance(DEFAULT_VISIBILITY_DISTANCE_FOR_UNIT_ELEMENT); int _boundaryLevelAdjust = 0; @@ -269,4 +297,7 @@ private: glm::vec4 _pidOutputs{ 0.0f }; }; +QScriptValue worldDetailQualityToScriptValue(QScriptEngine* engine, const WorldDetailQuality& worldDetailQuality); +void worldDetailQualityFromScriptValue(const QScriptValue& object, WorldDetailQuality& worldDetailQuality); + #endif // hifi_LODManager_h diff --git a/interface/src/PerformanceManager.cpp b/interface/src/PerformanceManager.cpp index 80c09e3fec..a7b9eff7cc 100644 --- a/interface/src/PerformanceManager.cpp +++ b/interface/src/PerformanceManager.cpp @@ -92,7 +92,7 @@ void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformanceP RenderScriptingInterface::getInstance()->setShadowsEnabled(true); qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::REALTIME); - DependencyManager::get()->setWorldDetailQuality(0.75f); + DependencyManager::get()->setWorldDetailQuality(WORLD_DETAIL_HIGH); break; case PerformancePreset::MID: @@ -104,7 +104,7 @@ void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformanceP RenderScriptingInterface::getInstance()->setShadowsEnabled(false); qApp->getRefreshRateManager().setRefreshRateProfile(RefreshRateManager::RefreshRateProfile::INTERACTIVE); - DependencyManager::get()->setWorldDetailQuality(0.5f); + DependencyManager::get()->setWorldDetailQuality(WORLD_DETAIL_MEDIUM); break; case PerformancePreset::LOW: @@ -114,7 +114,7 @@ void PerformanceManager::applyPerformancePreset(PerformanceManager::PerformanceP RenderScriptingInterface::getInstance()->setViewportResolutionScale(recommandedPpiScale); - DependencyManager::get()->setWorldDetailQuality(0.25f); + DependencyManager::get()->setWorldDetailQuality(WORLD_DETAIL_LOW); break; case PerformancePreset::UNKNOWN: diff --git a/interface/src/ui/PreferencesDialog.cpp b/interface/src/ui/PreferencesDialog.cpp index ec15dd8111..b7b5342066 100644 --- a/interface/src/ui/PreferencesDialog.cpp +++ b/interface/src/ui/PreferencesDialog.cpp @@ -58,18 +58,19 @@ void setupPreferences() { static const QString GRAPHICS_QUALITY { "Graphics Quality" }; { auto getter = []()->float { - return DependencyManager::get()->getWorldDetailQuality(); + return (int)DependencyManager::get()->getWorldDetailQuality(); }; - auto setter = [](float value) { - DependencyManager::get()->setWorldDetailQuality(value); + auto setter = [](int value) { + DependencyManager::get()->setWorldDetailQuality(static_cast(value)); }; - auto wodSlider = new SliderPreference(GRAPHICS_QUALITY, "World Detail", getter, setter); - wodSlider->setMin(0.25f); - wodSlider->setMax(0.75f); - wodSlider->setStep(0.25f); - preferences->addPreference(wodSlider); + auto wodButtons = new RadioButtonsPreference(GRAPHICS_QUALITY, "World Detail", getter, setter); + QStringList items; + items << "Low World Detail" << "Medium World Detail" << "High World Detail"; + wodButtons->setHeading("World Detail"); + wodButtons->setItems(items); + preferences->addPreference(wodButtons); auto getterShadow = []()->bool { auto menu = Menu::getInstance(); From 6a2e67ca54f0763b78bdf78bdad8e9580fc792c9 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 22 Oct 2019 21:07:04 +1300 Subject: [PATCH 3/4] Typo --- interface/src/LODManager.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/LODManager.h b/interface/src/LODManager.h index 1a516e0410..4708deb61b 100644 --- a/interface/src/LODManager.h +++ b/interface/src/LODManager.h @@ -267,7 +267,7 @@ signals: private: LODManager(); - void LODManager::setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode); + void setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode); std::mutex _automaticLODLock; bool _automaticLODAdjust = true; From ea864e4e9740b473989c8496f7b315c3d32fae31 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 23 Oct 2019 08:13:46 +1300 Subject: [PATCH 4/4] Remove unused variable --- interface/src/LODManager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/LODManager.cpp b/interface/src/LODManager.cpp index 1a72dffe20..4cd5025fc1 100644 --- a/interface/src/LODManager.cpp +++ b/interface/src/LODManager.cpp @@ -393,9 +393,7 @@ float LODManager::getLODTargetFPS() const { } void LODManager::setWorldDetailQuality(WorldDetailQuality quality, bool isHMDMode) { - static const float MIN_FPS = 10; float desiredFPS = isHMDMode ? QUALITY_TO_FPS_HMD[quality] : QUALITY_TO_FPS_DESKTOP[quality]; - if (isHMDMode) { _hmdWorldDetailQuality = quality; setHMDLODTargetFPS(desiredFPS);