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:
authorDaria Volvenkova <d.volvenkova@corp.mail.ru>2016-11-23 13:41:12 +0300
committerGitHub <noreply@github.com>2016-11-23 13:41:12 +0300
commitf36a01accc04908c2bbb6191f3e0c568f984f1f5 (patch)
tree45afa7c24566bec29780437c018fabcdf96958de
parentcb0cf73fc272ac9f94f152b7c7fca145ad7bd32f (diff)
parentb1b87d7561e1870b38c91853cab7cbdc218548c7 (diff)
Merge pull request #4778 from rokuz/traffic-improve-rendering
Improved traffic rendering
-rw-r--r--drape/batcher.cpp4
-rw-r--r--drape/batcher.hpp9
-rw-r--r--drape/shaders/traffic_fragment_shader.fsh9
-rw-r--r--drape_frontend/apply_feature_functors.cpp5
-rw-r--r--drape_frontend/apply_feature_functors.hpp3
-rw-r--r--drape_frontend/backend_renderer.cpp48
-rw-r--r--drape_frontend/backend_renderer.hpp5
-rw-r--r--drape_frontend/batchers_pool.hpp5
-rw-r--r--drape_frontend/drape_engine.cpp10
-rw-r--r--drape_frontend/drape_engine.hpp5
-rw-r--r--drape_frontend/engine_context.cpp5
-rw-r--r--drape_frontend/engine_context.hpp2
-rwxr-xr-xdrape_frontend/frontend_renderer.cpp21
-rw-r--r--drape_frontend/message.hpp3
-rw-r--r--drape_frontend/message_subclasses.hpp36
-rwxr-xr-xdrape_frontend/read_manager.cpp14
-rwxr-xr-xdrape_frontend/read_manager.hpp6
-rw-r--r--drape_frontend/rule_drawer.cpp67
-rw-r--r--drape_frontend/rule_drawer.hpp7
-rw-r--r--drape_frontend/tile_info.cpp3
-rw-r--r--drape_frontend/tile_info.hpp4
-rw-r--r--drape_frontend/traffic_generator.cpp197
-rw-r--r--drape_frontend/traffic_generator.hpp76
-rw-r--r--drape_frontend/traffic_renderer.cpp156
-rw-r--r--drape_frontend/traffic_renderer.hpp7
-rw-r--r--geometry/polyline2d.hpp2
-rw-r--r--map/framework.cpp20
-rw-r--r--map/framework.hpp3
-rw-r--r--map/traffic_manager.cpp89
-rw-r--r--map/traffic_manager.hpp9
30 files changed, 537 insertions, 293 deletions
diff --git a/drape/batcher.cpp b/drape/batcher.cpp
index c8bc1b548a..1f4cdc1ea9 100644
--- a/drape/batcher.cpp
+++ b/drape/batcher.cpp
@@ -283,9 +283,7 @@ IndicesRange Batcher::InsertPrimitives(GLState const & state, ref_ptr<AttributeP
Batcher * BatcherFactory::GetNew() const
{
- uint32_t const kIndexBufferSize = 5000;
- uint32_t const kVertexBufferSize = 5000;
- return new Batcher(kIndexBufferSize, kVertexBufferSize);
+ return new Batcher(m_indexBufferSize, m_vertexBufferSize);
}
SessionGuard::SessionGuard(Batcher & batcher, Batcher::TFlushFn const & flusher)
diff --git a/drape/batcher.hpp b/drape/batcher.hpp
index ca5f30f6a0..18eeac31d6 100644
--- a/drape/batcher.hpp
+++ b/drape/batcher.hpp
@@ -87,7 +87,16 @@ private:
class BatcherFactory
{
public:
+ BatcherFactory(uint32_t indexBufferSize, uint32_t vertexBufferSize)
+ : m_indexBufferSize(indexBufferSize)
+ , m_vertexBufferSize(vertexBufferSize)
+ {}
+
Batcher * GetNew() const;
+
+private:
+ uint32_t const m_indexBufferSize;
+ uint32_t const m_vertexBufferSize;
};
class SessionGuard
diff --git a/drape/shaders/traffic_fragment_shader.fsh b/drape/shaders/traffic_fragment_shader.fsh
index e7d10f0e9d..f432f86b62 100644
--- a/drape/shaders/traffic_fragment_shader.fsh
+++ b/drape/shaders/traffic_fragment_shader.fsh
@@ -5,9 +5,13 @@ varying float v_halfLength;
uniform sampler2D u_colorTex;
uniform sampler2D u_maskTex;
uniform float u_opacity;
+uniform float u_outline;
const float kAntialiasingThreshold = 0.92;
+const float kOutlineThreshold1 = 0.8;
+const float kOutlineThreshold2 = 0.5;
+
const vec3 kLightArrow = vec3(1.0, 1.0, 1.0);
const vec3 kDarkArrow = vec3(107.0 / 255.0, 81.0 / 255.0, 20.0 / 255.0);
@@ -20,6 +24,11 @@ void main(void)
vec4 mask = texture2D(u_maskTex, v_maskTexCoord);
color.a = u_opacity * (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(v_halfLength)));
color.rgb = mix(color.rgb, mask.rgb * mix(kLightArrow, kDarkArrow, step(alphaCode, 0.6)), mask.a);
+ if (u_outline > 0.0)
+ {
+ color.rgb = mix(color.rgb, vec3(1.0, 1.0, 1.0), step(kOutlineThreshold1, abs(v_halfLength)));
+ color.rgb = mix(color.rgb, vec3(1.0, 1.0, 1.0), smoothstep(kOutlineThreshold2, kOutlineThreshold1, abs(v_halfLength)));
+ }
gl_FragColor = color;
}
else
diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp
index 74688951a0..802a6b874a 100644
--- a/drape_frontend/apply_feature_functors.cpp
+++ b/drape_frontend/apply_feature_functors.cpp
@@ -802,4 +802,9 @@ void ApplyLineFeature::Finish()
}
}
+m2::PolylineD ApplyLineFeature::GetPolyline() const
+{
+ return HasGeometry() ? m2::PolylineD(m_spline->GetPath()) : m2::PolylineD();
+}
+
} // namespace df
diff --git a/drape_frontend/apply_feature_functors.hpp b/drape_frontend/apply_feature_functors.hpp
index a88792e0e4..b52b20fe9d 100644
--- a/drape_frontend/apply_feature_functors.hpp
+++ b/drape_frontend/apply_feature_functors.hpp
@@ -9,6 +9,7 @@
#include "indexer/point_to_int64.hpp"
#include "geometry/point2d.hpp"
+#include "geometry/polyline2d.hpp"
#include "geometry/spline.hpp"
#include "std/unordered_map.hpp"
@@ -144,6 +145,8 @@ public:
void ProcessRule(Stylist::TRuleWrapper const & rule);
void Finish();
+ m2::PolylineD GetPolyline() const;
+
private:
m2::SharedSpline m_spline;
vector<m2::SharedSpline> m_clippedSplines;
diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp
index d81d0c3bac..c3e187c372 100644
--- a/drape_frontend/backend_renderer.cpp
+++ b/drape_frontend/backend_renderer.cpp
@@ -27,7 +27,8 @@ namespace df
BackendRenderer::BackendRenderer(Params const & params)
: BaseRenderer(ThreadsCommutator::ResourceUploadThread, params)
, m_model(params.m_model)
- , m_readManager(make_unique_dp<ReadManager>(params.m_commutator, m_model, params.m_allow3dBuildings))
+ , m_readManager(make_unique_dp<ReadManager>(params.m_commutator, m_model,
+ params.m_allow3dBuildings, params.m_trafficEnabled))
, m_trafficGenerator(make_unique_dp<TrafficGenerator>(bind(&BackendRenderer::FlushTrafficRenderData, this, _1)))
, m_requestedTiles(params.m_requestedTiles)
, m_updateCurrentCountryFn(params.m_updateCurrentCountryFn)
@@ -331,37 +332,38 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
break;
}
- case Message::CacheTrafficSegments:
+ case Message::EnableTraffic:
{
- ref_ptr<CacheTrafficSegmentsMessage> msg = message;
- for (auto const & segment : msg->GetSegments())
- m_trafficGenerator->AddSegment(segment.first, segment.second);
+ ref_ptr<EnableTrafficMessage> msg = message;
+ m_readManager->SetTrafficEnabled(msg->IsTrafficEnabled());
+ m_commutator->PostMessage(ThreadsCommutator::RenderThread,
+ make_unique_dp<EnableTrafficMessage>(msg->IsTrafficEnabled()),
+ MessagePriority::Normal);
+ break;
+ }
+
+ case Message::FlushTrafficGeometry:
+ {
+ ref_ptr<FlushTrafficGeometryMessage> msg = message;
+ m_trafficGenerator->FlushSegmentsGeometry(msg->GetKey(), msg->GetSegments(), m_texMng);
break;
}
case Message::UpdateTraffic:
{
ref_ptr<UpdateTrafficMessage> msg = message;
- auto segments = m_trafficGenerator->GetSegmentsToUpdate(msg->GetSegmentsColoring());
- if (!segments.empty())
+ bool const needInvalidate = m_trafficGenerator->UpdateColoring(msg->GetSegmentsColoring());
+ if (m_trafficGenerator->IsColorsCacheRefreshed())
{
+ auto texCoords = m_trafficGenerator->ProcessCacheRefreshing();
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
- make_unique_dp<UpdateTrafficMessage>(segments),
+ make_unique_dp<SetTrafficTexCoordsMessage>(move(texCoords)),
MessagePriority::Normal);
}
-
- if (segments.size() < msg->GetSegmentsColoring().size())
- {
- m_trafficGenerator->GetTrafficGeom(m_texMng, msg->GetSegmentsColoring());
-
- if (m_trafficGenerator->IsColorsCacheRefreshed())
- {
- auto texCoords = m_trafficGenerator->ProcessCacheRefreshing();
- m_commutator->PostMessage(ThreadsCommutator::RenderThread,
- make_unique_dp<SetTrafficTexCoordsMessage>(move(texCoords)),
- MessagePriority::Normal);
- }
- }
+ m_commutator->PostMessage(ThreadsCommutator::RenderThread,
+ make_unique_dp<UpdateTrafficMessage>(move(msg->GetSegmentsColoring()),
+ needInvalidate),
+ MessagePriority::Normal);
break;
}
case Message::ClearTrafficData:
@@ -456,8 +458,10 @@ void BackendRenderer::Routine::Do()
void BackendRenderer::InitGLDependentResource()
{
+ int constexpr kBatchSize = 5000;
m_batchersPool = make_unique_dp<BatchersPool<TileKey, TileKeyStrictComparator>>(ReadManager::ReadCount(),
- bind(&BackendRenderer::FlushGeometry, this, _1, _2, _3));
+ bind(&BackendRenderer::FlushGeometry, this, _1, _2, _3),
+ kBatchSize, kBatchSize);
m_trafficGenerator->Init();
dp::TextureManager::Params params;
diff --git a/drape_frontend/backend_renderer.hpp b/drape_frontend/backend_renderer.hpp
index 6f8f08796e..15d138e0a3 100644
--- a/drape_frontend/backend_renderer.hpp
+++ b/drape_frontend/backend_renderer.hpp
@@ -38,18 +38,21 @@ public:
Params(ref_ptr<ThreadsCommutator> commutator, ref_ptr<dp::OGLContextFactory> factory,
ref_ptr<dp::TextureManager> texMng, MapDataProvider const & model,
TUpdateCurrentCountryFn const & updateCurrentCountryFn,
- ref_ptr<RequestedTiles> requestedTiles, bool allow3dBuildings)
+ ref_ptr<RequestedTiles> requestedTiles, bool allow3dBuildings,
+ bool trafficEnabled)
: BaseRenderer::Params(commutator, factory, texMng)
, m_model(model)
, m_updateCurrentCountryFn(updateCurrentCountryFn)
, m_requestedTiles(requestedTiles)
, m_allow3dBuildings(allow3dBuildings)
+ , m_trafficEnabled(trafficEnabled)
{}
MapDataProvider const & m_model;
TUpdateCurrentCountryFn m_updateCurrentCountryFn;
ref_ptr<RequestedTiles> m_requestedTiles;
bool m_allow3dBuildings;
+ bool m_trafficEnabled;
};
BackendRenderer(Params const & params);
diff --git a/drape_frontend/batchers_pool.hpp b/drape_frontend/batchers_pool.hpp
index d9586b46bf..8b14fb09fe 100644
--- a/drape_frontend/batchers_pool.hpp
+++ b/drape_frontend/batchers_pool.hpp
@@ -19,9 +19,10 @@ class BatchersPool
public:
using TFlushFn = function<void (TKey const & key, dp::GLState const & state, drape_ptr<dp::RenderBucket> && buffer)>;
- BatchersPool(int initBatchersCount, TFlushFn const & flushFn)
+ BatchersPool(int initBatchersCount, TFlushFn const & flushFn,
+ uint32_t indexBufferSize, uint32_t vertexBufferSize)
: m_flushFn(flushFn)
- , m_pool(initBatchersCount, dp::BatcherFactory())
+ , m_pool(initBatchersCount, dp::BatcherFactory(indexBufferSize, vertexBufferSize))
{}
~BatchersPool()
diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp
index 782bfcc390..d81085387e 100644
--- a/drape_frontend/drape_engine.cpp
+++ b/drape_frontend/drape_engine.cpp
@@ -71,7 +71,8 @@ DrapeEngine::DrapeEngine(Params && params)
BackendRenderer::Params brParams(frParams.m_commutator, frParams.m_oglContextFactory,
frParams.m_texMng, params.m_model,
params.m_model.UpdateCurrentCountryFn(),
- make_ref(m_requestedTiles), params.m_allow3dBuildings);
+ make_ref(m_requestedTiles), params.m_allow3dBuildings,
+ params.m_trafficEnabled);
m_backend = make_unique_dp<BackendRenderer>(brParams);
m_widgetsInfo = move(params.m_info);
@@ -533,13 +534,10 @@ void DrapeEngine::RequestSymbolsSize(vector<string> const & symbols,
MessagePriority::Normal);
}
-void DrapeEngine::CacheTrafficSegmentsGeometry(TrafficSegmentsGeometry const & segments)
+void DrapeEngine::EnableTraffic(bool trafficEnabled)
{
- if (segments.empty())
- return;
-
m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
- make_unique_dp<CacheTrafficSegmentsMessage>(segments),
+ make_unique_dp<EnableTrafficMessage>(trafficEnabled),
MessagePriority::Normal);
}
diff --git a/drape_frontend/drape_engine.hpp b/drape_frontend/drape_engine.hpp
index 00d5445224..ec90aea5f5 100644
--- a/drape_frontend/drape_engine.hpp
+++ b/drape_frontend/drape_engine.hpp
@@ -44,6 +44,7 @@ public:
gui::TWidgetsInitInfo && info,
pair<location::EMyPositionMode, bool> const & initialMyPositionMode,
bool allow3dBuildings,
+ bool trafficEnabled,
bool blockTapEvents,
bool showChoosePositionMark,
vector<m2::TriangleD> && boundAreaTriangles,
@@ -58,6 +59,7 @@ public:
, m_info(move(info))
, m_initialMyPositionMode(initialMyPositionMode)
, m_allow3dBuildings(allow3dBuildings)
+ , m_trafficEnabled(trafficEnabled)
, m_blockTapEvents(blockTapEvents)
, m_showChoosePositionMark(showChoosePositionMark)
, m_boundAreaTriangles(move(boundAreaTriangles))
@@ -74,6 +76,7 @@ public:
gui::TWidgetsInitInfo m_info;
pair<location::EMyPositionMode, bool> m_initialMyPositionMode;
bool m_allow3dBuildings;
+ bool m_trafficEnabled;
bool m_blockTapEvents;
bool m_showChoosePositionMark;
vector<m2::TriangleD> m_boundAreaTriangles;
@@ -162,7 +165,7 @@ public:
void RequestSymbolsSize(vector<string> const & symbols,
TRequestSymbolsSizeCallback const & callback);
- void CacheTrafficSegmentsGeometry(TrafficSegmentsGeometry const & segments);
+ void EnableTraffic(bool trafficEnabled);
void UpdateTraffic(TrafficSegmentsColoring const & segmentsColoring);
void ClearTrafficCache(MwmSet::MwmId const & mwmId);
diff --git a/drape_frontend/engine_context.cpp b/drape_frontend/engine_context.cpp
index 3f6ac8cc97..ff864cf128 100644
--- a/drape_frontend/engine_context.cpp
+++ b/drape_frontend/engine_context.cpp
@@ -35,6 +35,11 @@ void EngineContext::FlushOverlays(TMapShapes && shapes)
PostMessage(make_unique_dp<OverlayMapShapeReadedMessage>(m_tileKey, move(shapes)));
}
+void EngineContext::FlushTrafficGeometry(TrafficSegmentsGeometry && geometry)
+{
+ PostMessage(make_unique_dp<FlushTrafficGeometryMessage>(m_tileKey, move(geometry)));
+}
+
void EngineContext::EndReadTile()
{
PostMessage(make_unique_dp<TileReadEndMessage>(m_tileKey));
diff --git a/drape_frontend/engine_context.hpp b/drape_frontend/engine_context.hpp
index 54a66dd12c..febfc6189a 100644
--- a/drape_frontend/engine_context.hpp
+++ b/drape_frontend/engine_context.hpp
@@ -3,6 +3,7 @@
#include "drape_frontend/map_shape.hpp"
#include "drape_frontend/tile_utils.hpp"
#include "drape_frontend/threads_commutator.hpp"
+#include "drape_frontend/traffic_generator.hpp"
#include "drape/pointers.hpp"
@@ -29,6 +30,7 @@ public:
void BeginReadTile();
void Flush(TMapShapes && shapes);
void FlushOverlays(TMapShapes && shapes);
+ void FlushTrafficGeometry(TrafficSegmentsGeometry && geometry);
void EndReadTile();
private:
diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp
index fa99a26b2c..b7b9bdd8de 100755
--- a/drape_frontend/frontend_renderer.cpp
+++ b/drape_frontend/frontend_renderer.cpp
@@ -290,9 +290,11 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
}
}
}
-
if (changed)
UpdateCanBeDeletedStatus();
+
+ if (m_notFinishedTiles.empty())
+ m_trafficRenderer->OnGeometryReady(m_currentZoomLevel);
break;
}
@@ -739,10 +741,23 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
break;
}
+ case Message::EnableTraffic:
+ {
+ ref_ptr<EnableTrafficMessage> msg = message;
+ if (msg->IsTrafficEnabled())
+ InvalidateRect(m_userEventStream.GetCurrentScreen().ClipRect());
+ else
+ m_trafficRenderer->ClearGLDependentResources();
+ break;
+ }
+
case Message::UpdateTraffic:
{
ref_ptr<UpdateTrafficMessage> msg = message;
- m_trafficRenderer->UpdateTraffic(msg->GetSegmentsColoring());
+ if (msg->NeedInvalidate())
+ InvalidateRect(m_userEventStream.GetCurrentScreen().ClipRect());
+ else
+ m_trafficRenderer->UpdateTraffic(msg->GetSegmentsColoring());
break;
}
@@ -1584,6 +1599,8 @@ TTilesCollection FrontendRenderer::ResolveTileKeys(ScreenBase const & screen)
return group->GetTileKey().m_zoomLevel != m_currentZoomLevel;
});
+ m_trafficRenderer->OnUpdateViewport(result, m_currentZoomLevel, tilesToDelete);
+
return tiles;
}
diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp
index 6c9cd7a07c..19d4850a08 100644
--- a/drape_frontend/message.hpp
+++ b/drape_frontend/message.hpp
@@ -65,7 +65,8 @@ public:
RequestSymbolsSize,
RecoverGLResources,
SetVisibleViewport,
- CacheTrafficSegments,
+ EnableTraffic,
+ FlushTrafficGeometry,
SetTrafficTexCoords,
UpdateTraffic,
FlushTrafficData,
diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp
index 3ac7db418c..c460b16c6e 100644
--- a/drape_frontend/message_subclasses.hpp
+++ b/drape_frontend/message_subclasses.hpp
@@ -996,16 +996,32 @@ private:
TRequestSymbolsSizeCallback m_callback;
};
-class CacheTrafficSegmentsMessage : public Message
+class EnableTrafficMessage : public Message
{
public:
- explicit CacheTrafficSegmentsMessage(TrafficSegmentsGeometry const & segments)
- : m_segments(segments)
+ explicit EnableTrafficMessage(bool trafficEnabled)
+ : m_trafficEnabled(trafficEnabled)
{}
- Type GetType() const override { return Message::CacheTrafficSegments; }
+ Type GetType() const override { return Message::EnableTraffic; }
- TrafficSegmentsGeometry const & GetSegments() const { return m_segments; }
+ bool IsTrafficEnabled() const { return m_trafficEnabled; }
+
+private:
+ bool const m_trafficEnabled;
+};
+
+class FlushTrafficGeometryMessage : public BaseTileMessage
+{
+public:
+ FlushTrafficGeometryMessage(TileKey const & tileKey, TrafficSegmentsGeometry && segments)
+ : BaseTileMessage(tileKey)
+ , m_segments(move(segments))
+ {}
+
+ Type GetType() const override { return Message::FlushTrafficGeometry; }
+
+ TrafficSegmentsGeometry & GetSegments() { return m_segments; }
private:
TrafficSegmentsGeometry m_segments;
@@ -1032,15 +1048,23 @@ class UpdateTrafficMessage : public Message
public:
explicit UpdateTrafficMessage(TrafficSegmentsColoring const & segmentsColoring)
: m_segmentsColoring(segmentsColoring)
+ , m_needInvalidate(false)
+ {}
+
+ UpdateTrafficMessage(TrafficSegmentsColoring && segmentsColoring, bool needInvalidate)
+ : m_segmentsColoring(move(segmentsColoring))
+ , m_needInvalidate(needInvalidate)
{}
Type GetType() const override { return Message::UpdateTraffic; }
bool IsGLContextDependent() const override { return true; }
- TrafficSegmentsColoring const & GetSegmentsColoring() const { return m_segmentsColoring; }
+ TrafficSegmentsColoring & GetSegmentsColoring() { return m_segmentsColoring; }
+ bool NeedInvalidate() const { return m_needInvalidate; }
private:
TrafficSegmentsColoring m_segmentsColoring;
+ bool const m_needInvalidate;
};
class FlushTrafficDataMessage : public Message
diff --git a/drape_frontend/read_manager.cpp b/drape_frontend/read_manager.cpp
index e8a50861e6..a8fcae7570 100755
--- a/drape_frontend/read_manager.cpp
+++ b/drape_frontend/read_manager.cpp
@@ -36,12 +36,14 @@ struct LessCoverageCell
} // namespace
-ReadManager::ReadManager(ref_ptr<ThreadsCommutator> commutator, MapDataProvider & model, bool allow3dBuildings)
+ReadManager::ReadManager(ref_ptr<ThreadsCommutator> commutator, MapDataProvider & model,
+ bool allow3dBuildings, bool trafficEnabled)
: m_commutator(commutator)
, m_model(model)
, m_pool(make_unique_dp<threads::ThreadPool>(ReadCount(), bind(&ReadManager::OnTaskFinished, this, _1)))
, m_have3dBuildings(false)
, m_allow3dBuildings(allow3dBuildings)
+ , m_trafficEnabled(trafficEnabled)
, m_modeChanged(false)
, myPool(64, ReadMWMTaskFactory(m_model))
, m_counter(0)
@@ -202,6 +204,7 @@ void ReadManager::PushTaskBackForTileKey(TileKey const & tileKey, ref_ptr<dp::Te
shared_ptr<TileInfo> tileInfo(new TileInfo(make_unique_dp<EngineContext>(TileKey(tileKey, m_generationCounter),
m_commutator, texMng)));
tileInfo->Set3dBuildings(m_have3dBuildings && m_allow3dBuildings);
+ tileInfo->SetTrafficEnabled(m_trafficEnabled);
m_tileInfos.insert(tileInfo);
ReadMWMTask * task = myPool.Get();
@@ -267,4 +270,13 @@ void ReadManager::Allow3dBuildings(bool allow3dBuildings)
}
}
+void ReadManager::SetTrafficEnabled(bool trafficEnabled)
+{
+ if (m_trafficEnabled != trafficEnabled)
+ {
+ m_modeChanged = true;
+ m_trafficEnabled = trafficEnabled;
+ }
+}
+
} // namespace df
diff --git a/drape_frontend/read_manager.hpp b/drape_frontend/read_manager.hpp
index 22eb7119da..b4ea123851 100755
--- a/drape_frontend/read_manager.hpp
+++ b/drape_frontend/read_manager.hpp
@@ -27,7 +27,8 @@ class CoverageUpdateDescriptor;
class ReadManager
{
public:
- ReadManager(ref_ptr<ThreadsCommutator> commutator, MapDataProvider & model, bool allow3dBuildings);
+ ReadManager(ref_ptr<ThreadsCommutator> commutator, MapDataProvider & model,
+ bool allow3dBuildings, bool trafficEnabled);
void UpdateCoverage(ScreenBase const & screen, bool have3dBuildings,
TTilesCollection const & tiles, ref_ptr<dp::TextureManager> texMng);
@@ -38,6 +39,8 @@ public:
bool CheckTileKey(TileKey const & tileKey) const;
void Allow3dBuildings(bool allow3dBuildings);
+ void SetTrafficEnabled(bool trafficEnabled);
+
static size_t ReadCount();
private:
@@ -56,6 +59,7 @@ private:
ScreenBase m_currentViewport;
bool m_have3dBuildings;
bool m_allow3dBuildings;
+ bool m_trafficEnabled;
bool m_modeChanged;
struct LessByTileInfo
diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp
index ce9fa8fe10..3ada0a3f72 100644
--- a/drape_frontend/rule_drawer.cpp
+++ b/drape_frontend/rule_drawer.cpp
@@ -1,7 +1,8 @@
#include "drape_frontend/rule_drawer.hpp"
-#include "drape_frontend/stylist.hpp"
-#include "drape_frontend/engine_context.hpp"
+
#include "drape_frontend/apply_feature_functors.hpp"
+#include "drape_frontend/engine_context.hpp"
+#include "drape_frontend/stylist.hpp"
#include "drape_frontend/visual_params.hpp"
#include "indexer/feature.hpp"
@@ -24,8 +25,8 @@
#include "base/string_utils.hpp"
#endif
-namespace {
-
+namespace
+{
df::BaseApplyFeature::HotelData ExtractHotelData(FeatureType const & f)
{
df::BaseApplyFeature::HotelData result;
@@ -39,7 +40,29 @@ df::BaseApplyFeature::HotelData ExtractHotelData(FeatureType const & f)
return result;
}
-} // namespace
+void ExtractTrafficGeometry(FeatureType const & f, df::RoadClass const & roadClass, m2::PolylineD const & polyline,
+ df::TrafficSegmentsGeometry & geometry)
+{
+ df::TrafficSegmentsGeometry output;
+ if (polyline.GetSize() < 2)
+ return;
+
+ static vector<uint8_t> directions = {traffic::TrafficInfo::RoadSegmentId::kForwardDirection,
+ traffic::TrafficInfo::RoadSegmentId::kReverseDirection};
+ auto & segments = geometry[f.GetID().m_mwmId];
+ segments.reserve(segments.size() + directions.size() * (polyline.GetSize() - 1));
+ for (uint16_t segmentIndex = 0; segmentIndex + 1 < static_cast<uint16_t>(polyline.GetSize()); ++segmentIndex)
+ {
+ for (size_t dirIndex = 0; dirIndex < directions.size(); ++dirIndex)
+ {
+ auto const sid = traffic::TrafficInfo::RoadSegmentId(f.GetID().m_index, segmentIndex, directions[dirIndex]);
+ bool const isReversed = (directions[dirIndex] == traffic::TrafficInfo::RoadSegmentId::kReverseDirection);
+ segments.emplace_back(sid, df::TrafficSegmentGeometry(polyline.ExtractSegment(segmentIndex, isReversed), roadClass));
+ }
+ }
+}
+
+} // namespace
namespace df
{
@@ -47,12 +70,14 @@ namespace df
RuleDrawer::RuleDrawer(TDrawerCallback const & fn,
TCheckCancelledCallback const & checkCancelled,
TIsCountryLoadedByNameFn const & isLoadedFn,
- ref_ptr<EngineContext> context, bool is3dBuildings)
+ ref_ptr<EngineContext> context,
+ bool is3dBuildings, bool trafficEnabled)
: m_callback(fn)
, m_checkCancelled(checkCancelled)
, m_isLoadedFn(isLoadedFn)
, m_context(context)
, m_is3dBuidings(is3dBuildings)
+ , m_trafficEnabled(trafficEnabled)
, m_wasCancelled(false)
{
ASSERT(m_callback != nullptr, ());
@@ -85,6 +110,8 @@ RuleDrawer::~RuleDrawer()
overlayShapes.swap(m_mapShapes[df::OverlayType]);
m_context->FlushOverlays(move(overlayShapes));
}
+
+ m_context->FlushTrafficGeometry(move(m_trafficGeometry));
}
bool RuleDrawer::CheckCancelled()
@@ -245,6 +272,34 @@ void RuleDrawer::operator()(FeatureType const & f)
if (apply.HasGeometry())
s.ForEachRule(bind(&ApplyLineFeature::ProcessRule, &apply, _1));
apply.Finish();
+
+ if (m_trafficEnabled && zoomLevel >= kRoadClass0ZoomLevel)
+ {
+ vector<m2::PointD> points;
+ points.reserve(f.GetPointsCount());
+ f.ForEachPoint([&points](m2::PointD const & p) { points.emplace_back(p); }, FeatureType::BEST_GEOMETRY);
+ m2::PolylineD const polyline(points);
+
+ struct Checker
+ {
+ vector<ftypes::HighwayClass> m_highwayClasses;
+ int m_zoomLevel;
+ df::RoadClass m_roadClass;
+ };
+ static Checker const checkers[] = {
+ {{ftypes::HighwayClass::Trunk, ftypes::HighwayClass::Primary}, kRoadClass0ZoomLevel, df::RoadClass::Class0},
+ {{ftypes::HighwayClass::Secondary, ftypes::HighwayClass::Tertiary}, kRoadClass1ZoomLevel, df::RoadClass::Class1},
+ {{ftypes::HighwayClass::LivingStreet, ftypes::HighwayClass::Service}, kRoadClass2ZoomLevel, df::RoadClass::Class2}
+ };
+
+ auto const highwayClass = ftypes::GetHighwayClass(f);
+ for (size_t i = 0; i < ARRAY_SIZE(checkers); ++i)
+ {
+ auto const & classes = checkers[i].m_highwayClasses;
+ if (find(classes.begin(), classes.end(), highwayClass) != classes.end() && zoomLevel >= checkers[i].m_zoomLevel)
+ ExtractTrafficGeometry(f, checkers[i].m_roadClass, polyline, m_trafficGeometry);
+ }
+ }
}
else
{
diff --git a/drape_frontend/rule_drawer.hpp b/drape_frontend/rule_drawer.hpp
index 4af2842783..4b1c9c293d 100644
--- a/drape_frontend/rule_drawer.hpp
+++ b/drape_frontend/rule_drawer.hpp
@@ -2,6 +2,7 @@
#include "drape_frontend/map_shape.hpp"
#include "drape_frontend/tile_key.hpp"
+#include "drape_frontend/traffic_generator.hpp"
#include "drape/pointers.hpp"
@@ -29,7 +30,8 @@ public:
using TIsCountryLoadedByNameFn = function<bool (string const &)>;
RuleDrawer(TDrawerCallback const & drawerFn, TCheckCancelledCallback const & checkCancelled,
- TIsCountryLoadedByNameFn const & isLoadedFn, ref_ptr<EngineContext> context, bool is3dBuildings);
+ TIsCountryLoadedByNameFn const & isLoadedFn, ref_ptr<EngineContext> context,
+ bool is3dBuildings, bool trafficEnabled);
~RuleDrawer();
void operator() (FeatureType const & f);
@@ -47,6 +49,9 @@ private:
bool const m_is3dBuidings;
+ bool const m_trafficEnabled;
+ TrafficSegmentsGeometry m_trafficGeometry;
+
array<TMapShapes, df::MapShapeTypeCount> m_mapShapes;
bool m_wasCancelled;
};
diff --git a/drape_frontend/tile_info.cpp b/drape_frontend/tile_info.cpp
index 66ae5e59c4..b8ffbc54c3 100644
--- a/drape_frontend/tile_info.cpp
+++ b/drape_frontend/tile_info.cpp
@@ -17,6 +17,7 @@ namespace df
TileInfo::TileInfo(drape_ptr<EngineContext> && context)
: m_context(move(context))
, m_is3dBuildings(false)
+ , m_trafficEnabled(false)
, m_isCanceled(false)
{
}
@@ -69,7 +70,7 @@ void TileInfo::ReadFeatures(MapDataProvider const & model)
RuleDrawer drawer(bind(&TileInfo::InitStylist, this, _1, _2),
bind(&TileInfo::IsCancelled, this),
model.m_isCountryLoadedByName,
- make_ref(m_context), m_is3dBuildings);
+ make_ref(m_context), m_is3dBuildings, m_trafficEnabled);
model.ReadFeatures(bind<void>(ref(drawer), _1), m_featureInfo);
}
}
diff --git a/drape_frontend/tile_info.hpp b/drape_frontend/tile_info.hpp
index 3920662275..1c43d6e640 100644
--- a/drape_frontend/tile_info.hpp
+++ b/drape_frontend/tile_info.hpp
@@ -34,6 +34,9 @@ public:
void Set3dBuildings(bool buildings3d) { m_is3dBuildings = buildings3d; }
bool Get3dBuildings() const { return m_is3dBuildings; }
+ void SetTrafficEnabled(bool trafficEnabled) { m_trafficEnabled = trafficEnabled; }
+ bool GetTrafficEnabled() const { return m_trafficEnabled; }
+
m2::RectD GetGlobalRect() const;
TileKey const & GetTileKey() const { return m_context->GetTileKey(); }
bool operator <(TileInfo const & other) const { return GetTileKey() < other.GetTileKey(); }
@@ -50,6 +53,7 @@ private:
drape_ptr<EngineContext> m_context;
vector<FeatureID> m_featureInfo;
bool m_is3dBuildings;
+ bool m_trafficEnabled;
atomic<bool> m_isCanceled;
};
diff --git a/drape_frontend/traffic_generator.cpp b/drape_frontend/traffic_generator.cpp
index f23bcf007b..a692852b2b 100644
--- a/drape_frontend/traffic_generator.cpp
+++ b/drape_frontend/traffic_generator.cpp
@@ -85,12 +85,15 @@ void GenerateCapTriangles(glsl::vec3 const & pivot, vector<glsl::vec2> const & n
} // namespace
-TrafficHandle::TrafficHandle(TrafficSegmentID const & segmentId, glsl::vec2 const & texCoord,
- size_t verticesCount)
+TrafficHandle::TrafficHandle(traffic::TrafficInfo::RoadSegmentId const & segmentId, RoadClass const & roadClass,
+ m2::RectD const & boundingBox, glsl::vec2 const & texCoord, size_t verticesCount)
: OverlayHandle(FeatureID(), dp::Anchor::Center, 0, false)
, m_segmentId(segmentId)
+ , m_roadClass(roadClass)
+ , m_boundingBox(boundingBox)
, m_needUpdate(false)
{
+ ASSERT_NOT_EQUAL(verticesCount, 0, ());
m_buffer.resize(verticesCount);
for (size_t i = 0; i < m_buffer.size(); i++)
m_buffer[i] = texCoord;
@@ -148,16 +151,28 @@ void TrafficHandle::SetTexCoord(glsl::vec2 const & texCoord)
m_needUpdate = true;
}
-TrafficSegmentID TrafficHandle::GetSegmentId() const
+traffic::TrafficInfo::RoadSegmentId const & TrafficHandle::GetSegmentId() const
{
return m_segmentId;
}
+RoadClass const & TrafficHandle::GetRoadClass() const
+{
+ return m_roadClass;
+}
+
+m2::RectD const & TrafficHandle::GetBoundingBox() const
+{
+ return m_boundingBox;
+}
+
void TrafficGenerator::Init()
{
- int const kBatchersCount = 3;
+ int constexpr kBatchersCount = 3;
+ int constexpr kBatchSize = 65000;
m_batchersPool = make_unique_dp<BatchersPool<TrafficBatcherKey, TrafficBatcherKeyComparator>>(
- kBatchersCount, bind(&TrafficGenerator::FlushGeometry, this, _1, _2, _3));
+ kBatchersCount, bind(&TrafficGenerator::FlushGeometry, this, _1, _2, _3),
+ kBatchSize, kBatchSize);
}
void TrafficGenerator::ClearGLDependentResources()
@@ -166,41 +181,92 @@ void TrafficGenerator::ClearGLDependentResources()
m_batchersPool.reset();
}
-void TrafficGenerator::AddSegment(TrafficSegmentID const & segmentId, m2::PolylineD const & polyline)
+void TrafficGenerator::FlushSegmentsGeometry(TileKey const & tileKey, TrafficSegmentsGeometry const & geom,
+ ref_ptr<dp::TextureManager> textures)
{
- m_segments.insert(make_pair(segmentId, polyline));
-}
+ FillColorsCache(textures);
-void TrafficGenerator::ClearCache()
-{
- m_colorsCacheValid = false;
- m_segmentsCache.clear();
-}
+ dp::GLState state(gpu::TRAFFIC_PROGRAM, dp::GLState::GeometryLayer);
+ ASSERT(m_colorsCacheValid, ());
+ state.SetColorTexture(m_colorsCache[static_cast<size_t>(traffic::SpeedGroup::G0)].GetTexture());
+ state.SetMaskTexture(textures->GetTrafficArrowTexture());
-void TrafficGenerator::ClearCache(MwmSet::MwmId const & mwmId)
-{
- auto it = m_segmentsCache.begin();
- while (it != m_segmentsCache.end())
+ static vector<RoadClass> roadClasses = {RoadClass::Class0, RoadClass::Class1, RoadClass::Class2};
+
+ for (auto geomIt = geom.begin(); geomIt != geom.end(); ++geomIt)
{
- if (it->m_mwmId == mwmId)
- it = m_segmentsCache.erase(it);
- else
- ++it;
+ auto coloringIt = m_coloring.find(geomIt->first);
+ if (coloringIt != m_coloring.end())
+ {
+ for (auto const & roadClass : roadClasses)
+ m_batchersPool->ReserveBatcher(TrafficBatcherKey(geomIt->first, tileKey, roadClass));
+
+ auto & coloring = coloringIt->second;
+ for (size_t i = 0; i < geomIt->second.size(); i++)
+ {
+ traffic::TrafficInfo::RoadSegmentId const & sid = geomIt->second[i].first;
+ auto segmentColoringIt = coloring.find(sid);
+ if (segmentColoringIt != coloring.end())
+ {
+ TrafficSegmentGeometry const & g = geomIt->second[i].second;
+ ref_ptr<dp::Batcher> batcher = m_batchersPool->GetBatcher(TrafficBatcherKey(geomIt->first, tileKey, g.m_roadClass));
+
+ ASSERT(m_colorsCacheValid, ());
+ dp::TextureManager::ColorRegion const & colorRegion = m_colorsCache[static_cast<size_t>(segmentColoringIt->second)];
+
+ vector<TrafficStaticVertex> staticGeometry;
+ vector<TrafficDynamicVertex> dynamicGeometry;
+ bool const generateCaps = (tileKey.m_zoomLevel > kOutlineMinZoomLevel);
+ GenerateSegment(colorRegion, g.m_polyline, tileKey.GetGlobalRect().Center(), generateCaps, staticGeometry, dynamicGeometry);
+ ASSERT_EQUAL(staticGeometry.size(), dynamicGeometry.size(), ());
+
+ if ((staticGeometry.size() + dynamicGeometry.size()) == 0)
+ continue;
+
+ glsl::vec2 const uv = glsl::ToVec2(colorRegion.GetTexRect().Center());
+ drape_ptr<dp::OverlayHandle> handle = make_unique_dp<TrafficHandle>(sid, g.m_roadClass, g.m_polyline.GetLimitRect(), uv,
+ staticGeometry.size());
+
+ dp::AttributeProvider provider(2 /* stream count */, staticGeometry.size());
+ provider.InitStream(0 /* stream index */, GetTrafficStaticBindingInfo(), make_ref(staticGeometry.data()));
+ provider.InitStream(1 /* stream index */, GetTrafficDynamicBindingInfo(), make_ref(dynamicGeometry.data()));
+ batcher->InsertTriangleList(state, make_ref(&provider), move(handle));
+ }
+ }
+
+ for (auto const & roadClass : roadClasses)
+ m_batchersPool->ReleaseBatcher(TrafficBatcherKey(geomIt->first, tileKey, roadClass));
+ }
}
+
+ GLFunctions::glFlush();
}
-TrafficSegmentsColoring TrafficGenerator::GetSegmentsToUpdate(TrafficSegmentsColoring const & trafficColoring) const
+bool TrafficGenerator::UpdateColoring(TrafficSegmentsColoring const & coloring)
{
- TrafficSegmentsColoring result;
- for (auto const & segment : trafficColoring)
+ bool hasNew = false;
+ for (auto it = coloring.begin(); it != coloring.end(); ++it)
{
- if (m_segmentsCache.find(segment.m_id) != m_segmentsCache.end())
- result.push_back(segment);
+ if (!hasNew && m_coloring.find(it->first) == m_coloring.end())
+ hasNew = true;
+ m_coloring[it->first] = it->second;
}
- return result;
+ return hasNew;
+}
+
+void TrafficGenerator::ClearCache()
+{
+ m_colorsCacheValid = false;
+ m_coloring.clear();
+}
+
+void TrafficGenerator::ClearCache(MwmSet::MwmId const & mwmId)
+{
+ m_coloring.erase(mwmId);
}
-void TrafficGenerator::FlushGeometry(TrafficBatcherKey const & key, dp::GLState const & state, drape_ptr<dp::RenderBucket> && buffer)
+void TrafficGenerator::FlushGeometry(TrafficBatcherKey const & key, dp::GLState const & state,
+ drape_ptr<dp::RenderBucket> && buffer)
{
TrafficRenderData renderData(state);
renderData.m_bucket = move(buffer);
@@ -209,80 +275,9 @@ void TrafficGenerator::FlushGeometry(TrafficBatcherKey const & key, dp::GLState
m_flushRenderDataFn(move(renderData));
}
-void TrafficGenerator::GetTrafficGeom(ref_ptr<dp::TextureManager> textures,
- TrafficSegmentsColoring const & trafficColoring)
-{
- FillColorsCache(textures);
-
- dp::GLState state(gpu::TRAFFIC_PROGRAM, dp::GLState::GeometryLayer);
- ASSERT(m_colorsCacheValid, ());
- state.SetColorTexture(m_colorsCache[static_cast<size_t>(traffic::SpeedGroup::G0)].GetTexture());
- state.SetMaskTexture(textures->GetTrafficArrowTexture());
-
- int const kZoomLevel = 10;
-
- using TSegIter = TSegmentCollection::iterator;
- map<TileKey, list<pair<TSegIter, traffic::SpeedGroup>>> segmentsByTiles;
- for (auto const & segment : trafficColoring)
- {
- // Check if a segment hasn't been added.
- auto it = m_segments.find(segment.m_id);
- if (it == m_segments.end())
- continue;
-
- // Check if a segment has already generated.
- if (m_segmentsCache.find(segment.m_id) != m_segmentsCache.end())
- continue;
-
- m_segmentsCache.insert(segment.m_id);
- TileKey const tileKey = GetTileKeyByPoint(it->second.GetLimitRect().Center(), kZoomLevel);
- segmentsByTiles[tileKey].emplace_back(make_pair(it, segment.m_speedGroup));
- }
-
- for (auto const & s : segmentsByTiles)
- {
- TileKey const & tileKey = s.first;
-
- for (auto const & segmentPair : s.second)
- {
- TSegIter it = segmentPair.first;
-
- TrafficBatcherKey bk(it->first.m_mwmId, tileKey);
-
- m_batchersPool->ReserveBatcher(bk);
- ref_ptr<dp::Batcher> batcher = m_batchersPool->GetBatcher(bk);
-
- ASSERT(m_colorsCacheValid, ());
- dp::TextureManager::ColorRegion const & colorRegion = m_colorsCache[static_cast<size_t>(segmentPair.second)];
- m2::PolylineD const & polyline = it->second;
-
- vector<TrafficStaticVertex> staticGeometry;
- vector<TrafficDynamicVertex> dynamicGeometry;
- GenerateSegment(colorRegion, polyline, tileKey.GetGlobalRect().Center(), staticGeometry, dynamicGeometry);
- ASSERT_EQUAL(staticGeometry.size(), dynamicGeometry.size(), ());
-
- if ((staticGeometry.size() + dynamicGeometry.size()) == 0)
- continue;
-
- glsl::vec2 const uv = glsl::ToVec2(colorRegion.GetTexRect().Center());
- drape_ptr<dp::OverlayHandle> handle = make_unique_dp<TrafficHandle>(it->first, uv, staticGeometry.size());
-
- dp::AttributeProvider provider(2 /* stream count */, staticGeometry.size());
- provider.InitStream(0 /* stream index */, GetTrafficStaticBindingInfo(), make_ref(staticGeometry.data()));
- provider.InitStream(1 /* stream index */, GetTrafficDynamicBindingInfo(), make_ref(dynamicGeometry.data()));
- batcher->InsertTriangleList(state, make_ref(&provider), move(handle));
- }
-
- for (auto const & segmentPair : s.second)
- m_batchersPool->ReleaseBatcher(TrafficBatcherKey(segmentPair.first->first.m_mwmId, tileKey));
- }
-
- GLFunctions::glFlush();
-}
-
void TrafficGenerator::GenerateSegment(dp::TextureManager::ColorRegion const & colorRegion,
m2::PolylineD const & polyline, m2::PointD const & tileCenter,
- vector<TrafficStaticVertex> & staticGeometry,
+ bool generateCaps, vector<TrafficStaticVertex> & staticGeometry,
vector<TrafficDynamicVertex> & dynamicGeometry)
{
vector<m2::PointD> const & path = polyline.GetPoints();
@@ -339,7 +334,7 @@ void TrafficGenerator::GenerateSegment(dp::TextureManager::ColorRegion const & c
}
// Generate caps.
- if (firstFilled)
+ if (generateCaps && firstFilled)
{
int const kSegmentsCount = 4;
vector<glsl::vec2> normals;
diff --git a/drape_frontend/traffic_generator.hpp b/drape_frontend/traffic_generator.hpp
index 9b4bb35d4b..3703285bc6 100644
--- a/drape_frontend/traffic_generator.hpp
+++ b/drape_frontend/traffic_generator.hpp
@@ -26,6 +26,18 @@
namespace df
{
+enum class RoadClass : uint8_t
+{
+ Class0,
+ Class1,
+ Class2
+};
+
+int constexpr kRoadClass0ZoomLevel = 10;
+int constexpr kRoadClass1ZoomLevel = 12;
+int constexpr kRoadClass2ZoomLevel = 14;
+int constexpr kOutlineMinZoomLevel = 13;
+
struct TrafficSegmentID
{
MwmSet::MwmId m_mwmId;
@@ -52,20 +64,22 @@ struct TrafficSegmentID
inline bool operator!=(TrafficSegmentID const & r) const { return !(*this == r); }
};
-using TrafficSegmentsGeometry = vector<pair<TrafficSegmentID, m2::PolylineD>>;
-
-struct TrafficSegmentColoring
+struct TrafficSegmentGeometry
{
- TrafficSegmentID m_id;
- traffic::SpeedGroup m_speedGroup;
+ m2::PolylineD m_polyline;
+ RoadClass m_roadClass;
- TrafficSegmentColoring(TrafficSegmentID const & id, traffic::SpeedGroup const & speedGroup)
- : m_id(id)
- , m_speedGroup(speedGroup)
+ TrafficSegmentGeometry(m2::PolylineD && polyline, RoadClass const & roadClass)
+ : m_polyline(move(polyline))
+ , m_roadClass(roadClass)
{}
};
-using TrafficSegmentsColoring = vector<TrafficSegmentColoring>;
+using TrafficSegmentsGeometry = map<MwmSet::MwmId, vector<pair<traffic::TrafficInfo::RoadSegmentId,
+ TrafficSegmentGeometry>>>;
+using TrafficSegmentsColoring = map<MwmSet::MwmId, traffic::TrafficInfo::Coloring>;
+
+class TrafficHandle;
struct TrafficRenderData
{
@@ -73,6 +87,9 @@ struct TrafficRenderData
drape_ptr<dp::RenderBucket> m_bucket;
TileKey m_tileKey;
MwmSet::MwmId m_mwmId;
+ m2::RectD m_boundingBox;
+ vector<TrafficHandle *> m_handles;
+
TrafficRenderData(dp::GLState const & state) : m_state(state) {}
};
@@ -108,7 +125,9 @@ class TrafficHandle : public dp::OverlayHandle
using TBase = dp::OverlayHandle;
public:
- TrafficHandle(TrafficSegmentID const & segmentId, glsl::vec2 const & texCoord, size_t verticesCount);
+ TrafficHandle(traffic::TrafficInfo::RoadSegmentId const & segmentId, RoadClass const & roadClass,
+ m2::RectD const & boundingBox, glsl::vec2 const & texCoord,
+ size_t verticesCount);
void GetAttributeMutation(ref_ptr<dp::AttributeBufferMutator> mutator) const override;
bool Update(ScreenBase const & screen) override;
@@ -117,11 +136,15 @@ public:
void GetPixelShape(ScreenBase const & screen, bool perspective, Rects & rects) const override;
void SetTexCoord(glsl::vec2 const & texCoord);
- TrafficSegmentID GetSegmentId() const;
+ traffic::TrafficInfo::RoadSegmentId const & GetSegmentId() const;
+ RoadClass const & GetRoadClass() const;
+ m2::RectD const & GetBoundingBox() const;
private:
- TrafficSegmentID m_segmentId;
+ traffic::TrafficInfo::RoadSegmentId m_segmentId;
+ RoadClass m_roadClass;
vector<glsl::vec2> m_buffer;
+ m2::RectD m_boundingBox;
mutable bool m_needUpdate;
};
@@ -139,12 +162,9 @@ public:
void Init();
void ClearGLDependentResources();
- void AddSegment(TrafficSegmentID const & segmentId, m2::PolylineD const & polyline);
-
- TrafficSegmentsColoring GetSegmentsToUpdate(TrafficSegmentsColoring const & trafficColoring) const;
-
- void GetTrafficGeom(ref_ptr<dp::TextureManager> textures,
- TrafficSegmentsColoring const & trafficColoring);
+ void FlushSegmentsGeometry(TileKey const & tileKey, TrafficSegmentsGeometry const & geom,
+ ref_ptr<dp::TextureManager> textures);
+ bool UpdateColoring(TrafficSegmentsColoring const & coloring);
void ClearCache();
void ClearCache(MwmSet::MwmId const & mwmId);
@@ -156,13 +176,15 @@ private:
struct TrafficBatcherKey
{
TrafficBatcherKey() = default;
- TrafficBatcherKey(MwmSet::MwmId const & mwmId, TileKey const & tileKey)
+ TrafficBatcherKey(MwmSet::MwmId const & mwmId, TileKey const & tileKey, RoadClass const & roadClass)
: m_mwmId(mwmId)
, m_tileKey(tileKey)
+ , m_roadClass(roadClass)
{}
MwmSet::MwmId m_mwmId;
TileKey m_tileKey;
+ RoadClass m_roadClass;
};
struct TrafficBatcherKeyComparator
@@ -170,24 +192,26 @@ private:
bool operator() (TrafficBatcherKey const & lhs, TrafficBatcherKey const & rhs) const
{
if (lhs.m_mwmId == rhs.m_mwmId)
- return lhs.m_tileKey < rhs.m_tileKey;
+ {
+ if (lhs.m_tileKey.EqualStrict(rhs.m_tileKey))
+ return lhs.m_roadClass < rhs.m_roadClass;
+ return lhs.m_tileKey.LessStrict(rhs.m_tileKey);
+ }
return lhs.m_mwmId < rhs.m_mwmId;
}
};
- using TSegmentCollection = map<TrafficSegmentID, m2::PolylineD>;
-
void GenerateSegment(dp::TextureManager::ColorRegion const & colorRegion,
m2::PolylineD const & polyline, m2::PointD const & tileCenter,
- vector<TrafficStaticVertex> & staticGeometry,
+ bool generateCaps, vector<TrafficStaticVertex> & staticGeometry,
vector<TrafficDynamicVertex> & dynamicGeometry);
void FillColorsCache(ref_ptr<dp::TextureManager> textures);
- void FlushGeometry(TrafficBatcherKey const & key, dp::GLState const & state, drape_ptr<dp::RenderBucket> && buffer);
+ void FlushGeometry(TrafficBatcherKey const & key, dp::GLState const & state,
+ drape_ptr<dp::RenderBucket> && buffer);
- TSegmentCollection m_segments;
+ TrafficSegmentsColoring m_coloring;
- set<TrafficSegmentID> m_segmentsCache;
array<dp::TextureManager::ColorRegion, static_cast<size_t>(traffic::SpeedGroup::Count)> m_colorsCache;
bool m_colorsCacheValid = false;
bool m_colorsCacheRefreshed = false;
diff --git a/drape_frontend/traffic_renderer.cpp b/drape_frontend/traffic_renderer.cpp
index 70864ea21d..7d9ed2b914 100644
--- a/drape_frontend/traffic_renderer.cpp
+++ b/drape_frontend/traffic_renderer.cpp
@@ -19,8 +19,8 @@ namespace df
namespace
{
-int const kMinVisibleZoomLevel = 10;
int const kMinVisibleArrowZoomLevel = 16;
+int const kRoadClass2MinVisibleArrowZoomLevel = 17;
float const kTrafficArrowAspect = 24.0f / 8.0f;
@@ -29,63 +29,133 @@ float const kLeftWidthInPixel[] =
// 1 2 3 4 5 6 7 8 9 10
0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f,
//11 12 13 14 15 16 17 18 19 20
- 0.75f, 0.75f, 1.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 5.0f, 8.0f
+ 0.75f, 0.75f, 0.75f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 5.0f, 8.0f
};
float const kRightWidthInPixel[] =
{
// 1 2 3 4 5 6 7 8 9 10
- 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 4.0f, 4.0f,
+ 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 2.0f, 3.0f, 4.0f,
//11 12 13 14 15 16 17 18 19 20
4.0f, 4.0f, 4.0f, 2.0f, 2.0f, 3.0f, 3.0f, 4.0f, 5.0f, 8.0f
};
-float CalculateHalfWidth(ScreenBase const & screen, bool left)
+float const kRoadClass1WidthScalar[] =
+{
+ // 1 2 3 4 5 6 7 8 9 10
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ //11 12 13 14 15 16 17 18 19 20
+ 0.0f, 0.2f, 0.3f, 0.6f, 0.8f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f
+};
+
+float const kRoadClass2WidthScalar[] =
+{
+ // 1 2 3 4 5 6 7 8 9 10
+ 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f,
+ //11 12 13 14 15 16 17 18 19 20
+ 0.0f, 0.0f, 0.0f, 0.2f, 0.3f, 0.5f, 0.7f, 0.8f, 0.9f, 1.0f
+};
+
+float CalculateHalfWidth(ScreenBase const & screen, RoadClass const & roadClass, bool left)
{
double const zoomLevel = GetZoomLevel(screen.GetScale());
double zoom = trunc(zoomLevel);
int const index = zoom - 1.0;
float const lerpCoef = zoomLevel - zoom;
+ float const * widthScalar = nullptr;
+ if (roadClass == RoadClass::Class1)
+ widthScalar = kRoadClass1WidthScalar;
+ else if (roadClass == RoadClass::Class2)
+ widthScalar = kRoadClass2WidthScalar;
+
float const * halfWidth = left ? kLeftWidthInPixel : kRightWidthInPixel;
float radius = 0.0f;
if (index < scales::UPPER_STYLE_SCALE)
+ {
radius = halfWidth[index] + lerpCoef * (halfWidth[index + 1] - halfWidth[index]);
+ if (widthScalar != nullptr)
+ radius *= (widthScalar[index] + lerpCoef * (widthScalar[index + 1] - widthScalar[index]));
+ }
else
+ {
radius = halfWidth[scales::UPPER_STYLE_SCALE];
+ if (widthScalar != nullptr)
+ radius *= widthScalar[scales::UPPER_STYLE_SCALE];
+ }
return radius * VisualParams::Instance().GetVisualScale();
}
} // namespace
-void TrafficRenderer::AddRenderData(ref_ptr<dp::GpuProgramManager> mng,
- TrafficRenderData && renderData)
+void TrafficRenderer::AddRenderData(ref_ptr<dp::GpuProgramManager> mng, TrafficRenderData && renderData)
{
+ // Remove obsolete render data.
+ TileKey const tileKey(renderData.m_tileKey);
+ m_renderData.erase(remove_if(m_renderData.begin(), m_renderData.end(), [&tileKey](TrafficRenderData const & rd)
+ {
+ return tileKey == rd.m_tileKey && rd.m_tileKey.m_generation < tileKey.m_generation;
+ }), m_renderData.end());
+
+ // Add new render data.
m_renderData.emplace_back(move(renderData));
+ TrafficRenderData & rd = m_renderData.back();
- ref_ptr<dp::GpuProgram> program = mng->GetProgram(m_renderData.back().m_state.GetProgramIndex());
+ ref_ptr<dp::GpuProgram> program = mng->GetProgram(rd.m_state.GetProgramIndex());
program->Bind();
- m_renderData.back().m_bucket->GetBuffer()->Build(program);
+ rd.m_bucket->GetBuffer()->Build(program);
- for (size_t j = 0; j < m_renderData.back().m_bucket->GetOverlayHandlesCount(); j++)
+ rd.m_handles.reserve(rd.m_bucket->GetOverlayHandlesCount());
+ for (size_t j = 0; j < rd.m_bucket->GetOverlayHandlesCount(); j++)
{
- TrafficHandle * handle = static_cast<TrafficHandle *>(m_renderData.back().m_bucket->GetOverlayHandle(j).get());
- m_handles.insert(make_pair(handle->GetSegmentId(), handle));
+ TrafficHandle * handle = static_cast<TrafficHandle *>(rd.m_bucket->GetOverlayHandle(j).get());
+ rd.m_handles.emplace_back(handle);
+ rd.m_boundingBox.Add(handle->GetBoundingBox());
}
}
+void TrafficRenderer::OnUpdateViewport(CoverageResult const & coverage, int currentZoomLevel,
+ buffer_vector<TileKey, 8> const & tilesToDelete)
+{
+ m_renderData.erase(remove_if(m_renderData.begin(), m_renderData.end(),
+ [&coverage, &currentZoomLevel, &tilesToDelete](TrafficRenderData const & rd)
+ {
+ return rd.m_tileKey.m_zoomLevel == currentZoomLevel &&
+ (rd.m_tileKey.m_x < coverage.m_minTileX || rd.m_tileKey.m_x >= coverage.m_maxTileX ||
+ rd.m_tileKey.m_y < coverage.m_minTileY || rd.m_tileKey.m_y >= coverage.m_maxTileY ||
+ find(tilesToDelete.begin(), tilesToDelete.end(), rd.m_tileKey) != tilesToDelete.end());
+ }), m_renderData.end());
+}
+
+void TrafficRenderer::OnGeometryReady(int currentZoomLevel)
+{
+ m_renderData.erase(remove_if(m_renderData.begin(), m_renderData.end(),
+ [&currentZoomLevel](TrafficRenderData const & rd)
+ {
+ return rd.m_tileKey.m_zoomLevel != currentZoomLevel;
+ }), m_renderData.end());
+}
+
void TrafficRenderer::UpdateTraffic(TrafficSegmentsColoring const & trafficColoring)
{
- for (auto const & segment : trafficColoring)
+ for (TrafficRenderData & renderData : m_renderData)
{
- auto it = m_texCoords.find(static_cast<size_t>(segment.m_speedGroup));
- if (it == m_texCoords.end())
+ auto coloringIt = trafficColoring.find(renderData.m_mwmId);
+ if (coloringIt == trafficColoring.end())
continue;
- auto handleIt = m_handles.find(segment.m_id);
- if (handleIt != m_handles.end())
- handleIt->second->SetTexCoord(it->second);
+ for (size_t i = 0; i < renderData.m_handles.size(); i++)
+ {
+ auto it = coloringIt->second.find(renderData.m_handles[i]->GetSegmentId());
+ if (it != coloringIt->second.end())
+ {
+ auto texCoordIt = m_texCoords.find(static_cast<size_t>(it->second));
+ if (texCoordIt == m_texCoords.end())
+ continue;
+ renderData.m_handles[i]->SetTexCoord(texCoordIt->second);
+ }
+ }
}
}
@@ -93,15 +163,55 @@ void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel,
ref_ptr<dp::GpuProgramManager> mng,
dp::UniformValuesStorage const & commonUniforms)
{
- if (m_renderData.empty() || zoomLevel < kMinVisibleZoomLevel)
+ if (m_renderData.empty() || zoomLevel < kRoadClass0ZoomLevel)
return;
- float const pixelHalfWidth = CalculateHalfWidth(screen, true /* left */);
- float const invPixelLength = 1.0f / (2.0f * pixelHalfWidth * kTrafficArrowAspect);
+ m2::RectD const clipRect = screen.ClipRect();
GLFunctions::glClearDepth();
for (TrafficRenderData & renderData : m_renderData)
{
+ if (!clipRect.IsIntersect(renderData.m_boundingBox))
+ continue;
+
+ // Filter by road class.
+ float leftPixelHalfWidth = 0.0f;
+ float invLeftPixelLength = 0.0f;
+ float rightPixelHalfWidth = 0.0f;
+ int minVisibleArrowZoomLevel = kMinVisibleArrowZoomLevel;
+ float outline = 0.0f;
+
+ if (renderData.m_bucket->GetOverlayHandlesCount() > 0)
+ {
+ TrafficHandle * handle = static_cast<TrafficHandle *>(renderData.m_bucket->GetOverlayHandle(0).get());
+ ASSERT(handle != nullptr, ());
+
+ int visibleZoomLevel = kRoadClass0ZoomLevel;
+ if (handle->GetRoadClass() == RoadClass::Class0)
+ {
+ outline = (zoomLevel <= kOutlineMinZoomLevel ? 1.0 : 0.0);
+ }
+ else if (handle->GetRoadClass() == RoadClass::Class1)
+ {
+ visibleZoomLevel = kRoadClass1ZoomLevel;
+ }
+ else if (handle->GetRoadClass() == RoadClass::Class2)
+ {
+ visibleZoomLevel = kRoadClass2ZoomLevel;
+ minVisibleArrowZoomLevel = kRoadClass2MinVisibleArrowZoomLevel;
+ }
+
+ if (zoomLevel < visibleZoomLevel)
+ continue;
+
+ leftPixelHalfWidth = CalculateHalfWidth(screen, handle->GetRoadClass(), true /* left */);
+ invLeftPixelLength = 1.0f / (2.0f * leftPixelHalfWidth * kTrafficArrowAspect);
+ rightPixelHalfWidth = CalculateHalfWidth(screen, handle->GetRoadClass(), false /* left */);
+ float const kEps = 1e-5;
+ if (fabs(leftPixelHalfWidth) < kEps && fabs(rightPixelHalfWidth) < kEps)
+ continue;
+ }
+
ref_ptr<dp::GpuProgram> program = mng->GetProgram(renderData.m_state.GetProgramIndex());
program->Bind();
dp::ApplyState(renderData.m_state, program);
@@ -110,8 +220,9 @@ void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel,
math::Matrix<float, 4, 4> const mv = renderData.m_tileKey.GetTileBasedModelView(screen);
uniforms.SetMatrix4x4Value("modelView", mv.m_data);
uniforms.SetFloatValue("u_opacity", 1.0f);
- uniforms.SetFloatValue("u_trafficParams", pixelHalfWidth, CalculateHalfWidth(screen, false /* left */),
- invPixelLength, zoomLevel >= kMinVisibleArrowZoomLevel ? 1.0f : 0.0f);
+ uniforms.SetFloatValue("u_outline", outline);
+ uniforms.SetFloatValue("u_trafficParams", leftPixelHalfWidth, rightPixelHalfWidth,
+ invLeftPixelLength, zoomLevel >= minVisibleArrowZoomLevel ? 1.0f : 0.0f);
dp::ApplyUniforms(uniforms, program);
renderData.m_bucket->Render(renderData.m_state.GetDrawAsLine());
@@ -126,7 +237,6 @@ void TrafficRenderer::SetTexCoords(TrafficTexCoords && texCoords)
void TrafficRenderer::ClearGLDependentResources()
{
m_renderData.clear();
- m_handles.clear();
m_texCoords.clear();
}
diff --git a/drape_frontend/traffic_renderer.hpp b/drape_frontend/traffic_renderer.hpp
index d7d38af220..4544d1a9ce 100644
--- a/drape_frontend/traffic_renderer.hpp
+++ b/drape_frontend/traffic_renderer.hpp
@@ -1,6 +1,7 @@
#pragma once
#include "drape_frontend/traffic_generator.hpp"
+#include "drape_frontend/tile_utils.hpp"
#include "drape/gpu_program_manager.hpp"
#include "drape/pointers.hpp"
@@ -9,7 +10,6 @@
#include "geometry/screenbase.hpp"
#include "geometry/spline.hpp"
-#include "std/map.hpp"
#include "std/vector.hpp"
namespace df
@@ -34,10 +34,13 @@ public:
void ClearGLDependentResources();
void Clear(MwmSet::MwmId const & mwmId);
+ void OnUpdateViewport(CoverageResult const & coverage, int currentZoomLevel,
+ buffer_vector<TileKey, 8> const & tilesToDelete);
+ void OnGeometryReady(int currentZoomLevel);
+
private:
vector<TrafficRenderData> m_renderData;
TrafficTexCoords m_texCoords;
- map<TrafficSegmentID, TrafficHandle *> m_handles;
};
} // namespace df
diff --git a/geometry/polyline2d.hpp b/geometry/polyline2d.hpp
index 86dfe69972..abe2459ebe 100644
--- a/geometry/polyline2d.hpp
+++ b/geometry/polyline2d.hpp
@@ -115,7 +115,7 @@ public:
return m_points.back();
}
- Polyline ExtractSegment(size_t segmentIndex, bool reversed)
+ Polyline ExtractSegment(size_t segmentIndex, bool reversed) const
{
if (segmentIndex + 1 >= m_points.size())
return Polyline();
diff --git a/map/framework.cpp b/map/framework.cpp
index bb334c421b..5b1f751771 100644
--- a/map/framework.cpp
+++ b/map/framework.cpp
@@ -121,6 +121,7 @@ char const kMapStyleKey[] = "MapStyleKeyV1";
char const kAllow3dKey[] = "Allow3d";
char const kAllow3dBuildingsKey[] = "Buildings3d";
char const kAllowAutoZoom[] = "AutoZoom";
+char const kTrafficEnabledKey[] = "TrafficEnabled";
double const kDistEqualQueryMeters = 100.0;
@@ -343,8 +344,7 @@ Framework::Framework()
, m_isRenderingEnabled(true)
, m_trackingReporter(platform::CreateSocket(), TRACKING_REALTIME_HOST, TRACKING_REALTIME_PORT,
tracking::Reporter::kPushDelayMs)
- , m_trafficManager(m_model.GetIndex(), bind(&Framework::GetMwmsByRect, this, _1),
- kMaxTrafficCacheSizeBytes)
+ , m_trafficManager(bind(&Framework::GetMwmsByRect, this, _1), kMaxTrafficCacheSizeBytes)
, m_displacementModeManager([this](bool show) {
int const mode = show ? dp::displacement::kHotelMode : dp::displacement::kDefaultMode;
CallDrapeFunction(bind(&df::DrapeEngine::SetDisplacementMode, _1, mode));
@@ -1605,6 +1605,8 @@ void Framework::CreateDrapeEngine(ref_ptr<dp::OGLContextFactory> contextFactory,
Load3dMode(allow3d, allow3dBuildings);
bool const isAutozoomEnabled = LoadAutoZoom();
+ bool const trafficEnabled = LoadTrafficEnabled();
+ m_trafficManager.SetEnabled(trafficEnabled);
df::DrapeEngine::Params p(contextFactory,
make_ref(&m_stringsBundle),
@@ -1612,7 +1614,7 @@ void Framework::CreateDrapeEngine(ref_ptr<dp::OGLContextFactory> contextFactory,
df::MapDataProvider(idReadFn, featureReadFn, isCountryLoadedByNameFn, updateCurrentCountryFn),
params.m_visualScale, move(params.m_widgetsInitInfo),
make_pair(params.m_initialMyPositionState, params.m_hasMyPositionState),
- allow3dBuildings, params.m_isChoosePositionMode,
+ allow3dBuildings, trafficEnabled, params.m_isChoosePositionMode,
params.m_isChoosePositionMode, GetSelectedFeatureTriangles(), params.m_isFirstLaunch,
m_routingSession.IsActive() && m_routingSession.IsFollowing(), isAutozoomEnabled);
@@ -2646,6 +2648,18 @@ void Framework::Load3dMode(bool & allow3d, bool & allow3dBuildings)
allow3dBuildings = true;
}
+bool Framework::LoadTrafficEnabled()
+{
+ bool enabled = true; //TODO(@rokuz): temporary. It has to be false by default.
+ settings::Get(kTrafficEnabledKey, enabled);
+ return enabled;
+}
+
+void Framework::SaveTrafficEnabled(bool trafficEnabled)
+{
+ settings::Set(kTrafficEnabledKey, trafficEnabled);
+}
+
bool Framework::LoadAutoZoom()
{
bool allowAutoZoom = true;
diff --git a/map/framework.hpp b/map/framework.hpp
index 338eacc328..4f5f689e41 100644
--- a/map/framework.hpp
+++ b/map/framework.hpp
@@ -773,6 +773,9 @@ public:
void AllowAutoZoom(bool allowAutoZoom);
void SaveAutoZoom(bool allowAutoZoom);
+ bool LoadTrafficEnabled();
+ void SaveTrafficEnabled(bool trafficEnabled);
+
/// \returns true if altitude information along |m_route| is available and
/// false otherwise.
bool HasRouteAltitude() const;
diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp
index a614608094..bd3ff9fdd9 100644
--- a/map/traffic_manager.cpp
+++ b/map/traffic_manager.cpp
@@ -5,20 +5,16 @@
#include "drape_frontend/drape_engine.hpp"
#include "drape_frontend/visual_params.hpp"
+#include "indexer/ftypes_matcher.hpp"
#include "indexer/scales.hpp"
namespace
{
auto const kUpdateInterval = minutes(1);
-
-int const kMinTrafficZoom = 10;
-
} // namespace
-TrafficManager::TrafficManager(Index const & index, GetMwmsByRectFn const & getMwmsByRectFn,
- size_t maxCacheSizeBytes)
- : m_isEnabled(true) // TODO: true is temporary
- , m_index(index)
+TrafficManager::TrafficManager(GetMwmsByRectFn const & getMwmsByRectFn, size_t maxCacheSizeBytes)
+ : m_isEnabled(false)
, m_getMwmsByRectFn(getMwmsByRectFn)
, m_maxCacheSizeBytes(maxCacheSizeBytes)
, m_currentCacheSizeBytes(0)
@@ -41,6 +37,8 @@ TrafficManager::~TrafficManager()
void TrafficManager::SetEnabled(bool enabled)
{
m_isEnabled = enabled;
+ if (m_drapeEngine != nullptr)
+ m_drapeEngine->EnableTraffic(enabled);
}
void TrafficManager::SetDrapeEngine(ref_ptr<df::DrapeEngine> engine)
@@ -63,7 +61,7 @@ void TrafficManager::UpdateViewport(ScreenBase const & screen)
if (!m_isEnabled)
return;
- if (df::GetZoomLevel(screen.GetScale()) < kMinTrafficZoom)
+ if (df::GetZoomLevel(screen.GetScale()) < df::kRoadClass0ZoomLevel)
return;
// Request traffic.
@@ -97,57 +95,6 @@ void TrafficManager::UpdateMyPosition(MyPosition const & myPosition)
// 3. Do all routing stuff.
}
-void TrafficManager::CalculateSegmentsGeometry(traffic::TrafficInfo const & trafficInfo,
- df::TrafficSegmentsGeometry & output) const
-{
- size_t const coloringSize = trafficInfo.GetColoring().size();
- output.reserve(coloringSize);
-
- vector<FeatureID> features;
- features.reserve(coloringSize);
- for (auto const & c : trafficInfo.GetColoring())
- features.emplace_back(trafficInfo.GetMwmId(), c.first.m_fid);
-
- int constexpr kScale = scales::GetUpperScale();
- unordered_map<uint32_t, m2::PolylineD> polylines;
- auto featureReader = [&polylines](FeatureType & ft)
- {
- uint32_t const fid = ft.GetID().m_index;
- if (polylines.find(fid) != polylines.end())
- return;
-
- if (routing::IsRoad(feature::TypesHolder(ft)))
- {
- m2::PolylineD polyline;
- ft.ForEachPoint([&polyline](m2::PointD const & pt) { polyline.Add(pt); }, kScale);
- if (polyline.GetSize() > 1)
- polylines[fid] = polyline;
- }
- };
- m_index.ReadFeatures(featureReader, features);
-
- for (auto const & c : trafficInfo.GetColoring())
- {
- auto it = polylines.find(c.first.m_fid);
- if (it == polylines.end())
- continue;
- bool const isReversed = (c.first.m_dir == traffic::TrafficInfo::RoadSegmentId::kReverseDirection);
- m2::PolylineD polyline = it->second.ExtractSegment(c.first.m_idx, isReversed);
- if (polyline.GetSize() > 1)
- output.emplace_back(df::TrafficSegmentID(trafficInfo.GetMwmId(), c.first), move(polyline));
- }
-}
-
-void TrafficManager::CalculateSegmentsColoring(traffic::TrafficInfo const & trafficInfo,
- df::TrafficSegmentsColoring & output) const
-{
- for (auto const & c : trafficInfo.GetColoring())
- {
- df::TrafficSegmentID const sid (trafficInfo.GetMwmId(), c.first);
- output.emplace_back(sid, c.second);
- }
-}
-
void TrafficManager::ThreadRoutine()
{
vector<MwmSet::MwmId> mwms;
@@ -227,25 +174,17 @@ void TrafficManager::OnTrafficDataResponse(traffic::TrafficInfo const & info)
if (it == m_mwmInfos.end())
return;
- // Cache geometry for rendering if it's necessary.
- if (!it->second.m_isLoaded)
- {
- df::TrafficSegmentsGeometry geometry;
- CalculateSegmentsGeometry(info, geometry);
- it->second.m_isLoaded = true;
- m_drapeEngine->CacheTrafficSegmentsGeometry(geometry);
- }
-
- // Update traffic colors.
- df::TrafficSegmentsColoring coloring;
- CalculateSegmentsColoring(info, coloring);
-
- size_t dataSize = coloring.size() * sizeof(df::TrafficSegmentColoring);
+ // Update cache.
+ size_t constexpr kElementSize = sizeof(traffic::TrafficInfo::RoadSegmentId) + sizeof(traffic::SpeedGroup);
+ size_t const dataSize = info.GetColoring().size() * kElementSize;
+ it->second.m_isLoaded = true;
+ m_currentCacheSizeBytes += (dataSize - it->second.m_dataSize);
it->second.m_dataSize = dataSize;
- m_currentCacheSizeBytes += dataSize;
-
CheckCacheSize();
+ // Update traffic colors.
+ df::TrafficSegmentsColoring coloring;
+ coloring[info.GetMwmId()] = info.GetColoring();
m_drapeEngine->UpdateTraffic(coloring);
}
diff --git a/map/traffic_manager.hpp b/map/traffic_manager.hpp
index 9a209fe8a0..ae7838251c 100644
--- a/map/traffic_manager.hpp
+++ b/map/traffic_manager.hpp
@@ -42,8 +42,7 @@ public:
using GetMwmsByRectFn = function<vector<MwmSet::MwmId>(m2::RectD const &)>;
- TrafficManager(Index const & index, GetMwmsByRectFn const & getMwmsByRectFn,
- size_t maxCacheSizeBytes);
+ TrafficManager(GetMwmsByRectFn const & getMwmsByRectFn, size_t maxCacheSizeBytes);
~TrafficManager();
void SetEnabled(bool enabled);
@@ -56,11 +55,6 @@ public:
void SetDrapeEngine(ref_ptr<df::DrapeEngine> engine);
private:
- void CalculateSegmentsGeometry(traffic::TrafficInfo const & trafficInfo,
- df::TrafficSegmentsGeometry & output) const;
- void CalculateSegmentsColoring(traffic::TrafficInfo const & trafficInfo,
- df::TrafficSegmentsColoring & output) const;
-
void ThreadRoutine();
bool WaitForRequest(vector<MwmSet::MwmId> & mwms);
void RequestTrafficData();
@@ -70,7 +64,6 @@ private:
bool m_isEnabled;
- Index const & m_index;
GetMwmsByRectFn m_getMwmsByRectFn;
ref_ptr<df::DrapeEngine> m_drapeEngine;