diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f0e897d0..e55cd3ff1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,11 @@ else() add_compile_options(-ffast-math $<$:-Wno-psabi>) endif() +# Needed for std::execution::par +if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + add_compile_options(-fexperimental-library) +endif() + if (PLATFORM_WIN) add_definitions( -DWIN32_LEAN_AND_MEAN diff --git a/libs/drape/batcher.cpp b/libs/drape/batcher.cpp index d559ca126..cd0bf4c62 100644 --- a/libs/drape/batcher.cpp +++ b/libs/drape/batcher.cpp @@ -1,11 +1,9 @@ #include "drape/batcher.hpp" #include "drape/batcher_helpers.hpp" -#include "drape/cpu_buffer.hpp" #include "drape/index_storage.hpp" #include "drape/vertex_array_buffer.hpp" #include "base/assert.hpp" -#include "base/stl_helpers.hpp" #include @@ -190,14 +188,6 @@ void Batcher::ResetSession() m_buckets.clear(); } -void Batcher::SetFeatureMinZoom(int minZoom) -{ - m_featureMinZoom = minZoom; - - for (auto const & bucket : m_buckets) - bucket.second->SetFeatureMinZoom(m_featureMinZoom); -} - void Batcher::SetBatcherHash(uint64_t batcherHash) { m_batcherHash = batcherHash; diff --git a/libs/drape/batcher.hpp b/libs/drape/batcher.hpp index 2315ad257..c5ac26b6b 100644 --- a/libs/drape/batcher.hpp +++ b/libs/drape/batcher.hpp @@ -10,6 +10,7 @@ #include "base/macros.hpp" +#include #include #include #include @@ -68,7 +69,13 @@ public: void SetBatcherHash(uint64_t batcherHash); - void SetFeatureMinZoom(int minZoom); + inline void SetFeatureMinZoom(int minZoom) + { + m_featureMinZoom = minZoom; + + std::for_each(std::execution::par_unseq, m_buckets.begin(), m_buckets.end(), + [this](auto const & bucket) { bucket.second->SetFeatureMinZoom(m_featureMinZoom); }); + } private: template diff --git a/libs/drape/font_texture.cpp b/libs/drape/font_texture.cpp index 55407f3df..19cfbcd1d 100644 --- a/libs/drape/font_texture.cpp +++ b/libs/drape/font_texture.cpp @@ -5,8 +5,6 @@ #include "base/logging.hpp" #include -#include -#include #include "font_constants.hpp" diff --git a/libs/drape/gl_gpu_program.cpp b/libs/drape/gl_gpu_program.cpp index e3332a613..d2a00dc2c 100644 --- a/libs/drape/gl_gpu_program.cpp +++ b/libs/drape/gl_gpu_program.cpp @@ -1,7 +1,6 @@ #include "drape/gl_gpu_program.hpp" #include "drape/gl_functions.hpp" #include "drape/render_state.hpp" -#include "drape/support_manager.hpp" #include "base/logging.hpp" diff --git a/libs/drape/gl_gpu_program.hpp b/libs/drape/gl_gpu_program.hpp index 91ab30486..577eb8438 100644 --- a/libs/drape/gl_gpu_program.hpp +++ b/libs/drape/gl_gpu_program.hpp @@ -5,9 +5,8 @@ #include "drape/pointers.hpp" #include "drape/shader.hpp" -#include +#include #include -#include namespace dp { @@ -30,7 +29,7 @@ public: glConst m_type = gl_const::GLFloatType; }; - using UniformsInfo = std::map; + using UniformsInfo = std::unordered_map; UniformsInfo const & GetUniformsInfo() const; uint32_t GetNumericUniformsCount() const { return m_numericUniformsCount; } diff --git a/libs/drape/glyph_manager.cpp b/libs/drape/glyph_manager.cpp index e939a52b1..51c508716 100644 --- a/libs/drape/glyph_manager.cpp +++ b/libs/drape/glyph_manager.cpp @@ -16,6 +16,8 @@ #include "base/stl_helpers.hpp" #include "base/string_utils.hpp" +#include + #include #include #include @@ -203,9 +205,9 @@ FreetypeError constexpr g_FT_Errors[] = static void Close(FT_Stream) {} - void MarkGlyphReady(uint16_t glyphId) { m_readyGlyphs.emplace(glyphId); } + inline void MarkGlyphReady(uint16_t glyphId) { m_readyGlyphs.emplace(glyphId); } - bool IsGlyphReady(uint16_t glyphId) const { return m_readyGlyphs.find(glyphId) != m_readyGlyphs.end(); } + inline bool IsGlyphReady(uint16_t glyphId) const { return m_readyGlyphs.find(glyphId) != m_readyGlyphs.end(); } std::string GetName() const { return std::string(m_fontFace->family_name) + ':' + m_fontFace->style_name; } @@ -229,7 +231,9 @@ FreetypeError constexpr g_FT_Errors[] = hb_glyph_info_t const * glyphInfo = hb_buffer_get_glyph_infos(hbBuffer, &glyphCount); hb_glyph_position_t const * glyphPos = hb_buffer_get_glyph_positions(hbBuffer, &glyphCount); - for (unsigned int i = 0; i < glyphCount; ++i) + auto const range = std::ranges::views::iota(0u, glyphCount); + + std::for_each(std::execution::par_unseq, range.begin(), range.end(), [&, this](auto const i) { // TODO(AB): Check for missing glyph ID? auto const glyphId = static_cast(glyphInfo[i].codepoint); @@ -247,7 +251,7 @@ FreetypeError constexpr g_FT_Errors[] = // yAdvance is always zero for horizontal text layouts. outMetrics.AddGlyphMetrics(static_cast(fontIndex), glyphId, xOffset, yOffset, xAdvance, fontPixelSize); - } + }); } private: @@ -255,7 +259,7 @@ FreetypeError constexpr g_FT_Errors[] = FT_StreamRec_ m_stream; FT_Face m_fontFace; - std::set m_readyGlyphs; + std::unordered_set m_readyGlyphs; hb_font_t * m_harfbuzzFont{nullptr}; }; @@ -332,7 +336,6 @@ FreetypeError constexpr g_FT_Errors[] = using is_transparent = void; }; - // TODO(AB): Compare performance with std::map. std::unordered_map> m_textMetricsCache; hb_buffer_t * m_harfbuzzBuffer; }; @@ -598,7 +601,7 @@ FreetypeError constexpr g_FT_Errors[] = allGlyphs.m_glyphs.reserve(strings::CountChar(utf8)); - for (auto const & substring : segments) + std::for_each(std::execution::par_unseq, segments.begin(), segments.end(), [&, this](auto const & substring) { hb_buffer_clear_contents(m_impl->m_harfbuzzBuffer); @@ -626,7 +629,7 @@ FreetypeError constexpr g_FT_Errors[] = } } while (u32CharacterIter != end); - } + }); // Uncomment utf8 printing for debugging if necessary. It crashes JNI with non-modified UTF-8 strings on Android 5 // and 6. See https://github.com/organicmaps/organicmaps/issues/10685 diff --git a/libs/drape/render_bucket.cpp b/libs/drape/render_bucket.cpp index 5353fdd14..f4e94f571 100644 --- a/libs/drape/render_bucket.cpp +++ b/libs/drape/render_bucket.cpp @@ -6,7 +6,7 @@ #include "drape/overlay_tree.hpp" #include "drape/vertex_array_buffer.hpp" -#include "base/stl_helpers.hpp" +#include namespace dp { @@ -51,23 +51,25 @@ void RenderBucket::AddOverlayHandle(drape_ptr && handle) void RenderBucket::BeforeUpdate() { - for (auto & overlayHandle : m_overlay) - overlayHandle->BeforeUpdate(); + std::for_each(std::execution::par_unseq, m_overlay.begin(), m_overlay.end(), + [](auto & overlayHandle) { overlayHandle->BeforeUpdate(); }); } void RenderBucket::Update(ScreenBase const & modelView) { BeforeUpdate(); - for (auto & overlayHandle : m_overlay) + std::for_each(std::execution::par_unseq, m_overlay.begin(), m_overlay.end(), [&modelView](auto & overlayHandle) + { if (overlayHandle->IsVisible()) overlayHandle->Update(modelView); + }); } void RenderBucket::CollectOverlayHandles(ref_ptr tree) { BeforeUpdate(); - for (auto const & overlayHandle : m_overlay) - tree->Add(make_ref(overlayHandle)); + std::for_each(std::execution::par_unseq, m_overlay.begin(), m_overlay.end(), + [&tree](auto & overlayHandle) { tree->Add(make_ref(overlayHandle)); }); } bool RenderBucket::HasOverlayHandles() const @@ -102,7 +104,8 @@ void RenderBucket::Render(ref_ptr context, bool drawAsLine) ref_ptr rfpAttrib = make_ref(&attributeMutator); bool hasIndexMutation = false; - for (drape_ptr const & handle : m_overlay) + std::for_each(std::execution::par_unseq, m_overlay.begin(), m_overlay.end(), + [&, this](drape_ptr const & handle) { if (handle->IndexesRequired()) { @@ -113,7 +116,7 @@ void RenderBucket::Render(ref_ptr context, bool drawAsLine) if (handle->HasDynamicAttributes()) handle->GetAttributeMutation(rfpAttrib); - } + }); m_buffer->ApplyMutation(context, hasIndexMutation ? rfpIndex : nullptr, rfpAttrib); } @@ -129,7 +132,7 @@ void RenderBucket::SetFeatureMinZoom(int minZoom) void RenderBucket::RenderDebug(ref_ptr context, ScreenBase const & screen, ref_ptr debugRectRenderer) const { - if (!debugRectRenderer || !debugRectRenderer->IsEnabled() || m_overlay.empty()) + if (m_overlay.empty()) return; for (auto const & handle : m_overlay) diff --git a/libs/drape/symbols_texture.cpp b/libs/drape/symbols_texture.cpp index aa25912a1..9c9eada5b 100644 --- a/libs/drape/symbols_texture.cpp +++ b/libs/drape/symbols_texture.cpp @@ -264,39 +264,4 @@ void SymbolsTexture::Fail(ref_ptr context) Create(context, p, make_ref(&alphaTexture)); } - -bool SymbolsTexture::IsSymbolContained(std::string const & symbolName) const -{ - return m_definition.find(symbolName) != m_definition.end(); -} - -bool SymbolsTexture::DecodeToMemory(std::string const & skinPathName, std::string const & textureName, - std::vector & symbolsSkin, std::map & symbolsIndex, - uint32_t & skinWidth, uint32_t & skinHeight) -{ - auto definitionInserter = [&symbolsIndex](std::string const & name, m2::RectF const & rect) - { symbolsIndex.insert(make_pair(name, m2::RectU(rect))); }; - - bool result = true; - auto completionHandler = - [&result, &symbolsSkin, &skinWidth, &skinHeight](unsigned char * data, uint32_t width, uint32_t height) - { - size_t size = 4 * width * height; - symbolsSkin.resize(size); - memcpy(symbolsSkin.data(), data, size); - skinWidth = width; - skinHeight = height; - result = true; - }; - - auto failureHandler = [&result](std::string const & reason) - { - LOG(LERROR, (reason)); - result = false; - }; - - LoadSymbols(skinPathName, textureName, false /* convertToUV */, definitionInserter, completionHandler, - failureHandler); - return result; -} } // namespace dp diff --git a/libs/drape/symbols_texture.hpp b/libs/drape/symbols_texture.hpp index 7bf9139d7..8b2d77a31 100644 --- a/libs/drape/symbols_texture.hpp +++ b/libs/drape/symbols_texture.hpp @@ -2,7 +2,7 @@ #include "drape/texture.hpp" -#include +#include #include #include @@ -39,19 +39,17 @@ public: void Invalidate(ref_ptr context, std::string const & skinPathName, ref_ptr allocator, std::vector> & internalTextures); - bool IsSymbolContained(std::string const & symbolName) const; - - static bool DecodeToMemory(std::string const & skinPathName, std::string const & textureName, - std::vector & symbolsSkin, std::map & symbolsIndex, - uint32_t & skinWidth, uint32_t & skinHeight); + inline bool IsSymbolContained(std::string const & symbolName) const + { + return m_definition.find(symbolName) != m_definition.end(); + } private: void Fail(ref_ptr context); void Load(ref_ptr context, std::string const & skinPathName, ref_ptr allocator); - using TSymDefinition = std::map; std::string m_name; - mutable TSymDefinition m_definition; + mutable std::unordered_map m_definition; }; } // namespace dp diff --git a/libs/drape/texture_manager.cpp b/libs/drape/texture_manager.cpp index 9ceec7437..4f4b59aa0 100644 --- a/libs/drape/texture_manager.cpp +++ b/libs/drape/texture_manager.cpp @@ -539,12 +539,6 @@ GlyphFontAndId TextureManager::GetSpaceGlyph() const return m_spaceGlyph; } -bool TextureManager::AreGlyphsReady(TGlyphs const & glyphs) const -{ - CHECK(m_isInitialized, ()); - return m_glyphManager->AreGlyphsReady(glyphs); -} - ref_ptr TextureManager::GetSymbolsTexture() const { CHECK(m_isInitialized, ()); diff --git a/libs/drape/texture_manager.hpp b/libs/drape/texture_manager.hpp index 4f2f61930..8c17e7e51 100644 --- a/libs/drape/texture_manager.hpp +++ b/libs/drape/texture_manager.hpp @@ -95,7 +95,11 @@ public: TMultilineGlyphsBuffer & multilineGlyphRegions); // This method must be called only on Frontend renderer's thread. - bool AreGlyphsReady(TGlyphs const & glyphs) const; + inline bool AreGlyphsReady(TGlyphs const & glyphs) const + { + CHECK(m_isInitialized, ()); + return m_glyphManager->AreGlyphsReady(glyphs); + } GlyphFontAndId GetSpaceGlyph() const; diff --git a/libs/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp b/libs/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp index b83600b8e..a7f4ff05f 100644 --- a/libs/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp +++ b/libs/drape/vulkan/vulkan_vertex_array_buffer_impl.cpp @@ -3,16 +3,15 @@ #include "drape/vulkan/vulkan_base_context.hpp" #include "drape/vulkan/vulkan_gpu_buffer_impl.hpp" #include "drape/vulkan/vulkan_param_descriptor.hpp" -#include "drape/vulkan/vulkan_utils.hpp" #include "base/assert.hpp" #include "base/macros.hpp" +#include "drape/vulkan/vulkan_staging_buffer.hpp" #include #include #include #include -#include namespace dp { @@ -44,11 +43,11 @@ public: void RenderRange(ref_ptr context, bool drawAsLine, IndicesRange const & range) override { - CHECK(m_vertexArrayBuffer->HasBuffers(), ()); + ASSERT(m_vertexArrayBuffer->HasBuffers(), ()); ref_ptr vulkanContext = context; VkCommandBuffer commandBuffer = vulkanContext->GetCurrentRenderingCommandBuffer(); - CHECK(commandBuffer != nullptr, ()); + ASSERT(commandBuffer != nullptr, ()); vulkanContext->SetPrimitiveTopology(drawAsLine ? VK_PRIMITIVE_TOPOLOGY_LINE_LIST : VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST); @@ -71,24 +70,23 @@ public: for (auto & buffer : m_vertexArrayBuffer->m_staticBuffers) { ref_ptr b = buffer.second->GetBuffer(); - CHECK_LESS(bufferIndex, kMaxBuffersCount, ()); + ASSERT_LESS(bufferIndex, kMaxBuffersCount, ()); buffers[bufferIndex++] = b->GetVulkanBuffer(); } for (auto & buffer : m_vertexArrayBuffer->m_dynamicBuffers) { ref_ptr b = buffer.second->GetBuffer(); - CHECK_LESS(bufferIndex, kMaxBuffersCount, ()); + ASSERT_LESS(bufferIndex, kMaxBuffersCount, ()); buffers[bufferIndex++] = b->GetVulkanBuffer(); } vkCmdBindVertexBuffers(commandBuffer, 0, bufferIndex, buffers.data(), offsets.data()); - ref_ptr ib = m_vertexArrayBuffer->m_indexBuffer->GetBuffer(); - VkBuffer vulkanIndexBuffer = ib->GetVulkanBuffer(); - auto const indexType = dp::IndexStorage::IsSupported32bit() ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16; - vkCmdBindIndexBuffer(commandBuffer, vulkanIndexBuffer, 0, indexType); + vkCmdBindIndexBuffer( + commandBuffer, ref_ptr(m_vertexArrayBuffer->m_indexBuffer->GetBuffer())->GetVulkanBuffer(), + 0, m_indexType); - CHECK_LESS_OR_EQUAL(range.m_idxStart + range.m_idxCount, - m_objectManager->GetMemoryManager().GetDeviceLimits().maxDrawIndexedIndexValue, ()); + ASSERT_LESS_OR_EQUAL(range.m_idxStart + range.m_idxCount, + m_objectManager->GetMemoryManager().GetDeviceLimits().maxDrawIndexedIndexValue, ()); vkCmdDrawIndexed(commandBuffer, range.m_idxCount, 1, range.m_idxStart, 0, 0); } @@ -99,6 +97,7 @@ private: BindingInfoArray m_bindingInfo; uint8_t m_bindingInfoCount = 0; ParamDescriptorUpdater m_descriptorUpdater; + VkIndexType const m_indexType = dp::IndexStorage::IsSupported32bit() ? VK_INDEX_TYPE_UINT32 : VK_INDEX_TYPE_UINT16; }; } // namespace vulkan diff --git a/libs/drape_frontend/frontend_renderer.cpp b/libs/drape_frontend/frontend_renderer.cpp index d31c0db61..8116f6b30 100644 --- a/libs/drape_frontend/frontend_renderer.cpp +++ b/libs/drape_frontend/frontend_renderer.cpp @@ -37,14 +37,8 @@ #include "std/target_os.hpp" #include -#include -#include #include -#include -#include -#include -#include -#include +#include namespace df { @@ -1813,14 +1807,17 @@ void FrontendRenderer::BuildOverlayTree(ScreenBase const & modelView) return; BeginUpdateOverlayTree(modelView); - for (auto const layerId : - {DepthLayer::OverlayLayer, DepthLayer::RoutingBottomMarkLayer, DepthLayer::RoutingMarkLayer}) + constexpr std::array layers = {static_cast(DepthLayer::OverlayLayer), + static_cast(DepthLayer::RoutingBottomMarkLayer), + static_cast(DepthLayer::RoutingMarkLayer)}; + + std::for_each(std::execution::par_unseq, layers.begin(), layers.end(), [this, &modelView](uint8_t const layerId) { - RenderLayer & overlay = m_layers[static_cast(layerId)]; + RenderLayer & overlay = m_layers[layerId]; overlay.Sort(make_ref(m_overlayTree)); - for (auto & group : overlay.m_renderGroups) - UpdateOverlayTree(modelView, group); - } + std::for_each(std::execution::par_unseq, overlay.m_renderGroups.begin(), overlay.m_renderGroups.end(), + [this, &modelView](auto & group) { UpdateOverlayTree(modelView, group); }); + }); if (m_transitSchemeRenderer->IsSchemeVisible(GetCurrentZoom()) && !HasTransitRouteData()) m_transitSchemeRenderer->CollectOverlays(make_ref(m_overlayTree), modelView); EndUpdateOverlayTree(); diff --git a/libs/drape_frontend/path_text_handle.cpp b/libs/drape_frontend/path_text_handle.cpp index 5209d7669..a1796dbd6 100644 --- a/libs/drape_frontend/path_text_handle.cpp +++ b/libs/drape_frontend/path_text_handle.cpp @@ -11,8 +11,8 @@ namespace df namespace { double constexpr kValidPathSplineTurn = 15 * math::pi / 180; -double constexpr kCosTurn = 0.999989561; // cos(kValidPathSplineTurn) -double constexpr kSinTurn = 0.004569245; // sin(kValidPathSplineTurn) +double constexpr kCosTurn = 0.999989561; // cos(kValidPathSplineTurn) +double constexpr kSinTurn = 0.004569245; // sin(kValidPathSplineTurn) double constexpr kRoundStep = 23; int constexpr kMaxStepsCount = 7; @@ -122,11 +122,6 @@ ref_ptr const PathTextContext::GetLayout() const return make_ref(m_layout); } -void PathTextContext::BeforeUpdate() -{ - m_updated = false; -} - std::vector const & PathTextContext::GetOffsets() const { return m_globalOffsets; diff --git a/libs/drape_frontend/path_text_handle.hpp b/libs/drape_frontend/path_text_handle.hpp index 59f40ac68..dde5a3378 100644 --- a/libs/drape_frontend/path_text_handle.hpp +++ b/libs/drape_frontend/path_text_handle.hpp @@ -21,7 +21,8 @@ public: bool GetPivot(size_t textIndex, m2::PointD & pivot, m2::Spline::iterator & centerPointIter) const; - void BeforeUpdate(); + // TODO: these are unused? + inline void BeforeUpdate() { m_updated = false; } void Update(ScreenBase const & screen); std::vector const & GetOffsets() const; diff --git a/libs/drape_frontend/render_group.cpp b/libs/drape_frontend/render_group.cpp index 07306ab3d..238c9cbd8 100644 --- a/libs/drape_frontend/render_group.cpp +++ b/libs/drape_frontend/render_group.cpp @@ -8,9 +8,8 @@ #include "geometry/screenbase.hpp" -#include "base/stl_helpers.hpp" - #include +#include #include #include @@ -43,8 +42,8 @@ void RenderGroup::CollectOverlay(ref_ptr tree) if (CanBeDeleted()) return; - for (auto & renderBucket : m_renderBuckets) - renderBucket->CollectOverlayHandles(tree); + std::for_each(std::execution::par_unseq, m_renderBuckets.begin(), m_renderBuckets.end(), + [&](auto & renderBucket) { renderBucket->CollectOverlayHandles(tree); }); } bool RenderGroup::HasOverlayHandles() const @@ -78,8 +77,9 @@ void RenderGroup::Render(ref_ptr context, ref_ptrBind(); dp::ApplyState(context, programPtr, m_state); - for (auto & renderBucket : m_renderBuckets) - renderBucket->GetBuffer()->Build(context, programPtr); + std::for_each(std::execution::par_unseq, m_renderBuckets.begin(), m_renderBuckets.end(), + [&context, &programPtr](auto const & renderBucket) + { renderBucket->GetBuffer()->Build(context, programPtr); }); auto const program = m_state.GetProgram(); auto const program3d = m_state.GetProgram3d(); @@ -100,8 +100,9 @@ void RenderGroup::Render(ref_ptr context, ref_ptrGetParamsSetter()->Apply(context, programPtr, m_params); - for (auto & renderBucket : m_renderBuckets) - renderBucket->Render(context, m_state.GetDrawAsLine()); + std::for_each(std::execution::par_unseq, m_renderBuckets.begin(), m_renderBuckets.end(), + [&context, this](auto const & renderBucket) + { renderBucket->Render(context, m_state.GetDrawAsLine()); }); m_params.m_contrastGamma = glsl::vec2(glyphParams.m_contrast, glyphParams.m_gamma); m_params.m_isOutlinePass = 0.0f; @@ -112,11 +113,14 @@ void RenderGroup::Render(ref_ptr context, ref_ptrGetParamsSetter()->Apply(context, programPtr, m_params); - for (auto & renderBucket : m_renderBuckets) - renderBucket->Render(context, m_state.GetDrawAsLine()); + std::for_each(std::execution::par_unseq, m_renderBuckets.begin(), m_renderBuckets.end(), + [&context, this](auto const & renderBucket) + { renderBucket->Render(context, m_state.GetDrawAsLine()); }); - for (auto const & renderBucket : m_renderBuckets) - renderBucket->RenderDebug(context, screen, debugRectRenderer); + if (debugRectRenderer && debugRectRenderer->IsEnabled()) + std::for_each(std::execution::par_unseq, m_renderBuckets.begin(), m_renderBuckets.end(), + [&context, &screen, &debugRectRenderer](auto const & renderBucket) + { renderBucket->RenderDebug(context, screen, debugRectRenderer); }); } void RenderGroup::AddBucket(drape_ptr && bucket)