Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorr.kuznetsov <r.kuznetsov@corp.mail.ru>2016-09-06 11:43:03 +0300
committerr.kuznetsov <r.kuznetsov@corp.mail.ru>2016-09-06 15:12:30 +0300
commitb3752b5aacda9fb4b383ee2933467a7bd2f69cf6 (patch)
tree391789097e2cf38668df3633b6016f1f5f6170c3 /drape_frontend
parentfeda627f30fd97b62f904c43ca3c8f3f1e608ca0 (diff)
Added tile-based model view for user marks
Diffstat (limited to 'drape_frontend')
-rw-r--r--drape_frontend/apply_feature_functors.cpp8
-rw-r--r--drape_frontend/apply_feature_functors.hpp4
-rw-r--r--drape_frontend/area_shape.cpp8
-rw-r--r--drape_frontend/backend_renderer.cpp11
-rw-r--r--drape_frontend/circle_shape.cpp2
-rw-r--r--drape_frontend/drape_engine.cpp12
-rw-r--r--drape_frontend/drape_engine.hpp6
-rwxr-xr-xdrape_frontend/frontend_renderer.cpp73
-rwxr-xr-xdrape_frontend/frontend_renderer.hpp4
-rw-r--r--drape_frontend/gps_track_renderer.cpp6
-rw-r--r--drape_frontend/line_shape.cpp10
-rw-r--r--drape_frontend/map_shape.hpp2
-rw-r--r--drape_frontend/message.hpp1
-rw-r--r--drape_frontend/message_subclasses.hpp51
-rw-r--r--drape_frontend/my_position.cpp4
-rw-r--r--drape_frontend/path_symbol_shape.cpp2
-rw-r--r--drape_frontend/poi_symbol_shape.cpp2
-rwxr-xr-xdrape_frontend/render_group.cpp16
-rwxr-xr-xdrape_frontend/render_group.hpp15
-rw-r--r--drape_frontend/route_shape.cpp16
-rw-r--r--drape_frontend/selection_shape.cpp2
-rw-r--r--drape_frontend/text_layout.cpp2
-rw-r--r--drape_frontend/text_shape.cpp4
-rw-r--r--drape_frontend/user_mark_shapes.cpp213
-rw-r--r--drape_frontend/user_mark_shapes.hpp26
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