From 17d3a0abb9e424315f50f676c61b7218236e6a78 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Wed, 7 Dec 2016 10:28:38 +0300 Subject: [PATCH 1/5] Fixed freeze on traffic turning on --- map/traffic_manager.cpp | 4 ++++ map/traffic_manager.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index 797a1889b2..a3ec600e87 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -101,6 +101,7 @@ void TrafficManager::SetEnabled(bool enabled) void TrafficManager::Clear() { m_mwmCache.clear(); + m_lastMwmsByRect.clear(); m_activeMwms.clear(); m_requestedMwms.clear(); } @@ -147,6 +148,9 @@ void TrafficManager::UpdateViewport(ScreenBase const & screen) // Request traffic. auto mwms = m_getMwmsByRectFn(screen.ClipRect()); + if (m_lastMwmsByRect == mwms) + return; + m_lastMwmsByRect = mwms; { lock_guard lock(m_mutex); diff --git a/map/traffic_manager.hpp b/map/traffic_manager.hpp index d2f208a356..67dcc7d323 100644 --- a/map/traffic_manager.hpp +++ b/map/traffic_manager.hpp @@ -133,6 +133,7 @@ private: bool m_isRunning; condition_variable m_condition; + vector m_lastMwmsByRect; set m_activeMwms; vector m_requestedMwms; From 086c963b37cf7e1834da8faa6feda77f27ec1000 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Wed, 7 Dec 2016 10:29:10 +0300 Subject: [PATCH 2/5] Added low priority messages --- drape_frontend/engine_context.cpp | 4 +++- drape_frontend/message.hpp | 3 ++- drape_frontend/message_queue.cpp | 33 +++++++++++++++++++++++++------ drape_frontend/message_queue.hpp | 1 + 4 files changed, 33 insertions(+), 8 deletions(-) diff --git a/drape_frontend/engine_context.cpp b/drape_frontend/engine_context.cpp index ff864cf128..63452369c4 100644 --- a/drape_frontend/engine_context.cpp +++ b/drape_frontend/engine_context.cpp @@ -37,7 +37,9 @@ void EngineContext::FlushOverlays(TMapShapes && shapes) void EngineContext::FlushTrafficGeometry(TrafficSegmentsGeometry && geometry) { - PostMessage(make_unique_dp(m_tileKey, move(geometry))); + m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(m_tileKey, move(geometry)), + MessagePriority::Low); } void EngineContext::EndReadTile() diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index 19d4850a08..429bbda4d0 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -85,7 +85,8 @@ enum class MessagePriority { Normal, High, - UberHighSingleton + UberHighSingleton, + Low }; } // namespace df diff --git a/drape_frontend/message_queue.cpp b/drape_frontend/message_queue.cpp index fce3e04e30..59b7850b04 100644 --- a/drape_frontend/message_queue.cpp +++ b/drape_frontend/message_queue.cpp @@ -22,18 +22,25 @@ MessageQueue::~MessageQueue() drape_ptr MessageQueue::PopMessage(bool waitForMessage) { unique_lock lock(m_mutex); - if (waitForMessage && m_messages.empty()) + if (waitForMessage && m_messages.empty() && m_lowPriorityMessages.empty()) { m_isWaiting = true; m_condition.wait(lock, [this]() { return !m_isWaiting; }); m_isWaiting = false; } - if (m_messages.empty()) + if (m_messages.empty() && m_lowPriorityMessages.empty()) return nullptr; - drape_ptr msg = move(m_messages.front().first); - m_messages.pop_front(); + if (!m_messages.empty()) + { + drape_ptr msg = move(m_messages.front().first); + m_messages.pop_front(); + return msg; + } + + drape_ptr msg = move(m_lowPriorityMessages.front()); + m_lowPriorityMessages.pop_front(); return msg; } @@ -73,6 +80,11 @@ void MessageQueue::PushMessage(drape_ptr && message, MessagePriority pr m_messages.emplace_front(move(message), priority); break; } + case MessagePriority::Low: + { + m_lowPriorityMessages.emplace_back(move(message)); + break; + } default: ASSERT(false, ("Unknown message priority type")); } @@ -92,6 +104,14 @@ void MessageQueue::FilterMessages(TFilterMessageFn needFilterMessageFn) else ++it; } + + for (auto it = m_lowPriorityMessages.begin(); it != m_lowPriorityMessages.end(); ) + { + if (needFilterMessageFn(make_ref(*it))) + it = m_lowPriorityMessages.erase(it); + else + ++it; + } } #ifdef DEBUG_MESSAGE_QUEUE @@ -99,13 +119,13 @@ void MessageQueue::FilterMessages(TFilterMessageFn needFilterMessageFn) bool MessageQueue::IsEmpty() const { lock_guard lock(m_mutex); - return m_messages.empty(); + return m_messages.empty() && m_lowPriorityMessages.empty(); } size_t MessageQueue::GetSize() const { lock_guard lock(m_mutex); - return m_messages.size(); + return m_messages.size() + m_lowPriorityMessages.size(); } #endif @@ -128,6 +148,7 @@ void MessageQueue::CancelWaitImpl() void MessageQueue::ClearQuery() { m_messages.clear(); + m_lowPriorityMessages.clear(); } } // namespace df diff --git a/drape_frontend/message_queue.hpp b/drape_frontend/message_queue.hpp index dc2147191b..5330827735 100644 --- a/drape_frontend/message_queue.hpp +++ b/drape_frontend/message_queue.hpp @@ -43,6 +43,7 @@ private: bool m_isWaiting; using TMessageNode = pair, MessagePriority>; deque m_messages; + deque> m_lowPriorityMessages; }; } // namespace df From 46b80961c94ddde7aeaaaba988266f557d1a6d06 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Wed, 7 Dec 2016 10:30:34 +0300 Subject: [PATCH 3/5] Added preallocation of vectors in RuleDrawer --- drape_frontend/rule_drawer.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp index 5ba75f0d91..f78fcb7086 100644 --- a/drape_frontend/rule_drawer.cpp +++ b/drape_frontend/rule_drawer.cpp @@ -29,6 +29,8 @@ namespace { int constexpr kOutlineMinZoomLevel = 16; + // 10 11 12 13 14 15 16 17 18 19 +vector const kAverageSegmentsCount = { 10000, 5000, 10000, 5000, 2500, 5000, 2000, 1000, 500, 500 }; df::BaseApplyFeature::HotelData ExtractHotelData(FeatureType const & f) { @@ -65,7 +67,12 @@ void ExtractTrafficGeometry(FeatureType const & f, df::RoadClass const & roadCla static vector 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)); + + int const index = zoomLevel - 10; // 10 - the first zoom level in kAverageSegmentsCount. + ASSERT_GREATER(index, 0, ()); + ASSERT_LESS(index, kAverageSegmentsCount.size(), ()); + segments.reserve(kAverageSegmentsCount[index]); + for (uint16_t segIndex = 0; segIndex + 1 < static_cast(polyline.GetSize()); ++segIndex) { for (size_t dirIndex = 0; dirIndex < directions.size(); ++dirIndex) From a3b8b93f874167e9ab710aec2e6672f243de6415 Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Wed, 7 Dec 2016 12:38:40 +0300 Subject: [PATCH 4/5] Added attribute provider reuse --- drape/attribute_provider.cpp | 12 ++++++++++++ drape/attribute_provider.hpp | 3 +++ drape_frontend/rule_drawer.cpp | 2 +- drape_frontend/traffic_generator.cpp | 22 ++++++++++++++-------- drape_frontend/traffic_generator.hpp | 5 +++++ 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/drape/attribute_provider.cpp b/drape/attribute_provider.cpp index 1271c8feb0..768bcee738 100644 --- a/drape/attribute_provider.cpp +++ b/drape/attribute_provider.cpp @@ -84,6 +84,18 @@ void AttributeProvider::InitStream(uint8_t streamIndex, INIT_STREAM(streamIndex); } +void AttributeProvider::Reset(uint32_t vertexCount) +{ + m_vertexCount = vertexCount; +} + +void AttributeProvider::UpdateStream(uint8_t streamIndex, ref_ptr data) +{ + ASSERT_LESS(streamIndex, GetStreamCount(), ()); + m_streams[streamIndex].m_data = data; + INIT_STREAM(streamIndex); +} + #ifdef DEBUG void AttributeProvider::CheckStreams() const { diff --git a/drape/attribute_provider.hpp b/drape/attribute_provider.hpp index 05432e7484..6782358932 100644 --- a/drape/attribute_provider.hpp +++ b/drape/attribute_provider.hpp @@ -27,6 +27,9 @@ public: BindingInfo const & bindingInfo, ref_ptr data); + void Reset(uint32_t vertexCount); + void UpdateStream(uint8_t streamIndex, ref_ptr data); + private: int32_t m_vertexCount; diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp index f78fcb7086..32058ef6b6 100644 --- a/drape_frontend/rule_drawer.cpp +++ b/drape_frontend/rule_drawer.cpp @@ -69,7 +69,7 @@ void ExtractTrafficGeometry(FeatureType const & f, df::RoadClass const & roadCla auto & segments = geometry[f.GetID().m_mwmId]; int const index = zoomLevel - 10; // 10 - the first zoom level in kAverageSegmentsCount. - ASSERT_GREATER(index, 0, ()); + ASSERT_GREATER_OR_EQUAL(index, 0, ()); ASSERT_LESS(index, kAverageSegmentsCount.size(), ()); segments.reserve(kAverageSegmentsCount[index]); diff --git a/drape_frontend/traffic_generator.cpp b/drape_frontend/traffic_generator.cpp index f6a4855197..819408bfa0 100644 --- a/drape_frontend/traffic_generator.cpp +++ b/drape_frontend/traffic_generator.cpp @@ -187,6 +187,12 @@ void TrafficGenerator::Init() m_batchersPool = make_unique_dp>( kBatchersCount, bind(&TrafficGenerator::FlushGeometry, this, _1, _2, _3), kBatchSize, kBatchSize); + + m_providerLines.InitStream(0 /* stream index */, GetTrafficLineStaticBindingInfo(), nullptr); + m_providerLines.InitStream(1 /* stream index */, GetTrafficDynamicBindingInfo(), nullptr); + + m_providerTriangles.InitStream(0 /* stream index */, GetTrafficStaticBindingInfo(), nullptr); + m_providerTriangles.InitStream(1 /* stream index */, GetTrafficDynamicBindingInfo(), nullptr); } void TrafficGenerator::ClearGLDependentResources() @@ -268,13 +274,13 @@ void TrafficGenerator::FlushSegmentsGeometry(TileKey const & tileKey, TrafficSeg drape_ptr handle = make_unique_dp(sid, g.m_roadClass, g.m_polyline.GetLimitRect(), uv, staticGeometry.size()); - dp::AttributeProvider provider(2 /* stream count */, staticGeometry.size()); - provider.InitStream(0 /* stream index */, GetTrafficLineStaticBindingInfo(), make_ref(staticGeometry.data())); - provider.InitStream(1 /* stream index */, GetTrafficDynamicBindingInfo(), make_ref(dynamicGeometry.data())); + m_providerLines.Reset(staticGeometry.size()); + m_providerLines.UpdateStream(0 /* stream index */, make_ref(staticGeometry.data())); + m_providerLines.UpdateStream(1 /* stream index */, make_ref(dynamicGeometry.data())); dp::GLState curLineState = lineState; curLineState.SetLineWidth(w * df::VisualParams::Instance().GetVisualScale()); - batcher->InsertLineStrip(curLineState, make_ref(&provider), move(handle)); + batcher->InsertLineStrip(curLineState, make_ref(&m_providerLines), move(handle)); generatedAsLine = true; } } @@ -293,10 +299,10 @@ void TrafficGenerator::FlushSegmentsGeometry(TileKey const & tileKey, TrafficSeg drape_ptr handle = make_unique_dp(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)); + m_providerTriangles.Reset(staticGeometry.size()); + m_providerTriangles.UpdateStream(0 /* stream index */, make_ref(staticGeometry.data())); + m_providerTriangles.UpdateStream(1 /* stream index */, make_ref(dynamicGeometry.data())); + batcher->InsertTriangleList(state, make_ref(&m_providerTriangles), move(handle)); } } } diff --git a/drape_frontend/traffic_generator.hpp b/drape_frontend/traffic_generator.hpp index 69c22c4e9a..ceacb32c19 100644 --- a/drape_frontend/traffic_generator.hpp +++ b/drape_frontend/traffic_generator.hpp @@ -169,6 +169,8 @@ public: explicit TrafficGenerator(TFlushRenderDataFn flushFn) : m_flushRenderDataFn(flushFn) + , m_providerTriangles(2 /* stream count */, 0 /* vertices count*/) + , m_providerLines(2 /* stream count */, 0 /* vertices count*/) {} void Init(); @@ -237,6 +239,9 @@ private: drape_ptr> m_batchersPool; TFlushRenderDataFn m_flushRenderDataFn; + + dp::AttributeProvider m_providerTriangles; + dp::AttributeProvider m_providerLines; }; } // namespace df From c6b1b10015153078da6a926022dba7d38e0e1cda Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Wed, 7 Dec 2016 14:02:16 +0300 Subject: [PATCH 5/5] Review fixes --- drape_frontend/rule_drawer.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drape_frontend/rule_drawer.cpp b/drape_frontend/rule_drawer.cpp index 32058ef6b6..49368bf3e3 100644 --- a/drape_frontend/rule_drawer.cpp +++ b/drape_frontend/rule_drawer.cpp @@ -29,7 +29,10 @@ namespace { int constexpr kOutlineMinZoomLevel = 16; - // 10 11 12 13 14 15 16 17 18 19 + +// The first zoom level in kAverageSegmentsCount. +int constexpr kFirstZoomInAverageSegments = 10; +// 10 11 12 13 14 15 16 17 18 19 vector const kAverageSegmentsCount = { 10000, 5000, 10000, 5000, 2500, 5000, 2000, 1000, 500, 500 }; df::BaseApplyFeature::HotelData ExtractHotelData(FeatureType const & f) @@ -68,7 +71,7 @@ void ExtractTrafficGeometry(FeatureType const & f, df::RoadClass const & roadCla traffic::TrafficInfo::RoadSegmentId::kReverseDirection}; auto & segments = geometry[f.GetID().m_mwmId]; - int const index = zoomLevel - 10; // 10 - the first zoom level in kAverageSegmentsCount. + int const index = zoomLevel - kFirstZoomInAverageSegments; ASSERT_GREATER_OR_EQUAL(index, 0, ()); ASSERT_LESS(index, kAverageSegmentsCount.size(), ()); segments.reserve(kAverageSegmentsCount[index]);