From 91bfa7677c71b19366b8c88b7a1abe9b86ad4b76 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 2 Sep 2016 14:41:49 -0700 Subject: [PATCH 1/2] Updating stats display for threaded rendering --- interface/resources/qml/Stats.qml | 5 +++ interface/src/Application.cpp | 2 +- interface/src/ui/Stats.cpp | 8 +++-- interface/src/ui/Stats.h | 6 ++++ .../display-plugins/OpenGLDisplayPlugin.cpp | 36 ++++++++++--------- .../src/display-plugins/OpenGLDisplayPlugin.h | 4 +++ libraries/plugins/src/plugins/DisplayPlugin.h | 2 ++ plugins/oculus/src/OculusDisplayPlugin.cpp | 1 + plugins/openvr/src/OpenVrDisplayPlugin.cpp | 2 +- 9 files changed, 45 insertions(+), 21 deletions(-) diff --git a/interface/resources/qml/Stats.qml b/interface/resources/qml/Stats.qml index 180e5e1bcc..a0750c1f7f 100644 --- a/interface/resources/qml/Stats.qml +++ b/interface/resources/qml/Stats.qml @@ -59,6 +59,11 @@ Item { font.pixelSize: root.fontSize text: "Avatars: " + root.avatarCount } + Text { + color: root.fontColor; + font.pixelSize: root.fontSize + text: "Frame Rate: " + root.framerate.toFixed(2); + } Text { color: root.fontColor; font.pixelSize: root.fontSize diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9c44876e6e..d846a5c6d1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1685,7 +1685,6 @@ void Application::paintGL() { Finally clearFlag([this] { _inPaint = false; }); _frameCount++; - _frameCounter.increment(); auto lastPaintBegin = usecTimestampNow(); PROFILE_RANGE_EX(__FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); @@ -1922,6 +1921,7 @@ void Application::paintGL() { { PROFILE_RANGE(__FUNCTION__ "/pluginOutput"); PerformanceTimer perfTimer("pluginOutput"); + _frameCounter.increment(); displayPlugin->submitFrame(frame); } diff --git a/interface/src/ui/Stats.cpp b/interface/src/ui/Stats.cpp index 7fdf5cd57d..fbe272a562 100644 --- a/interface/src/ui/Stats.cpp +++ b/interface/src/ui/Stats.cpp @@ -117,10 +117,12 @@ void Stats::updateStats(bool force) { // we need to take one avatar out so we don't include ourselves STAT_UPDATE(avatarCount, avatarManager->size() - 1); STAT_UPDATE(serverCount, (int)nodeList->size()); - STAT_UPDATE(renderrate, qApp->getFps()); + STAT_UPDATE(framerate, qApp->getFps()); if (qApp->getActiveDisplayPlugin()) { - STAT_UPDATE(presentrate, qApp->getActiveDisplayPlugin()->presentRate()); - STAT_UPDATE(presentnewrate, qApp->getActiveDisplayPlugin()->newFramePresentRate()); + auto displayPlugin = qApp->getActiveDisplayPlugin(); + STAT_UPDATE(renderrate, displayPlugin->renderRate()); + STAT_UPDATE(presentrate, displayPlugin->presentRate()); + STAT_UPDATE(presentnewrate, displayPlugin->newFramePresentRate()); STAT_UPDATE(presentdroprate, qApp->getActiveDisplayPlugin()->droppedFrameRate()); } else { STAT_UPDATE(presentrate, -1); diff --git a/interface/src/ui/Stats.h b/interface/src/ui/Stats.h index 4be2d88d9e..138f24cf19 100644 --- a/interface/src/ui/Stats.h +++ b/interface/src/ui/Stats.h @@ -32,8 +32,13 @@ class Stats : public QQuickItem { Q_PROPERTY(float audioPacketlossDownstream READ getAudioPacketLossDownstream) STATS_PROPERTY(int, serverCount, 0) + // How often the app is creating new gpu::Frames + STATS_PROPERTY(float, framerate, 0) + // How often the display plugin is executing a given frame STATS_PROPERTY(float, renderrate, 0) + // How often the display plugin is presenting to the device STATS_PROPERTY(float, presentrate, 0) + STATS_PROPERTY(float, presentnewrate, 0) STATS_PROPERTY(float, presentdroprate, 0) STATS_PROPERTY(int, simrate, 0) @@ -116,6 +121,7 @@ public slots: void forceUpdateStats() { updateStats(true); } signals: + void framerateChanged(); void expandedChanged(); void timingExpandedChanged(); void serverCountChanged(); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 5ee097d355..4c683a27f8 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -475,32 +475,28 @@ bool OpenGLDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) { } void OpenGLDisplayPlugin::submitFrame(const gpu::FramePointer& newFrame) { - if (_lockCurrentTexture) { - return; - } - withNonPresentThreadLock([&] { _newFrameQueue.push(newFrame); }); } void OpenGLDisplayPlugin::updateFrameData() { + if (_lockCurrentTexture) { + return; + } withPresentThreadLock([&] { - gpu::FramePointer oldFrame = _currentFrame; - uint32_t skippedCount = 0; if (!_newFrameQueue.empty()) { // We're changing frames, so we can cleanup any GL resources that might have been used by the old frame _gpuContext->recycle(); } + if (_newFrameQueue.size() > 1) { + _droppedFrameRate.increment(_newFrameQueue.size() - 1); + } while (!_newFrameQueue.empty()) { _currentFrame = _newFrameQueue.front(); _newFrameQueue.pop(); _gpuContext->consumeFrameUpdates(_currentFrame); - if (_currentFrame && oldFrame) { - skippedCount += (_currentFrame->frameIndex - oldFrame->frameIndex) - 1; - } } - _droppedFrameRate.increment(skippedCount); }); } @@ -598,6 +594,7 @@ void OpenGLDisplayPlugin::internalPresent() { batch.draw(gpu::TRIANGLE_STRIP, 4); }); swapBuffers(); + _presentRate.increment(); } void OpenGLDisplayPlugin::present() { @@ -612,6 +609,13 @@ void OpenGLDisplayPlugin::present() { if (_currentFrame) { { + withPresentThreadLock([&] { + _renderRate.increment(); + if (_currentFrame != _lastFrame) { + _newFrameRate.increment(); + } + _lastFrame = _currentFrame; + }); // Execute the frame rendering commands PROFILE_RANGE_EX("execute", 0xff00ff00, (uint64_t)presentCount()) _gpuContext->executeFrame(_currentFrame); @@ -628,7 +632,6 @@ void OpenGLDisplayPlugin::present() { PROFILE_RANGE_EX("internalPresent", 0xff00ffff, (uint64_t)presentCount()) internalPresent(); } - _presentRate.increment(); } } @@ -637,17 +640,18 @@ float OpenGLDisplayPlugin::newFramePresentRate() const { } float OpenGLDisplayPlugin::droppedFrameRate() const { - float result; - withNonPresentThreadLock([&] { - result = _droppedFrameRate.rate(); - }); - return result; + return _droppedFrameRate.rate(); } float OpenGLDisplayPlugin::presentRate() const { return _presentRate.rate(); } +float OpenGLDisplayPlugin::renderRate() const { + return _renderRate.rate(); +} + + void OpenGLDisplayPlugin::swapBuffers() { static auto context = _container->getPrimaryWidget()->context(); context->swapBuffers(); diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index 51b33c9bcd..afd8f7d45b 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -62,6 +62,8 @@ public: float droppedFrameRate() const override; + float renderRate() const override; + bool beginFrameRender(uint32_t frameIndex) override; virtual bool wantVsync() const { return true; } @@ -109,8 +111,10 @@ protected: RateCounter<> _droppedFrameRate; RateCounter<> _newFrameRate; RateCounter<> _presentRate; + RateCounter<> _renderRate; gpu::FramePointer _currentFrame; + gpu::FramePointer _lastFrame; gpu::FramebufferPointer _compositeFramebuffer; gpu::PipelinePointer _overlayPipeline; gpu::PipelinePointer _simplePipeline; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 288cee3223..5111bda95f 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -178,6 +178,8 @@ public: virtual bool beginFrameRender(uint32_t frameIndex) { return true; } virtual float devicePixelRatio() { return 1.0f; } + // Rate at which we render frames + 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 new frames are being presented to the display device diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index f1cad94281..838a4121cd 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -139,6 +139,7 @@ void OculusDisplayPlugin::hmdPresent() { logWarning("Failed to present"); } } + _presentRate.increment(); } bool OculusDisplayPlugin::isHmdMounted() const { diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 76ca9abc79..4c4fcbbd37 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -174,6 +174,7 @@ public: vr::Texture_t texture{ (void*)oglplus::GetName(_framebuffer->color), vr::API_OpenGL, vr::ColorSpace_Auto }; vr::VRCompositor()->Submit(vr::Eye_Left, &texture, &leftBounds); vr::VRCompositor()->Submit(vr::Eye_Right, &texture, &rightBounds); + _plugin._presentRate.increment(); PoseData nextRender, nextSim; nextRender.frameIndex = _plugin.presentCount(); vr::VRCompositor()->WaitGetPoses(nextRender.vrPoses, vr::k_unMaxTrackedDeviceCount, nextSim.vrPoses, vr::k_unMaxTrackedDeviceCount); @@ -192,7 +193,6 @@ public: nextRender.update(sensorResetMat); nextSim.update(sensorResetMat); - _plugin.withNonPresentThreadLock([&] { _nextRender = nextRender; _nextSim = nextSim; From b6ef6fec733aa498260b6037271e3d16741c9c08 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 2 Sep 2016 15:43:25 -0700 Subject: [PATCH 2/2] Revert "fill in linked node data for avatar identity packets, also" --- assignment-client/src/avatars/AvatarMixer.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index ddedb7849a..65989b389e 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -413,9 +413,6 @@ void AvatarMixer::handleAvatarDataPacket(QSharedPointer message } void AvatarMixer::handleAvatarIdentityPacket(QSharedPointer message, SharedNodePointer senderNode) { - auto nodeList = DependencyManager::get(); - nodeList->updateNodeWithDataFromPacket(message, senderNode); - if (senderNode->getLinkedData()) { AvatarMixerClientData* nodeData = dynamic_cast(senderNode->getLinkedData()); if (nodeData != nullptr) {