diff --git a/drape/CMakeLists.txt b/drape/CMakeLists.txt index 4cc46e6093..c5fc48816d 100644 --- a/drape/CMakeLists.txt +++ b/drape/CMakeLists.txt @@ -40,6 +40,7 @@ set( ${DRAPE_ROOT}/data_buffer_impl.hpp ${DRAPE_ROOT}/debug_rect_renderer.cpp ${DRAPE_ROOT}/debug_rect_renderer.hpp + ${DRAPE_ROOT}/drape_diagnostics.hpp ${DRAPE_ROOT}/drape_global.hpp ${DRAPE_ROOT}/dynamic_texture.hpp ${DRAPE_ROOT}/font_texture.cpp diff --git a/drape/debug_rect_renderer.hpp b/drape/debug_rect_renderer.hpp index 19e0ef5820..2c98279bf4 100644 --- a/drape/debug_rect_renderer.hpp +++ b/drape/debug_rect_renderer.hpp @@ -1,5 +1,7 @@ #pragma once +#include "drape/drape_diagnostics.hpp" + #include "drape/gpu_program_manager.hpp" #include "drape/overlay_tree.hpp" #include "drape/pointers.hpp" @@ -7,8 +9,6 @@ #include "geometry/rect2d.hpp" #include "geometry/screenbase.hpp" -//#define RENDER_DEBUG_RECTS - namespace dp { @@ -39,3 +39,4 @@ private: }; } // namespace dp + diff --git a/drape/drape_common.pri b/drape/drape_common.pri index 132d156d30..eb987ee144 100644 --- a/drape/drape_common.pri +++ b/drape/drape_common.pri @@ -66,6 +66,7 @@ HEADERS += \ $$DRAPE_DIR/data_buffer.hpp \ $$DRAPE_DIR/data_buffer_impl.hpp \ $$DRAPE_DIR/debug_rect_renderer.hpp \ + $$DRAPE_DIR/drape_diagnostics.hpp \ $$DRAPE_DIR/drape_global.hpp \ $$DRAPE_DIR/dynamic_texture.hpp \ $$DRAPE_DIR/font_texture.hpp \ diff --git a/drape/drape_diagnostics.hpp b/drape/drape_diagnostics.hpp new file mode 100644 index 0000000000..d8fc2a5a9b --- /dev/null +++ b/drape/drape_diagnostics.hpp @@ -0,0 +1,19 @@ +#pragma once + +//#define DRAW_TILE_NET +//#define RENDER_DEBUG_RECTS +//#define COLLECT_DISPLACEMENT_INFO + +//#define DRAPE_MEASURER +//#define SCENARIO_ENABLE + +#ifdef DRAPE_MEASURER + +//#define RENDER_STATISTIC +//#define TILES_STATISTIC +//#define GENERATING_STATISTIC + +//#define TRACK_GPU_MEM +//#define TRACK_GLYPH_USAGE + +#endif diff --git a/drape/overlay_tree.hpp b/drape/overlay_tree.hpp index ef669d1a7b..061540efb3 100644 --- a/drape/overlay_tree.hpp +++ b/drape/overlay_tree.hpp @@ -1,5 +1,6 @@ #pragma once +#include "drape/drape_diagnostics.hpp" #include "drape/overlay_handle.hpp" #include "geometry/screenbase.hpp" @@ -14,8 +15,6 @@ namespace dp { -//#define COLLECT_DISPLACEMENT_INFO - namespace detail { diff --git a/drape/utils/glyph_usage_tracker.cpp b/drape/utils/glyph_usage_tracker.cpp index b4d4a0f67b..0713944df7 100644 --- a/drape/utils/glyph_usage_tracker.cpp +++ b/drape/utils/glyph_usage_tracker.cpp @@ -9,18 +9,10 @@ namespace dp { -GlyphUsageTracker & GlyphUsageTracker::Instance() +string GlyphUsageTracker::GlyphUsageStatistic::ToString() const { - static GlyphUsageTracker s_inst; - return s_inst; -} - -string GlyphUsageTracker::Report() -{ - lock_guard lock(m_mutex); - ostringstream ss; - ss << "\n ===== Glyphs Usage Report ===== \n"; + ss << " ----- Glyphs usage report ----- \n"; ss << " Current language = " << languages::GetCurrentOrig() << "\n"; ss << " Invalid glyphs count = " << m_invalidGlyphs.size() << "\n"; ss << " Invalid glyphs: { "; @@ -40,11 +32,23 @@ string GlyphUsageTracker::Report() ss << "}\n"; } ss << " }\n"; - ss << " ===== Glyphs Usage Report ===== \n"; + ss << " ----- Glyphs usage report ----- \n"; return ss.str(); } +GlyphUsageTracker & GlyphUsageTracker::Instance() +{ + static GlyphUsageTracker s_inst; + return s_inst; +} + +GlyphUsageTracker::GlyphUsageStatistic GlyphUsageTracker::Report() +{ + lock_guard lock(m_mutex); + return m_glyphStat; +} + void GlyphUsageTracker::AddInvalidGlyph(strings::UniString const & str, strings::UniChar const & c) { lock_guard lock(m_mutex); @@ -52,7 +56,7 @@ void GlyphUsageTracker::AddInvalidGlyph(strings::UniString const & str, strings: if (m_processedStrings.find(strings::ToUtf8(str)) != m_processedStrings.end()) return; - ++m_invalidGlyphs[c]; + ++m_glyphStat.m_invalidGlyphs[c]; m_processedStrings.insert(strings::ToUtf8(str)); } @@ -65,7 +69,7 @@ void GlyphUsageTracker::AddUnexpectedGlyph(strings::UniString const & str, strin if (m_processedStrings.find(strings::ToUtf8(str)) != m_processedStrings.end()) return; - UnexpectedGlyphData & data = m_unexpectedGlyphs[c]; + UnexpectedGlyphData & data = m_glyphStat.m_unexpectedGlyphs[c]; ++data.m_counter; data.m_expectedGroups.emplace(expectedGroup); data.m_group = group; diff --git a/drape/utils/glyph_usage_tracker.hpp b/drape/utils/glyph_usage_tracker.hpp index 8555265e09..ee92268ef2 100644 --- a/drape/utils/glyph_usage_tracker.hpp +++ b/drape/utils/glyph_usage_tracker.hpp @@ -1,5 +1,7 @@ #pragma once +#include "drape/drape_diagnostics.hpp" + #include "base/string_utils.hpp" #include "std/map.hpp" @@ -9,31 +11,12 @@ #include "std/string.hpp" #include "std/unordered_set.hpp" -//#define TRACK_GLYPH_USAGE - namespace dp { class GlyphUsageTracker { public: - static GlyphUsageTracker & Instance(); - - void AddInvalidGlyph(strings::UniString const & str, strings::UniChar const & c); - void AddUnexpectedGlyph(strings::UniString const & str, strings::UniChar const & c, - size_t const group, size_t const expectedGroup); - - string Report(); - -private: - GlyphUsageTracker() = default; - GlyphUsageTracker(GlyphUsageTracker const & rhs) = delete; - GlyphUsageTracker(GlyphUsageTracker && rhs) = delete; - -private: - using InvalidGlyphs = map; - InvalidGlyphs m_invalidGlyphs; - struct UnexpectedGlyphData { size_t m_counter = 0; @@ -41,8 +24,31 @@ private: set m_expectedGroups; }; using UnexpectedGlyphs = map; - UnexpectedGlyphs m_unexpectedGlyphs; + using InvalidGlyphs = map; + struct GlyphUsageStatistic + { + string ToString() const; + + InvalidGlyphs m_invalidGlyphs; + UnexpectedGlyphs m_unexpectedGlyphs; + }; + + static GlyphUsageTracker & Instance(); + + void AddInvalidGlyph(strings::UniString const & str, strings::UniChar const & c); + void AddUnexpectedGlyph(strings::UniString const & str, strings::UniChar const & c, + size_t const group, size_t const expectedGroup); + + GlyphUsageStatistic Report(); + +private: + GlyphUsageTracker() = default; + GlyphUsageTracker(GlyphUsageTracker const & rhs) = delete; + GlyphUsageTracker(GlyphUsageTracker && rhs) = delete; + +private: + GlyphUsageStatistic m_glyphStat; unordered_set m_processedStrings; mutex m_mutex; diff --git a/drape/utils/gpu_mem_tracker.cpp b/drape/utils/gpu_mem_tracker.cpp index 7aa95c2021..2c477440c4 100644 --- a/drape/utils/gpu_mem_tracker.cpp +++ b/drape/utils/gpu_mem_tracker.cpp @@ -6,50 +6,58 @@ namespace dp { +string GPUMemTracker::GPUMemorySnapshot::ToString() const +{ + ostringstream ss; + ss << " Summary Allocated = " << m_summaryAllocatedInMb << "Mb\n"; + ss << " Summary Used = " << m_summaryUsedInMb << "Mb\n"; + ss << " Tags registered = " << m_tagStats.size() << "\n"; + + for (auto const it : m_tagStats) + { + ss << " Tag = " << it.first << " \n"; + ss << " Object count = " << it.second.m_objectsCount << "\n"; + ss << " Allocated = " << it.second.m_alocatedInMb << "Mb\n"; + ss << " Used = " << it.second.m_usedInMb << "Mb\n"; + } + + return ss.str(); +} + GPUMemTracker & GPUMemTracker::Inst() { static GPUMemTracker s_inst; return s_inst; } -string GPUMemTracker::Report() +GPUMemTracker::GPUMemorySnapshot GPUMemTracker::GetMemorySnapshot() { - uint32_t summaryUsed = 0; - uint32_t summaryAllocated = 0; + GPUMemorySnapshot memStat; - typedef tuple TTagStat; - map tagStats; - - for (auto const it : m_memTracker) { - TTagStat & stat = tagStats[it.first.first]; - get<0>(stat)++; - get<1>(stat) += it.second.first; - get<2>(stat) += it.second.second; + threads::MutexGuard g(m_mutex); + for (auto const it : m_memTracker) + { + TagMemorySnapshot & tagStat = memStat.m_tagStats[it.first.first]; + tagStat.m_objectsCount++; + tagStat.m_alocatedInMb += it.second.first; + tagStat.m_usedInMb += it.second.second; - summaryAllocated += it.second.first; - summaryUsed += it.second.second; + memStat.m_summaryAllocatedInMb += it.second.first; + memStat.m_summaryUsedInMb += it.second.second; + } } float byteToMb = static_cast(1024 * 1024); - - ostringstream ss; - ss << " ===== Mem Report ===== \n"; - ss << " Summary Allocated = " << summaryAllocated / byteToMb << "\n"; - ss << " Summary Used = " << summaryUsed / byteToMb << "\n"; - ss << " Tags registered = " << tagStats.size() << "\n"; - - for (auto const it : tagStats) + for (auto & it : memStat.m_tagStats) { - ss << " Tag = " << it.first << " \n"; - ss << " Object count = " << get<0>(it.second) << "\n"; - ss << " Allocated = " << get<1>(it.second) / byteToMb << "\n"; - ss << " Used = " << get<2>(it.second) / byteToMb << "\n"; + it.second.m_alocatedInMb /= byteToMb; + it.second.m_usedInMb /= byteToMb; } + memStat.m_summaryAllocatedInMb /= byteToMb; + memStat.m_summaryUsedInMb /= byteToMb; - ss << " ===== Mem Report ===== \n"; - - return ss.str(); + return memStat; } void GPUMemTracker::AddAllocated(string const & tag, uint32_t id, uint32_t size) @@ -63,7 +71,7 @@ void GPUMemTracker::SetUsed(string const & tag, uint32_t id, uint32_t size) threads::MutexGuard g(m_mutex); TAlocUsedMem & node = m_memTracker[make_pair(tag, id)]; node.second = size; - ASSERT_LESS_OR_EQUAL(node.second, node.first, ("Can't use more then allocated")); + ASSERT_LESS_OR_EQUAL(node.second, node.first, ("Can't use more than allocated")); } void GPUMemTracker::RemoveDeallocated(string const & tag, uint32_t id) diff --git a/drape/utils/gpu_mem_tracker.hpp b/drape/utils/gpu_mem_tracker.hpp index eb350f9f22..724bd2c6ac 100644 --- a/drape/utils/gpu_mem_tracker.hpp +++ b/drape/utils/gpu_mem_tracker.hpp @@ -1,5 +1,7 @@ #pragma once +#include "drape/drape_diagnostics.hpp" + #include "base/mutex.hpp" #include "std/map.hpp" @@ -7,18 +9,32 @@ #include "std/string.hpp" #include "std/utility.hpp" - -//#define TRACK_GPU_MEM - namespace dp { class GPUMemTracker : private noncopyable { public: + struct TagMemorySnapshot + { + uint32_t m_objectsCount = 0; + uint32_t m_alocatedInMb = 0; + uint32_t m_usedInMb = 0; + }; + + struct GPUMemorySnapshot + { + string ToString() const; + + uint32_t m_summaryAllocatedInMb = 0; + uint32_t m_summaryUsedInMb = 0; + map m_tagStats; + }; + static GPUMemTracker & Inst(); - string Report(); + GPUMemorySnapshot GetMemorySnapshot(); + void AddAllocated(string const & tag, uint32_t id, uint32_t size); void SetUsed(string const & tag, uint32_t id, uint32_t size); void RemoveDeallocated(string const & tag, uint32_t id); diff --git a/drape_frontend/CMakeLists.txt b/drape_frontend/CMakeLists.txt index 7013f7bc53..8cae36a799 100644 --- a/drape_frontend/CMakeLists.txt +++ b/drape_frontend/CMakeLists.txt @@ -69,6 +69,8 @@ set( drape_api_renderer.hpp drape_engine.cpp drape_engine.hpp + drape_measurer.cpp + drape_measurer.hpp engine_context.cpp engine_context.hpp framebuffer.cpp diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index 0d4d4ba2de..aafe232c2e 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -3,6 +3,7 @@ #include "drape_frontend/backend_renderer.hpp" #include "drape_frontend/batchers_pool.hpp" #include "drape_frontend/drape_api_builder.hpp" +#include "drape_frontend/drape_measurer.hpp" #include "drape_frontend/gps_track_shape.hpp" #include "drape_frontend/map_shape.hpp" #include "drape_frontend/message_subclasses.hpp" @@ -204,11 +205,17 @@ void BackendRenderer::AcceptMessage(ref_ptr message) if (m_requestedTiles->CheckTileKey(tileKey) && m_readManager->CheckTileKey(tileKey)) { ref_ptr batcher = m_batchersPool->GetBatcher(tileKey); +#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC) + DrapeMeasurer::Instance().StartShapesGeneration(); +#endif for (drape_ptr const & shape : msg->GetShapes()) { batcher->SetFeatureMinZoom(shape->GetFeatureMinZoom()); shape->Draw(batcher, m_texMng); } +#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC) + DrapeMeasurer::Instance().EndShapesGeneration(static_cast(msg->GetShapes().size())); +#endif } break; } @@ -221,6 +228,9 @@ void BackendRenderer::AcceptMessage(ref_ptr message) { CleanupOverlays(tileKey); +#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC) + DrapeMeasurer::Instance().StartOverlayShapesGeneration(); +#endif OverlayBatcher batcher(tileKey); for (drape_ptr const & shape : msg->GetShapes()) batcher.Batch(shape, m_texMng); @@ -232,6 +242,11 @@ void BackendRenderer::AcceptMessage(ref_ptr message) m_overlays.reserve(m_overlays.size() + renderData.size()); move(renderData.begin(), renderData.end(), back_inserter(m_overlays)); } + +#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC) + DrapeMeasurer::Instance().EndOverlayShapesGeneration( + static_cast(msg->GetShapes().size())); +#endif } break; } diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 953748b5f9..3edb8a5d4b 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -574,12 +574,13 @@ void DrapeEngine::SetFontScaleFactor(double scaleFactor) VisualParams::Instance().SetFontScale(scaleFactor); } -void DrapeEngine::RunScenario(ScenarioManager::Scenario && scenario, - ScenarioManager::OnFinishHandler const & handler) +void DrapeEngine::RunScenario(ScenarioManager::ScenarioData && scenarioData, + ScenarioManager::ScenarioCallback const & onStartFn, + ScenarioManager::ScenarioCallback const & onFinishFn) { auto const & manager = m_frontend->GetScenarioManager(); if (manager != nullptr) - manager->RunScenario(move(scenario), handler); + manager->RunScenario(move(scenarioData), onStartFn, onFinishFn); } } // namespace df diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 57359552e0..2e42ba7a55 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -177,8 +177,9 @@ public: void SetFontScaleFactor(double scaleFactor); - void RunScenario(ScenarioManager::Scenario && scenario, - ScenarioManager::OnFinishHandler const & handler); + void RunScenario(ScenarioManager::ScenarioData && scenarioData, + ScenarioManager::ScenarioCallback const & onStartFn, + ScenarioManager::ScenarioCallback const & onFinishFn); private: void AddUserEvent(drape_ptr && e); diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro index dc89b16712..6f2e85a753 100755 --- a/drape_frontend/drape_frontend.pro +++ b/drape_frontend/drape_frontend.pro @@ -8,7 +8,6 @@ include($$ROOT_DIR/common.pri) INCLUDEPATH *= $$ROOT_DIR/3party/protobuf/src INCLUDEPATH *= $$ROOT_DIR/3party/expat/lib INCLUDEPATH *= $$ROOT_DIR/3party/freetype/include -#DEFINES += DRAW_INFO SOURCES += \ $$ROOT_DIR/3party/agg/agg_curves.cpp \ @@ -50,6 +49,7 @@ SOURCES += \ drape_api_builder.cpp \ drape_api_renderer.cpp \ drape_engine.cpp \ + drape_measurer.cpp \ engine_context.cpp \ framebuffer.cpp \ frontend_renderer.cpp \ @@ -150,6 +150,7 @@ HEADERS += \ drape_api_builder.hpp \ drape_api_renderer.hpp \ drape_engine.hpp \ + drape_measurer.hpp \ engine_context.hpp \ framebuffer.hpp \ frontend_renderer.hpp \ diff --git a/drape_frontend/drape_measurer.cpp b/drape_frontend/drape_measurer.cpp new file mode 100644 index 0000000000..18f95cbeb3 --- /dev/null +++ b/drape_frontend/drape_measurer.cpp @@ -0,0 +1,417 @@ +#include "drape_measurer.hpp" + +namespace df +{ + +DrapeMeasurer & DrapeMeasurer::Instance() +{ + static DrapeMeasurer s_inst; + return s_inst; +} + +void DrapeMeasurer::StartBenchmark() +{ + using namespace std::chrono; + m_isEnabled = true; + + auto currentTime = std::chrono::steady_clock::now(); + +#ifdef GENERATING_STATISTIC + m_startScenePreparingTime = currentTime; + m_maxScenePreparingTime = steady_clock::duration::zero(); + + m_startShapesGenTime = currentTime; + m_totalShapesGenTime = steady_clock::duration::zero(); + m_totalShapesCount = 0; + + m_startOverlayShapesGenTime = currentTime; + m_totalOverlayShapesGenTime = steady_clock::duration::zero(); + m_totalOverlayShapesCount = 0; +#endif + +#ifdef TILES_STATISTIC + { + lock_guard lock(m_tilesMutex); + m_tilesReadInfo.clear(); + } +#endif + +#ifdef RENDER_STATISTIC + m_totalTPF = steady_clock::duration::zero(); + m_totalTPFCount = 0; + + m_minFPS = std::numeric_limits::max(); + m_totalFPS = 0.0; + m_totalFPSCount = 0; +#endif + +#if defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM) + m_startFrameRenderTime = currentTime; + m_totalFrameRenderTime = steady_clock::duration::zero(); + m_totalFramesCount = 0; +#endif + +#ifdef TRACK_GPU_MEM + m_maxSnapshotValues = dp::GPUMemTracker::GPUMemorySnapshot(); + m_summarySnapshotValues = dp::GPUMemTracker::GPUMemorySnapshot(); + m_numberOfSnapshots = 0; +#endif +} + +void DrapeMeasurer::StopBenchmark() +{ + m_isEnabled = false; +} + +#ifdef GENERATING_STATISTIC +void DrapeMeasurer::StartScenePreparing() +{ + if (!m_isEnabled) + return; + + m_startScenePreparingTime = std::chrono::steady_clock::now(); +} + +void DrapeMeasurer::EndScenePreparing() +{ + if (!m_isEnabled) + return; + + m_maxScenePreparingTime = max(m_maxScenePreparingTime, + std::chrono::steady_clock::now() - m_startScenePreparingTime); +} + +void DrapeMeasurer::StartShapesGeneration() +{ + m_startShapesGenTime = std::chrono::steady_clock::now(); +} + +void DrapeMeasurer::EndShapesGeneration(uint32_t shapesCount) +{ + m_totalShapesGenTime += std::chrono::steady_clock::now() - m_startShapesGenTime; + m_totalShapesCount += shapesCount; +} + +void DrapeMeasurer::StartOverlayShapesGeneration() +{ + m_startOverlayShapesGenTime = std::chrono::steady_clock::now(); +} + +void DrapeMeasurer::EndOverlayShapesGeneration(uint32_t shapesCount) +{ + m_totalOverlayShapesGenTime += std::chrono::steady_clock::now() - m_startOverlayShapesGenTime; + m_totalOverlayShapesCount += shapesCount; +} + +std::string DrapeMeasurer::GeneratingStatistic::ToString() const +{ + std::ostringstream ss; + ss << " ----- Generation statistic report ----- \n"; + ss << " Max scene preparing time, ms = " << m_maxScenePreparingTimeInMs << "\n"; + ss << " Shapes total generation time, ms = " << m_shapeGenTimeInMs << "\n"; + ss << " Shapes total count = " << m_shapesCount + << ", (" << static_cast(m_shapeGenTimeInMs) / m_shapesCount << " ms per shape)\n"; + ss << " Overlay shapes total generation time, ms = " << m_overlayShapeGenTimeInMs << "\n"; + ss << " Overlay shapes total count = " << m_overlayShapesCount + << ", (" << static_cast(m_overlayShapeGenTimeInMs) / m_overlayShapesCount << " ms per overlay)\n"; + ss << " ----- Generation statistic report ----- \n"; + + return ss.str(); +} + +DrapeMeasurer::GeneratingStatistic DrapeMeasurer::GetGeneratingStatistic() +{ + using namespace std::chrono; + + GeneratingStatistic statistic; + statistic.m_shapesCount = m_totalShapesCount; + statistic.m_shapeGenTimeInMs = + static_cast(duration_cast(m_totalShapesGenTime).count()); + + statistic.m_overlayShapesCount = m_totalOverlayShapesCount; + statistic.m_overlayShapeGenTimeInMs = + static_cast(duration_cast(m_totalOverlayShapesGenTime).count()); + + statistic.m_maxScenePreparingTimeInMs = + static_cast(duration_cast(m_maxScenePreparingTime).count()); + + return statistic; +} + +#endif + +#ifdef RENDER_STATISTIC +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 << " Frame render time, ms = " << m_frameRenderTimeInMs << "\n"; + ss << " ----- Render statistic report ----- \n"; + + return ss.str(); +} + +DrapeMeasurer::RenderStatistic DrapeMeasurer::GetRenderStatistic() +{ + using namespace std::chrono; + + RenderStatistic statistic; + statistic.m_FPS = m_totalFPS / m_totalFPSCount; + statistic.m_minFPS = m_minFPS; + statistic.m_frameRenderTimeInMs = + static_cast(duration_cast(m_totalTPF).count()) / m_totalTPFCount; + + return statistic; +} +#endif + +#if defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM) +void DrapeMeasurer::BeforeRenderFrame() +{ + if (!m_isEnabled) + return; + + m_startFrameRenderTime = std::chrono::steady_clock::now(); +} + +void DrapeMeasurer::AfterRenderFrame() +{ + using namespace std::chrono; + + if (!m_isEnabled) + return; + + ++m_totalFramesCount; + m_totalFrameRenderTime += steady_clock::now() - m_startFrameRenderTime; + + auto elapsed = duration_cast(m_totalFrameRenderTime).count(); + if (elapsed > 1000) + { +#ifdef RENDER_STATISTIC + double fps = m_totalFramesCount * 1000.0 / elapsed; + m_minFPS = std::min(m_minFPS, static_cast(fps)); + + m_totalFPS += fps; + ++m_totalFPSCount; + + m_totalTPF += m_totalFrameRenderTime / m_totalFramesCount; + ++m_totalTPFCount; +#endif + + m_totalFramesCount = 0; + m_totalFrameRenderTime = steady_clock::duration::zero(); + +#ifdef TRACK_GPU_MEM + TakeGPUMemorySnapshot(); +#endif + } +} +#endif + +#ifdef TILES_STATISTIC +std::string DrapeMeasurer::TileStatistic::ToString() const +{ + std::ostringstream ss; + ss << " ----- Tiles read statistic report ----- \n"; + ss << " Tile read time, ms = " << m_tileReadTimeInMs << "\n"; + ss << " Tiles count = " << m_totalTilesCount << "\n"; + ss << " ----- Tiles read statistic report ----- \n"; + + return ss.str(); +} + +void DrapeMeasurer::StartTileReading() +{ + if (!m_isEnabled) + return; + + threads::ThreadID tid = threads::GetCurrentThreadID(); + std::shared_ptr tileInfo; + { + lock_guard lock(m_tilesMutex); + auto const it = m_tilesReadInfo.find(tid); + if (it != m_tilesReadInfo.end()) + { + tileInfo = it->second; + } + else + { + tileInfo = std::make_shared(); + m_tilesReadInfo.insert(make_pair(tid, tileInfo)); + } + } + + auto const currentTime = std::chrono::steady_clock::now(); + tileInfo->m_startTileReadTime = currentTime; +} + +void DrapeMeasurer::EndTileReading() +{ + if (!m_isEnabled) + return; + + auto const currentTime = std::chrono::steady_clock::now(); + + threads::ThreadID tid = threads::GetCurrentThreadID(); + std::shared_ptr tileInfo; + { + lock_guard lock(m_tilesMutex); + auto const it = m_tilesReadInfo.find(tid); + if (it != m_tilesReadInfo.end()) + tileInfo = it->second; + else + return; + } + + auto passedTime = currentTime - tileInfo->m_startTileReadTime; + tileInfo->m_totalTileReadTime += passedTime; + ++tileInfo->m_totalTilesCount; +} + +DrapeMeasurer::TileStatistic DrapeMeasurer::GetTileStatistic() +{ + using namespace std::chrono; + TileStatistic statistic; + { + lock_guard lock(m_tilesMutex); + for (auto const & it : m_tilesReadInfo) + { + statistic.m_tileReadTimeInMs += + static_cast(duration_cast(it.second->m_totalTileReadTime).count()); + statistic.m_totalTilesCount += it.second->m_totalTilesCount; + } + } + if (statistic.m_totalTilesCount > 0) + statistic.m_tileReadTimeInMs /= statistic.m_totalTilesCount; + + return statistic; +} +#endif + +#ifdef TRACK_GPU_MEM +std::string DrapeMeasurer::GPUMemoryStatistic::ToString() const +{ + std::ostringstream ss; + ss << " ----- GPU memory report ----- \n"; + ss << " --Max memory values:\n"; + ss << m_maxMemoryValues.ToString(); + ss << "\n --Average memory values:\n"; + ss << m_averageMemoryValues.ToString(); + ss << " ----- GPU memory report ----- \n"; + + return ss.str(); +} + +void DrapeMeasurer::TakeGPUMemorySnapshot() +{ + dp::GPUMemTracker::GPUMemorySnapshot snap = dp::GPUMemTracker::Inst().GetMemorySnapshot(); + for (auto const & tagPair : snap.m_tagStats) + { + auto itMax = m_maxSnapshotValues.m_tagStats.find(tagPair.first); + if (itMax != m_maxSnapshotValues.m_tagStats.end()) + { + itMax->second.m_objectsCount = std::max(itMax->second.m_objectsCount, + tagPair.second.m_objectsCount); + itMax->second.m_alocatedInMb = std::max(itMax->second.m_alocatedInMb, + tagPair.second.m_alocatedInMb); + itMax->second.m_usedInMb = std::max(itMax->second.m_alocatedInMb, + tagPair.second.m_usedInMb); + } + else + { + m_maxSnapshotValues.m_tagStats.insert(tagPair); + } + + auto itSummary = m_summarySnapshotValues.m_tagStats.find(tagPair.first); + if (itSummary != m_summarySnapshotValues.m_tagStats.end()) + { + itSummary->second.m_objectsCount += tagPair.second.m_objectsCount; + itSummary->second.m_alocatedInMb += tagPair.second.m_alocatedInMb; + itSummary->second.m_usedInMb += tagPair.second.m_usedInMb; + } + else + { + m_summarySnapshotValues.m_tagStats.insert(tagPair); + } + } + + m_maxSnapshotValues.m_summaryAllocatedInMb = std::max(snap.m_summaryAllocatedInMb, + m_maxSnapshotValues.m_summaryAllocatedInMb); + m_maxSnapshotValues.m_summaryUsedInMb = std::max(snap.m_summaryUsedInMb, + m_maxSnapshotValues.m_summaryUsedInMb); + + m_summarySnapshotValues.m_summaryAllocatedInMb += snap.m_summaryAllocatedInMb; + m_summarySnapshotValues.m_summaryUsedInMb += snap.m_summaryUsedInMb; + + ++m_numberOfSnapshots; +} + +DrapeMeasurer::GPUMemoryStatistic DrapeMeasurer::GetGPUMemoryStatistic() +{ + GPUMemoryStatistic statistic; + statistic.m_maxMemoryValues = m_maxSnapshotValues; + + statistic.m_averageMemoryValues = m_summarySnapshotValues; + if (m_numberOfSnapshots > 0) + { + for (auto & tagPair : statistic.m_averageMemoryValues.m_tagStats) + { + tagPair.second.m_objectsCount /= m_numberOfSnapshots; + tagPair.second.m_alocatedInMb /= m_numberOfSnapshots; + tagPair.second.m_usedInMb /= m_numberOfSnapshots; + } + statistic.m_averageMemoryValues.m_summaryAllocatedInMb /= m_numberOfSnapshots; + statistic.m_averageMemoryValues.m_summaryUsedInMb /= m_numberOfSnapshots; + } + return statistic; +} +#endif + +std::string DrapeMeasurer::DrapeStatistic::ToString() const +{ + std::ostringstream ss; + ss << "\n ===== Drape statistic report ===== \n"; +#ifdef RENDER_STATISTIC + ss << "\n" << m_renderStatistic.ToString() << "\n"; +#endif +#ifdef TILES_STATISTIC + ss << "\n" << m_tileStatistic.ToString() << "\n"; +#endif +#ifdef GENERATING_STATISTIC + ss << "\n" << m_generatingStatistic.ToString() << "\n"; +#endif +#ifdef TRACK_GPU_MEM + ss << "\n" << m_gpuMemStatistic.ToString() << "\n"; +#endif +#ifdef TRACK_GLYPH_USAGE + ss << "\n" << m_glyphStatistic.ToString() << "\n"; +#endif + ss << "\n ===== Drape statistic report ===== \n\n"; + + return ss.str(); +} + +DrapeMeasurer::DrapeStatistic DrapeMeasurer::GetDrapeStatistic() +{ + DrapeStatistic statistic; +#ifdef RENDER_STATISTIC + statistic.m_renderStatistic = GetRenderStatistic(); +#endif +#ifdef TILES_STATISTIC + statistic.m_tileStatistic = GetTileStatistic(); +#endif +#ifdef GENERATING_STATISTIC + statistic.m_generatingStatistic = GetGeneratingStatistic(); +#endif +#ifdef TRACK_GPU_MEM + statistic.m_gpuMemStatistic = GetGPUMemoryStatistic(); +#endif +#ifdef TRACK_GLYPH_USAGE + statistic.m_glyphStatistic = dp::GlyphUsageTracker::Instance().Report(); +#endif + return statistic; +} + +} // namespace df diff --git a/drape_frontend/drape_measurer.hpp b/drape_frontend/drape_measurer.hpp new file mode 100644 index 0000000000..b64d46e1ee --- /dev/null +++ b/drape_frontend/drape_measurer.hpp @@ -0,0 +1,175 @@ +#pragma once + +#include "drape/drape_diagnostics.hpp" +#include "drape/utils/gpu_mem_tracker.hpp" +#include "drape/utils/glyph_usage_tracker.hpp" + +#include "base/thread.hpp" +#include "base/timer.hpp" + +#include +#include +#include +#include +#include +#include + +namespace df +{ + +class DrapeMeasurer +{ +public: + static DrapeMeasurer & Instance(); + + void StartBenchmark(); + void StopBenchmark(); + +#ifdef RENDER_STATISTIC + struct RenderStatistic + { + std::string ToString() const; + + uint32_t m_FPS = 0; + uint32_t m_minFPS = 0; + uint32_t m_frameRenderTimeInMs = 0; + }; + + RenderStatistic GetRenderStatistic(); +#endif + +#ifdef TILES_STATISTIC + struct TileStatistic + { + std::string ToString() const; + + uint32_t m_totalTilesCount = 0; + uint32_t m_tileReadTimeInMs = 0; + }; + + void StartTileReading(); + void EndTileReading(); + + TileStatistic GetTileStatistic(); +#endif + +#ifdef GENERATING_STATISTIC + struct GeneratingStatistic + { + std::string ToString() const; + + uint32_t m_maxScenePreparingTimeInMs = 0; + + uint32_t m_shapesCount = 0; + uint32_t m_shapeGenTimeInMs = 0; + + uint32_t m_overlayShapesCount = 0; + uint32_t m_overlayShapeGenTimeInMs = 0; + }; + + void StartScenePreparing(); + void EndScenePreparing(); + + void StartShapesGeneration(); + void EndShapesGeneration(uint32_t shapesCount); + + void StartOverlayShapesGeneration(); + void EndOverlayShapesGeneration(uint32_t shapesCount); + + GeneratingStatistic GetGeneratingStatistic(); +#endif + +#ifdef TRACK_GPU_MEM + struct GPUMemoryStatistic + { + std::string ToString() const; + + dp::GPUMemTracker::GPUMemorySnapshot m_averageMemoryValues; + dp::GPUMemTracker::GPUMemorySnapshot m_maxMemoryValues; + }; + + GPUMemoryStatistic GetGPUMemoryStatistic(); +#endif + +#if defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM) + void BeforeRenderFrame(); + void AfterRenderFrame(); +#endif + + struct DrapeStatistic + { + std::string ToString() const; + +#ifdef RENDER_STATISTIC + RenderStatistic m_renderStatistic; +#endif +#ifdef TILES_STATISTIC + TileStatistic m_tileStatistic; +#endif +#ifdef GENERATING_STATISTIC + GeneratingStatistic m_generatingStatistic; +#endif +#ifdef TRACK_GPU_MEM + GPUMemoryStatistic m_gpuMemStatistic; +#endif +#ifdef TRACK_GLYPH_USAGE + dp::GlyphUsageTracker::GlyphUsageStatistic m_glyphStatistic; +#endif + }; + + DrapeStatistic GetDrapeStatistic(); + +private: + DrapeMeasurer() = default; + + bool m_isEnabled = false; + +#ifdef GENERATING_STATISTIC + std::chrono::time_point m_startScenePreparingTime; + std::chrono::nanoseconds m_maxScenePreparingTime; + + std::chrono::time_point m_startShapesGenTime; + std::chrono::nanoseconds m_totalShapesGenTime; + uint32_t m_totalShapesCount = 0; + + std::chrono::time_point m_startOverlayShapesGenTime; + std::chrono::nanoseconds m_totalOverlayShapesGenTime; + uint32_t m_totalOverlayShapesCount = 0; +#endif + +#ifdef TILES_STATISTIC + struct TileReadInfo + { + std::chrono::time_point m_startTileReadTime; + std::chrono::nanoseconds m_totalTileReadTime; + uint32_t m_totalTilesCount = 0; + }; + std::map> m_tilesReadInfo; + std::mutex m_tilesMutex; +#endif + +#ifdef RENDER_STATISTIC + std::chrono::nanoseconds m_totalTPF; + uint32_t m_totalTPFCount = 0; + + uint32_t m_minFPS = std::numeric_limits::max(); + double m_totalFPS = 0.0; + uint32_t m_totalFPSCount = 0; +#endif + +#if defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM) + std::chrono::time_point m_startFrameRenderTime; + std::chrono::nanoseconds m_totalFrameRenderTime; + uint32_t m_totalFramesCount = 0; +#endif + +#ifdef TRACK_GPU_MEM + void TakeGPUMemorySnapshot(); + + dp::GPUMemTracker::GPUMemorySnapshot m_maxSnapshotValues; + dp::GPUMemTracker::GPUMemorySnapshot m_summarySnapshotValues; + uint32_t m_numberOfSnapshots = 0; +#endif +}; + +} diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index adcbf297f2..21f764f83e 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -2,6 +2,8 @@ #include "drape_frontend/gui/drape_gui.hpp" #include "drape_frontend/gui/ruler_helper.hpp" #include "drape_frontend/animation_system.hpp" +#include "drape_frontend/batch_merge_helper.hpp" +#include "drape_frontend/drape_measurer.hpp" #include "drape_frontend/framebuffer.hpp" #include "drape_frontend/frontend_renderer.hpp" #include "drape_frontend/message_subclasses.hpp" @@ -10,7 +12,7 @@ #include "drape_frontend/transparent_layer.hpp" #include "drape_frontend/visual_params.hpp" #include "drape_frontend/user_mark_shapes.hpp" -#include "drape_frontend/batch_merge_helper.hpp" + #include "drape/debug_rect_renderer.hpp" #include "drape/shader_def.hpp" @@ -140,11 +142,6 @@ FrontendRenderer::FrontendRenderer(Params const & params) , m_scenarioManager(new ScenarioManager(this)) #endif { -#ifdef DRAW_INFO - m_tpf = 0.0; - m_fps = 0.0; -#endif - #ifdef DEBUG m_isTeardowned = false; #endif @@ -174,43 +171,6 @@ void FrontendRenderer::Teardown() #endif } -#ifdef DRAW_INFO -void FrontendRenderer::BeforeDrawFrame() -{ - m_frameStartTime = m_timer.ElapsedSeconds(); -} - -void FrontendRenderer::AfterDrawFrame() -{ - m_drawedFrames++; - - double elapsed = m_timer.ElapsedSeconds(); - m_tpfs.push_back(elapsed - m_frameStartTime); - - if (elapsed > 1.0) - { - m_timer.Reset(); - m_fps = m_drawedFrames / elapsed; - m_drawedFrames = 0; - - m_tpf = accumulate(m_tpfs.begin(), m_tpfs.end(), 0.0) / m_tpfs.size(); - - LOG(LINFO, ("Average Fps : ", m_fps)); - LOG(LINFO, ("Average Tpf : ", m_tpf)); - -#if defined(TRACK_GPU_MEM) - string report = dp::GPUMemTracker::Inst().Report(); - LOG(LINFO, (report)); -#endif -#if defined(TRACK_GLYPH_USAGE) - string glyphReport = dp::GlyphUsageTracker::Instance().Report(); - LOG(LINFO, (glyphReport)); -#endif - } -} - -#endif - void FrontendRenderer::UpdateCanBeDeletedStatus() { m2::RectD const & screenRect = m_userEventStream.GetCurrentScreen().ClipRect(); @@ -302,7 +262,12 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) UpdateCanBeDeletedStatus(); if (m_notFinishedTiles.empty()) + { +#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC) + DrapeMeasurer::Instance().EndScenePreparing(); +#endif m_trafficRenderer->OnGeometryReady(m_currentZoomLevel); + } break; } @@ -1110,8 +1075,8 @@ void FrontendRenderer::EndUpdateOverlayTree() void FrontendRenderer::RenderScene(ScreenBase const & modelView) { -#ifdef DRAW_INFO - BeforeDrawFrame(); +#if defined(DRAPE_MEASURER) && (defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM)) + DrapeMeasurer::Instance().BeforeRenderFrame(); #endif GLFunctions::glEnable(gl_const::GLDepthTest); @@ -1174,8 +1139,8 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) dp::DebugRectRenderer::Instance().DrawArrow(modelView, arrow); #endif -#ifdef DRAW_INFO - AfterDrawFrame(); +#if defined(DRAPE_MEASURER) && (defined(RENDER_STATISTIC) || defined(TRACK_GPU_MEM)) + DrapeMeasurer::Instance().AfterRenderFrame(); #endif MergeBuckets(); @@ -1620,6 +1585,10 @@ TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen) m_trafficRenderer->OnUpdateViewport(result, m_currentZoomLevel, tilesToDelete); +#if defined(DRAPE_MEASURER) && defined(GENERATING_STATISTIC) + DrapeMeasurer::Instance().StartScenePreparing(); +#endif + return tiles; } diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index e416cffd30..e06ee32451 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -2,12 +2,6 @@ #include "base/thread.hpp" -#ifdef DRAW_INFO - #include "base/timer.hpp" - #include "std/vector.hpp" - #include "std/numeric.hpp" -#endif - #include "drape_frontend/gui/layer_render.hpp" #include "drape_frontend/backend_renderer.hpp" @@ -130,19 +124,6 @@ public: void Teardown(); -#ifdef DRAW_INFO - double m_tpf; - double m_fps; - - my::Timer m_timer; - double m_frameStartTime; - vector m_tpfs; - int m_drawedFrames; - - void BeforeDrawFrame(); - void AfterDrawFrame(); -#endif - void AddUserEvent(drape_ptr && event); /// MyPositionController::Listener diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp index 92989c3bf2..4939725eee 100644 --- a/drape_frontend/rule_drawer.cpp +++ b/drape_frontend/rule_drawer.cpp @@ -6,6 +6,8 @@ #include "drape_frontend/traffic_renderer.hpp" #include "drape_frontend/visual_params.hpp" +#include "drape/drape_diagnostics.hpp" + #include "indexer/feature.hpp" #include "indexer/feature_algo.hpp" #include "indexer/feature_visibility.hpp" @@ -17,8 +19,6 @@ #include "std/bind.hpp" -//#define DRAW_TILE_NET - #ifdef DRAW_TILE_NET #include "drape_frontend/line_shape.hpp" #include "drape_frontend/text_shape.hpp" diff --git a/drape_frontend/scenario_manager.cpp b/drape_frontend/scenario_manager.cpp index d9855592e2..37d17d0904 100644 --- a/drape_frontend/scenario_manager.cpp +++ b/drape_frontend/scenario_manager.cpp @@ -29,7 +29,7 @@ void ScenarioManager::Interrupt() InterruptImpl(); } -bool ScenarioManager::RunScenario(Scenario && scenario, OnFinishHandler const & handler) +bool ScenarioManager::RunScenario(ScenarioData && scenarioData, ScenarioCallback const & onStartFn, ScenarioCallback const & onFinishFn) { std::lock_guard lock(m_mutex); if (m_thread != nullptr) @@ -37,11 +37,12 @@ bool ScenarioManager::RunScenario(Scenario && scenario, OnFinishHandler const & if (m_isFinished) InterruptImpl(); else - return false; // The only scenatio can be executed currently. + return false; // The only scenario can be executed currently. } - std::swap(m_scenario, scenario); - m_onFinishHandler = handler; + std::swap(m_scenarioData, scenarioData); + m_onStartHandler = onStartFn; + m_onFinishHandler = onFinishFn; m_thread = my::make_unique(&ScenarioManager::ThreadRoutine, this); #ifdef DEBUG m_threadId = m_thread->get_id(); @@ -65,7 +66,11 @@ bool ScenarioManager::IsRunning() void ScenarioManager::ThreadRoutine() { - for (auto const & action : m_scenario) + string const scenarioName = m_scenarioData.m_name; + if (m_onStartHandler != nullptr) + m_onStartHandler(scenarioName); + + for (auto const & action : m_scenarioData.m_scenario) { // Interrupt scenario if it's necessary. { @@ -100,10 +105,10 @@ void ScenarioManager::ThreadRoutine() } } - OnFinishHandler handler = nullptr; + ScenarioCallback handler = nullptr; { std::lock_guard lock(m_mutex); - m_scenario.clear(); + m_scenarioData.m_scenario.clear(); m_isFinished = true; if (m_onFinishHandler != nullptr) { @@ -113,7 +118,7 @@ void ScenarioManager::ThreadRoutine() } if (handler != nullptr) - handler(); + handler(scenarioName); } void ScenarioManager::InterruptImpl() diff --git a/drape_frontend/scenario_manager.hpp b/drape_frontend/scenario_manager.hpp index 0388a8a8c4..a174a62095 100644 --- a/drape_frontend/scenario_manager.hpp +++ b/drape_frontend/scenario_manager.hpp @@ -2,6 +2,8 @@ #include "drape_frontend/frontend_renderer.hpp" +#include "drape/drape_diagnostics.hpp" + #include "geometry/point2d.hpp" #include "base/stl_add.hpp" @@ -13,8 +15,6 @@ #include #include -#define SCENARIO_ENABLE - namespace df { @@ -65,12 +65,19 @@ public: }; using Scenario = std::vector>; - using OnFinishHandler = std::function; + using ScenarioCallback = std::function; + + struct ScenarioData + { + std::string m_name; + Scenario m_scenario; + }; ScenarioManager(FrontendRenderer * frontendRenderer); ~ScenarioManager(); - bool RunScenario(Scenario && scenario, OnFinishHandler const & handler); + bool RunScenario(ScenarioData && scenarioData, + ScenarioCallback const & startHandler, ScenarioCallback const & finishHandler); void Interrupt(); bool IsRunning(); @@ -81,10 +88,11 @@ private: FrontendRenderer * m_frontendRenderer; std::mutex m_mutex; - Scenario m_scenario; + ScenarioData m_scenarioData; bool m_needInterrupt; bool m_isFinished; - OnFinishHandler m_onFinishHandler; + ScenarioCallback m_onStartHandler; + ScenarioCallback m_onFinishHandler; #ifdef DEBUG std::thread::id m_threadId; #endif diff --git a/drape_frontend/tile_info.cpp b/drape_frontend/tile_info.cpp index b8ffbc54c3..d147e4bb14 100644 --- a/drape_frontend/tile_info.cpp +++ b/drape_frontend/tile_info.cpp @@ -1,3 +1,4 @@ +#include "drape_frontend/drape_measurer.hpp" #include "drape_frontend/engine_context.hpp" #include "drape_frontend/map_data_provider.hpp" #include "drape_frontend/rule_drawer.hpp" @@ -57,6 +58,9 @@ void TileInfo::ReadFeatureIndex(MapDataProvider const & model) void TileInfo::ReadFeatures(MapDataProvider const & model) { +#if defined(DRAPE_MEASURER) && defined(TILES_STATISTIC) + DrapeMeasurer::Instance().StartTileReading(); +#endif m_context->BeginReadTile(); // Reading can be interrupted by exception throwing @@ -73,6 +77,9 @@ void TileInfo::ReadFeatures(MapDataProvider const & model) make_ref(m_context), m_is3dBuildings, m_trafficEnabled); model.ReadFeatures(bind(ref(drawer), _1), m_featureInfo); } +#if defined(DRAPE_MEASURER) && defined(TILES_STATISTIC) + DrapeMeasurer::Instance().EndTileReading(); +#endif } void TileInfo::Cancel() diff --git a/map/benchmark_tools.cpp b/map/benchmark_tools.cpp index c15401107a..6ed66a76e0 100644 --- a/map/benchmark_tools.cpp +++ b/map/benchmark_tools.cpp @@ -1,6 +1,7 @@ #include "map/benchmark_tools.hpp" #include "map/framework.hpp" +#include "drape_frontend/drape_measurer.hpp" #include "drape_frontend/scenario_manager.hpp" #include "platform/http_client.hpp" @@ -16,28 +17,51 @@ namespace { -struct ScenarioData -{ - std::string m_name; - df::ScenarioManager::Scenario m_scenario; -}; struct BenchmarkHandle { - std::vector m_scenariosRoRun; + std::vector m_scenariosToRun; size_t m_currentScenario = 0; std::vector m_regionsToDownload; size_t m_regionsToDownloadCounter = 0; + +#ifdef DRAPE_MEASURER + std::vector> m_drapeStatistic; +#endif }; void RunScenario(Framework * framework, std::shared_ptr handle) { - if (handle->m_currentScenario >= handle->m_scenariosRoRun.size()) - return; - - auto & scenarioData = handle->m_scenariosRoRun[handle->m_currentScenario]; - framework->GetDrapeEngine()->RunScenario(std::move(scenarioData.m_scenario), [framework, handle] + if (handle->m_currentScenario >= handle->m_scenariosToRun.size()) { +#ifdef DRAPE_MEASURER + for (auto const & it : handle->m_drapeStatistic) + { + LOG(LINFO, ("\n ***** Report for scenario", it.first, "*****\n", + it.second.ToString(), + "\n ***** Report for scenario", it.first, "*****\n")); + + } +#endif + return; + } + + auto & scenarioData = handle->m_scenariosToRun[handle->m_currentScenario]; + + framework->GetDrapeEngine()->RunScenario(std::move(scenarioData), + [handle](std::string const & name) + { +#ifdef DRAPE_MEASURER + df::DrapeMeasurer::Instance().StartBenchmark(); +#endif + }, + [framework, handle](std::string const & name) + { +#ifdef DRAPE_MEASURER + df::DrapeMeasurer::Instance().StopBenchmark(); + auto const drapeStatistic = df::DrapeMeasurer::Instance().GetDrapeStatistic(); + handle->m_drapeStatistic.push_back(make_pair(name, drapeStatistic)); +#endif GetPlatform().RunOnGuiThread([framework, handle]() { handle->m_currentScenario++; @@ -71,18 +95,18 @@ void RunGraphicsBenchmark(Framework * framework) if (scenariosNode == nullptr || !json_is_array(scenariosNode)) return; size_t const sz = json_array_size(scenariosNode); - handle->m_scenariosRoRun.resize(sz); + handle->m_scenariosToRun.resize(sz); for (size_t i = 0; i < sz; ++i) { auto scenarioElem = json_array_get(scenariosNode, i); if (scenarioElem == nullptr) return; - my::FromJSONObject(scenarioElem, "name", handle->m_scenariosRoRun[i].m_name); + my::FromJSONObject(scenarioElem, "name", handle->m_scenariosToRun[i].m_name); json_t * stepsNode = json_object_get(scenarioElem, "steps"); if (stepsNode != nullptr && json_is_array(stepsNode)) { size_t const stepsCount = json_array_size(stepsNode); - auto & scenario = handle->m_scenariosRoRun[i].m_scenario; + auto & scenario = handle->m_scenariosToRun[i].m_scenario; scenario.reserve(stepsCount); for (size_t j = 0; j < stepsCount; ++j) { @@ -121,7 +145,7 @@ void RunGraphicsBenchmark(Framework * framework) { return; } - if (handle->m_scenariosRoRun.empty()) + if (handle->m_scenariosToRun.empty()) return; // Find out regions to download. @@ -159,7 +183,7 @@ void RunGraphicsBenchmark(Framework * framework) return; } - // Run scenartios without downloading. + // Run scenarios without downloading. RunScenario(framework, handle); #endif } diff --git a/xcode/drape/drape.xcodeproj/project.pbxproj b/xcode/drape/drape.xcodeproj/project.pbxproj index 559538a9c3..416a4adf97 100644 --- a/xcode/drape/drape.xcodeproj/project.pbxproj +++ b/xcode/drape/drape.xcodeproj/project.pbxproj @@ -105,6 +105,7 @@ 6743D3451C3533AE0095054B /* support_manager.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 6743D3431C3533AE0095054B /* support_manager.hpp */; }; 675D21991BFB876E00717E4F /* projection.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 675D21971BFB876E00717E4F /* projection.cpp */; }; 675D219A1BFB876E00717E4F /* projection.hpp in Headers */ = {isa = PBXBuildFile; fileRef = 675D21981BFB876E00717E4F /* projection.hpp */; }; + BB035F6C1E3A2A5C00519962 /* drape_diagnostics.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BB035F6B1E3A2A5C00519962 /* drape_diagnostics.hpp */; }; BB06FBE91DDDFFBE00B41AF0 /* area_vertex_shader.vsh in Sources */ = {isa = PBXBuildFile; fileRef = BB06FBC01DDDFDC300B41AF0 /* area_vertex_shader.vsh */; }; BB06FBEA1DDDFFBE00B41AF0 /* area3d_outline_vertex_shader.vsh in Sources */ = {isa = PBXBuildFile; fileRef = BB06FBC11DDDFDC300B41AF0 /* area3d_outline_vertex_shader.vsh */; }; BB06FBEB1DDDFFBE00B41AF0 /* area3d_vertex_shader.vsh in Sources */ = {isa = PBXBuildFile; fileRef = BB06FBC21DDDFDC300B41AF0 /* area3d_vertex_shader.vsh */; }; @@ -278,6 +279,7 @@ 6743D3431C3533AE0095054B /* support_manager.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = support_manager.hpp; sourceTree = ""; }; 675D21971BFB876E00717E4F /* projection.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = projection.cpp; sourceTree = ""; }; 675D21981BFB876E00717E4F /* projection.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = projection.hpp; sourceTree = ""; }; + BB035F6B1E3A2A5C00519962 /* drape_diagnostics.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = drape_diagnostics.hpp; sourceTree = ""; }; BB06FBC01DDDFDC300B41AF0 /* area_vertex_shader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = area_vertex_shader.vsh; sourceTree = ""; }; BB06FBC11DDDFDC300B41AF0 /* area3d_outline_vertex_shader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = area3d_outline_vertex_shader.vsh; sourceTree = ""; }; BB06FBC21DDDFDC300B41AF0 /* area3d_vertex_shader.vsh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; path = area3d_vertex_shader.vsh; sourceTree = ""; }; @@ -391,6 +393,7 @@ 6729A50E1A69213A007D5872 /* cpu_buffer.hpp */, 6729A50F1A69213A007D5872 /* data_buffer.cpp */, 6729A5101A69213A007D5872 /* data_buffer.hpp */, + BB035F6B1E3A2A5C00519962 /* drape_diagnostics.hpp */, 6729A5111A69213A007D5872 /* drape_global.hpp */, 347F32F71C45383E009758CC /* debug_rect_renderer.cpp */, 347F32F81C45383E009758CC /* debug_rect_renderer.hpp */, @@ -577,6 +580,7 @@ 6729A57F1A69213A007D5872 /* glIncludes.hpp in Headers */, 6729A5A91A69213A007D5872 /* texture_of_colors.hpp in Headers */, 6729A5871A69213A007D5872 /* gpu_buffer.hpp in Headers */, + BB035F6C1E3A2A5C00519962 /* drape_diagnostics.hpp in Headers */, 6729A56E1A69213A007D5872 /* buffer_base.hpp in Headers */, 6729A58F1A69213A007D5872 /* index_buffer.hpp in Headers */, ); diff --git a/xcode/drape_frontend/drape_frontend.xcodeproj/project.pbxproj b/xcode/drape_frontend/drape_frontend.xcodeproj/project.pbxproj index f6b033793b..8dcb47445b 100644 --- a/xcode/drape_frontend/drape_frontend.xcodeproj/project.pbxproj +++ b/xcode/drape_frontend/drape_frontend.xcodeproj/project.pbxproj @@ -208,6 +208,8 @@ 67E91C7C1BDFC85E005CEE88 /* selection_shape.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 670947701BDF9BE0005014C0 /* selection_shape.cpp */; }; 67E91C7D1BDFC85E005CEE88 /* user_marks_provider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6709478B1BDF9BE0005014C0 /* user_marks_provider.cpp */; }; 67E91C7E1BDFC85E005CEE88 /* visual_params.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6709478F1BDF9BE1005014C0 /* visual_params.cpp */; }; + BB035F6F1E3A2AAE00519962 /* drape_measurer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BB035F6D1E3A2AAE00519962 /* drape_measurer.cpp */; }; + BB035F701E3A2AAE00519962 /* drape_measurer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = BB035F6E1E3A2AAE00519962 /* drape_measurer.hpp */; }; F6B283101C1B04680081957A /* gps_track_point.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6B2830B1C1B04680081957A /* gps_track_point.hpp */; }; F6B283111C1B04680081957A /* gps_track_renderer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F6B2830C1C1B04680081957A /* gps_track_renderer.cpp */; }; F6B283121C1B04680081957A /* gps_track_renderer.hpp in Headers */ = {isa = PBXBuildFile; fileRef = F6B2830D1C1B04680081957A /* gps_track_renderer.hpp */; }; @@ -421,6 +423,8 @@ 675D218B1BFB871D00717E4F /* text_engine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_engine.h; sourceTree = ""; }; 677A2DE31C0DD55D00635A00 /* requested_tiles.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = requested_tiles.cpp; sourceTree = ""; }; 677A2DE41C0DD55D00635A00 /* requested_tiles.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = requested_tiles.hpp; sourceTree = ""; }; + BB035F6D1E3A2AAE00519962 /* drape_measurer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = drape_measurer.cpp; sourceTree = ""; }; + BB035F6E1E3A2AAE00519962 /* drape_measurer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = drape_measurer.hpp; sourceTree = ""; }; F6B2830B1C1B04680081957A /* gps_track_point.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gps_track_point.hpp; sourceTree = ""; }; F6B2830C1C1B04680081957A /* gps_track_renderer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gps_track_renderer.cpp; sourceTree = ""; }; F6B2830D1C1B04680081957A /* gps_track_renderer.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = gps_track_renderer.hpp; sourceTree = ""; }; @@ -468,6 +472,8 @@ 347F520A1DC2334A0064B273 /* drape_api_renderer.hpp */, 347F520B1DC2334A0064B273 /* drape_api.cpp */, 347F520C1DC2334A0064B273 /* drape_api.hpp */, + BB035F6D1E3A2AAE00519962 /* drape_measurer.cpp */, + BB035F6E1E3A2AAE00519962 /* drape_measurer.hpp */, 34C624BF1DABDB0400510300 /* traffic_generator.cpp */, 34C624C01DABDB0400510300 /* traffic_generator.hpp */, 34C624C11DABDB0400510300 /* traffic_renderer.cpp */, @@ -806,6 +812,7 @@ 670948751BDF9C7F005014C0 /* geometry_processors.hpp in Headers */, 6709487A1BDF9C7F005014C0 /* icon_info.hpp in Headers */, 670948151BDF9C39005014C0 /* base_interpolator.hpp in Headers */, + BB035F701E3A2AAE00519962 /* drape_measurer.hpp in Headers */, 670947A61BDF9BE1005014C0 /* my_position.hpp in Headers */, 675D21901BFB871D00717E4F /* software_renderer.hpp in Headers */, 670947A81BDF9BE1005014C0 /* navigator.hpp in Headers */, @@ -923,6 +930,7 @@ 45580ABA1E28DB2600CD535D /* scenario_manager.cpp in Sources */, 670947C81BDF9BE1005014C0 /* text_shape.cpp in Sources */, 34C624C31DABDB0400510300 /* traffic_generator.cpp in Sources */, + BB035F6F1E3A2AAE00519962 /* drape_measurer.cpp in Sources */, 670947CC1BDF9BE1005014C0 /* tile_info.cpp in Sources */, 34C624C51DABDB0400510300 /* traffic_renderer.cpp in Sources */, 670947961BDF9BE1005014C0 /* line_shape.cpp in Sources */,