diff --git a/libs/drape/symbols_texture.cpp b/libs/drape/symbols_texture.cpp index aa25912a1..ba3afe86f 100644 --- a/libs/drape/symbols_texture.cpp +++ b/libs/drape/symbols_texture.cpp @@ -231,14 +231,6 @@ void SymbolsTexture::Invalidate(ref_ptr context, std::strin Load(context, skinPathName, allocator); } -void SymbolsTexture::Invalidate(ref_ptr context, std::string const & skinPathName, - ref_ptr allocator, - std::vector> & internalTextures) -{ - internalTextures.push_back(std::move(m_hwTexture)); - Invalidate(context, skinPathName, allocator); -} - ref_ptr SymbolsTexture::FindResource(Texture::Key const & key, bool & newResource) { newResource = false; diff --git a/libs/drape/symbols_texture.hpp b/libs/drape/symbols_texture.hpp index 7bf9139d7..4c5117be0 100644 --- a/libs/drape/symbols_texture.hpp +++ b/libs/drape/symbols_texture.hpp @@ -36,8 +36,6 @@ public: void Invalidate(ref_ptr context, std::string const & skinPathName, ref_ptr allocator); - void Invalidate(ref_ptr context, std::string const & skinPathName, - ref_ptr allocator, std::vector> & internalTextures); bool IsSymbolContained(std::string const & symbolName) const; diff --git a/libs/drape/texture.hpp b/libs/drape/texture.hpp index 8becf4850..be52ef6e1 100644 --- a/libs/drape/texture.hpp +++ b/libs/drape/texture.hpp @@ -73,6 +73,12 @@ public: static bool IsPowerOfTwo(uint32_t width, uint32_t height); + void DeferredCleanup(std::vector> & toCleanup) + { + toCleanup.push_back(std::move(m_hwTexture)); + Destroy(); + } + protected: void Destroy(); bool AllocateTexture(ref_ptr context, ref_ptr allocator); diff --git a/libs/drape/texture_manager.cpp b/libs/drape/texture_manager.cpp index 9ceec7437..be65b3f19 100644 --- a/libs/drape/texture_manager.cpp +++ b/libs/drape/texture_manager.cpp @@ -87,6 +87,10 @@ drape_ptr CreateArrowTexture(ref_ptr context, useDefaultResourceFolder ? StaticTexture::kDefaultResource : std::string(), dp::TextureFormat::RGBA8, textureAllocator, true /* allowOptional */); } + + // There is no "arrow-texture.png". + // BackendRenderer::m_arrow3dPreloadedData mesh is used by default. + /// @todo Texture arrow is still present in case if somebody wants to use it? return make_unique_dp(context, "arrow-texture.png", StaticTexture::kDefaultResource, dp::TextureFormat::RGBA8, textureAllocator, true /* allowOptional */); } @@ -315,39 +319,7 @@ void TextureManager::Init(ref_ptr context, Params const & p m_smaaSearchTexture = make_unique_dp(context, "smaa-search.png", StaticTexture::kDefaultResource, dp::TextureFormat::Red, make_ref(m_textureAllocator)); - // Initialize patterns (reserved ./data/patterns.txt lines count). - std::set patterns; - - double const visualScale = params.m_visualScale; - uint32_t rowsCount = 0; - impl::ParsePatternsList(params.m_patterns, [&](buffer_vector const & pattern) - { - PenPatternT toAdd; - for (double d : pattern) - toAdd.push_back(PatternFloat2Pixel(d * visualScale)); - - if (!patterns.insert(toAdd).second) - return; - - if (IsTrianglePattern(toAdd)) - { - rowsCount = rowsCount + toAdd[2] + toAdd[3]; - } - else - { - ASSERT_EQUAL(toAdd.size(), 2, ()); - ++rowsCount; - } - }); - - m_stipplePenTexture = make_unique_dp(StipplePenTextureSize(rowsCount, m_maxTextureSize), - make_ref(m_textureAllocator)); - - LOG(LDEBUG, ("Patterns texture size =", m_stipplePenTexture->GetWidth(), m_stipplePenTexture->GetHeight())); - - ref_ptr stipplePenTex = make_ref(m_stipplePenTexture); - for (auto const & p : patterns) - stipplePenTex->ReservePattern(p); + InitStipplePen(params); // Initialize colors (reserved ./data/colors.txt lines count). std::vector colors; @@ -380,25 +352,73 @@ void TextureManager::Init(ref_ptr context, Params const & p m_nothingToUpload.clear(); } +void TextureManager::InitStipplePen(Params const & params) +{ + // Initialize patterns (reserved ./data/patterns.txt lines count). + std::set patterns; + uint32_t rowsCount = 0; + + impl::ParsePatternsList(params.m_patterns, [&](buffer_vector const & pattern) + { + PenPatternT toAdd; + for (double d : pattern) + toAdd.push_back(PatternFloat2Pixel(d * params.m_visualScale)); + + if (!patterns.insert(toAdd).second) + return; + + if (IsTrianglePattern(toAdd)) + { + rowsCount = rowsCount + toAdd[2] + toAdd[3]; + } + else + { + ASSERT_EQUAL(toAdd.size(), 2, ()); + ++rowsCount; + } + }); + + m_stipplePenTexture = make_unique_dp(StipplePenTextureSize(rowsCount, m_maxTextureSize), + make_ref(m_textureAllocator)); + + LOG(LDEBUG, ("Patterns texture size =", m_stipplePenTexture->GetWidth(), m_stipplePenTexture->GetHeight())); + + ref_ptr stipplePenTex = make_ref(m_stipplePenTexture); + for (auto const & p : patterns) + stipplePenTex->ReservePattern(p); +} + void TextureManager::OnSwitchMapStyle(ref_ptr context) { CHECK(m_isInitialized, ()); + bool const isVulkan = context->GetApiVersion() == dp::ApiVersion::Vulkan; + // Here we need invalidate only textures which can be changed in map style switch. // Now we update only symbol textures, if we need update other textures they must be added here. // For Vulkan we use m_texturesToCleanup to defer textures destroying. - for (auto const & m_symbolTexture : m_symbolTextures) + for (auto const & texture : m_symbolTextures) { - ref_ptr symbolsTexture = make_ref(m_symbolTexture); - ASSERT(symbolsTexture != nullptr, ()); + ref_ptr symbolsTexture = make_ref(texture); + if (isVulkan) + symbolsTexture->DeferredCleanup(m_texturesToCleanup); - if (context->GetApiVersion() != dp::ApiVersion::Vulkan) - symbolsTexture->Invalidate(context, m_resPostfix, make_ref(m_textureAllocator)); - else - symbolsTexture->Invalidate(context, m_resPostfix, make_ref(m_textureAllocator), m_texturesToCleanup); + symbolsTexture->Invalidate(context, m_resPostfix, make_ref(m_textureAllocator)); } } +void TextureManager::OnVisualScaleChanged(ref_ptr context, Params const & params) +{ + m_resPostfix = params.m_resPostfix; + + OnSwitchMapStyle(context); + + if (context->GetApiVersion() == dp::ApiVersion::Vulkan) + m_stipplePenTexture->DeferredCleanup(m_texturesToCleanup); + + InitStipplePen(params); +} + void TextureManager::InvalidateArrowTexture(ref_ptr context, std::string const & texturePath /* = {} */, bool useDefaultResourceFolder /* = false */) @@ -416,10 +436,13 @@ void TextureManager::ApplyInvalidatedStaticTextures() } } -void TextureManager::GetTexturesToCleanup(std::vector> & textures) +std::vector> TextureManager::GetTexturesToCleanup() { CHECK(m_isInitialized, ()); - std::swap(textures, m_texturesToCleanup); + + auto res = std::move(m_texturesToCleanup); + m_texturesToCleanup.clear(); + return res; } bool TextureManager::GetSymbolRegionSafe(std::string const & symbolName, SymbolRegion & region) diff --git a/libs/drape/texture_manager.hpp b/libs/drape/texture_manager.hpp index 4f2f61930..60dd83f43 100644 --- a/libs/drape/texture_manager.hpp +++ b/libs/drape/texture_manager.hpp @@ -77,7 +77,9 @@ public: void Init(ref_ptr context, Params const & params); void OnSwitchMapStyle(ref_ptr context); - void GetTexturesToCleanup(std::vector> & textures); + void OnVisualScaleChanged(ref_ptr context, Params const & params); + + std::vector> GetTexturesToCleanup(); bool GetSymbolRegionSafe(std::string const & symbolName, SymbolRegion & region); void GetSymbolRegion(std::string const & symbolName, SymbolRegion & region); @@ -121,6 +123,8 @@ public: ref_ptr GetTextureAllocator() const; private: + void InitStipplePen(Params const & params); + struct GlyphGroup { std::set m_glyphKeys; diff --git a/libs/drape_frontend/backend_renderer.cpp b/libs/drape_frontend/backend_renderer.cpp index c2654b804..d14f191cf 100644 --- a/libs/drape_frontend/backend_renderer.cpp +++ b/libs/drape_frontend/backend_renderer.cpp @@ -17,8 +17,6 @@ #include "drape/support_manager.hpp" #include "drape/texture_manager.hpp" -#include "indexer/scales.hpp" - #include "platform/platform.hpp" #include "base/file_name_utils.hpp" @@ -355,18 +353,37 @@ void BackendRenderer::AcceptMessage(ref_ptr message) m_trafficGenerator->InvalidateTexturesCache(); m_transitBuilder->RebuildSchemes(m_context, m_texMng); - // For Vulkan we initialize deferred cleaning up. - if (m_context->GetApiVersion() == dp::ApiVersion::Vulkan) - { - std::vector> textures; - m_texMng->GetTexturesToCleanup(textures); - if (!textures.empty()) - { - m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(std::move(textures)), MessagePriority::Normal); - } - } + CleanupTextures(); + break; + } + case Message::Type::VisualScaleChanged: + { + ref_ptr msg = message; + msg->FilterDependentMessages(); + + CHECK(m_context != nullptr, ()); + + dp::TextureManager::Params params; + params.m_resPostfix = VisualParams::Instance().GetResourcePostfix(); + params.m_visualScale = df::VisualParams::Instance().GetVisualScale(); +#ifdef BUILD_DESIGNER + params.m_patterns = "patterns_design.txt"; +#else + params.m_patterns = "patterns.txt"; +#endif // BUILD_DESIGNER + + m_texMng->OnVisualScaleChanged(m_context, params); + + RecacheMapShapes(); + RecacheGui(m_lastWidgetsInfo, false /* needResetOldGui */); +#ifdef RENDER_DEBUG_INFO_LABELS + RecacheDebugLabels(); +#endif + m_trafficGenerator->InvalidateTexturesCache(); + m_transitBuilder->RebuildSchemes(m_context, m_texMng); + + CleanupTextures(); break; } @@ -611,21 +628,8 @@ void BackendRenderer::AcceptMessage(ref_ptr message) m_arrow3dPreloadedData = Arrow3d::PreloadMesh(m_arrow3dCustomDecl, m_texMng); } - // Recache map shapes. RecacheMapShapes(); - - // For Vulkan we initialize deferred cleaning up. - if (m_context->GetApiVersion() == dp::ApiVersion::Vulkan) - { - std::vector> textures; - m_texMng->GetTexturesToCleanup(textures); - if (!textures.empty()) - { - m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(std::move(textures)), MessagePriority::Normal); - } - } - + CleanupTextures(); break; } @@ -772,6 +776,18 @@ void BackendRenderer::RecacheMapShapes() m_commutator->PostMessage(ThreadsCommutator::RenderThread, std::move(msg), MessagePriority::Normal); } +void BackendRenderer::CleanupTextures() +{ + // For Vulkan we initialize deferred cleaning up. + if (m_context->GetApiVersion() == dp::ApiVersion::Vulkan) + { + auto textures = m_texMng->GetTexturesToCleanup(); + if (!textures.empty()) + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(std::move(textures)), MessagePriority::Normal); + } +} + void BackendRenderer::FlushGeometry(TileKey const & key, dp::RenderState const & state, drape_ptr && buffer) { diff --git a/libs/drape_frontend/backend_renderer.hpp b/libs/drape_frontend/backend_renderer.hpp index a9ad6f78a..16fbc68b0 100644 --- a/libs/drape_frontend/backend_renderer.hpp +++ b/libs/drape_frontend/backend_renderer.hpp @@ -83,6 +83,7 @@ private: void RecacheGui(gui::TWidgetsInitInfo const & initInfo, bool needResetOldGui); void RecacheChoosePositionMark(); void RecacheMapShapes(); + void CleanupTextures(); #ifdef RENDER_DEBUG_INFO_LABELS void RecacheDebugLabels(); diff --git a/libs/drape_frontend/drape_engine.cpp b/libs/drape_frontend/drape_engine.cpp index dcd1d1cbc..50e3372c3 100644 --- a/libs/drape_frontend/drape_engine.cpp +++ b/libs/drape_frontend/drape_engine.cpp @@ -897,10 +897,8 @@ void DrapeEngine::UpdateVisualScale(double vs, bool needStopRendering) if (needStopRendering) SetRenderingEnabled(); - RecacheGui(false); - RecacheMapShapes(); - m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(), MessagePriority::Normal); + m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, make_unique_dp(), + MessagePriority::High); } void DrapeEngine::UpdateMyPositionRoutingOffset(bool useDefault, int offsetY) diff --git a/libs/drape_frontend/frontend_renderer.cpp b/libs/drape_frontend/frontend_renderer.cpp index 94fc630e9..37f07850a 100644 --- a/libs/drape_frontend/frontend_renderer.cpp +++ b/libs/drape_frontend/frontend_renderer.cpp @@ -640,51 +640,11 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) break; } - case Message::Type::RecoverContextDependentResources: - { - UpdateContextDependentResources(); - break; - } + case Message::Type::RecoverContextDependentResources: UpdateContextDependentResources(); break; - case Message::Type::UpdateMapStyle: - { -#ifdef BUILD_DESIGNER - classificator::Load(); -#endif // BUILD_DESIGNER + case Message::Type::UpdateMapStyle: UpdateAll(); break; - // Clear all graphics. - for (RenderLayer & layer : m_layers) - { - layer.m_renderGroups.clear(); - layer.m_isDirty = false; - } - - // Must be recreated on map style changing. - CHECK(m_context != nullptr, ()); - m_transitBackground = make_unique_dp(m_context); - - // Invalidate read manager. - { - BaseBlockingMessage::Blocker blocker; - m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(blocker), MessagePriority::Normal); - blocker.Wait(); - } - - // Delete all messages which can contain render states (and textures references inside). - auto f = [this]() { InstantMessageFilter([](ref_ptr msg) { return msg->ContainsRenderState(); }); }; - - // Notify backend renderer and wait for completion. - { - BaseBlockingMessage::Blocker blocker; - m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(blocker, std::move(f)), MessagePriority::Normal); - blocker.Wait(); - } - - UpdateContextDependentResources(); - break; - } + case Message::Type::VisualScaleChanged: UpdateAll(); break; case Message::Type::AllowAutoZoom: { @@ -1023,6 +983,46 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) } } +template +void FrontendRenderer::UpdateAll() +{ +#ifdef BUILD_DESIGNER + classificator::Load(); +#endif // BUILD_DESIGNER + + // Clear all graphics. + for (RenderLayer & layer : m_layers) + { + layer.m_renderGroups.clear(); + layer.m_isDirty = false; + } + + // Must be recreated on map style changing. + CHECK(m_context != nullptr, ()); + m_transitBackground = make_unique_dp(m_context); + + // Invalidate read manager. + { + BaseBlockingMessage::Blocker blocker; + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(blocker), MessagePriority::Normal); + blocker.Wait(); + } + + // Delete all messages which can contain render states (and textures references inside). + auto f = [this]() { InstantMessageFilter([](ref_ptr msg) { return msg->ContainsRenderState(); }); }; + + // Notify backend renderer and wait for completion. + { + BaseBlockingMessage::Blocker blocker; + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, make_unique_dp(blocker, std::move(f)), + MessagePriority::Normal); + blocker.Wait(); + } + + UpdateContextDependentResources(); +} + std::unique_ptr FrontendRenderer::CreateRoutine() { return std::make_unique(*this); diff --git a/libs/drape_frontend/frontend_renderer.hpp b/libs/drape_frontend/frontend_renderer.hpp index a594ef604..ba7f4c541 100644 --- a/libs/drape_frontend/frontend_renderer.hpp +++ b/libs/drape_frontend/frontend_renderer.hpp @@ -247,6 +247,9 @@ private: void ReleaseResources(); void UpdateContextDependentResources(); + template + void UpdateAll(); + void BeginUpdateOverlayTree(ScreenBase const & modelView); void UpdateOverlayTree(ScreenBase const & modelView, drape_ptr & renderGroup); void EndUpdateOverlayTree(); diff --git a/libs/drape_frontend/message.cpp b/libs/drape_frontend/message.cpp index 8cd07c011..65ee7bc7e 100644 --- a/libs/drape_frontend/message.cpp +++ b/libs/drape_frontend/message.cpp @@ -103,6 +103,7 @@ std::string DebugPrint(Message::Type msgType) case Message::Type::EnableIsolines: return "EnableIsolines"; case Message::Type::OnEnterBackground: return "OnEnterBackground"; case Message::Type::Arrow3dRecache: return "Arrow3dRecache"; + case Message::Type::VisualScaleChanged: return "VisualScaleChanged"; } ASSERT(false, ("Unknown message type.")); return "Unknown type"; diff --git a/libs/drape_frontend/message.hpp b/libs/drape_frontend/message.hpp index 1aa50d585..b0ce44799 100644 --- a/libs/drape_frontend/message.hpp +++ b/libs/drape_frontend/message.hpp @@ -103,7 +103,8 @@ public: NotifyGraphicsReady, EnableIsolines, OnEnterBackground, - Arrow3dRecache + Arrow3dRecache, + VisualScaleChanged, }; virtual ~Message() = default; diff --git a/libs/drape_frontend/message_subclasses.hpp b/libs/drape_frontend/message_subclasses.hpp index e0fc00574..7a0fe6ed3 100644 --- a/libs/drape_frontend/message_subclasses.hpp +++ b/libs/drape_frontend/message_subclasses.hpp @@ -1,7 +1,6 @@ #pragma once #include "drape_frontend/circles_pack_shape.hpp" -#include "drape_frontend/color_constants.hpp" #include "drape_frontend/custom_features_context.hpp" #include "drape_frontend/drape_api.hpp" #include "drape_frontend/drape_api_builder.hpp" @@ -14,8 +13,7 @@ #include "drape_frontend/overlay_batcher.hpp" #include "drape_frontend/postprocess_renderer.hpp" #include "drape_frontend/render_node.hpp" -#include "drape_frontend/render_state_extension.hpp" -#include "drape_frontend/route_builder.hpp" +#include "drape_frontend/route_shape.hpp" #include "drape_frontend/selection_shape.hpp" #include "drape_frontend/tile_utils.hpp" #include "drape_frontend/traffic_generator.hpp" @@ -26,13 +24,10 @@ #include "drape/pointers.hpp" #include "drape/render_bucket.hpp" -#include "drape/viewport.hpp" #include "platform/location.hpp" -#include "geometry/polyline2d.hpp" #include "geometry/rect2d.hpp" -#include "geometry/screenbase.hpp" #include "geometry/triangle2d.hpp" #include @@ -40,7 +35,6 @@ #include #include #include -#include #include namespace df @@ -737,6 +731,12 @@ public: Type GetType() const override { return Type::UpdateMapStyle; } }; +class UpdateVisualScaleMessage : public Message +{ +public: + Type GetType() const override { return Type::VisualScaleChanged; } +}; + class FollowRouteMessage : public Message { public: @@ -783,6 +783,14 @@ private: FilterMessagesHandler m_filterMessagesHandler; }; +class VisualScaleChangedMessage : public SwitchMapStyleMessage +{ +public: + using SwitchMapStyleMessage::SwitchMapStyleMessage; + + Type GetType() const override { return Type::VisualScaleChanged; } +}; + class InvalidateMessage : public Message { public: