diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index a60ea9657c..43d86dbeaf 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -140,25 +140,25 @@ void BackendRenderer::AcceptMessage(ref_ptr message) m_batchersPool->ReleaseBatcher(msg->GetKey()); break; } + case Message::FinishTileRead: + { + ref_ptr msg = message; + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(msg->MoveTiles(), + msg->GetTileRequestGeneration()), + MessagePriority::Normal); + break; + } case Message::FinishReading: { - ref_ptr msg = message; - if (msg->IsEnableFlushOverlays()) + TOverlaysRenderData overlays; + overlays.swap(m_overlays); + if (!overlays.empty()) { - TOverlaysRenderData overlays; - overlays.swap(m_overlays); - if (!overlays.empty()) - { - m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(move(overlays)), - MessagePriority::Normal); - } + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(move(overlays)), + MessagePriority::Normal); } - - m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(move(msg->MoveTiles()), - msg->GetTileRequestGeneration()), - MessagePriority::Normal); break; } case Message::MapShapeReaded: diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 37ff14d720..c1055d813a 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -195,6 +195,42 @@ void FrontendRenderer::AfterDrawFrame() #endif +void FrontendRenderer::UpdateFeaturesWaitingStatus() +{ + m2::RectD const & screenRect = m_userEventStream.GetCurrentScreen().ClipRect(); + + vector notFinishedTileRects; + notFinishedTileRects.reserve(m_notFinishedTiles.size()); + for (auto const & tileKey : m_notFinishedTiles) + notFinishedTileRects.push_back(tileKey.GetGlobalRect()); + + for (RenderLayer & layer : m_layers) + { + for (auto & group : layer.m_renderGroups) + { + if (group->IsFeaturesWaiting()) + { + m2::RectD const tileRect = group->GetTileKey().GetGlobalRect(); + bool waitTileFeatures = false; + if (!notFinishedTileRects.empty() && tileRect.IsIntersect(screenRect)) + { + for (auto const & notFinishedRect : notFinishedTileRects) + { + if (notFinishedRect.IsIntersect(tileRect)) + { + waitTileFeatures = true; + break; + } + } + } + + layer.m_isDirty |= group->UpdateFeaturesWaitingStatus(waitTileFeatures, m_currentZoomLevel, + make_ref(m_overlayTree), m_bucketsToDelete); + } + } + } +} + void FrontendRenderer::AcceptMessage(ref_ptr message) { switch (message->GetType()) @@ -243,19 +279,29 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) break; } - case Message::FinishReading: + case Message::FinishTileRead: { - ref_ptr msg = message; + ref_ptr msg = message; bool const isLastRequest = m_tileRequestGeneration == msg->GetTileRequestGeneration(); + if (!isLastRequest) + break; + + bool changed = false; for (auto const & tileKey : msg->GetTiles()) { - if (CheckTileGenerations(tileKey) && isLastRequest) + if (CheckTileGenerations(tileKey)) { auto it = m_notFinishedTiles.find(tileKey); if (it != m_notFinishedTiles.end()) + { m_notFinishedTiles.erase(it); + changed = true; + } } } + + if (changed) + UpdateFeaturesWaitingStatus(); break; } @@ -856,37 +902,6 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) BeforeDrawFrame(); #endif - m2::RectD const & screenRect = modelView.ClipRect(); - vector notFinishedTileRects; - notFinishedTileRects.reserve(m_notFinishedTiles.size()); - for (auto const & tileKey : m_notFinishedTiles) - notFinishedTileRects.push_back(tileKey.GetGlobalRect()); - - for (RenderLayer & layer : m_layers) - { - for (auto & group : layer.m_renderGroups) - { - if (group->IsFeaturesWaiting()) - { - m2::RectD const tileRect = group->GetTileKey().GetGlobalRect(); - bool waitTileFeatures = false; - if (!notFinishedTileRects.empty() && tileRect.IsIntersect(screenRect)) - { - for (auto const & notFinishedRect : notFinishedTileRects) - { - if (notFinishedRect.IsIntersect(tileRect)) - { - waitTileFeatures = true; - break; - } - } - } - layer.m_isDirty |= group->UpdateFeaturesWaitingStatus(waitTileFeatures, m_currentZoomLevel, - make_ref(m_overlayTree), m_bucketsToDelete); - } - } - } - bool const isPerspective = modelView.isPerspective(); GLFunctions::glEnable(gl_const::GLDepthTest); @@ -1196,8 +1211,12 @@ void FrontendRenderer::CheckPerspectiveMinScale() void FrontendRenderer::ResolveZoomLevel(ScreenBase const & screen) { + int const prevZoomLevel = m_currentZoomLevel; m_currentZoomLevel = GetDrawTileScale(screen); + if (prevZoomLevel != m_currentZoomLevel) + UpdateFeaturesWaitingStatus(); + CheckIsometryMinScale(screen); CheckPerspectiveMinScale(); } diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 1f565a964b..6b95ee10d4 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -216,6 +216,7 @@ private: double rotationAngle, double angleFOV); void InvalidateRect(m2::RectD const & gRect); bool CheckTileGenerations(TileKey const & tileKey); + void UpdateFeaturesWaitingStatus(); void OnCompassTapped(); diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index a83af1cfd4..af50beefbc 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -12,6 +12,7 @@ public: TileReadStarted, TileReadEnded, FinishReading, + FinishTileRead, FlushTile, FlushOverlays, MapShapeReaded, diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 163341b389..d856526c1b 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -90,23 +90,27 @@ private: class FinishReadingMessage : public Message { public: - template FinishReadingMessage(T && tiles, uint64_t tileRequestGeneration, bool enableFlushOverlays = true) + FinishReadingMessage() = default; + Type GetType() const override { return Message::FinishReading; } +}; + +class FinishTileReadMessage : public Message +{ +public: + template FinishTileReadMessage(T && tiles, uint64_t tileRequestGeneration) : m_tiles(forward(tiles)) , m_tileRequestGeneration(tileRequestGeneration) - , m_enableFlushOverlays(enableFlushOverlays) {} - Type GetType() const override { return Message::FinishReading; } + Type GetType() const override { return Message::FinishTileRead; } TTilesCollection const & GetTiles() const { return m_tiles; } TTilesCollection && MoveTiles() { return move(m_tiles); } uint64_t GetTileRequestGeneration() const { return m_tileRequestGeneration; } - bool IsEnableFlushOverlays() const { return m_enableFlushOverlays; } private: TTilesCollection m_tiles; uint64_t m_tileRequestGeneration; - bool m_enableFlushOverlays; }; class FlushRenderBucketMessage : public BaseTileMessage diff --git a/drape_frontend/read_manager.cpp b/drape_frontend/read_manager.cpp index f0d94c43ca..bf2d8666a2 100755 --- a/drape_frontend/read_manager.cpp +++ b/drape_frontend/read_manager.cpp @@ -60,9 +60,7 @@ void ReadManager::OnTaskFinished(threads::IRoutine * task) { lock_guard lock(m_finishedTilesMutex); - // add finished tile to collection - if (!task->IsCancelled()) - m_finishedTiles.emplace(t->GetTileKey()); + m_activeTiles.erase(t->GetTileKey()); // decrement counter ASSERT(m_counter > 0, ()); @@ -70,9 +68,17 @@ void ReadManager::OnTaskFinished(threads::IRoutine * task) if (m_counter == 0) { m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(m_finishedTiles, m_tileRequestGeneration), + make_unique_dp(), + MessagePriority::Normal); + } + + if (!task->IsCancelled()) + { + TTilesCollection tiles; + tiles.emplace(t->GetTileKey()); + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(move(tiles), m_tileRequestGeneration), MessagePriority::Normal); - m_finishedTiles.clear(); } } @@ -94,11 +100,12 @@ void ReadManager::UpdateCoverage(ScreenBase const & screen, bool is3dBuildings, { m_modeChanged = false; + for_each(m_tileInfos.begin(), m_tileInfos.end(), bind(&ReadManager::CancelTileInfo, this, _1)); + m_tileInfos.clear(); + IncreaseCounter(static_cast(tiles.size()), tileRequestGeneration); m_generationCounter++; - for_each(m_tileInfos.begin(), m_tileInfos.end(), bind(&ReadManager::CancelTileInfo, this, _1)); - m_tileInfos.clear(); for_each(tiles.begin(), tiles.end(), bind(&ReadManager::PushTaskBackForTileKey, this, _1, texMng)); } else @@ -112,6 +119,8 @@ void ReadManager::UpdateCoverage(ScreenBase const & screen, bool is3dBuildings, tiles.begin(), tiles.end(), back_inserter(outdatedTiles), LessCoverageCell()); + for_each(outdatedTiles.begin(), outdatedTiles.end(), bind(&ReadManager::ClearTileInfo, this, _1)); + // Find rects that go in into viewport. buffer_vector newTiles; #ifdef _MSC_VER @@ -130,9 +139,8 @@ void ReadManager::UpdateCoverage(ScreenBase const & screen, bool is3dBuildings, outdatedTiles.begin(), outdatedTiles.end(), back_inserter(readyTiles), LessCoverageCell()); - IncreaseCounter(static_cast(newTiles.size()), tileRequestGeneration, &readyTiles); - - for_each(outdatedTiles.begin(), outdatedTiles.end(), bind(&ReadManager::ClearTileInfo, this, _1)); + IncreaseCounter(static_cast(newTiles.size()), tileRequestGeneration); + CheckFinishedTiles(readyTiles); for_each(newTiles.begin(), newTiles.end(), bind(&ReadManager::PushTaskBackForTileKey, this, _1, texMng)); } @@ -188,7 +196,7 @@ bool ReadManager::CheckTileKey(TileKey const & tileKey) const size_t ReadManager::ReadCount() { - return max(static_cast(GetPlatform().CpuCores()) - 2, 1); + return max(static_cast(GetPlatform().CpuCores()) - 2, 2); } bool ReadManager::MustDropAllTiles(ScreenBase const & screen) const @@ -205,16 +213,34 @@ void ReadManager::PushTaskBackForTileKey(TileKey const & tileKey, ref_ptrSet3dBuildings(m_need3dBuildings && m_allow3dBuildings); m_tileInfos.insert(tileInfo); ReadMWMTask * task = myPool.Get(); + task->Init(tileInfo); + { + lock_guard lock(m_finishedTilesMutex); + m_activeTiles.insert(tileKey); + } m_pool->PushBack(task); } -void ReadManager::PushTaskFront(shared_ptr const & tileToReread) +void ReadManager::CheckFinishedTiles(TTileInfoCollection const & requestedTiles) { - tileToReread->Set3dBuildings(m_need3dBuildings && m_allow3dBuildings); - ReadMWMTask * task = myPool.Get(); - task->Init(tileToReread); - m_pool->PushFront(task); + if (requestedTiles.empty()) + return; + + TTilesCollection finishedTiles; + + lock_guard lock(m_finishedTilesMutex); + + for (auto const & tile : requestedTiles) + if (m_activeTiles.find(tile->GetTileKey()) == m_activeTiles.end()) + finishedTiles.emplace(tile->GetTileKey()); + + if (!finishedTiles.empty()) + { + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(move(finishedTiles), m_tileRequestGeneration), + MessagePriority::Normal); + } } void ReadManager::CancelTileInfo(shared_ptr const & tileToCancel) @@ -228,27 +254,17 @@ void ReadManager::ClearTileInfo(shared_ptr const & tileToClear) m_tileInfos.erase(tileToClear); } -void ReadManager::IncreaseCounter(int value, uint64_t tileRequestGeneration, - TTileInfoCollection * readyTiles) +void ReadManager::IncreaseCounter(int value, uint64_t tileRequestGeneration) { lock_guard lock(m_finishedTilesMutex); m_counter += value; m_tileRequestGeneration = tileRequestGeneration; - if (readyTiles != nullptr) + if (m_counter == 0) { - bool const enableFlushOverlays = !m_finishedTiles.empty(); - for (shared_ptr & tile : *readyTiles) - m_finishedTiles.emplace(tile->GetTileKey()); - - if (m_counter == 0) - { - m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(m_finishedTiles, m_tileRequestGeneration, - enableFlushOverlays), - MessagePriority::Normal); - m_finishedTiles.clear(); - } + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(), + MessagePriority::Normal); } } diff --git a/drape_frontend/read_manager.hpp b/drape_frontend/read_manager.hpp index d4b8e1c833..f1c84a4894 100755 --- a/drape_frontend/read_manager.hpp +++ b/drape_frontend/read_manager.hpp @@ -45,7 +45,6 @@ private: bool MustDropAllTiles(ScreenBase const & screen) const; void PushTaskBackForTileKey(TileKey const & tileKey, ref_ptr texMng); - void PushTaskFront(shared_ptr const & tileToReread); private: ref_ptr m_commutator; @@ -74,17 +73,17 @@ private: ObjectPool myPool; int m_counter; - set m_finishedTiles; mutex m_finishedTilesMutex; uint64_t m_generationCounter; uint64_t m_tileRequestGeneration; using TTileInfoCollection = buffer_vector, 8>; + TTilesCollection m_activeTiles; void CancelTileInfo(shared_ptr const & tileToCancel); void ClearTileInfo(shared_ptr const & tileToClear); - void IncreaseCounter(int value, uint64_t tileRequestGeneration, - TTileInfoCollection * readyTiles = nullptr); + void IncreaseCounter(int value, uint64_t tileRequestGeneration); + void CheckFinishedTiles(TTileInfoCollection const & requestedTiles); }; } // namespace df