diff options
author | r.kuznetsov <r.kuznetsov@corp.mail.ru> | 2016-09-06 11:43:03 +0300 |
---|---|---|
committer | r.kuznetsov <r.kuznetsov@corp.mail.ru> | 2016-09-06 15:12:30 +0300 |
commit | b3752b5aacda9fb4b383ee2933467a7bd2f69cf6 (patch) | |
tree | 391789097e2cf38668df3633b6016f1f5f6170c3 /drape_frontend | |
parent | feda627f30fd97b62f904c43ca3c8f3f1e608ca0 (diff) |
Added tile-based model view for user marks
Diffstat (limited to 'drape_frontend')
25 files changed, 288 insertions, 212 deletions
diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index f3c38b68da..0710a5716f 100644 --- a/drape_frontend/apply_feature_functors.cpp +++ b/drape_frontend/apply_feature_functors.cpp @@ -424,13 +424,13 @@ void ApplyPointFeature::Finish() ApplyAreaFeature::ApplyAreaFeature(m2::PointD const & tileCenter, TInsertShapeFn const & insertShape, FeatureID const & id, - m2::RectD tileRect, float minPosZ, + m2::RectD const & clipRect, float minPosZ, float posZ, int minVisibleScale, uint8_t rank, CaptionDescription const & captions) : TBase(tileCenter, insertShape, id, minVisibleScale, rank, captions, posZ) , m_minPosZ(minPosZ) , m_isBuilding(posZ > 0.0f) - , m_tileRect(tileRect) + , m_clipRect(clipRect) {} void ApplyAreaFeature::operator()(m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3) @@ -459,9 +459,9 @@ void ApplyAreaFeature::operator()(m2::PointD const & p1, m2::PointD const & p2, }; if (m2::CrossProduct(p2 - p1, p3 - p1) < 0) - m2::ClipTriangleByRect(m_tileRect, p1, p2, p3, clipFunctor); + m2::ClipTriangleByRect(m_clipRect, p1, p2, p3, clipFunctor); else - m2::ClipTriangleByRect(m_tileRect, p1, p3, p2, clipFunctor); + m2::ClipTriangleByRect(m_clipRect, p1, p3, p2, clipFunctor); } void ApplyAreaFeature::ProcessBuildingPolygon(m2::PointD const & p1, m2::PointD const & p2, diff --git a/drape_frontend/apply_feature_functors.hpp b/drape_frontend/apply_feature_functors.hpp index b95baf4ab0..e95efe075c 100644 --- a/drape_frontend/apply_feature_functors.hpp +++ b/drape_frontend/apply_feature_functors.hpp @@ -99,7 +99,7 @@ class ApplyAreaFeature : public ApplyPointFeature public: ApplyAreaFeature(m2::PointD const & tileCenter, TInsertShapeFn const & insertShape, FeatureID const & id, - m2::RectD tileRect, float minPosZ, + m2::RectD const & clipRect, float minPosZ, float posZ, int minVisibleScale, uint8_t rank, CaptionDescription const & captions); @@ -125,7 +125,7 @@ private: vector<pair<TEdge, int>> m_edges; float const m_minPosZ; bool const m_isBuilding; - m2::RectD m_tileRect; + m2::RectD m_clipRect; }; class ApplyLineFeature : public BaseApplyFeature diff --git a/drape_frontend/area_shape.cpp b/drape_frontend/area_shape.cpp index 6955ccb2df..44c7f9b459 100644 --- a/drape_frontend/area_shape.cpp +++ b/drape_frontend/area_shape.cpp @@ -36,8 +36,8 @@ void AreaShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> t for (auto const & edge : m_buildingEdges) { - glsl::vec2 const startPt = glsl::ToVec2(ConvertPt(edge.m_startVertex, m_params.m_tileCenter, kShapeCoordScalar)); - glsl::vec2 const endPt = glsl::ToVec2(ConvertPt(edge.m_endVertex, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const startPt = glsl::ToVec2(ConvertToLocal(edge.m_startVertex, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const endPt = glsl::ToVec2(ConvertToLocal(edge.m_endVertex, m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec3 normal(glsl::ToVec2(edge.m_normal), 0.0f); vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(startPt, -m_params.m_minPosZ), normal, colorPoint)); @@ -52,7 +52,7 @@ void AreaShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> t glsl::vec3 normal(0.0f, 0.0f, -1.0f); for (auto const & vertex : m_vertexes) { - glsl::vec2 const pt = glsl::ToVec2(ConvertPt(vertex, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(vertex, m_params.m_tileCenter, kShapeCoordScalar)); vertexes.emplace_back(gpu::Area3dVertex(glsl::vec3(pt, -m_params.m_posZ), normal, colorPoint)); } @@ -70,7 +70,7 @@ void AreaShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> t vertexes.resize(m_vertexes.size()); transform(m_vertexes.begin(), m_vertexes.end(), vertexes.begin(), [&colorPoint, this](m2::PointF const & vertex) { - return gpu::AreaVertex(glsl::vec3(glsl::ToVec2(ConvertPt(vertex, m_params.m_tileCenter, kShapeCoordScalar)), + return gpu::AreaVertex(glsl::vec3(glsl::ToVec2(ConvertToLocal(vertex, m_params.m_tileCenter, kShapeCoordScalar)), m_params.m_depth), colorPoint); }); diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index b26819750b..94a9f16654 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -221,18 +221,19 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message) case Message::UpdateUserMarkLayer: { ref_ptr<UpdateUserMarkLayerMessage> msg = message; - TileKey const & key = msg->GetKey(); UserMarksProvider const * marksProvider = msg->StartProcess(); if (marksProvider->IsDirty()) { + size_t const layerId = msg->GetLayerId(); m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp<ClearUserMarkLayerMessage>(key), + make_unique_dp<ClearUserMarkLayerMessage>(layerId), MessagePriority::Normal); - m_batchersPool->ReserveBatcher(key); - CacheUserMarks(marksProvider, m_batchersPool->GetTileBatcher(key), m_texMng); - m_batchersPool->ReleaseBatcher(key); + TUserMarkShapes shapes = CacheUserMarks(marksProvider, m_texMng); + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp<FlushUserMarksMessage>(layerId, move(shapes)), + MessagePriority::Normal); } msg->EndProcess(); break; diff --git a/drape_frontend/circle_shape.cpp b/drape_frontend/circle_shape.cpp index 537133d0b5..8cdb09bcd4 100644 --- a/drape_frontend/circle_shape.cpp +++ b/drape_frontend/circle_shape.cpp @@ -25,7 +25,7 @@ void CircleShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManager> dp::TextureManager::ColorRegion region; textures->GetColorRegion(m_params.m_color, region); glsl::vec2 const colorPoint(glsl::ToVec2(region.GetTexRect().Center())); - glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); buffer_vector<gpu::SolidTexturingVertex, 22> vertexes; vertexes.push_back(gpu::SolidTexturingVertex diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index 445d939146..42b4b554a2 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -143,24 +143,24 @@ void DrapeEngine::SetModelViewAnyRect(m2::AnyRectD const & rect, bool isAnim) AddUserEvent(make_unique_dp<SetAnyRectEvent>(rect, isAnim)); } -void DrapeEngine::ClearUserMarksLayer(df::TileKey const & tileKey) +void DrapeEngine::ClearUserMarksLayer(size_t layerId) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp<ClearUserMarkLayerMessage>(tileKey), + make_unique_dp<ClearUserMarkLayerMessage>(layerId), MessagePriority::Normal); } -void DrapeEngine::ChangeVisibilityUserMarksLayer(TileKey const & tileKey, bool isVisible) +void DrapeEngine::ChangeVisibilityUserMarksLayer(size_t layerId, bool isVisible) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp<ChangeUserMarkLayerVisibilityMessage>(tileKey, isVisible), + make_unique_dp<ChangeUserMarkLayerVisibilityMessage>(layerId, isVisible), MessagePriority::Normal); } -void DrapeEngine::UpdateUserMarksLayer(TileKey const & tileKey, UserMarksProvider * provider) +void DrapeEngine::UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provider) { m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, - make_unique_dp<UpdateUserMarkLayerMessage>(tileKey, provider), + make_unique_dp<UpdateUserMarkLayerMessage>(layerId, provider), MessagePriority::Normal); } diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp index 63f38e616f..8eacbbde71 100644 --- a/drape_frontend/drape_engine.hpp +++ b/drape_frontend/drape_engine.hpp @@ -100,9 +100,9 @@ public: using TModelViewListenerFn = FrontendRenderer::TModelViewChanged; void SetModelViewListener(TModelViewListenerFn && fn); - void ClearUserMarksLayer(TileKey const & tileKey); - void ChangeVisibilityUserMarksLayer(TileKey const & tileKey, bool isVisible); - void UpdateUserMarksLayer(TileKey const & tileKey, UserMarksProvider * provider); + void ClearUserMarksLayer(size_t layerId); + void ChangeVisibilityUserMarksLayer(size_t layerId, bool isVisible); + void UpdateUserMarksLayer(size_t layerId, UserMarksProvider * provider); void SetRenderingEnabled(ref_ptr<dp::OGLContextFactory> contextFactory = nullptr); void SetRenderingDisabled(bool const destroyContext); diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 55c0999e4e..94d0e14362 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -248,23 +248,10 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) dp::GLState const & state = msg->GetState(); TileKey const & key = msg->GetKey(); drape_ptr<dp::RenderBucket> bucket = msg->AcceptBuffer(); - if (!IsUserMarkLayer(key)) - { - if (key.m_zoomLevel == m_currentZoomLevel && CheckTileGenerations(key)) - { - PrepareBucket(state, bucket); - AddToRenderGroup(state, move(bucket), key); - } - } - else + if (key.m_zoomLevel == m_currentZoomLevel && CheckTileGenerations(key)) { PrepareBucket(state, bucket); - - ref_ptr<dp::GpuProgram> program = m_gpuProgramManager->GetProgram(state.GetProgramIndex()); - ref_ptr<dp::GpuProgram> program3d = m_gpuProgramManager->GetProgram(state.GetProgram3dIndex()); - - m_userMarkRenderGroups.emplace_back(make_unique_dp<UserMarkRenderGroup>(state, key, move(bucket))); - m_userMarkRenderGroups.back()->SetRenderParams(program, program3d, make_ref(&m_generalUniforms)); + AddToRenderGroup(state, move(bucket), key); } break; } @@ -275,7 +262,6 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) TOverlaysRenderData renderData = msg->AcceptRenderData(); for (auto & overlayRenderData : renderData) { - ASSERT(!IsUserMarkLayer(overlayRenderData.m_tileKey), ()); if (overlayRenderData.m_tileKey.m_zoomLevel == m_currentZoomLevel && CheckTileGenerations(overlayRenderData.m_tileKey)) { @@ -315,30 +301,46 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message) break; } + case Message::FlushUserMarks: + { + ref_ptr<FlushUserMarksMessage> msg = message; + size_t const layerId = msg->GetLayerId(); + for (UserMarkShape & shape : msg->GetShapes()) + { + 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<UserMarkRenderGroup>(layerId, shape.m_state, shape.m_tileKey, + move(shape.m_bucket)); + m_userMarkRenderGroups.push_back(move(group)); + m_userMarkRenderGroups.back()->SetRenderParams(program, program3d, make_ref(&m_generalUniforms)); + } + break; + } + case Message::ClearUserMarkLayer: { - TileKey const & tileKey = ref_ptr<ClearUserMarkLayerMessage>(message)->GetKey(); - auto const functor = [&tileKey](drape_ptr<UserMarkRenderGroup> const & g) + ref_ptr<ClearUserMarkLayerMessage> msg = message; + size_t const layerId = msg->GetLayerId(); + auto const functor = [&layerId](drape_ptr<UserMarkRenderGroup> const & g) { - return g->GetTileKey() == tileKey; + return g->GetLayerId() == layerId; }; auto const iter = remove_if(m_userMarkRenderGroups.begin(), m_userMarkRenderGroups.end(), functor); - m_userMarkRenderGroups.erase(iter, m_userMarkRenderGroups.end()); break; } case Message::ChangeUserMarkLayerVisibility: { - ref_ptr<ChangeUserMarkLayerVisibilityMessage> m = message; - TileKey const & key = m->GetKey(); - if (m->IsVisible()) - m_userMarkVisibility.insert(key); + ref_ptr<ChangeUserMarkLayerVisibilityMessage> msg = message; + if (msg->IsVisible()) + m_userMarkVisibility.insert(msg->GetLayerId()); else - m_userMarkVisibility.erase(key); + m_userMarkVisibility.erase(msg->GetLayerId()); break; } @@ -1074,12 +1076,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) m_routeRenderer->RenderRoute(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); - for (drape_ptr<UserMarkRenderGroup> const & group : m_userMarkRenderGroups) - { - ASSERT(group.get() != nullptr, ()); - if (m_userMarkVisibility.find(group->GetTileKey()) != m_userMarkVisibility.end()) - RenderSingleGroup(modelView, make_ref(group)); - } + RenderUserMarksLayer(modelView); m_routeRenderer->RenderRouteSigns(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); @@ -1127,6 +1124,20 @@ void FrontendRenderer::RenderOverlayLayer(ScreenBase const & modelView) for (drape_ptr<RenderGroup> & group : overlay.m_renderGroups) RenderSingleGroup(modelView, make_ref(group)); } + +void FrontendRenderer::RenderUserMarksLayer(ScreenBase const & modelView) +{ + double const kExtension = 1.1; + m2::RectD screenRect = modelView.ClipRect(); + screenRect.Scale(kExtension); + for (auto const & group : m_userMarkRenderGroups) + { + ASSERT(group.get() != nullptr, ()); + if (m_userMarkVisibility.find(group->GetLayerId()) != m_userMarkVisibility.end() && + screenRect.IsIntersect(group->GetTileKey().GetGlobalRect())) + RenderSingleGroup(modelView, make_ref(group)); + } +} void FrontendRenderer::BuildOverlayTree(ScreenBase const & modelView) { diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index 48418794a7..fd19a10e81 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -37,6 +37,7 @@ #include "std/function.hpp" #include "std/map.hpp" #include "std/array.hpp" +#include "std/unordered_set.hpp" namespace dp { @@ -170,6 +171,7 @@ private: void Render2dLayer(ScreenBase const & modelView); void Render3dLayer(ScreenBase const & modelView); void RenderOverlayLayer(ScreenBase const & modelView); + void RenderUserMarksLayer(ScreenBase const & modelView); ////// ScreenBase const & ProcessEvents(bool & modelViewChanged, bool & viewportChanged); void PrepareScene(ScreenBase const & modelView); @@ -270,7 +272,7 @@ private: array<RenderLayer, RenderLayer::LayerCountID> m_layers; vector<drape_ptr<UserMarkRenderGroup>> m_userMarkRenderGroups; - set<TileKey> m_userMarkVisibility; + unordered_set<size_t> m_userMarkVisibility; drape_ptr<gui::LayerRenderer> m_guiRenderer; drape_ptr<MyPositionController> m_myPositionController; diff --git a/drape_frontend/gps_track_renderer.cpp b/drape_frontend/gps_track_renderer.cpp index fcb47e6f70..6dfe0a692b 100644 --- a/drape_frontend/gps_track_renderer.cpp +++ b/drape_frontend/gps_track_renderer.cpp @@ -235,7 +235,7 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, if (m_points.size() == 1) { dp::Color const color = GetColorBySpeed(m_points.front().m_speedMPS); - m2::PointD const pt = MapShape::ConvertPt(m_points.front().m_point, m_pivot, kShapeCoordScalar); + m2::PointD const pt = MapShape::ConvertToLocal(m_points.front().m_point, m_pivot, kShapeCoordScalar); m_handlesCache[cacheIndex].first->SetPoint(0, pt, m_radius, color); m_handlesCache[cacheIndex].second++; } @@ -253,7 +253,7 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, if (screen.ClipRect().IsIntersect(pointRect)) { dp::Color const color = CalculatePointColor(static_cast<size_t>(it.GetIndex()), pt, it.GetLength(), it.GetFullLength()); - m2::PointD const convertedPt = MapShape::ConvertPt(pt, m_pivot, kShapeCoordScalar); + m2::PointD const convertedPt = MapShape::ConvertToLocal(pt, m_pivot, kShapeCoordScalar); m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, convertedPt, m_radius, color); m_handlesCache[cacheIndex].second++; if (m_handlesCache[cacheIndex].second >= m_handlesCache[cacheIndex].first->GetPointsCount()) @@ -272,7 +272,7 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, #ifdef SHOW_RAW_POINTS for (size_t i = 0; i < m_points.size(); i++) { - m2::PointD const convertedPt = MapShape::ConvertPt(m_points[i].m_point, m_pivot, kShapeCoordScalar); + m2::PointD const convertedPt = MapShape::ConvertToLocal(m_points[i].m_point, m_pivot, kShapeCoordScalar); m_handlesCache[cacheIndex].first->SetPoint(m_handlesCache[cacheIndex].second, convertedPt, m_radius * 1.2, dp::Color(0, 0, 255, 255)); m_handlesCache[cacheIndex].second++; if (m_handlesCache[cacheIndex].second >= m_handlesCache[cacheIndex].first->GetPointsCount()) diff --git a/drape_frontend/line_shape.cpp b/drape_frontend/line_shape.cpp index 20d95615a5..8130117f56 100644 --- a/drape_frontend/line_shape.cpp +++ b/drape_frontend/line_shape.cpp @@ -336,8 +336,8 @@ void LineShape::Construct<DashedLineBuilder>(DashedLineBuilder & builder) const if (path[i].EqualDxDy(path[i - 1], 1.0E-5)) continue; - glsl::vec2 const p1 = glsl::ToVec2(ConvertPt(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); - glsl::vec2 const p2 = glsl::ToVec2(ConvertPt(path[i], m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const p1 = glsl::ToVec2(ConvertToLocal(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const p2 = glsl::ToVec2(ConvertToLocal(path[i], m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 tangent, leftNormal, rightNormal; CalculateTangentAndNormals(p1, p2, tangent, leftNormal, rightNormal); @@ -379,7 +379,7 @@ void LineShape::Construct<SolidLineBuilder>(SolidLineBuilder & builder) const generateJoins = false; // build geometry - glsl::vec2 firstPoint = glsl::ToVec2(ConvertPt(path.front(), m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 firstPoint = glsl::ToVec2(ConvertToLocal(path.front(), m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 lastPoint; bool hasConstructedSegments = false; for (size_t i = 1; i < path.size(); ++i) @@ -387,8 +387,8 @@ void LineShape::Construct<SolidLineBuilder>(SolidLineBuilder & builder) const if (path[i].EqualDxDy(path[i - 1], 1.0E-5)) continue; - glsl::vec2 const p1 = glsl::ToVec2(ConvertPt(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); - glsl::vec2 const p2 = glsl::ToVec2(ConvertPt(path[i], m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const p1 = glsl::ToVec2(ConvertToLocal(path[i - 1], m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const p2 = glsl::ToVec2(ConvertToLocal(path[i], m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 tangent, leftNormal, rightNormal; CalculateTangentAndNormals(p1, p2, tangent, leftNormal, rightNormal); diff --git a/drape_frontend/map_shape.hpp b/drape_frontend/map_shape.hpp index 8582670328..52579140b8 100644 --- a/drape_frontend/map_shape.hpp +++ b/drape_frontend/map_shape.hpp @@ -35,7 +35,7 @@ public: void SetFeatureMinZoom(int minZoom) { m_minZoom = minZoom; } int GetFeatureMinZoom() const { return m_minZoom; } - static m2::PointD ConvertPt(m2::PointD const & basePt, m2::PointD const & tileCenter, double scalar) + static m2::PointD ConvertToLocal(m2::PointD const & basePt, m2::PointD const & tileCenter, double scalar) { return (basePt - tileCenter) * scalar; } diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index bdc97bc437..e237b93c6c 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -23,6 +23,7 @@ public: ClearUserMarkLayer, ChangeUserMarkLayerVisibility, UpdateUserMarkLayer, + FlushUserMarks, GuiLayerRecached, GuiRecache, GuiLayerLayout, diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 8ffd1ef3b3..e2263ee5fa 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -13,6 +13,7 @@ #include "drape_frontend/selection_shape.hpp" #include "drape_frontend/tile_utils.hpp" #include "drape_frontend/user_marks_provider.hpp" +#include "drape_frontend/user_mark_shapes.hpp" #include "drape_frontend/viewport.hpp" #include "geometry/polyline2d.hpp" @@ -191,20 +192,33 @@ private: bool m_needInvalidateAll; }; -class ClearUserMarkLayerMessage : public BaseTileMessage +class BaseUserMarkLayerMessage : public Message { public: - ClearUserMarkLayerMessage(TileKey const & tileKey) - : BaseTileMessage(tileKey) {} + BaseUserMarkLayerMessage(size_t layerId) + : m_layerId(layerId) + {} + + size_t GetLayerId() const { return m_layerId; } + +private: + size_t m_layerId; +}; + +class ClearUserMarkLayerMessage : public BaseUserMarkLayerMessage +{ +public: + ClearUserMarkLayerMessage(size_t layerId) + : BaseUserMarkLayerMessage(layerId) {} Type GetType() const override { return Message::ClearUserMarkLayer; } }; -class ChangeUserMarkLayerVisibilityMessage : public BaseTileMessage +class ChangeUserMarkLayerVisibilityMessage : public BaseUserMarkLayerMessage { public: - ChangeUserMarkLayerVisibilityMessage(TileKey const & tileKey, bool isVisible) - : BaseTileMessage(tileKey) + ChangeUserMarkLayerVisibilityMessage(size_t layerId, bool isVisible) + : BaseUserMarkLayerMessage(layerId) , m_isVisible(isVisible) {} Type GetType() const override { return Message::ChangeUserMarkLayerVisibility; } @@ -215,17 +229,17 @@ private: bool m_isVisible; }; -class UpdateUserMarkLayerMessage : public BaseTileMessage +class UpdateUserMarkLayerMessage : public BaseUserMarkLayerMessage { public: - UpdateUserMarkLayerMessage(TileKey const & tileKey, UserMarksProvider * provider) - : BaseTileMessage(tileKey) + UpdateUserMarkLayerMessage(size_t layerId, UserMarksProvider * provider) + : BaseUserMarkLayerMessage(layerId) , m_provider(provider) { m_provider->IncrementCounter(); } - ~UpdateUserMarkLayerMessage() + ~UpdateUserMarkLayerMessage() override { ASSERT(m_inProcess == false, ()); m_provider->DecrementCounter(); @@ -259,6 +273,23 @@ private: #endif }; +class FlushUserMarksMessage : public BaseUserMarkLayerMessage +{ +public: + FlushUserMarksMessage(size_t layerId, TUserMarkShapes && shapes) + : BaseUserMarkLayerMessage(layerId) + , m_shapes(move(shapes)) + {} + + Type GetType() const override { return Message::FlushUserMarks; } + bool IsGLContextDependent() const override { return true; } + + TUserMarkShapes & GetShapes() { return m_shapes; } + +private: + TUserMarkShapes m_shapes; +}; + class GuiLayerRecachedMessage : public Message { public: diff --git a/drape_frontend/my_position.cpp b/drape_frontend/my_position.cpp index 98afdd7f2f..99f6b89ef6 100644 --- a/drape_frontend/my_position.cpp +++ b/drape_frontend/my_position.cpp @@ -110,7 +110,7 @@ void MyPosition::RenderAccuracy(ScreenBase const & screen, int zoomLevel, math::Matrix<float, 4, 4> mv = key.GetTileBasedModelView(screen); uniforms.SetMatrix4x4Value("modelView", mv.m_data); - m2::PointD const pos = MapShape::ConvertPt(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + m2::PointD const pos = MapShape::ConvertToLocal(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); uniforms.SetFloatValue("u_position", pos.x, pos.y, 0.0f); uniforms.SetFloatValue("u_accuracy", pixelAccuracy); uniforms.SetFloatValue("u_opacity", 1.0f); @@ -134,7 +134,7 @@ void MyPosition::RenderMyPosition(ScreenBase const & screen, int zoomLevel, math::Matrix<float, 4, 4> mv = key.GetTileBasedModelView(screen); uniforms.SetMatrix4x4Value("modelView", mv.m_data); - m2::PointD const pos = MapShape::ConvertPt(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + m2::PointD const pos = MapShape::ConvertToLocal(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); uniforms.SetFloatValue("u_position", pos.x, pos.y, dp::depth::MY_POSITION_MARK); uniforms.SetFloatValue("u_azimut", -(m_azimuth + screen.GetAngle())); uniforms.SetFloatValue("u_opacity", 1.0); diff --git a/drape_frontend/path_symbol_shape.cpp b/drape_frontend/path_symbol_shape.cpp index 8715588fce..54b9ff03dc 100644 --- a/drape_frontend/path_symbol_shape.cpp +++ b/drape_frontend/path_symbol_shape.cpp @@ -40,7 +40,7 @@ void PathSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureMana glsl::vec2 dummy(0.0, 0.0); while (!splineIter.BeginAgain()) { - glsl::vec2 const pivot = glsl::ToVec2(ConvertPt(splineIter.m_pos, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const pivot = glsl::ToVec2(ConvertToLocal(splineIter.m_pos, m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec2 n = halfH * glsl::normalize(glsl::vec2(-splineIter.m_dir.y, splineIter.m_dir.x)); glsl::vec2 d = halfW * glsl::normalize(glsl::vec2(splineIter.m_dir.x, splineIter.m_dir.y)); float nLength = glsl::length(n) * pToGScale; diff --git a/drape_frontend/poi_symbol_shape.cpp b/drape_frontend/poi_symbol_shape.cpp index 8567d4e4f0..1fd1b13495 100644 --- a/drape_frontend/poi_symbol_shape.cpp +++ b/drape_frontend/poi_symbol_shape.cpp @@ -108,7 +108,7 @@ void PoiSymbolShape::Draw(ref_ptr<dp::Batcher> batcher, ref_ptr<dp::TextureManag dp::TextureManager::SymbolRegion region; textures->GetSymbolRegion(m_params.m_symbolName, region); - glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_pt, m_params.m_tileCenter, kShapeCoordScalar)); glsl::vec4 const position = glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ); m2::PointU const pixelSize = region.GetPixelSize(); diff --git a/drape_frontend/render_group.cpp b/drape_frontend/render_group.cpp index 7cc96170f0..ac5e7b63b2 100755 --- a/drape_frontend/render_group.cpp +++ b/drape_frontend/render_group.cpp @@ -192,12 +192,12 @@ bool RenderGroupComparator::operator()(drape_ptr<RenderGroup> const & l, drape_p return false; } -UserMarkRenderGroup::UserMarkRenderGroup(dp::GLState const & state, - TileKey const & tileKey, +UserMarkRenderGroup::UserMarkRenderGroup(size_t layerId, dp::GLState const & state, TileKey const & tileKey, drape_ptr<dp::RenderBucket> && bucket) : TBase(state, tileKey) , m_renderBucket(move(bucket)) , m_animation(new OpacityAnimation(0.25 /*duration*/, 0.0 /* minValue */, 1.0 /* maxValue*/)) + , m_layerId(layerId) { m_mapping.AddRangePoint(0.6, 1.3); m_mapping.AddRangePoint(0.85, 0.8); @@ -222,8 +222,11 @@ void UserMarkRenderGroup::Render(ScreenBase const & screen) { BaseRenderGroup::Render(screen); - math::Matrix<float, 4, 4> mv = screen.GetModelView(); - m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + // Set tile-based model-view matrix. + { + math::Matrix<float, 4, 4> mv = GetTileKey().GetTileBasedModelView(screen); + m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + } ref_ptr<dp::GpuProgram> shader = screen.isPerspective() ? m_shader3d : m_shader; dp::ApplyUniforms(m_uniforms, shader); @@ -234,6 +237,11 @@ void UserMarkRenderGroup::Render(ScreenBase const & screen) } } +size_t UserMarkRenderGroup::GetLayerId() const +{ + return m_layerId; +} + string DebugPrint(RenderGroup const & group) { ostringstream out; diff --git a/drape_frontend/render_group.hpp b/drape_frontend/render_group.hpp index de62ad03dd..c28fdd2ca1 100755 --- a/drape_frontend/render_group.hpp +++ b/drape_frontend/render_group.hpp @@ -26,6 +26,8 @@ public: : m_state(state) , m_tileKey(tileKey) {} + virtual ~BaseRenderGroup() {} + void SetRenderParams(ref_ptr<dp::GpuProgram> shader, ref_ptr<dp::GpuProgram> shader3d, ref_ptr<dp::UniformValuesStorage> generalUniforms); @@ -50,11 +52,11 @@ private: class RenderGroup : public BaseRenderGroup { - typedef BaseRenderGroup TBase; + using TBase = BaseRenderGroup; friend class BatchMergeHelper; public: RenderGroup(dp::GLState const & state, TileKey const & tileKey); - ~RenderGroup(); + ~RenderGroup() override; void Update(ScreenBase const & modelView); void CollectOverlay(ref_ptr<dp::OverlayTree> tree); @@ -91,20 +93,23 @@ public: class UserMarkRenderGroup : public BaseRenderGroup { - typedef BaseRenderGroup TBase; + using TBase = BaseRenderGroup; public: - UserMarkRenderGroup(dp::GLState const & state, TileKey const & tileKey, + UserMarkRenderGroup(size_t layerId, dp::GLState const & state, TileKey const & tileKey, drape_ptr<dp::RenderBucket> && bucket); - ~UserMarkRenderGroup(); + ~UserMarkRenderGroup() override; void UpdateAnimation() override; void Render(ScreenBase const & screen) override; + size_t GetLayerId() const; + private: drape_ptr<dp::RenderBucket> m_renderBucket; unique_ptr<OpacityAnimation> m_animation; ValueMapping<float> m_mapping; + size_t m_layerId; }; } // namespace df diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index 9954e098e7..5a839d5a17 100644 --- a/drape_frontend/route_shape.cpp +++ b/drape_frontend/route_shape.cpp @@ -142,10 +142,10 @@ void RouteShape::PrepareGeometry(vector<m2::PointD> const & path, m2::PointD con (i < segments.size() - 1) ? &segments[i + 1] : nullptr); // Generate main geometry. - m2::PointD const startPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[StartPoint]), - pivot, kShapeCoordScalar); - m2::PointD const endPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[EndPoint]), - pivot, kShapeCoordScalar); + m2::PointD const startPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[StartPoint]), + pivot, kShapeCoordScalar); + m2::PointD const endPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[EndPoint]), + pivot, kShapeCoordScalar); glsl::vec3 const startPivot = glsl::vec3(glsl::ToVec2(startPt), kDepth); glsl::vec3 const endPivot = glsl::vec3(glsl::ToVec2(endPt), kDepth); @@ -248,10 +248,10 @@ void RouteShape::PrepareArrowGeometry(vector<m2::PointD> const & path, m2::Point (i < segments.size() - 1) ? &segments[i + 1] : nullptr); // Generate main geometry. - m2::PointD const startPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[StartPoint]), - pivot, kShapeCoordScalar); - m2::PointD const endPt = MapShape::ConvertPt(glsl::FromVec2(segments[i].m_points[EndPoint]), - pivot, kShapeCoordScalar); + m2::PointD const startPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[StartPoint]), + pivot, kShapeCoordScalar); + m2::PointD const endPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[EndPoint]), + pivot, kShapeCoordScalar); glsl::vec4 const startPivot = glsl::vec4(glsl::ToVec2(startPt), depth, 1.0); glsl::vec4 const endPivot = glsl::vec4(glsl::ToVec2(endPt), depth, 1.0); diff --git a/drape_frontend/selection_shape.cpp b/drape_frontend/selection_shape.cpp index 224ab48197..caafa84566 100644 --- a/drape_frontend/selection_shape.cpp +++ b/drape_frontend/selection_shape.cpp @@ -140,7 +140,7 @@ void SelectionShape::Render(ScreenBase const & screen, int zoomLevel, ref_ptr<dp math::Matrix<float, 4, 4> mv = key.GetTileBasedModelView(screen); uniforms.SetMatrix4x4Value("modelView", mv.m_data); - m2::PointD const pos = MapShape::ConvertPt(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); + m2::PointD const pos = MapShape::ConvertToLocal(m_position, key.GetGlobalRect().Center(), kShapeCoordScalar); uniforms.SetFloatValue("u_position", pos.x, pos.y, -m_positionZ); float accuracy = m_mapping.GetValue(m_animation.GetT()); diff --git a/drape_frontend/text_layout.cpp b/drape_frontend/text_layout.cpp index 545dfa3878..dd758b09df 100644 --- a/drape_frontend/text_layout.cpp +++ b/drape_frontend/text_layout.cpp @@ -482,7 +482,7 @@ bool PathTextLayout::CacheDynamicGeometry(m2::Spline::iterator const & iter, flo glsl::vec2 pxPivot = glsl::ToVec2(iter.m_pos); buffer.resize(4 * m_metrics.size()); - glsl::vec4 const pivot(glsl::ToVec2(MapShape::ConvertPt(globalPivot, m_tileCenter, kShapeCoordScalar)), depth, 0.0f); + glsl::vec4 const pivot(glsl::ToVec2(MapShape::ConvertToLocal(globalPivot, m_tileCenter, kShapeCoordScalar)), depth, 0.0f); for (size_t i = 0; i < m_metrics.size(); ++i) { GlyphRegion const & g = m_metrics[i]; diff --git a/drape_frontend/text_shape.cpp b/drape_frontend/text_shape.cpp index b1bcee28c6..1147282e66 100644 --- a/drape_frontend/text_shape.cpp +++ b/drape_frontend/text_shape.cpp @@ -197,7 +197,7 @@ void TextShape::DrawSubStringPlain(StraightTextLayout const & layout, dp::FontDe textures->GetColorRegion(font.m_color, color); textures->GetColorRegion(font.m_outlineColor, outline); - glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_basePoint, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_basePoint, m_params.m_tileCenter, kShapeCoordScalar)); layout.Cache(glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ), baseOffset, color, staticBuffer, dynamicBuffer); @@ -245,7 +245,7 @@ void TextShape::DrawSubStringOutlined(StraightTextLayout const & layout, dp::Fon textures->GetColorRegion(font.m_color, color); textures->GetColorRegion(font.m_outlineColor, outline); - glsl::vec2 const pt = glsl::ToVec2(ConvertPt(m_basePoint, m_params.m_tileCenter, kShapeCoordScalar)); + glsl::vec2 const pt = glsl::ToVec2(ConvertToLocal(m_basePoint, m_params.m_tileCenter, kShapeCoordScalar)); layout.Cache(glsl::vec4(pt, m_params.m_depth, -m_params.m_posZ), baseOffset, color, outline, staticBuffer, dynamicBuffer); diff --git a/drape_frontend/user_mark_shapes.cpp b/drape_frontend/user_mark_shapes.cpp index e186f9fcc4..6700da3e6d 100644 --- a/drape_frontend/user_mark_shapes.cpp +++ b/drape_frontend/user_mark_shapes.cpp @@ -1,6 +1,9 @@ -#include "user_mark_shapes.hpp" +#include "drape_frontend/user_mark_shapes.hpp" -#include "line_shape.hpp" +#include "drape_frontend/line_shape.hpp" +#include "drape_frontend/map_shape.hpp" +#include "drape_frontend/shape_view_params.hpp" +#include "drape_frontend/tile_utils.hpp" #include "drape/utils/vertex_decl.hpp" #include "drape/shader_def.hpp" @@ -13,40 +16,6 @@ namespace df namespace { - int const ZUserMarksLayer = -1; - int const YSearchMarksLayer = 1; - int const YApiMarksLayer = 2; - int const YBookmarksLayer = 3; - int const YDebugLayer = 4; -} - -TileKey GetSearchTileKey() -{ - return TileKey(0, YSearchMarksLayer, ZUserMarksLayer); -} - -TileKey GetApiTileKey() -{ - return TileKey(0, YApiMarksLayer, ZUserMarksLayer); -} - -TileKey GetDebugTileKey() -{ - return TileKey(0, YDebugLayer, ZUserMarksLayer); -} - -TileKey GetBookmarkTileKey(size_t categoryIndex) -{ - return TileKey(categoryIndex, YBookmarksLayer, ZUserMarksLayer); -} - -bool IsUserMarkLayer(TileKey const & tileKey) -{ - return tileKey.m_zoomLevel == ZUserMarksLayer; -} - -namespace -{ template <typename TCreateVector> void AlignFormingNormals(TCreateVector const & fn, dp::Anchor anchor, @@ -87,8 +56,7 @@ struct UserPointVertex : gpu::BaseVertex , m_normal(normal) , m_texCoord(texCoord) , m_isAnim(isAnim ? 1.0 : -1.0) - { - } + {} static dp::BindingInfo GetBinding() { @@ -110,104 +78,143 @@ struct UserPointVertex : gpu::BaseVertex using UPV = UserPointVertex; -void CacheUserPoints(UserMarksProvider const * provider, - ref_ptr<dp::Batcher> batcher, - ref_ptr<dp::TextureManager> textures) +void CacheUserPoints(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures, + TUserMarkShapes & outShapes) { size_t markCount = provider->GetUserPointCount(); if (markCount == 0) return; - uint32_t vertexCount = dp::Batcher::VertexPerQuad * markCount; // 4 vertex per quad - - buffer_vector<UPV, 1024> buffer; - buffer.reserve(vertexCount); - - vector<UserPointMark const *> marks; - marks.reserve(markCount); + int const kZoomLevel = 10; + map<TileKey, vector<UserPointMark const *>> marks; for (size_t i = 0; i < markCount; ++i) - marks.push_back(provider->GetUserPointMark(i)); - - sort(marks.begin(), marks.end(), [](UserPointMark const * v1, UserPointMark const * v2) { - return v1->GetPivot().y < v2->GetPivot().y; - }); + UserPointMark const * userMark = provider->GetUserPointMark(i); + TileKey const tileKey = GetTileKeyByPoint(userMark->GetPivot(), kZoomLevel); + marks[tileKey].push_back(userMark); + } - dp::TextureManager::SymbolRegion region; - for (size_t i = 0; i < marks.size(); ++i) + for (auto it = marks.begin(); it != marks.end(); ++it) { - UserPointMark const * pointMark = marks[i]; - textures->GetSymbolRegion(pointMark->GetSymbolName(), region); - m2::RectF const & texRect = region.GetTexRect(); - m2::PointF pxSize = region.GetPixelSize(); - dp::Anchor anchor = pointMark->GetAnchor(); - glsl::vec3 pos = glsl::vec3(glsl::ToVec2(pointMark->GetPivot()), pointMark->GetDepth()); - bool 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); - } + 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::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer); - state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM); - state.SetColorTexture(region.GetTexture()); + dp::TextureManager::SymbolRegion region; - dp::AttributeProvider attribProvider(1, buffer.size()); - attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); + uint32_t const vertexCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::VertexPerQuad; + uint32_t const indicesCount = static_cast<uint32_t>(it->second.size()) * dp::Batcher::IndexPerQuad; + buffer_vector<UPV, 128> buffer; + buffer.reserve(vertexCount); - batcher->InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); + 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); + + dp::Batcher batcher(indicesCount, vertexCount); + dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state, + drape_ptr<dp::RenderBucket> && b) + { + outShapes.emplace_back(UserMarkShape(state, move(b), key)); + }); + dp::AttributeProvider attribProvider(1, 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<dp::Batcher> batcher, - ref_ptr<dp::TextureManager> textures) +void CacheUserLines(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures, + TUserMarkShapes & outShapes) { + int const kZoomLevel = 10; + map<TileKey, vector<pair<UserLineMark const *, m2::SharedSpline>>> userLines; for (size_t i = 0; i < provider->GetUserLineCount(); ++i) { UserLineMark const * line = provider->GetUserLineMark(i); - size_t pointCount = line->GetPointCount(); + size_t const pointCount = line->GetPointCount(); vector<m2::PointD> points; + m2::RectD rect; points.reserve(pointCount); for (size_t i = 0; i < pointCount; ++i) + { points.push_back(line->GetPoint(i)); + rect.Add(points.back()); + } - m2::SharedSpline spline(points); + TileKey const tileKey = GetTileKeyByPoint(rect.Center(), kZoomLevel); + userLines[tileKey].push_back(make_pair(line, m2::SharedSpline(points))); + } - for (size_t layerIndex = 0; layerIndex < line->GetLayerCount(); ++layerIndex) + int const kBatchSize = 5000; + for (auto it = userLines.begin(); it != userLines.end(); ++it) + { + TileKey const & key = it->first; + dp::Batcher batcher(kBatchSize, kBatchSize); + dp::SessionGuard guard(batcher, [&key, &outShapes](dp::GLState const & state, + drape_ptr<dp::RenderBucket> && b) + { + outShapes.emplace_back(UserMarkShape(state, move(b), key)); + }); + for (auto const & lineData : it->second) { - LineViewParams params; - params.m_baseGtoPScale = 1.0f; - params.m_cap = dp::RoundCap; - params.m_join = dp::RoundJoin; - params.m_color = line->GetColor(layerIndex); - params.m_depth = line->GetLayerDepth(layerIndex); - params.m_width = line->GetWidth(layerIndex); - params.m_minVisibleScale = 1; - params.m_rank = 0; - - LineShape(spline, params).Draw(batcher, textures); + UserLineMark const * line = lineData.first; + for (size_t layerIndex = 0; layerIndex < line->GetLayerCount(); ++layerIndex) + { + LineViewParams params; + params.m_tileCenter = key.GetGlobalRect().Center(); + params.m_baseGtoPScale = 1.0f; + params.m_cap = dp::RoundCap; + params.m_join = dp::RoundJoin; + params.m_color = line->GetColor(layerIndex); + params.m_depth = line->GetLayerDepth(layerIndex); + params.m_width = line->GetWidth(layerIndex); + params.m_minVisibleScale = 1; + params.m_rank = 0; + + LineShape(lineData.second, params).Draw(make_ref(&batcher), textures); + } } } } } // namespace -void CacheUserMarks(UserMarksProvider const * provider, - ref_ptr<dp::Batcher> batcher, - ref_ptr<dp::TextureManager> textures) +TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, ref_ptr<dp::TextureManager> textures) { - CacheUserPoints(provider, batcher, textures); - CacheUserLines(provider, batcher, textures); + 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 361d6c86b3..bd0e35e1ff 100644 --- a/drape_frontend/user_mark_shapes.hpp +++ b/drape_frontend/user_mark_shapes.hpp @@ -12,12 +12,22 @@ namespace df { - TileKey GetSearchTileKey(); - TileKey GetApiTileKey(); - TileKey GetDebugTileKey(); - TileKey GetBookmarkTileKey(size_t categoryIndex); - bool IsUserMarkLayer(TileKey const & tileKey); - - void CacheUserMarks(UserMarksProvider const * provider, ref_ptr<dp::Batcher> batcher, - ref_ptr<dp::TextureManager> textures); + +struct UserMarkShape +{ + dp::GLState m_state; + drape_ptr<dp::RenderBucket> m_bucket; + TileKey m_tileKey; + + UserMarkShape(dp::GLState const & state, drape_ptr<dp::RenderBucket> && bucket, + TileKey const & tileKey) + : m_state(state), m_bucket(move(bucket)), m_tileKey(tileKey) + {} +}; + +using TUserMarkShapes = vector<UserMarkShape>; + +TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, + ref_ptr<dp::TextureManager> textures); + } // namespace df |