From 9e1671a1bf0f004c62d2af97f69386df33a6381c Mon Sep 17 00:00:00 2001 From: danteruiz Date: Thu, 25 Apr 2019 16:02:12 -0700 Subject: [PATCH] making requested changes --- interface/resources/qml/Stats.qml | 4 +- interface/src/RefreshRateManager.cpp | 17 +++++++-- interface/src/RefreshRateManager.h | 2 +- interface/src/ui/Stats.cpp | 4 ++ interface/src/ui/Stats.h | 6 +++ .../display-plugins/OpenGLDisplayPlugin.cpp | 17 +++++---- .../src/display-plugins/OpenGLDisplayPlugin.h | 2 +- .../display-plugins/RefreshRateController.cpp | 37 ++++++++++--------- .../display-plugins/RefreshRateController.h | 17 ++++----- 9 files changed, 65 insertions(+), 41 deletions(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 05886f59ce..97c4aa9b41 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -81,7 +81,9 @@ Item { visible: root.expanded text: " RefreshRateController:\n " + "refreshRateTarget:\t " + root.refreshRateTarget + "\n " + - "refreshRateMode:\t " + root.refreshRateMode ; + "refreshRateMode:\t " + root.refreshRateMode + "\n " + + "refreshRateRegime:\t " + root.refreshRateRegime + "\n " + + "uxMode:\t " + root.uxMode; } StatText { visible: root.expanded diff --git a/interface/src/RefreshRateManager.cpp b/interface/src/RefreshRateManager.cpp index f67c6cf34f..c4a35da1f6 100644 --- a/interface/src/RefreshRateManager.cpp +++ b/interface/src/RefreshRateManager.cpp @@ -84,9 +84,20 @@ void RefreshRateManager::setRefreshRateProfile(RefreshRateManager::RefreshRatePr } RefreshRateManager::RefreshRateProfile RefreshRateManager::getRefreshRateProfile() const { - return (RefreshRateManager::RefreshRateProfile) _refreshRateModeLock.resultWithReadLock([&] { - return _refreshRateMode.get(); - }); + RefreshRateManager::RefreshRateProfile profile = RefreshRateManager::RefreshRateProfile::REALTIME; + + if (getUXMode() != RefreshRateManager::UXMode::HMD) { + profile =(RefreshRateManager::RefreshRateProfile) _refreshRateModeLock.resultWithReadLock([&] { + return _refreshRateMode.get(); + }); + } + + return profile; +} + +RefreshRateManager::RefreshRateRegime RefreshRateManager::getRefreshRateRegime() const { + return getUXMode() == RefreshRateManager::UXMode::HMD ? RefreshRateManager::RefreshRateRegime::RUNNING : + _refreshRateRegime; } void RefreshRateManager::setRefreshRateRegime(RefreshRateManager::RefreshRateRegime refreshRateRegime) { diff --git a/interface/src/RefreshRateManager.h b/interface/src/RefreshRateManager.h index 884725928c..ee7debe3ef 100644 --- a/interface/src/RefreshRateManager.h +++ b/interface/src/RefreshRateManager.h @@ -49,7 +49,7 @@ public: RefreshRateProfile getRefreshRateProfile() const; void setRefreshRateRegime(RefreshRateRegime refreshRateRegime); - RefreshRateRegime getRefreshRateRegime() const { return _refreshRateRegime; } + RefreshRateRegime getRefreshRateRegime() const; void setUXMode(UXMode uxMode); UXMode getUXMode() const { return _uxMode; } diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index c254c0f1b7..9b50b9e5da 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -224,7 +224,11 @@ void Stats::updateStats(bool force) { if (_expanded || force) { RefreshRateManager& refreshRateManager = qApp->getRefreshRateManager(); std::string refreshRateMode = RefreshRateManager::refreshRateProfileToString(refreshRateManager.getRefreshRateProfile()); + std::string refreshRateRegime = RefreshRateManager::refreshRateRegimeToString(refreshRateManager.getRefreshRateRegime()); + std::string uxMode = RefreshRateManager::uxModeToString(refreshRateManager.getUXMode()); STAT_UPDATE(refreshRateMode, QString::fromStdString(refreshRateMode)); + STAT_UPDATE(refreshRateRegime, QString::fromStdString(refreshRateRegime)); + STAT_UPDATE(uxMode, QString::fromStdString(uxMode)); STAT_UPDATE(refreshRateTarget, refreshRateManager.getActiveRefreshRate()); SharedNodePointer avatarMixer = nodeList->soloNodeOfType(NodeType::AvatarMixer); if (avatarMixer) { diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index 5c39001fda..7709f2d6dc 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -208,6 +208,8 @@ class Stats : public QQuickItem { STATS_PROPERTY(int, avatarCount, 0) STATS_PROPERTY(int, refreshRateTarget, 0) STATS_PROPERTY(QString, refreshRateMode, QString()) + STATS_PROPERTY(QString, refreshRateRegime, QString()) + STATS_PROPERTY(QString, uxMode, QString()) STATS_PROPERTY(int, heroAvatarCount, 0) STATS_PROPERTY(int, physicsObjectCount, 0) STATS_PROPERTY(int, updatedAvatarCount, 0) @@ -1074,6 +1076,10 @@ signals: void refreshRateModeChanged(); + void refreshRateRegimeChanged(); + + void uxModeChanged(); + // QQuickItem signals. /**jsdoc diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 3b0f13f946..6af7f1f92d 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -183,18 +183,14 @@ public: } // Execute the frame and present it to the display device. - _refreshRateController->clockStartTime(); { PROFILE_RANGE(render, "PluginPresent") gl::globalLock(); - currentPlugin->present(); + currentPlugin->present(_refreshRateController); gl::globalRelease(false); CHECK_GL_ERROR(); } - // stop time - _refreshRateController->clockEndTime(); - _refreshRateController->sleepThreadIfNeeded(this); - // sleep if needed + _refreshRateController->sleepThreadIfNeeded(this, currentPlugin->isHmd()); } _context->doneCurrent(); @@ -697,7 +693,7 @@ void OpenGLDisplayPlugin::internalPresent() { _presentRate.increment(); } -void OpenGLDisplayPlugin::present() { +void OpenGLDisplayPlugin::present(const std::shared_ptr& refreshRateController) { auto frameId = (uint64_t)presentCount(); PROFILE_RANGE_EX(render, __FUNCTION__, 0xffffff00, frameId) uint64_t startPresent = usecTimestampNow(); @@ -708,6 +704,7 @@ void OpenGLDisplayPlugin::present() { } incrementPresentCount(); + refreshRateController->clockStartTime(); if (_currentFrame) { auto correction = getViewCorrection(); getGLBackend()->setCameraCorrection(correction, _prevRenderView); @@ -745,6 +742,7 @@ void OpenGLDisplayPlugin::present() { } // Take the composite framebuffer and send it to the output device + refreshRateController->clockEndTime(); { PROFILE_RANGE_EX(render, "internalPresent", 0xff00ffff, frameId) internalPresent(); @@ -752,7 +750,10 @@ void OpenGLDisplayPlugin::present() { gpu::Backend::freeGPUMemSize.set(gpu::gl::getFreeDedicatedMemory()); } else if (alwaysPresent()) { + refreshRateController->clockEndTime(); internalPresent(); + } else { + refreshRateController->clockEndTime(); } _movingAveragePresent.addSample((float)(usecTimestampNow() - startPresent)); } @@ -772,7 +773,7 @@ float OpenGLDisplayPlugin::presentRate() const { std::function OpenGLDisplayPlugin::getRefreshRateOperator() { return [](int targetRefreshRate) { auto refreshRateController = DependencyManager::get()->getRefreshRateController(); - refreshRateController->setRefreshRateLimit(targetRefreshRate); + refreshRateController->setRefreshRateLimitPeriod(targetRefreshRate); }; } diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 8e6caae892..562c5af5cf 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -128,7 +128,7 @@ protected: void withOtherThreadContext(std::function f) const; - void present(); + void present(const std::shared_ptr& refreshRateController); virtual void swapBuffers(); ivec4 eyeViewport(Eye eye) const; diff --git a/libraries/display-plugins/src/display-plugins/RefreshRateController.cpp b/libraries/display-plugins/src/display-plugins/RefreshRateController.cpp index 2e583d5c9b..2d9b553163 100644 --- a/libraries/display-plugins/src/display-plugins/RefreshRateController.cpp +++ b/libraries/display-plugins/src/display-plugins/RefreshRateController.cpp @@ -12,31 +12,32 @@ #include "RefreshRateController.h" #include +#include -int refreshRateConverter(int refreshRate) { - const float ONE_SECOND_IN_MILLISECONDS = 1000.0f; - const float ONE_TIME_UNIT = 1.0f; - float frameInOneTimeUnit = ONE_TIME_UNIT / (float) refreshRate; - float convertedRefreshRate = frameInOneTimeUnit * ONE_SECOND_IN_MILLISECONDS; - return (int) convertedRefreshRate; +long int hzToDurationNanoseconds(int refreshRate) { + return (int64_t) (NSECS_PER_SECOND / (quint64) refreshRate); } -void RefreshRateController::setRefreshRateLimit(int refreshRateLimit) { - _refreshRateLimit = refreshRateConverter(refreshRateLimit); +int durationNanosecondsToHz(int64_t refreshRateLimitPeriod) { + return (int) (NSECS_PER_SECOND / (quint64) refreshRateLimitPeriod); } -int RefreshRateController::getRefreshRateLimit() const { - return refreshRateConverter(_refreshRateLimit); +void RefreshRateController::setRefreshRateLimitPeriod(int refreshRateLimit) { + _refreshRateLimitPeriod = hzToDurationNanoseconds(refreshRateLimit); } -void RefreshRateController::sleepThreadIfNeeded(QThread* thread) { - auto startTimeFromEpoch = _startTime.time_since_epoch(); - auto endTimeFromEpoch = _endTime.time_since_epoch(); +int RefreshRateController::getRefreshRateLimitPeriod() const { + return durationNanosecondsToHz(_refreshRateLimitPeriod); +} - auto startMs = std::chrono::duration_cast(startTimeFromEpoch).count(); - auto endMs = std::chrono::duration_cast(endTimeFromEpoch).count(); - auto duration = endMs - startMs; - if (duration < _refreshRateLimit) { - thread->msleep(_refreshRateLimit - duration); +void RefreshRateController::sleepThreadIfNeeded(QThread* thread, bool isHmd) { + if (!isHmd) { + static const std::chrono::nanoseconds EPSILON = std::chrono::milliseconds(1); + auto duration = std::chrono::duration_cast(_endTime - _startTime); + auto refreshRateLimitPeriod = std::chrono::nanoseconds(_refreshRateLimitPeriod); + auto sleepDuration = refreshRateLimitPeriod - (duration + EPSILON); + if (sleepDuration.count() > 0) { + thread->msleep(std::chrono::duration_cast(sleepDuration).count()); + } } } diff --git a/libraries/display-plugins/src/display-plugins/RefreshRateController.h b/libraries/display-plugins/src/display-plugins/RefreshRateController.h index dc46b7c01d..15adee3d3d 100644 --- a/libraries/display-plugins/src/display-plugins/RefreshRateController.h +++ b/libraries/display-plugins/src/display-plugins/RefreshRateController.h @@ -24,17 +24,16 @@ public: RefreshRateController() = default; ~RefreshRateController() = default; - void setRefreshRateLimit(int refreshRateLimiti); - int getRefreshRateLimit() const; + void setRefreshRateLimitPeriod(int refreshRateLimit); + int getRefreshRateLimitPeriod() const; - void clockStartTime() { _startTime = std::chrono::system_clock::now(); } - void clockEndTime() { _endTime = std::chrono::system_clock::now(); } - void sleepThreadIfNeeded(QThread* thread); + void clockStartTime() { _startTime = std::chrono::high_resolution_clock::now(); } + void clockEndTime() { _endTime = std::chrono::high_resolution_clock::now(); } + void sleepThreadIfNeeded(QThread* thread, bool isHmd); private: - - std::chrono::time_point _startTime { std::chrono::system_clock::now() }; - std::chrono::time_point _endTime { std::chrono::system_clock::now() }; - std::atomic_int _refreshRateLimit { 50 }; // milliseconds + std::chrono::time_point _startTime { std::chrono::high_resolution_clock::now() }; + std::chrono::time_point _endTime { std::chrono::high_resolution_clock::now() }; + std::atomic _refreshRateLimitPeriod { 50 }; };