From b3752b5aacda9fb4b383ee2933467a7bd2f69cf6 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Tue, 6 Sep 2016 11:43:03 +0300 Subject: [PATCH] Added tile-based model view for user marks --- drape/batcher.cpp | 2 +- drape/shaders/user_mark.vsh | 6 +- drape_frontend/apply_feature_functors.cpp | 8 +- drape_frontend/apply_feature_functors.hpp | 4 +- drape_frontend/area_shape.cpp | 8 +- drape_frontend/backend_renderer.cpp | 11 +- drape_frontend/circle_shape.cpp | 2 +- drape_frontend/drape_engine.cpp | 12 +- drape_frontend/drape_engine.hpp | 6 +- drape_frontend/frontend_renderer.cpp | 73 +++++--- drape_frontend/frontend_renderer.hpp | 4 +- drape_frontend/gps_track_renderer.cpp | 6 +- drape_frontend/line_shape.cpp | 10 +- drape_frontend/map_shape.hpp | 2 +- drape_frontend/message.hpp | 1 + drape_frontend/message_subclasses.hpp | 51 ++++- drape_frontend/my_position.cpp | 4 +- drape_frontend/path_symbol_shape.cpp | 2 +- drape_frontend/poi_symbol_shape.cpp | 2 +- drape_frontend/render_group.cpp | 16 +- drape_frontend/render_group.hpp | 15 +- drape_frontend/route_shape.cpp | 16 +- drape_frontend/selection_shape.cpp | 2 +- drape_frontend/text_layout.cpp | 2 +- drape_frontend/text_shape.cpp | 4 +- drape_frontend/user_mark_shapes.cpp | 219 +++++++++++----------- drape_frontend/user_mark_shapes.hpp | 24 ++- geometry/screenbase.cpp | 11 +- map/bookmark.hpp | 2 +- map/bookmark_manager.cpp | 2 +- map/user_mark_container.cpp | 97 +++++----- 31 files changed, 346 insertions(+), 278 deletions(-) diff --git a/drape/batcher.cpp b/drape/batcher.cpp index 0153267db0..ea72fe4f88 100644 --- a/drape/batcher.cpp +++ b/drape/batcher.cpp @@ -262,7 +262,7 @@ Batcher * BatcherFactory::GetNew() const return new Batcher(kIndexBufferSize, kVertexBufferSize); } -SessionGuard::SessionGuard(Batcher & batcher, const Batcher::TFlushFn & flusher) +SessionGuard::SessionGuard(Batcher & batcher, Batcher::TFlushFn const & flusher) : m_batcher(batcher) { m_batcher.StartSession(flusher); diff --git a/drape/shaders/user_mark.vsh b/drape/shaders/user_mark.vsh index d5ab17330f..0fce199d47 100644 --- a/drape/shaders/user_mark.vsh +++ b/drape/shaders/user_mark.vsh @@ -16,10 +16,8 @@ void main(void) if (a_animate > 0.0) normal = u_interpolationT * normal; - // Here we intentionally decrease precision of 'pos' calculation - // to eliminate jittering effect in process of billboard reconstruction. - lowp vec4 p = vec4(a_position, 1) * modelView; - highp vec4 pos = vec4(normal, 0, 0) + p; + vec4 p = vec4(a_position, 1) * modelView; + vec4 pos = vec4(normal, 0, 0) + p; pos = pos * projection; float w = pos.w; pos.xyw = (pivotTransform * vec4(pos.xy, 0.0, w)).xyw; 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> 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 batcher, ref_ptr 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 batcher, ref_ptr 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 batcher, ref_ptr 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) case Message::UpdateUserMarkLayer: { ref_ptr 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(key), + make_unique_dp(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(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 batcher, ref_ptr 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 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(rect, isAnim)); } -void DrapeEngine::ClearUserMarksLayer(df::TileKey const & tileKey) +void DrapeEngine::ClearUserMarksLayer(size_t layerId) { m_threadCommutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(tileKey), + make_unique_dp(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(tileKey, isVisible), + make_unique_dp(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(tileKey, provider), + make_unique_dp(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 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) dp::GLState const & state = msg->GetState(); TileKey const & key = msg->GetKey(); drape_ptr 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 program = m_gpuProgramManager->GetProgram(state.GetProgramIndex()); - ref_ptr program3d = m_gpuProgramManager->GetProgram(state.GetProgram3dIndex()); - - m_userMarkRenderGroups.emplace_back(make_unique_dp(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) 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) break; } + case Message::FlushUserMarks: + { + ref_ptr 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(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(message)->GetKey(); - auto const functor = [&tileKey](drape_ptr const & g) + ref_ptr msg = message; + size_t const layerId = msg->GetLayerId(); + auto const functor = [&layerId](drape_ptr 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 m = message; - TileKey const & key = m->GetKey(); - if (m->IsVisible()) - m_userMarkVisibility.insert(key); + ref_ptr 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 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 & 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 m_layers; vector> m_userMarkRenderGroups; - set m_userMarkVisibility; + unordered_set m_userMarkVisibility; drape_ptr m_guiRenderer; drape_ptr 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(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 & 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 & 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 & 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 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 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 batcher, ref_ptr batcher, ref_ptrGetSymbolRegion(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 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 && 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 mv = screen.GetModelView(); - m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + // Set tile-based model-view matrix. + { + math::Matrix mv = GetTileKey().GetTileBasedModelView(screen); + m_uniforms.SetMatrix4x4Value("modelView", mv.m_data); + } ref_ptr 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 shader, ref_ptr shader3d, ref_ptr 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 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 && bucket); - ~UserMarkRenderGroup(); + ~UserMarkRenderGroup() override; void UpdateAnimation() override; void Render(ScreenBase const & screen) override; + size_t GetLayerId() const; + private: drape_ptr m_renderBucket; unique_ptr m_animation; ValueMapping 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 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 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 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" @@ -11,40 +14,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 { @@ -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 batcher, - ref_ptr textures) +void CacheUserPoints(UserMarksProvider const * provider, ref_ptr 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 buffer; - buffer.reserve(vertexCount); - - vector marks; - marks.reserve(markCount); + int const kZoomLevel = 10; + map> 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; - }); - - dp::TextureManager::SymbolRegion region; - for (size_t i = 0; i < marks.size(); ++i) - { - 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); + UserPointMark const * userMark = provider->GetUserPointMark(i); + TileKey const tileKey = GetTileKeyByPoint(userMark->GetPivot(), kZoomLevel); + marks[tileKey].push_back(userMark); } - dp::GLState state(gpu::BOOKMARK_PROGRAM, dp::GLState::UserMarkLayer); - state.SetProgram3dIndex(gpu::BOOKMARK_BILLBOARD_PROGRAM); - state.SetColorTexture(region.GetTexture()); + for (auto it = marks.begin(); it != marks.end(); ++it) + { + TileKey const & key = it->first; + m2::PointD const tileCenter = key.GetGlobalRect().Center(); - dp::AttributeProvider attribProvider(1, buffer.size()); - attribProvider.InitStream(0, UPV::GetBinding(), make_ref(buffer.data())); + sort(it->second.begin(), it->second.end(), [](UserPointMark const * v1, UserPointMark const * v2) + { + return v1->GetPivot().y < v2->GetPivot().y; + }); - batcher->InsertListOfStrip(state, make_ref(&attribProvider), dp::Batcher::VertexPerQuad); + 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); + + dp::Batcher batcher(indicesCount, vertexCount); + 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, 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 batcher, - ref_ptr textures) +void CacheUserLines(UserMarksProvider const * provider, ref_ptr textures, + TUserMarkShapes & outShapes) { + int const kZoomLevel = 10; + map>> 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 points; + m2::RectD rect; points.reserve(pointCount); for (size_t i = 0; i < pointCount; ++i) - points.push_back(line->GetPoint(i)); - - m2::SharedSpline spline(points); - - for (size_t layerIndex = 0; layerIndex < line->GetLayerCount(); ++layerIndex) { - 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; + points.push_back(line->GetPoint(i)); + rect.Add(points.back()); + } - LineShape(spline, params).Draw(batcher, textures); + TileKey const tileKey = GetTileKeyByPoint(rect.Center(), kZoomLevel); + userLines[tileKey].push_back(make_pair(line, m2::SharedSpline(points))); + } + + 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 && b) + { + outShapes.emplace_back(UserMarkShape(state, move(b), key)); + }); + for (auto const & lineData : it->second) + { + 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 batcher, - ref_ptr textures) +TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, ref_ptr 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 batcher, - ref_ptr textures); +struct UserMarkShape +{ + 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; + +TUserMarkShapes CacheUserMarks(UserMarksProvider const * provider, + ref_ptr textures); + } // namespace df diff --git a/geometry/screenbase.cpp b/geometry/screenbase.cpp index be334dbdf3..a052b87c4d 100644 --- a/geometry/screenbase.cpp +++ b/geometry/screenbase.cpp @@ -512,10 +512,13 @@ bool ScreenBase::IsReverseProjection3d(m2::PointD const & pt) const ScreenBase::Matrix3dT ScreenBase::GetModelView() const { - return ScreenBase::Matrix3dT { m_GtoP(0, 0), m_GtoP(1, 0), 0, m_GtoP(2, 0), - m_GtoP(0, 1), m_GtoP(1, 1), 0, m_GtoP(2, 1), - 0, 0, 1, 0, - 0, 0, 0, 1 }; + return ScreenBase::Matrix3dT + { + m_GtoP(0, 0), m_GtoP(1, 0), 0, m_GtoP(2, 0), + m_GtoP(0, 1), m_GtoP(1, 1), 0, m_GtoP(2, 1), + 0, 0, 1, 0, + 0, 0, 0, 1 + }; } ScreenBase::Matrix3dT ScreenBase::GetModelView(m2::PointD const & pivot, double scalar) const diff --git a/map/bookmark.hpp b/map/bookmark.hpp index 6d5f8362c5..60c9242eae 100644 --- a/map/bookmark.hpp +++ b/map/bookmark.hpp @@ -136,7 +136,7 @@ public: }; BookmarkCategory(string const & name, Framework & framework); - ~BookmarkCategory(); + ~BookmarkCategory() override; size_t GetUserLineCount() const override; df::UserLineMark const * GetUserLineMark(size_t index) const override; diff --git a/map/bookmark_manager.cpp b/map/bookmark_manager.cpp index dd013cd7e3..fa50285751 100644 --- a/map/bookmark_manager.cpp +++ b/map/bookmark_manager.cpp @@ -148,7 +148,7 @@ size_t BookmarkManager::LastEditedBMCategory() } if (m_categories.empty()) - m_categories.push_back(new BookmarkCategory(m_framework.GetStringsBundle().GetString("my_places"), m_framework)); + CreateBmCategory(m_framework.GetStringsBundle().GetString("my_places")); return 0; } diff --git a/map/user_mark_container.cpp b/map/user_mark_container.cpp index 198aeb6e57..401a435994 100644 --- a/map/user_mark_container.cpp +++ b/map/user_mark_container.cpp @@ -13,59 +13,48 @@ namespace { - class FindMarkFunctor + +class FindMarkFunctor +{ +public: + FindMarkFunctor(UserMark ** mark, double & minD, m2::AnyRectD const & rect) + : m_mark(mark) + , m_minD(minD) + , m_rect(rect) { - public: - FindMarkFunctor(UserMark ** mark, double & minD, m2::AnyRectD const & rect) - : m_mark(mark) - , m_minD(minD) - , m_rect(rect) - { - m_globalCenter = rect.GlobalCenter(); - } - - void operator()(UserMark * mark) - { - m2::PointD const & org = mark->GetPivot(); - if (m_rect.IsPointInside(org)) - { - double minDCandidate = m_globalCenter.SquareLength(org); - if (minDCandidate < m_minD) - { - *m_mark = mark; - m_minD = minDCandidate; - } - } - } - - UserMark ** m_mark; - double & m_minD; - m2::AnyRectD const & m_rect; - m2::PointD m_globalCenter; - }; - - df::TileKey CreateTileKey(UserMarkContainer const * cont) - { - switch (cont->GetType()) - { - case UserMarkType::API_MARK: - return df::GetApiTileKey(); - case UserMarkType::SEARCH_MARK: - return df::GetSearchTileKey(); - case UserMarkType::BOOKMARK_MARK: - return df::GetBookmarkTileKey(reinterpret_cast(cont)); - case UserMarkType::DEBUG_MARK: - return df::GetDebugTileKey(); - } - - ASSERT(false, ()); - return df::TileKey(); + m_globalCenter = rect.GlobalCenter(); } - size_t const VisibleFlag = 0; - size_t const DrawableFlag = 1; + void operator()(UserMark * mark) + { + m2::PointD const & org = mark->GetPivot(); + if (m_rect.IsPointInside(org)) + { + double minDCandidate = m_globalCenter.SquareLength(org); + if (minDCandidate < m_minD) + { + *m_mark = mark; + m_minD = minDCandidate; + } + } + } + + UserMark ** m_mark; + double & m_minD; + m2::AnyRectD const & m_rect; + m2::PointD m_globalCenter; +}; + +size_t const VisibleFlag = 0; +size_t const DrawableFlag = 1; + +size_t GenerateLayerId(UserMarkContainer const * cont) +{ + return reinterpret_cast(cont); } +} // namespace + UserMarkContainer::UserMarkContainer(double layerDepth, UserMarkType type, Framework & fm) : m_framework(fm) , m_layerDepth(layerDepth) @@ -97,9 +86,11 @@ UserMark const * UserMarkContainer::FindMarkInRect(m2::AnyRectD const & rect, do namespace { + unique_ptr g_selectionUserMark; unique_ptr g_myPosition; -} + +} // namespace void UserMarkContainer::InitStaticMarks(UserMarkContainer * container) { @@ -135,15 +126,15 @@ void UserMarkContainer::ReleaseController() if (engine == nullptr) return; - df::TileKey key = CreateTileKey(this); - engine->ChangeVisibilityUserMarksLayer(key, IsVisible() && IsDrawable()); + size_t const layerId = GenerateLayerId(this); + engine->ChangeVisibilityUserMarksLayer(layerId, IsVisible() && IsDrawable()); if (IsDirty()) { if (GetUserPointCount() == 0 && GetUserLineCount() == 0) - engine->ClearUserMarksLayer(key); + engine->ClearUserMarksLayer(layerId); else - engine->UpdateUserMarksLayer(key, this); + engine->UpdateUserMarksLayer(layerId, this); } }