From 90f55f0cd5d68060b5e81d19dc996b8a7b0442fc Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Tue, 8 Nov 2016 09:13:53 -0800 Subject: [PATCH 1/3] Add stutter tracking --- interface/resources/qml/Stats.qml | 4 ++++ interface/src/ui/Stats.cpp | 3 ++- interface/src/ui/Stats.h | 5 ++++- libraries/plugins/src/plugins/DisplayPlugin.h | 2 ++ plugins/openvr/src/OpenVrDisplayPlugin.cpp | 10 ++++++++++ plugins/openvr/src/OpenVrDisplayPlugin.h | 3 +++ 6 files changed, 25 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 9c55b1ce2d..cb7186456f 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -69,6 +69,10 @@ Item { StatText { text: "Present Drop Rate: " + root.presentdroprate.toFixed(2); } + StatText { + text: "Stutter Rate: " + root.stutterrate.toFixed(3); + visible: root.stutterrate != -1; + } StatText { text: "Simrate: " + root.simrate } diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index edf72d9758..bad2c3c056 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -128,7 +128,8 @@ void Stats::updateStats(bool force) { STAT_UPDATE(renderrate, displayPlugin->renderRate()); STAT_UPDATE(presentrate, displayPlugin->presentRate()); STAT_UPDATE(presentnewrate, displayPlugin->newFramePresentRate()); - STAT_UPDATE(presentdroprate, qApp->getActiveDisplayPlugin()->droppedFrameRate()); + STAT_UPDATE(presentdroprate, displayPlugin->droppedFrameRate()); + STAT_UPDATE(stutterrate, displayPlugin->stutterRate()); } else { STAT_UPDATE(presentrate, -1); STAT_UPDATE(presentnewrate, -1); diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index ffa5c08bc6..5d1aac4287 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -36,7 +36,9 @@ class Stats : public QQuickItem { STATS_PROPERTY(float, renderrate, 0) // How often the display plugin is presenting to the device STATS_PROPERTY(float, presentrate, 0) - + // How often the display device reprojecting old frames + STATS_PROPERTY(float, stutterrate, 0) + STATS_PROPERTY(float, presentnewrate, 0) STATS_PROPERTY(float, presentdroprate, 0) STATS_PROPERTY(int, simrate, 0) @@ -140,6 +142,7 @@ signals: void presentrateChanged(); void presentnewrateChanged(); void presentdroprateChanged(); + void stutterrateChanged(); void simrateChanged(); void avatarSimrateChanged(); void avatarCountChanged(); diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 3a9107390a..c87669c99a 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -188,6 +188,8 @@ public: virtual float renderRate() const { return -1.0f; } // Rate at which we present to the display device virtual float presentRate() const { return -1.0f; } + // Rate at which old frames are presented to the device display + virtual float stutterRate() const { return -1.0f; } // Rate at which new frames are being presented to the display device virtual float newFramePresentRate() const { return -1.0f; } // Rate at which rendered frames are being skipped diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 1a4067a847..e300ad3ece 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -641,6 +641,12 @@ void OpenVrDisplayPlugin::hmdPresent() { vr::VRCompositor()->PostPresentHandoff(); _presentRate.increment(); } + + vr::Compositor_FrameTiming frameTiming; + memset(&frameTiming, 0, sizeof(vr::Compositor_FrameTiming)); + frameTiming.m_nSize = sizeof(vr::Compositor_FrameTiming); + vr::VRCompositor()->GetFrameTiming(&frameTiming); + _stutterRate.increment(frameTiming.m_nNumDroppedFrames); } void OpenVrDisplayPlugin::postPreview() { @@ -702,3 +708,7 @@ bool OpenVrDisplayPlugin::isKeyboardVisible() { int OpenVrDisplayPlugin::getRequiredThreadCount() const { return Parent::getRequiredThreadCount() + (_threadedSubmit ? 1 : 0); } + +float OpenVrDisplayPlugin::stutterRate() const { + return _stutterRate.rate(); +} diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index 3403bae27c..0f4c5a6320 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -58,6 +58,8 @@ public: // Possibly needs an additional thread for VR submission int getRequiredThreadCount() const override; + float stutterRate() const override; + protected: bool internalActivate() override; void internalDeactivate() override; @@ -77,6 +79,7 @@ private: vr::HmdMatrix34_t _lastGoodHMDPose; mat4 _sensorResetMat; bool _threadedSubmit { true }; + RateCounter<> _stutterRate; CompositeInfo::Array _compositeInfos; size_t _renderingIndex { 0 }; From c7d68aa9cf16a3e5433246858267ca5cb48ed21d Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 10 Nov 2016 12:10:01 -0800 Subject: [PATCH 2/3] Add stutter stat logging --- interface/src/Application.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cc81396d84..089983d8ca 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1197,6 +1197,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo properties["present_rate"] = displayPlugin->presentRate(); properties["new_frame_present_rate"] = displayPlugin->newFramePresentRate(); properties["dropped_frame_rate"] = displayPlugin->droppedFrameRate(); + properties["stutter_rate"] = displayPlugin->stutterRate(); properties["sim_rate"] = getAverageSimsPerSecond(); properties["avatar_sim_rate"] = getAvatarSimrate(); properties["has_async_reprojection"] = displayPlugin->hasAsyncReprojection(); From 162f24decd7cb736cc722c933374aebeb0ad7f7a Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 11 Nov 2016 10:12:41 -0800 Subject: [PATCH 3/3] Add stutter tracking for Oculus --- .../src/display-plugins/hmd/HmdDisplayPlugin.cpp | 4 ++++ .../src/display-plugins/hmd/HmdDisplayPlugin.h | 5 ++++- plugins/oculus/src/OculusDisplayPlugin.cpp | 10 ++++++++++ plugins/openvr/src/OpenVrDisplayPlugin.cpp | 4 ---- plugins/openvr/src/OpenVrDisplayPlugin.h | 3 --- 5 files changed, 18 insertions(+), 8 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 2e66659de7..c5d7ac5690 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -710,3 +710,7 @@ void HmdDisplayPlugin::compositeExtra() { HmdDisplayPlugin::~HmdDisplayPlugin() { qDebug() << "Destroying HmdDisplayPlugin"; } + +float HmdDisplayPlugin::stutterRate() const { + return _stutterRate.rate(); +} diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index e50183dd90..435f547899 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -44,6 +44,8 @@ public: return false; } + float stutterRate() const override; + protected: virtual void hmdPresent() = 0; virtual bool isHmdMounted() const = 0; @@ -108,8 +110,9 @@ protected: QMap _frameInfos; FrameInfo _currentPresentFrameInfo; FrameInfo _currentRenderFrameInfo; + RateCounter<> _stutterRate; - bool _disablePreview{ true }; + bool _disablePreview { true }; private: ivec4 getViewportForSourceSize(const uvec2& size) const; float getLeftCenterPixel() const; diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index 415965e948..143204be17 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -146,6 +146,16 @@ void OculusDisplayPlugin::hmdPresent() { if (!OVR_SUCCESS(result)) { logWarning("Failed to present"); } + + static int droppedFrames = 0; + ovrPerfStats perfStats; + ovr_GetPerfStats(_session, &perfStats); + for (int i = 0; i < perfStats.FrameStatsCount; ++i) { + const auto& frameStats = perfStats.FrameStats[i]; + int delta = frameStats.CompositorDroppedFrameCount - droppedFrames; + _stutterRate.increment(delta); + droppedFrames = frameStats.CompositorDroppedFrameCount; + } } _presentRate.increment(); } diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index e300ad3ece..7f0ac4d5e0 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -708,7 +708,3 @@ bool OpenVrDisplayPlugin::isKeyboardVisible() { int OpenVrDisplayPlugin::getRequiredThreadCount() const { return Parent::getRequiredThreadCount() + (_threadedSubmit ? 1 : 0); } - -float OpenVrDisplayPlugin::stutterRate() const { - return _stutterRate.rate(); -} diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.h b/plugins/openvr/src/OpenVrDisplayPlugin.h index 0f4c5a6320..3403bae27c 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.h +++ b/plugins/openvr/src/OpenVrDisplayPlugin.h @@ -58,8 +58,6 @@ public: // Possibly needs an additional thread for VR submission int getRequiredThreadCount() const override; - float stutterRate() const override; - protected: bool internalActivate() override; void internalDeactivate() override; @@ -79,7 +77,6 @@ private: vr::HmdMatrix34_t _lastGoodHMDPose; mat4 _sensorResetMat; bool _threadedSubmit { true }; - RateCounter<> _stutterRate; CompositeInfo::Array _compositeInfos; size_t _renderingIndex { 0 };