diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index 544f66e33f..68abfcba2c 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -32,6 +32,7 @@ BackendRenderer::BackendRenderer(Params && params) , m_readManager(make_unique_dp(params.m_commutator, m_model, params.m_allow3dBuildings, params.m_trafficEnabled)) , m_trafficGenerator(make_unique_dp(bind(&BackendRenderer::FlushTrafficRenderData, this, _1))) + , m_userMarkGenerator(make_unique_dp(bind(&BackendRenderer::FlushUserMarksRenderData, this, _1, _2))) , m_requestedTiles(params.m_requestedTiles) , m_updateCurrentCountryFn(params.m_updateCurrentCountryFn) , m_metalineManager(make_unique_dp(params.m_commutator, m_model)) @@ -167,6 +168,7 @@ void BackendRenderer::AcceptMessage(ref_ptr message) { ref_ptr msg = message; m_batchersPool->ReleaseBatcher(msg->GetKey()); + m_userMarkGenerator->GenerateUserMarksGeometry(msg->GetKey(), m_texMng); break; } @@ -251,21 +253,11 @@ void BackendRenderer::AcceptMessage(ref_ptr message) case Message::UpdateUserMarkLayer: { ref_ptr msg = message; - - UserMarksProvider const * marksProvider = msg->StartProcess(); - if (marksProvider->IsDirty()) - { - size_t const layerId = msg->GetLayerId(); - m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(layerId), - MessagePriority::Normal); - - TUserMarkShapes shapes = CacheUserMarks(marksProvider, m_texMng); - m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(layerId, move(shapes)), - MessagePriority::Normal); - } - msg->EndProcess(); + size_t const layerId = msg->GetLayerId(); + m_userMarkGenerator->SetUserMarks(static_cast(layerId), msg->AcceptRenderParams()); + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(layerId), + MessagePriority::Normal); break; } @@ -579,6 +571,13 @@ void BackendRenderer::FlushTrafficRenderData(TrafficRenderData && renderData) MessagePriority::Normal); } +void BackendRenderer::FlushUserMarksRenderData(GroupID groupId, TUserMarksRenderData && renderData) +{ + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(groupId, std::move(renderData)), + MessagePriority::Normal); +} + void BackendRenderer::CleanupOverlays(TileKey const & tileKey) { auto const functor = [&tileKey](OverlayRenderData const & data) diff --git a/drape_frontend/backend_renderer.hpp b/drape_frontend/backend_renderer.hpp index 4c8d3c6002..1fdca5e181 100644 --- a/drape_frontend/backend_renderer.hpp +++ b/drape_frontend/backend_renderer.hpp @@ -9,6 +9,7 @@ #include "drape_frontend/overlay_batcher.hpp" #include "drape_frontend/requested_tiles.hpp" #include "drape_frontend/traffic_generator.hpp" +#include "drape_frontend/user_mark_generator.hpp" #include "drape/pointers.hpp" #include "drape/viewport.hpp" @@ -95,6 +96,7 @@ private: void FlushGeometry(TileKey const & key, dp::GLState const & state, drape_ptr && buffer); void FlushTrafficRenderData(TrafficRenderData && renderData); + void FlushUserMarksRenderData(GroupID groupId, TUserMarksRenderData && renderData); void CleanupOverlays(TileKey const & tileKey); @@ -103,6 +105,7 @@ private: drape_ptr m_readManager; drape_ptr m_routeBuilder; drape_ptr m_trafficGenerator; + drape_ptr m_userMarkGenerator; drape_ptr m_drapeApiBuilder; gui::LayerCacher m_guiCacher; diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index a53ff02a95..15a53e8751 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -209,8 +209,23 @@ void DrapeEngine::ChangeVisibilityUserMarksLayer(size_t layerId, bool isVisible) void DrapeEngine::UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provider) { + auto renderCollection = make_unique_dp(); + renderCollection->reserve(provider->GetUserPointCount()); + for (size_t i = 0, sz = provider->GetUserPointCount(); i < sz; ++i) + { + UserPointMark const * mark = provider->GetUserPointMark(i); + UserMarkRenderParams renderInfo; + renderInfo.m_anchor = mark->GetAnchor(); + renderInfo.m_depth = mark->GetDepth(); + renderInfo.m_isVisible = mark->IsVisible(); + renderInfo.m_pivot = mark->GetPivot(); + renderInfo.m_pixelOffset = mark->GetPixelOffset(); + renderInfo.m_runCreationAnim = mark->RunCreationAnim(); + renderInfo.m_symbolName = mark->GetSymbolName(); + renderCollection->emplace_back(std::move(renderInfo)); + } m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp(layerId, provider), + make_unique_dp(layerId, std::move(renderCollection)), MessagePriority::Normal); } diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro index 6e488d2f8e..634500eedc 100755 --- a/drape_frontend/drape_frontend.pro +++ b/drape_frontend/drape_frontend.pro @@ -114,7 +114,6 @@ SOURCES += \ watch/geometry_processors.cpp \ watch/feature_processor.cpp \ watch/default_font.cpp \ - user_mark_builder.cpp \ user_mark_generator.cpp HEADERS += \ @@ -237,7 +236,6 @@ HEADERS += \ watch/brush_info.hpp \ watch/geometry_processors.hpp \ watch/feature_processor.hpp \ - user_mark_builder.hpp \ user_mark_generator.hpp OTHER_FILES += \ diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index acb9ed16b4..3cfadf5b05 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -298,13 +298,14 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) { ref_ptr msg = message; size_t const layerId = msg->GetLayerId(); - for (UserMarkShape & shape : msg->GetShapes()) + TUserMarksRenderData marksRenderData = msg->AcceptRenderData(); + for (UserMarkRenderData & renderData : marksRenderData) { - PrepareBucket(shape.m_state, shape.m_bucket); - auto program = m_gpuProgramManager->GetProgram(shape.m_state.GetProgramIndex()); - auto program3d = m_gpuProgramManager->GetProgram(shape.m_state.GetProgram3dIndex()); - auto group = make_unique_dp(layerId, shape.m_state, shape.m_tileKey, - std::move(shape.m_bucket)); + PrepareBucket(renderData.m_state, renderData.m_bucket); + auto program = m_gpuProgramManager->GetProgram(renderData.m_state.GetProgramIndex()); + auto program3d = m_gpuProgramManager->GetProgram(renderData.m_state.GetProgram3dIndex()); + auto group = make_unique_dp(layerId, renderData.m_state, renderData.m_tileKey, + std::move(renderData.m_bucket)); m_userMarkRenderGroups.push_back(std::move(group)); m_userMarkRenderGroups.back()->SetRenderParams(program, program3d, make_ref(&m_generalUniforms)); } @@ -1302,7 +1303,7 @@ void FrontendRenderer::RenderUserMarksLayer(ScreenBase const & modelView) for (auto const & group : m_userMarkRenderGroups) { ASSERT(group.get() != nullptr, ()); - if (m_userMarkVisibility.find(group->GetLayerId()) != m_userMarkVisibility.end()) + //if (m_userMarkVisibility.find(group->GetLayerId()) != m_userMarkVisibility.end()) { if (!group->CanBeClipped() || screenRect.IsIntersect(group->GetTileKey().GetGlobalRect())) RenderSingleGroup(modelView, make_ref(group)); diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index 7f4129bea8..334b80f2ab 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -23,6 +23,7 @@ public: ClearUserMarkLayer, ChangeUserMarkLayerVisibility, UpdateUserMarkLayer, + InvalidateUserMarks, FlushUserMarks, GuiLayerRecached, GuiRecache, diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 6ae27cc987..312b63584e 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -16,6 +16,7 @@ #include "drape_frontend/selection_shape.hpp" #include "drape_frontend/tile_utils.hpp" #include "drape_frontend/traffic_generator.hpp" +#include "drape_frontend/user_mark_generator.hpp" #include "drape_frontend/user_mark_shapes.hpp" #include "drape_frontend/user_marks_provider.hpp" @@ -237,62 +238,47 @@ private: class UpdateUserMarkLayerMessage : public BaseUserMarkLayerMessage { public: - UpdateUserMarkLayerMessage(size_t layerId, UserMarksProvider * provider) + UpdateUserMarkLayerMessage(size_t layerId, drape_ptr && renderParams) : BaseUserMarkLayerMessage(layerId) - , m_provider(provider) - { - m_provider->IncrementCounter(); - } + , m_renderParams(std::move(renderParams)) + {} ~UpdateUserMarkLayerMessage() override - { - ASSERT(m_inProcess == false, ()); - m_provider->DecrementCounter(); - if (m_provider->IsPendingOnDelete() && m_provider->CanBeDeleted()) - delete m_provider; - } + {} Type GetType() const override { return Message::UpdateUserMarkLayer; } - UserMarksProvider const * StartProcess() - { - m_provider->BeginRead(); -#ifdef DEBUG - m_inProcess = true; -#endif - return m_provider; - } - - void EndProcess() - { -#ifdef DEBUG - m_inProcess = false; -#endif - m_provider->EndRead(); - } + drape_ptr && AcceptRenderParams() { return std::move(m_renderParams); } private: - UserMarksProvider * m_provider; -#ifdef DEBUG - bool m_inProcess; -#endif + drape_ptr m_renderParams; }; class FlushUserMarksMessage : public BaseUserMarkLayerMessage { public: - FlushUserMarksMessage(size_t layerId, TUserMarkShapes && shapes) + FlushUserMarksMessage(size_t layerId, TUserMarksRenderData && renderData) : BaseUserMarkLayerMessage(layerId) - , m_shapes(move(shapes)) + , m_renderData(move(renderData)) {} Type GetType() const override { return Message::FlushUserMarks; } bool IsGLContextDependent() const override { return true; } - TUserMarkShapes & GetShapes() { return m_shapes; } + TUserMarksRenderData && AcceptRenderData() { return std::move(m_renderData); } private: - TUserMarkShapes m_shapes; + TUserMarksRenderData m_renderData; +}; + +class InvalidateUserMarksMessage : public BaseUserMarkLayerMessage +{ +public: + InvalidateUserMarksMessage(size_t layerId) + : BaseUserMarkLayerMessage(layerId) + {} + + Type GetType() const override { return Message::InvalidateUserMarks; } }; class GuiLayerRecachedMessage : public Message diff --git a/drape_frontend/user_mark_builder.cpp b/drape_frontend/user_mark_builder.cpp deleted file mode 100644 index ce52ec8c31..0000000000 --- a/drape_frontend/user_mark_builder.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "drape_frontend/user_mark_builder.hpp" - -namespace df -{ -UserMarkBuilder::UserMarkBuilder(TFlushFn const & flushFn) - : m_flushFn(flushFn) -{ - -} - -void UserMarkBuilder::BuildUserMarks(UserMarksRenderCollection const & marks, MarkIndexesCollection && indexes, - ref_ptr textures) -{ - -} -} // namespace df diff --git a/drape_frontend/user_mark_builder.hpp b/drape_frontend/user_mark_builder.hpp deleted file mode 100644 index 51a950d6fb..0000000000 --- a/drape_frontend/user_mark_builder.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include "drape_frontend/user_mark_shapes.hpp" -#include "drape_frontend/user_mark_generator.hpp" - -namespace df -{ -class UserMarkBuilder -{ -public: - using TFlushFn = function; - - UserMarkBuilder(TFlushFn const & flushFn); - - void BuildUserMarks(MarkGroups const & marks, MarkIndexesGroups && indexes, - ref_ptr textures); -private: - TFlushFn m_flushFn; -}; -} diff --git a/drape_frontend/user_mark_generator.cpp b/drape_frontend/user_mark_generator.cpp index 41088d9736..ce7e75ea67 100644 --- a/drape_frontend/user_mark_generator.cpp +++ b/drape_frontend/user_mark_generator.cpp @@ -1,8 +1,14 @@ #include "drape_frontend/user_mark_generator.hpp" +#include "drape_frontend/map_shape.hpp" +#include "drape_frontend/shader_def.hpp" +#include "drape_frontend/shape_view_params.hpp" + +#include "drape/utils/vertex_decl.hpp" namespace df { -UserMarkGenerator::UserMarkGenerator() +UserMarkGenerator::UserMarkGenerator(TFlushFn const & flushFn) + : m_flushFn(flushFn) { } @@ -24,46 +30,91 @@ void UserMarkGenerator::UpdateMarksIndex(uint32_t groupId) { auto itGroupIndexes = tileGroups.second->find(groupId); if (itGroupIndexes != tileGroups.second->end()) - itGroupIndexes->second->clear(); + { + itGroupIndexes->second->m_markIndexes.clear(); + } } UserMarksRenderCollection & marks = *m_marks[groupId]; for (size_t markIndex = 0; markIndex < marks.size(); ++markIndex) { - for (size_t zoomLevel = 1; zoomLevel <= scales::GetUpperScale(); ++zoomLevel) + for (int zoomLevel = 1; zoomLevel <= scales::GetUpperScale(); ++zoomLevel) { TileKey const tileKey = GetTileKeyByPoint(marks[markIndex].m_pivot, zoomLevel); - - ref_ptr tileGroups; - auto itTileGroups = m_marksIndex.find(tileKey); - if (itTileGroups == m_marksIndex.end()) - { - auto tileIndexesGroups = make_unique_dp(); - tileGroups = make_ref(tileIndexesGroups); - m_marksIndex.insert(make_pair(tileKey, std::move(tileIndexesGroups))); - } - else - { - tileGroups = make_ref(itTileGroups->second); - } - - ref_ptr groupIndexes; - auto itGroupIndexes = tileGroups->find(groupId); - if (itGroupIndexes == tileGroups->end()) - { - auto groupMarkIndexes = make_unique_dp(); - groupIndexes = make_ref(groupMarkIndexes); - tileGroups->insert(make_pair(groupId, std::move(groupMarkIndexes))); - } - else - { - groupIndexes = make_ref(itGroupIndexes->second); - } - - groupIndexes->push_back(static_cast(markIndex)); + ref_ptr groupIndexes = GetIndexesCollection(tileKey, groupId); + groupIndexes->m_markIndexes.push_back(static_cast(markIndex)); } } + CleanIndex(); +} + +void UserMarkGenerator::UpdateLinesIndex(uint32_t groupId) +{ + for (auto & tileGroups : m_marksIndex) + { + auto itGroupIndexes = tileGroups.second->find(groupId); + if (itGroupIndexes != tileGroups.second->end()) + { + itGroupIndexes->second->m_lineIndexes.clear(); + } + } + + UserLinesRenderCollection & lines = *m_lines[groupId]; + for (size_t lineIndex = 0; lineIndex < lines.size(); ++lineIndex) + { + for (int zoomLevel = 1; zoomLevel <= scales::GetUpperScale(); ++zoomLevel) + { + // TODO: Calculate tiles for the line. + std::set tiles; + for (size_t i = 0, sz = lines[lineIndex].m_points.size(); i < sz; ++i) + { + tiles.insert(GetTileKeyByPoint(lines[lineIndex].m_points[i], zoomLevel)); + } + for (auto const & tileKey : tiles) + { + ref_ptr groupIndexes = GetIndexesCollection(tileKey, groupId); + groupIndexes->m_lineIndexes.push_back(static_cast(lineIndex)); + } + } + } + + CleanIndex(); +} + +ref_ptr UserMarkGenerator::GetIndexesCollection(TileKey const & tileKey, GroupID groupId) +{ + ref_ptr tileGroups; + auto itTileGroups = m_marksIndex.find(tileKey); + if (itTileGroups == m_marksIndex.end()) + { + auto tileIndexesGroups = make_unique_dp(); + tileGroups = make_ref(tileIndexesGroups); + m_marksIndex.insert(make_pair(tileKey, std::move(tileIndexesGroups))); + } + else + { + tileGroups = make_ref(itTileGroups->second); + } + + ref_ptr groupIndexes; + auto itGroupIndexes = tileGroups->find(groupId); + if (itGroupIndexes == tileGroups->end()) + { + auto groupMarkIndexes = make_unique_dp(); + groupIndexes = make_ref(groupMarkIndexes); + tileGroups->insert(make_pair(groupId, std::move(groupMarkIndexes))); + } + else + { + groupIndexes = make_ref(itGroupIndexes->second); + } + + return groupIndexes; +} + +void UserMarkGenerator::CleanIndex() +{ for (auto tileIt = m_marksIndex.begin(); tileIt != m_marksIndex.end();) { if (tileIt->second->empty()) @@ -73,11 +124,6 @@ void UserMarkGenerator::UpdateMarksIndex(uint32_t groupId) } } -void UserMarkGenerator::UpdateLinesIndex(uint32_t groupId) -{ - -} - void UserMarkGenerator::SetGroupVisibility(GroupID groupId, bool isVisible) { m_groupsVisibility[groupId] = isVisible; @@ -93,63 +139,18 @@ void UserMarkGenerator::GenerateUserMarksGeometry(TileKey const & tileKey, ref_p for (auto & groupPair : indexesGroups) { GroupID groupId = groupPair.first; - MarkIndexesCollection & indexes = *groupPair.second; + UserMarksRenderCollection const & renderParams = *m_marks[groupId]; + MarkIndexesCollection const & indexes = groupPair.second->m_markIndexes; - if (!m_groupsVisibility[groupId]) - continue; + //if (!m_groupsVisibility[groupId]) + // continue; - UserMarkBatcherKey batcherKey(tileKey, groupId); - m_batchersPool->ReserveBatcher(batcherKey); - ref_ptr batcher = m_batchersPool->GetBatcher(batcherKey); + TUserMarksRenderData renderData; + UserMarkShape::Draw(tileKey, textures, renderParams, indexes, renderData); - dp::TextureManager::SymbolRegion region; - - uint32_t const vertexCount = static_cast(it->second.size()) * dp::Batcher::VertexPerQuad; - uint32_t const indicesCount = static_cast(it->second.size()) * dp::Batcher::IndexPerQuad; - buffer_vector buffer; - buffer.reserve(vertexCount); - - for (auto const markIndex : indexes) - { - UserMarkRenderInfo const & renderInfo = m_marks[markIndex]; - if (!renderInfo.m_isVisible) - continue; - textures->GetSymbolRegion(renderInfo.m_symbolName, region); - m2::RectF const & texRect = region.GetTexRect(); - m2::PointF const pxSize = region.GetPixelSize(); - dp::Anchor const anchor = renderInfo.m_anchor; - m2::PointD const pt = MapShape::ConvertToLocal(renderInfo.m_pivot, tileKey.GetGlobalRect().Center(), kShapeCoordScalar); - glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), renderInfo.m_depth); - bool const runAnim = renderInfo.m_runCreationAnim; - - glsl::vec2 left, right, up, down; - AlignHorizontal(pxSize.x * 0.5f, anchor, left, right); - AlignVertical(pxSize.y * 0.5f, anchor, up, down); - - m2::PointD const pixelOffset = pointMark->GetPixelOffset(); - glsl::vec2 const offset(pixelOffset.x, pixelOffset.y); - - buffer.emplace_back(pos, left + down + offset, glsl::ToVec2(texRect.LeftTop()), runAnim); - buffer.emplace_back(pos, left + up + offset, glsl::ToVec2(texRect.LeftBottom()), runAnim); - buffer.emplace_back(pos, right + down + offset, glsl::ToVec2(texRect.RightTop()), runAnim); - buffer.emplace_back(pos, right + up + offset, glsl::ToVec2(texRect.RightBottom()), runAnim); - } - - dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer); - state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM); - state.SetColorTexture(region.GetTexture()); - state.SetTextureFilter(gl_const::GLNearest); - - uint32_t const kMaxSize = 65000; - dp::Batcher batcher(min(indicesCount, kMaxSize), min(vertexCount, kMaxSize)); - dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state, - drape_ptr && b) - { - outShapes.emplace_back(UserMarkShape(state, move(b), key)); - }); - dp::AttributeProvider attribProvider(1, static_cast(buffer.size())); - attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); - batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); + m_flushFn(groupId, std::move(renderData)); } } + + } // namespace df diff --git a/drape_frontend/user_mark_generator.hpp b/drape_frontend/user_mark_generator.hpp index 6d6d628e8c..342c497858 100644 --- a/drape_frontend/user_mark_generator.hpp +++ b/drape_frontend/user_mark_generator.hpp @@ -16,47 +16,24 @@ namespace df { -struct UserMarkRenderInfo -{ - m2::PointD m_pivot; - m2::PointD m_pixelOffset; - std::string m_symbolName; - dp::Anchor m_anchor; - float m_depth; - bool m_runCreationAnim; - bool m_isVisible; -}; - -struct LineLayer -{ - dp::Color m_color; - float m_width; - float m_depth; -}; - -struct UserLineRenderInfo -{ - std::vector m_layers; - std::vector m_points; -}; - -using UserMarksRenderCollection = std::vector; -using UserLinesRenderCollection = std::vector; using GroupID = uint32_t; - using MarkGroups = std::map>; using LineGroups = std::map>; -using MarkIndexesCollection = std::vector; -using MarkIndexesGroups = std::map>; +struct IndexesCollection +{ + MarkIndexesCollection m_markIndexes; + LineIndexesCollection m_lineIndexes; +}; +using MarkIndexesGroups = std::map>; using MarksIndex = std::map>; class UserMarkGenerator { public: - using TFlushFn = function; + using TFlushFn = function; UserMarkGenerator(TFlushFn const & flushFn); @@ -67,38 +44,12 @@ public: void GenerateUserMarksGeometry(TileKey const & tileKey, ref_ptr textures); -private: - TFlushFn m_flushFn; private: void UpdateMarksIndex(GroupID groupId); void UpdateLinesIndex(GroupID groupId); - struct UserMarkBatcherKey - { - UserMarkBatcherKey() = default; - UserMarkBatcherKey(TileKey const & tileKey, GroupID groupId) - : m_tileKey(tileKey) - , m_groupId(groupId) - {} - GroupID m_groupId; - TileKey m_tileKey; - }; - - struct UserMarkBatcherKeyComparator - { - bool operator() (UserMarkBatcherKey const & lhs, UserMarkBatcherKey const & rhs) const - { - if (lhs.m_groupId == rhs.m_groupId) - return lhs.m_tileKey.LessStrict(rhs.m_tileKey); - return lhs.m_groupId < rhs.m_groupId; - } - }; - - void FlushGeometry(UserMarkBatcherKey const & key, dp::GLState const & state, - drape_ptr && buffer); - - drape_ptr> m_batchersPool; - TFlushFn m_flushRenderDataFn; + ref_ptr GetIndexesCollection(TileKey const & tileKey, GroupID groupId); + void CleanIndex(); std::map m_groupsVisibility; @@ -106,6 +57,8 @@ private: LineGroups m_lines; MarksIndex m_marksIndex; + + TFlushFn m_flushFn; }; } // namespace df diff --git a/drape_frontend/user_mark_shapes.cpp b/drape_frontend/user_mark_shapes.cpp index 1cdc0084c3..2e0b934b22 100644 --- a/drape_frontend/user_mark_shapes.cpp +++ b/drape_frontend/user_mark_shapes.cpp @@ -77,84 +77,7 @@ struct UserPointVertex : gpu::BaseVertex }; using UPV = UserPointVertex; - -void CacheUserPoints(UserMarksProvider const * provider, ref_ptr textures, - TUserMarkShapes & outShapes) -{ - size_t markCount = provider->GetUserPointCount(); - if (markCount == 0) - return; - - int const kZoomLevel = 10; - map> marks; - for (size_t i = 0; i < markCount; ++i) - { - UserPointMark const * userMark = provider->GetUserPointMark(i); - if (!userMark->IsVisible()) - continue; - TileKey const tileKey = GetTileKeyByPoint(userMark->GetPivot(), kZoomLevel); - marks[tileKey].push_back(userMark); - } - - for (auto it = marks.begin(); it != marks.end(); ++it) - { - TileKey const & key = it->first; - m2::PointD const tileCenter = key.GetGlobalRect().Center(); - - sort(it->second.begin(), it->second.end(), [](UserPointMark const * v1, UserPointMark const * v2) - { - return v1->GetPivot().y < v2->GetPivot().y; - }); - - dp::TextureManager::SymbolRegion region; - - uint32_t const vertexCount = static_cast(it->second.size()) * dp::Batcher::VertexPerQuad; - uint32_t const indicesCount = static_cast(it->second.size()) * dp::Batcher::IndexPerQuad; - buffer_vector buffer; - buffer.reserve(vertexCount); - - for (size_t i = 0; i < it->second.size(); ++i) - { - UserPointMark const * pointMark = it->second[i]; - textures->GetSymbolRegion(pointMark->GetSymbolName(), region); - m2::RectF const & texRect = region.GetTexRect(); - m2::PointF const pxSize = region.GetPixelSize(); - dp::Anchor const anchor = pointMark->GetAnchor(); - m2::PointD const pt = MapShape::ConvertToLocal(pointMark->GetPivot(), tileCenter, kShapeCoordScalar); - glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), pointMark->GetDepth()); - bool const runAnim = pointMark->RunCreationAnim(); - - glsl::vec2 left, right, up, down; - AlignHorizontal(pxSize.x * 0.5f, anchor, left, right); - AlignVertical(pxSize.y * 0.5f, anchor, up, down); - - m2::PointD const pixelOffset = pointMark->GetPixelOffset(); - glsl::vec2 const offset(pixelOffset.x, pixelOffset.y); - - buffer.emplace_back(pos, left + down + offset, glsl::ToVec2(texRect.LeftTop()), runAnim); - buffer.emplace_back(pos, left + up + offset, glsl::ToVec2(texRect.LeftBottom()), runAnim); - buffer.emplace_back(pos, right + down + offset, glsl::ToVec2(texRect.RightTop()), runAnim); - buffer.emplace_back(pos, right + up + offset, glsl::ToVec2(texRect.RightBottom()), runAnim); - } - - dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer); - state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM); - state.SetColorTexture(region.GetTexture()); - state.SetTextureFilter(gl_const::GLNearest); - - uint32_t const kMaxSize = 65000; - dp::Batcher batcher(min(indicesCount, kMaxSize), min(vertexCount, kMaxSize)); - dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state, - drape_ptr && b) - { - outShapes.emplace_back(UserMarkShape(state, move(b), key)); - }); - dp::AttributeProvider attribProvider(1, static_cast(buffer.size())); - attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); - batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); - } -} - +/* void CacheUserLines(UserMarksProvider const * provider, ref_ptr textures, TUserMarkShapes & outShapes) { @@ -186,7 +109,7 @@ void CacheUserLines(UserMarksProvider const * provider, ref_ptr && b) { - outShapes.emplace_back(UserMarkShape(state, move(b), key)); + outShapes.emplace_back(UserMarksRenderData(state, move(b), key)); }); for (auto const & lineData : it->second) { @@ -209,15 +132,77 @@ void CacheUserLines(UserMarksProvider const * provider, ref_ptr textures) +// static +void UserMarkShape::Draw(TileKey const & tileKey, ref_ptr textures, + UserMarksRenderCollection const & renderParams, MarkIndexesCollection const & indexes, + TUserMarksRenderData & renderData) +{ + uint32_t const vertexCount = static_cast(indexes.size()) * dp::Batcher::VertexPerQuad; + uint32_t const indicesCount = static_cast(indexes.size()) * dp::Batcher::IndexPerQuad; + buffer_vector buffer; + buffer.reserve(vertexCount); + + // TODO: Sort once on render params receiving. + MarkIndexesCollection sortedIndexes = indexes; + sort(sortedIndexes.begin(), sortedIndexes.end(), [&renderParams](uint32_t ind1, uint32_t ind2) + { + return renderParams[ind1].m_pivot.y > renderParams[ind2].m_pivot.y; + }); + + dp::TextureManager::SymbolRegion region; + for (auto const markIndex : sortedIndexes) + { + UserMarkRenderParams const & renderInfo = renderParams[markIndex]; + if (!renderInfo.m_isVisible) + continue; + textures->GetSymbolRegion(renderInfo.m_symbolName, region); + m2::RectF const & texRect = region.GetTexRect(); + m2::PointF const pxSize = region.GetPixelSize(); + dp::Anchor const anchor = renderInfo.m_anchor; + m2::PointD const pt = MapShape::ConvertToLocal(renderInfo.m_pivot, tileKey.GetGlobalRect().Center(), kShapeCoordScalar); + glsl::vec3 const pos = glsl::vec3(glsl::ToVec2(pt), renderInfo.m_depth); + bool const runAnim = renderInfo.m_runCreationAnim; + + glsl::vec2 left, right, up, down; + AlignHorizontal(pxSize.x * 0.5f, anchor, left, right); + AlignVertical(pxSize.y * 0.5f, anchor, up, down); + + m2::PointD const pixelOffset = renderInfo.m_pixelOffset; + glsl::vec2 const offset(pixelOffset.x, pixelOffset.y); + + buffer.emplace_back(pos, left + down + offset, glsl::ToVec2(texRect.LeftTop()), runAnim); + buffer.emplace_back(pos, left + up + offset, glsl::ToVec2(texRect.LeftBottom()), runAnim); + buffer.emplace_back(pos, right + down + offset, glsl::ToVec2(texRect.RightTop()), runAnim); + buffer.emplace_back(pos, right + up + offset, glsl::ToVec2(texRect.RightBottom()), runAnim); + } + + dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer); + state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM); + state.SetColorTexture(region.GetTexture()); + state.SetTextureFilter(gl_const::GLNearest); + + uint32_t const kMaxSize = 65000; + dp::Batcher batcher(min(indicesCount, kMaxSize), min(vertexCount, kMaxSize)); + dp::SessionGuard guard(batcher, [&tileKey, &renderData](dp::GLState const & state, + drape_ptr && b) + { + renderData.emplace_back(UserMarkRenderData(state, move(b), tileKey)); + }); + + dp::AttributeProvider attribProvider(1, static_cast(buffer.size())); + attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); + + batcher.InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); +} + +// static +void UserLineShape::Draw(TileKey const & tileKey, ref_ptr textures, + UserLinesRenderCollection const & renderParams, LineIndexesCollection const & indexes, + TUserMarksRenderData & renderData) { - TUserMarkShapes shapes; - CacheUserPoints(provider, textures, shapes); - CacheUserLines(provider, textures, shapes); - return shapes; } } // namespace df diff --git a/drape_frontend/user_mark_shapes.hpp b/drape_frontend/user_mark_shapes.hpp index bd0e35e1ff..36fc58bcfc 100644 --- a/drape_frontend/user_mark_shapes.hpp +++ b/drape_frontend/user_mark_shapes.hpp @@ -13,21 +13,64 @@ namespace df { -struct UserMarkShape +struct UserMarkRenderParams { + m2::PointD m_pivot; + m2::PointD m_pixelOffset; + std::string m_symbolName; + dp::Anchor m_anchor; + float m_depth; + bool m_runCreationAnim; + bool m_isVisible; +}; + +struct LineLayer +{ + dp::Color m_color; + float m_width; + float m_depth; +}; + +struct UserLineRenderParams +{ + std::vector m_layers; + std::vector m_points; +}; + +using UserMarksRenderCollection = std::vector; +using UserLinesRenderCollection = std::vector; + +using MarkIndexesCollection = std::vector; +using LineIndexesCollection = std::vector; + +struct UserMarkRenderData +{ + UserMarkRenderData(dp::GLState const & state, + drape_ptr && bucket, + TileKey const & tileKey) + : m_state(state), m_bucket(move(bucket)), m_tileKey(tileKey) + {} + dp::GLState m_state; drape_ptr m_bucket; TileKey m_tileKey; - - UserMarkShape(dp::GLState const & state, drape_ptr && bucket, - TileKey const & tileKey) - : m_state(state), m_bucket(move(bucket)), m_tileKey(tileKey) - {} }; -using TUserMarkShapes = vector; +using TUserMarksRenderData = std::vector; -TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, - ref_ptr textures); +class UserMarkShape +{ +public: + static void Draw(TileKey const & tileKey, ref_ptr textures, + UserMarksRenderCollection const & renderParams, MarkIndexesCollection const & indexes, + TUserMarksRenderData & renderData); +}; + +class UserLineShape +{ +public: + static void Draw(TileKey const & tileKey, ref_ptr textures, UserLinesRenderCollection const & renderParams, + LineIndexesCollection const & indexes, TUserMarksRenderData & renderData); +}; } // namespace df diff --git a/map/user_mark_container.cpp b/map/user_mark_container.cpp index 401a435994..c777739ca8 100644 --- a/map/user_mark_container.cpp +++ b/map/user_mark_container.cpp @@ -3,7 +3,6 @@ #include "drape_frontend/drape_engine.hpp" #include "drape_frontend/tile_key.hpp" -#include "drape_frontend/user_mark_shapes.hpp" #include "base/scope_guard.hpp" #include "base/macros.hpp"