From 51445dc038b21bbeaf28c0cef461770342eb7b1d Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Thu, 18 Oct 2018 09:54:49 +0300 Subject: [PATCH] Improved drape measurer --- drape/graphics_context.hpp | 3 +- drape/metal/metal_base_context.hpp | 3 +- drape/metal/metal_base_context.mm | 10 ++++++ drape/oglcontext.cpp | 5 +++ drape/oglcontext.hpp | 3 +- drape_frontend/drape_measurer.cpp | 49 +++++++++++++++++++++++++--- drape_frontend/drape_measurer.hpp | 9 +++++ drape_frontend/frontend_renderer.cpp | 27 +++++++++++++++ map/benchmark_tools.cpp | 2 +- 9 files changed, 103 insertions(+), 8 deletions(-) diff --git a/drape/graphics_context.hpp b/drape/graphics_context.hpp index 6c1b88c83e..6600d64f60 100644 --- a/drape/graphics_context.hpp +++ b/drape/graphics_context.hpp @@ -67,7 +67,8 @@ public: virtual ApiVersion GetApiVersion() const = 0; virtual std::string GetRendererName() const = 0; virtual std::string GetRendererVersion() const = 0; - + + virtual void DebugSynchronizeWithCPU() {} virtual void PushDebugLabel(std::string const & label) = 0; virtual void PopDebugLabel() = 0; diff --git a/drape/metal/metal_base_context.hpp b/drape/metal/metal_base_context.hpp index 88d694c970..516a75f8b7 100644 --- a/drape/metal/metal_base_context.hpp +++ b/drape/metal/metal_base_context.hpp @@ -37,7 +37,8 @@ public: ApiVersion GetApiVersion() const override; std::string GetRendererName() const override; std::string GetRendererVersion() const override; - + + void DebugSynchronizeWithCPU() override; void PushDebugLabel(std::string const & label) override; void PopDebugLabel() override; diff --git a/drape/metal/metal_base_context.mm b/drape/metal/metal_base_context.mm index d6b5459506..52f225d48b 100644 --- a/drape/metal/metal_base_context.mm +++ b/drape/metal/metal_base_context.mm @@ -372,6 +372,16 @@ void MetalBaseContext::SetSystemPrograms(drape_ptr && programClearCo m_cleaner.Init(make_ref(this), std::move(programClearColor), std::move(programClearDepth), std::move(programClearColorAndDepth)); } + +void MetalBaseContext::DebugSynchronizeWithCPU() +{ + FinishCurrentEncoding(); + RequestFrameDrawable(); + [m_frameCommandBuffer commit]; + m_frameDrawable = nil; + [m_frameCommandBuffer waitUntilCompleted]; + m_frameCommandBuffer = nil; +} } // namespace metal void RenderFrameMediator(std::function && renderFrameFunction) diff --git a/drape/oglcontext.cpp b/drape/oglcontext.cpp index bb220f90a2..f72056f285 100644 --- a/drape/oglcontext.cpp +++ b/drape/oglcontext.cpp @@ -82,6 +82,11 @@ std::string OGLContext::GetRendererVersion() const return GLFunctions::glGetString(gl_const::GLVersion); } +void OGLContext::DebugSynchronizeWithCPU() +{ + GLFunctions::glFinish(); +} + void OGLContext::SetClearColor(dp::Color const & color) { GLFunctions::glClearColor(color.GetRedF(), color.GetGreenF(), color.GetBlueF(), color.GetAlphaF()); diff --git a/drape/oglcontext.hpp b/drape/oglcontext.hpp index 4a2a452b66..a395ee14b0 100644 --- a/drape/oglcontext.hpp +++ b/drape/oglcontext.hpp @@ -12,7 +12,8 @@ public: std::string GetRendererName() const override; std::string GetRendererVersion() const override; void ApplyFramebuffer(std::string const & framebufferLabel) override {} - + + void DebugSynchronizeWithCPU() override; void PushDebugLabel(std::string const & label) override {} void PopDebugLabel() override {} diff --git a/drape_frontend/drape_measurer.cpp b/drape_frontend/drape_measurer.cpp index bf1d24d263..dbc88983ad 100644 --- a/drape_frontend/drape_measurer.cpp +++ b/drape_frontend/drape_measurer.cpp @@ -53,6 +53,10 @@ void DrapeMeasurer::StartBenchmark() m_startFrameRenderTime = currentTime; m_totalFrameRenderTime = steady_clock::duration::zero(); m_totalFramesCount = 0; + + m_immediateRenderingFramesCount = 0; + m_immediateRenderingTimeSum = steady_clock::duration::zero(); + m_immediateRenderingMinFps = std::numeric_limits::max(); #endif #ifdef TRACK_GPU_MEM @@ -150,7 +154,9 @@ std::string DrapeMeasurer::RenderStatistic::ToString() const std::ostringstream ss; ss << " ----- Render statistic report ----- \n"; ss << " FPS = " << m_FPS << "\n"; - ss << " min FPS = " << m_minFPS << "\n"; + ss << " Min FPS = " << m_minFPS << "\n"; + ss << " Immediate rendering FPS = " << m_immediateRenderingFPS << "\n"; + ss << " Immediate rendering min FPS = " << m_immediateRenderingMinFPS << "\n"; ss << " Frame render time, ms = " << m_frameRenderTimeInMs << "\n"; if (!m_fpsDistribution.empty()) { @@ -186,6 +192,14 @@ DrapeMeasurer::RenderStatistic DrapeMeasurer::GetRenderStatistic() statistic.m_fpsDistribution[fps.first] = static_cast(fps.second) / totalCount; } + statistic.m_immediateRenderingMinFPS = m_immediateRenderingMinFps; + if (m_immediateRenderingFramesCount > 0) + { + auto const timeSumMs = duration_cast(m_immediateRenderingTimeSum).count(); + auto const avgFrameTimeMs = static_cast(timeSumMs) / m_immediateRenderingFramesCount; + statistic.m_immediateRenderingFPS = static_cast(1000.0 / avgFrameTimeMs); + } + return statistic; } #endif @@ -199,6 +213,33 @@ void DrapeMeasurer::BeforeRenderFrame() m_startFrameRenderTime = std::chrono::steady_clock::now(); } +void DrapeMeasurer::BeforeImmediateRendering() +{ + if (!m_isEnabled) + return; + + m_startImmediateRenderingTime = std::chrono::steady_clock::now(); +} + +void DrapeMeasurer::AfterImmediateRendering() +{ + using namespace std::chrono; + + if (!m_isEnabled) + return; + + ++m_immediateRenderingFramesCount; + + auto const elapsed = steady_clock::now() - m_startImmediateRenderingTime; + m_immediateRenderingTimeSum += elapsed; + auto const elapsedMs = duration_cast(elapsed).count(); + if (elapsedMs > 0) + { + auto const fps = static_cast(1000 / elapsedMs); + m_immediateRenderingMinFps = std::min(m_immediateRenderingMinFps, fps); + } +} + void DrapeMeasurer::AfterRenderFrame() { using namespace std::chrono; @@ -207,10 +248,10 @@ void DrapeMeasurer::AfterRenderFrame() return; ++m_totalFramesCount; - m_totalFrameRenderTime += steady_clock::now() - m_startFrameRenderTime; + m_totalFrameRenderTime += (steady_clock::now() - m_startFrameRenderTime); - auto elapsed = duration_cast(m_totalFrameRenderTime).count(); - if (elapsed > 1000) + auto const elapsed = duration_cast(m_totalFrameRenderTime).count(); + if (elapsed >= 30) { #ifdef RENDER_STATISTIC double fps = m_totalFramesCount * 1000.0 / elapsed; diff --git a/drape_frontend/drape_measurer.hpp b/drape_frontend/drape_measurer.hpp index f35d8f5217..5e30be00a2 100644 --- a/drape_frontend/drape_measurer.hpp +++ b/drape_frontend/drape_measurer.hpp @@ -34,6 +34,8 @@ public: uint32_t m_minFPS = 0; uint32_t m_frameRenderTimeInMs = 0; std::map m_fpsDistribution; + uint32_t m_immediateRenderingFPS = 0; + uint32_t m_immediateRenderingMinFPS = 0; }; RenderStatistic GetRenderStatistic(); @@ -94,6 +96,8 @@ public: #if defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM) void BeforeRenderFrame(); + void BeforeImmediateRendering(); + void AfterImmediateRendering(); void AfterRenderFrame(); #endif @@ -157,10 +161,15 @@ private: double m_totalFPS = 0.0; uint32_t m_totalFPSCount = 0; std::unordered_map m_fpsDistribution; + + uint32_t m_immediateRenderingMinFps = std::numeric_limits::max(); + std::chrono::nanoseconds m_immediateRenderingTimeSum; + uint64_t m_immediateRenderingFramesCount = 0; #endif #if defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM) std::chrono::time_point m_startFrameRenderTime; + std::chrono::time_point m_startImmediateRenderingTime; std::chrono::nanoseconds m_totalFrameRenderTime; uint32_t m_totalFramesCount = 0; #endif diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 80a1129e9a..db0ccad393 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -154,6 +154,27 @@ public: DrapeMeasurer::Instance().AfterRenderFrame(); } }; + +class DrapeImmediateRenderingMeasurerGuard +{ +public: + DrapeImmediateRenderingMeasurerGuard(ref_ptr context) + : m_context(context) + { + DrapeMeasurer::Instance().BeforeImmediateRendering(); + } + + ~DrapeImmediateRenderingMeasurerGuard() + { + DrapeMeasurer::Instance().AfterImmediateRendering(); +#ifdef DISABLE_SCREEN_PRESENTATION + m_context->DebugSynchronizeWithCPU(); +#endif + } + +private: + ref_ptr m_context; +}; #endif } // namespace @@ -1279,6 +1300,10 @@ void FrontendRenderer::EndUpdateOverlayTree() void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFrame) { CHECK(m_context != nullptr, ()); +#if defined(DRAPE_MEASURER) && (defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM)) + DrapeImmediateRenderingMeasurerGuard drapeMeasurerGuard(m_context); +#endif + PreRender3dLayer(modelView); if (m_postprocessRenderer->BeginFrame(m_context, activeFrame)) @@ -1679,7 +1704,9 @@ void FrontendRenderer::RenderFrame() while (availableTime > 0.0); } +#ifndef DISABLE_SCREEN_PRESENTATION m_context->Present(); +#endif // Limit fps in following mode. double constexpr kFrameTime = 1.0 / 30.0; diff --git a/map/benchmark_tools.cpp b/map/benchmark_tools.cpp index d1fed2978c..1e7c91d92e 100644 --- a/map/benchmark_tools.cpp +++ b/map/benchmark_tools.cpp @@ -61,7 +61,7 @@ void RunScenario(Framework * framework, std::shared_ptr handle) df::DrapeMeasurer::Instance().StartBenchmark(); #endif }, - [framework, handle](std::string const & name) + [framework, handle](std::string const & name) { #ifdef DRAPE_MEASURER df::DrapeMeasurer::Instance().StopBenchmark();