diff --git a/drape_frontend/backend_renderer.cpp b/drape_frontend/backend_renderer.cpp index 96f15c0451..d81d0c3bac 100644 --- a/drape_frontend/backend_renderer.cpp +++ b/drape_frontend/backend_renderer.cpp @@ -28,7 +28,7 @@ BackendRenderer::BackendRenderer(Params const & params) : BaseRenderer(ThreadsCommutator::ResourceUploadThread, params) , m_model(params.m_model) , m_readManager(make_unique_dp(params.m_commutator, m_model, params.m_allow3dBuildings)) - , m_trafficGenerator(make_unique_dp()) + , m_trafficGenerator(make_unique_dp(bind(&BackendRenderer::FlushTrafficRenderData, this, _1))) , m_requestedTiles(params.m_requestedTiles) , m_updateCurrentCountryFn(params.m_updateCurrentCountryFn) { @@ -200,7 +200,7 @@ void BackendRenderer::AcceptMessage(ref_ptr message) auto const & tileKey = msg->GetKey(); if (m_requestedTiles->CheckTileKey(tileKey) && m_readManager->CheckTileKey(tileKey)) { - ref_ptr batcher = m_batchersPool->GetTileBatcher(tileKey); + ref_ptr batcher = m_batchersPool->GetBatcher(tileKey); for (drape_ptr const & shape : msg->GetShapes()) { batcher->SetFeatureMinZoom(shape->GetFeatureMinZoom()); @@ -352,11 +352,7 @@ void BackendRenderer::AcceptMessage(ref_ptr message) if (segments.size() < msg->GetSegmentsColoring().size()) { - vector data; - m_trafficGenerator->GetTrafficGeom(m_texMng, msg->GetSegmentsColoring(), data); - m_commutator->PostMessage(ThreadsCommutator::RenderThread, - make_unique_dp(move(data)), - MessagePriority::Normal); + m_trafficGenerator->GetTrafficGeom(m_texMng, msg->GetSegmentsColoring()); if (m_trafficGenerator->IsColorsCacheRefreshed()) { @@ -368,7 +364,17 @@ void BackendRenderer::AcceptMessage(ref_ptr message) } break; } + case Message::ClearTrafficData: + { + ref_ptr msg = message; + m_trafficGenerator->ClearCache(msg->GetMwmId()); + + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(msg->GetMwmId()), + MessagePriority::Normal); + break; + } case Message::DrapeApiAddLines: { ref_ptr msg = message; @@ -403,6 +409,7 @@ void BackendRenderer::ReleaseResources() m_batchersPool.reset(); m_routeBuilder.reset(); m_overlays.clear(); + m_trafficGenerator.reset(); m_texMng->Release(); m_contextFactory->getResourcesUploadContext()->doneCurrent(); @@ -426,7 +433,7 @@ void BackendRenderer::OnContextDestroy() m_batchersPool.reset(); m_texMng->Release(); m_overlays.clear(); - m_trafficGenerator->ClearCache(); + m_trafficGenerator->ClearGLDependentResources(); m_contextFactory->getResourcesUploadContext()->doneCurrent(); } @@ -449,8 +456,10 @@ void BackendRenderer::Routine::Do() void BackendRenderer::InitGLDependentResource() { - m_batchersPool = make_unique_dp(ReadManager::ReadCount(), - bind(&BackendRenderer::FlushGeometry, this, _1)); + m_batchersPool = make_unique_dp>(ReadManager::ReadCount(), + bind(&BackendRenderer::FlushGeometry, this, _1, _2, _3)); + m_trafficGenerator->Init(); + dp::TextureManager::Params params; params.m_resPostfix = VisualParams::Instance().GetResourcePostfix(); params.m_visualScale = df::VisualParams::Instance().GetVisualScale(); @@ -475,10 +484,19 @@ void BackendRenderer::RecacheMapShapes() m_commutator->PostMessage(ThreadsCommutator::RenderThread, move(msg), MessagePriority::High); } -void BackendRenderer::FlushGeometry(drape_ptr && message) +void BackendRenderer::FlushGeometry(TileKey const & key, dp::GLState const & state, drape_ptr && buffer) { GLFunctions::glFlush(); - m_commutator->PostMessage(ThreadsCommutator::RenderThread, move(message), MessagePriority::Normal); + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(key, state, move(buffer)), + MessagePriority::Normal); +} + +void BackendRenderer::FlushTrafficRenderData(TrafficRenderData && renderData) +{ + m_commutator->PostMessage(ThreadsCommutator::RenderThread, + make_unique_dp(move(renderData)), + MessagePriority::Normal); } void BackendRenderer::CleanupOverlays(TileKey const & tileKey) diff --git a/drape_frontend/backend_renderer.hpp b/drape_frontend/backend_renderer.hpp index d85a22db71..6f8f08796e 100644 --- a/drape_frontend/backend_renderer.hpp +++ b/drape_frontend/backend_renderer.hpp @@ -3,6 +3,7 @@ #include "drape_frontend/gui/layer_render.hpp" #include "drape_frontend/base_renderer.hpp" +#include "drape_frontend/batchers_pool.hpp" #include "drape_frontend/drape_api_builder.hpp" #include "drape_frontend/map_data_provider.hpp" #include "drape_frontend/overlay_batcher.hpp" @@ -24,7 +25,6 @@ namespace df { class Message; -class BatchersPool; class ReadManager; class RouteBuilder; @@ -88,12 +88,14 @@ private: void ReleaseResources(); void InitGLDependentResource(); - void FlushGeometry(drape_ptr && message); + void FlushGeometry(TileKey const & key, dp::GLState const & state, drape_ptr && buffer); + + void FlushTrafficRenderData(TrafficRenderData && renderData); void CleanupOverlays(TileKey const & tileKey); MapDataProvider m_model; - drape_ptr m_batchersPool; + drape_ptr> m_batchersPool; drape_ptr m_readManager; drape_ptr m_routeBuilder; drape_ptr m_trafficGenerator; diff --git a/drape_frontend/batchers_pool.cpp b/drape_frontend/batchers_pool.cpp deleted file mode 100644 index ce0423cdfe..0000000000 --- a/drape_frontend/batchers_pool.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "drape_frontend/batchers_pool.hpp" -#include "drape_frontend/message_subclasses.hpp" - -#include "drape/batcher.hpp" - -#include "base/assert.hpp" - -#include "std/bind.hpp" - -namespace df -{ - -using dp::Batcher; - -namespace -{ - -void FlushGeometry(BatchersPool::TSendMessageFn const & sendMessage, - TileKey const & key, - dp::GLState const & state, - drape_ptr && buffer) -{ - sendMessage(make_unique_dp(key, state, move(buffer))); -} - -} // namespace - -BatchersPool::BatchersPool(int initBatcherCount, TSendMessageFn const & sendMessageFn) - : m_sendMessageFn(sendMessageFn) - , m_pool(initBatcherCount, dp::BatcherFactory()) -{} - -BatchersPool::~BatchersPool() -{ - for_each(m_batchs.begin(), m_batchs.end(), [this](pair const & p) - { - m_pool.Return(p.second.first); - }); - - m_batchs.clear(); -} - -void BatchersPool::ReserveBatcher(TileKey const & key) -{ - TIterator it = m_batchs.find(key); - if (it != m_batchs.end()) - { - it->second.second++; - return; - } - Batcher * batcher = m_pool.Get(); - m_batchs.insert(make_pair(key, make_pair(batcher, 1))); - batcher->StartSession(bind(&FlushGeometry, m_sendMessageFn, key, _1, _2)); -} - -ref_ptr BatchersPool::GetTileBatcher(TileKey const & key) -{ - TIterator it = m_batchs.find(key); - ASSERT(it != m_batchs.end(), ()); - return make_ref(it->second.first); -} - -void BatchersPool::ReleaseBatcher(TileKey const & key) -{ - TIterator it = m_batchs.find(key); - ASSERT(it != m_batchs.end(), ()); - ASSERT_GREATER(it->second.second, 0, ()); - if ((--it->second.second)== 0) - { - Batcher * batcher = it->second.first; - batcher->EndSession(); - m_pool.Return(batcher); - m_batchs.erase(it); - } -} - -} // namespace df diff --git a/drape_frontend/batchers_pool.hpp b/drape_frontend/batchers_pool.hpp index 85e2b7145a..c573d6d7fd 100644 --- a/drape_frontend/batchers_pool.hpp +++ b/drape_frontend/batchers_pool.hpp @@ -1,11 +1,12 @@ #pragma once -#include "drape_frontend/tile_info.hpp" - #include "drape/pointers.hpp" #include "drape/object_pool.hpp" #include "drape/batcher.hpp" +#include "base/assert.hpp" + +#include "std/bind.hpp" #include "std/map.hpp" #include "std/stack.hpp" #include "std/function.hpp" @@ -13,25 +14,67 @@ namespace df { -class Message; // Not thread safe +template class BatchersPool { public: - typedef function &&)> TSendMessageFn; + typedef function && buffer)> TFlushFn; - BatchersPool(int initBatcherCount, TSendMessageFn const & sendMessageFn); - ~BatchersPool(); + BatchersPool(int initBatcherCount, TFlushFn const & flushFn) + : m_flushFn(flushFn) + , m_pool(initBatcherCount, dp::BatcherFactory()) + {} - void ReserveBatcher(TileKey const & key); - ref_ptr GetTileBatcher(TileKey const & key); - void ReleaseBatcher(TileKey const & key); + ~BatchersPool() + { + for_each(m_batchs.begin(), m_batchs.end(), [this](pair const & p) + { + m_pool.Return(p.second.first); + }); + + m_batchs.clear(); + } + + void ReserveBatcher(TKey const & key) + { + TIterator it = m_batchs.find(key); + if (it != m_batchs.end()) + { + it->second.second++; + return; + } + dp::Batcher * batcher = m_pool.Get(); + m_batchs.insert(make_pair(key, make_pair(batcher, 1))); + batcher->StartSession(bind(m_flushFn, key, _1, _2)); + } + + ref_ptr GetBatcher(TKey const & key) + { + TIterator it = m_batchs.find(key); + ASSERT(it != m_batchs.end(), ()); + return make_ref(it->second.first); + } + + void ReleaseBatcher(TKey const & key) + { + TIterator it = m_batchs.find(key); + ASSERT(it != m_batchs.end(), ()); + ASSERT_GREATER(it->second.second, 0, ()); + if ((--it->second.second)== 0) + { + dp::Batcher * batcher = it->second.first; + batcher->EndSession(); + m_pool.Return(batcher); + m_batchs.erase(it); + } + } private: typedef pair TBatcherPair; - typedef map TBatcherMap; - typedef TBatcherMap::iterator TIterator; - TSendMessageFn m_sendMessageFn; + typedef map TBatcherMap; + typedef typename TBatcherMap::iterator TIterator; + TFlushFn m_flushFn; ObjectPool m_pool; TBatcherMap m_batchs; diff --git a/drape_frontend/drape_engine.cpp b/drape_frontend/drape_engine.cpp index fc873eccd2..782bfcc390 100644 --- a/drape_frontend/drape_engine.cpp +++ b/drape_frontend/drape_engine.cpp @@ -555,7 +555,9 @@ void DrapeEngine::UpdateTraffic(TrafficSegmentsColoring const & segmentsColoring void DrapeEngine::ClearTrafficCache(MwmSet::MwmId const & mwmId) { - // TODO(@rokuz): implement + m_threadCommutator->PostMessage(ThreadsCommutator::ResourceUploadThread, + make_unique_dp(mwmId), + MessagePriority::Normal); } void DrapeEngine::SetFontScaleFactor(double scaleFactor) diff --git a/drape_frontend/drape_frontend.pro b/drape_frontend/drape_frontend.pro index cfbc65a284..b65e2f9ce9 100755 --- a/drape_frontend/drape_frontend.pro +++ b/drape_frontend/drape_frontend.pro @@ -43,7 +43,6 @@ SOURCES += \ arrow3d.cpp \ backend_renderer.cpp \ base_renderer.cpp \ - batchers_pool.cpp \ batch_merge_helper.cpp \ circle_shape.cpp \ color_constants.cpp \ diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index a2288f8bd7..2ceee8dd3a 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -760,6 +760,11 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) break; } + case Message::ClearTrafficData: + { + ref_ptr msg = message; + m_trafficRenderer->Clear(msg->GetMwmId()); + } case Message::DrapeApiFlush: { ref_ptr msg = message; @@ -823,6 +828,8 @@ void FrontendRenderer::UpdateGLResources() MessagePriority::Normal); } + m_trafficRenderer->ClearGLDependentResources(); + // Request new tiles. ScreenBase screen = m_userEventStream.GetCurrentScreen(); m_lastReadedModelView = screen; @@ -1599,7 +1606,7 @@ void FrontendRenderer::OnContextDestroy() m_myPositionController->ResetRenderShape(); m_routeRenderer->ClearGLDependentResources(); m_gpsTrackRenderer->ClearRenderData(); - m_trafficRenderer->Clear(); + m_trafficRenderer->ClearGLDependentResources(); m_drapeApiRenderer->Clear(); #ifdef RENDER_DEBUG_RECTS @@ -1766,6 +1773,7 @@ void FrontendRenderer::ReleaseResources() m_routeRenderer.reset(); m_framebuffer.reset(); m_transparentLayer.reset(); + m_trafficRenderer.reset(); m_gpuProgramManager.reset(); m_contextFactory->getDrawContext()->doneCurrent(); diff --git a/drape_frontend/message.hpp b/drape_frontend/message.hpp index 7c6d351920..6c9cd7a07c 100644 --- a/drape_frontend/message.hpp +++ b/drape_frontend/message.hpp @@ -69,6 +69,7 @@ public: SetTrafficTexCoords, UpdateTraffic, FlushTrafficData, + ClearTrafficData, DrapeApiAddLines, DrapeApiRemove, DrapeApiFlush, diff --git a/drape_frontend/message_subclasses.hpp b/drape_frontend/message_subclasses.hpp index 6d45e9cac4..f1b67c14f8 100644 --- a/drape_frontend/message_subclasses.hpp +++ b/drape_frontend/message_subclasses.hpp @@ -999,6 +999,8 @@ public: {} Type GetType() const override { return Message::SetTrafficTexCoords; } + bool IsGLContextDependent() const override { return true; } + TrafficTexCoords && AcceptTexCoords() { return move(m_texCoords); } private: @@ -1013,6 +1015,8 @@ public: {} Type GetType() const override { return Message::UpdateTraffic; } + bool IsGLContextDependent() const override { return true; } + TrafficSegmentsColoring const & GetSegmentsColoring() const { return m_segmentsColoring; } private: @@ -1022,15 +1026,31 @@ private: class FlushTrafficDataMessage : public Message { public: - explicit FlushTrafficDataMessage(vector && trafficData) + explicit FlushTrafficDataMessage(TrafficRenderData && trafficData) : m_trafficData(move(trafficData)) {} Type GetType() const override { return Message::FlushTrafficData; } - vector && AcceptTrafficData() { return move(m_trafficData); } + bool IsGLContextDependent() const override { return true; } + + TrafficRenderData && AcceptTrafficData() { return move(m_trafficData); } private: - vector m_trafficData; + TrafficRenderData m_trafficData; +}; + +class ClearTrafficDataMessage : public Message +{ +public: + explicit ClearTrafficDataMessage(MwmSet::MwmId const & mwmId) + : m_mwmId(mwmId) + {} + + Type GetType() const override { return Message::ClearTrafficData; } + MwmSet::MwmId const & GetMwmId() { return m_mwmId; } + +private: + MwmSet::MwmId m_mwmId; }; class DrapeApiAddLinesMessage : public Message diff --git a/drape_frontend/traffic_generator.cpp b/drape_frontend/traffic_generator.cpp index 6fb79e1996..6e7a5d9881 100644 --- a/drape_frontend/traffic_generator.cpp +++ b/drape_frontend/traffic_generator.cpp @@ -7,7 +7,6 @@ #include "drape_frontend/tile_utils.hpp" #include "drape/attribute_provider.hpp" -#include "drape/batcher.hpp" #include "drape/glsl_func.hpp" #include "drape/shader_def.hpp" #include "drape/texture_manager.hpp" @@ -154,6 +153,18 @@ TrafficSegmentID TrafficHandle::GetSegmentId() const return m_segmentId; } +void TrafficGenerator::Init() +{ + m_batchersPool = make_unique_dp>( + 1, bind(&TrafficGenerator::FlushGeometry, this, _1, _2, _3)); +} + +void TrafficGenerator::ClearGLDependentResources() +{ + ClearCache(); + m_batchersPool.reset(); +} + void TrafficGenerator::AddSegment(TrafficSegmentID const & segmentId, m2::PolylineD const & polyline) { m_segments.insert(make_pair(segmentId, polyline)); @@ -165,6 +176,18 @@ void TrafficGenerator::ClearCache() m_segmentsCache.clear(); } +void TrafficGenerator::ClearCache(MwmSet::MwmId const & mwmId) +{ + auto it = m_segmentsCache.begin(); + while (it != m_segmentsCache.end()) + { + if (it->m_mwmId == mwmId) + it = m_segmentsCache.erase(it); + else + ++it; + } +} + TrafficSegmentsColoring TrafficGenerator::GetSegmentsToUpdate(TrafficSegmentsColoring const & trafficColoring) const { TrafficSegmentsColoring result; @@ -176,9 +199,17 @@ TrafficSegmentsColoring TrafficGenerator::GetSegmentsToUpdate(TrafficSegmentsCol return result; } +void TrafficGenerator::FlushGeometry(TrafficBatcherKey const & key, dp::GLState const & state, drape_ptr && buffer) +{ + TrafficRenderData renderData(state); + renderData.m_bucket = move(buffer); + renderData.m_mwmId = key.m_mwmId; + renderData.m_tileKey = key.m_tileKey; + m_flushRenderDataFn(move(renderData)); +} + void TrafficGenerator::GetTrafficGeom(ref_ptr textures, - TrafficSegmentsColoring const & trafficColoring, - vector & data) + TrafficSegmentsColoring const & trafficColoring) { FillColorsCache(textures); @@ -188,7 +219,6 @@ void TrafficGenerator::GetTrafficGeom(ref_ptr textures, state.SetMaskTexture(textures->GetTrafficArrowTexture()); int const kZoomLevel = 10; - uint32_t const kBatchSize = 5000; using TSegIter = TSegmentCollection::iterator; map>> segmentsByTiles; @@ -211,18 +241,16 @@ void TrafficGenerator::GetTrafficGeom(ref_ptr textures, for (auto const & s : segmentsByTiles) { TileKey const & tileKey = s.first; - dp::Batcher batcher(kBatchSize, kBatchSize); - dp::SessionGuard guard(batcher, [&data, &tileKey](dp::GLState const & state, drape_ptr && b) - { - TrafficRenderData bucket(state); - bucket.m_bucket = move(b); - bucket.m_tileKey = tileKey; - data.emplace_back(move(bucket)); - }); for (auto const & segmentPair : s.second) { TSegIter it = segmentPair.first; + + TrafficBatcherKey bk(it->first.m_mwmId, tileKey); + + m_batchersPool->ReserveBatcher(bk); + ref_ptr batcher = m_batchersPool->GetBatcher(bk); + ASSERT(m_colorsCacheValid, ()); dp::TextureManager::ColorRegion const & colorRegion = m_colorsCache[static_cast(segmentPair.second)]; m2::PolylineD const & polyline = it->second; @@ -241,8 +269,11 @@ void TrafficGenerator::GetTrafficGeom(ref_ptr textures, 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)); + 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(); diff --git a/drape_frontend/traffic_generator.hpp b/drape_frontend/traffic_generator.hpp index eec4aaf286..1b8eb8a132 100644 --- a/drape_frontend/traffic_generator.hpp +++ b/drape_frontend/traffic_generator.hpp @@ -1,5 +1,6 @@ #pragma once +#include "drape_frontend/batchers_pool.hpp" #include "drape_frontend/tile_key.hpp" #include "drape/color.hpp" @@ -71,6 +72,7 @@ struct TrafficRenderData dp::GLState m_state; drape_ptr m_bucket; TileKey m_tileKey; + MwmSet::MwmId m_mwmId; TrafficRenderData(dp::GLState const & state) : m_state(state) {} }; @@ -128,22 +130,51 @@ using TrafficTexCoords = unordered_map; class TrafficGenerator final { public: - TrafficGenerator() = default; + typedef function TFlushRenderDataFn; + + TrafficGenerator(TFlushRenderDataFn flushFn) + : m_flushRenderDataFn(flushFn) + {} + + void Init(); + void ClearGLDependentResources(); void AddSegment(TrafficSegmentID const & segmentId, m2::PolylineD const & polyline); TrafficSegmentsColoring GetSegmentsToUpdate(TrafficSegmentsColoring const & trafficColoring) const; void GetTrafficGeom(ref_ptr textures, - TrafficSegmentsColoring const & trafficColoring, - vector & data); + TrafficSegmentsColoring const & trafficColoring); void ClearCache(); + void ClearCache(MwmSet::MwmId const & mwmId); bool IsColorsCacheRefreshed() const { return m_colorsCacheRefreshed; } TrafficTexCoords ProcessCacheRefreshing(); private: + struct TrafficBatcherKey + { + TrafficBatcherKey() = default; + TrafficBatcherKey(MwmSet::MwmId const & mwmId, TileKey const & tileKey) + : m_mwmId(mwmId) + , m_tileKey(tileKey) + {} + + MwmSet::MwmId m_mwmId; + TileKey m_tileKey; + }; + + struct TrafficBatcherKeyComparator + { + bool operator() (TrafficBatcherKey const & lhs, TrafficBatcherKey const & rhs) const + { + if (lhs.m_mwmId == rhs.m_mwmId) + return lhs.m_tileKey < rhs.m_tileKey; + return lhs.m_mwmId < rhs.m_mwmId; + } + }; + using TSegmentCollection = map; void GenerateSegment(dp::TextureManager::ColorRegion const & colorRegion, @@ -152,12 +183,17 @@ private: vector & dynamicGeometry); void FillColorsCache(ref_ptr textures); + void FlushGeometry(TrafficBatcherKey const & key, dp::GLState const & state, drape_ptr && buffer); + TSegmentCollection m_segments; set m_segmentsCache; array(traffic::SpeedGroup::Count)> m_colorsCache; bool m_colorsCacheValid = false; bool m_colorsCacheRefreshed = false; + + drape_ptr> m_batchersPool; + TFlushRenderDataFn m_flushRenderDataFn; }; } // namespace df diff --git a/drape_frontend/traffic_renderer.cpp b/drape_frontend/traffic_renderer.cpp index 8444aab29d..370a13919c 100644 --- a/drape_frontend/traffic_renderer.cpp +++ b/drape_frontend/traffic_renderer.cpp @@ -60,24 +60,18 @@ float CalculateHalfWidth(ScreenBase const & screen, bool left) } // namespace void TrafficRenderer::AddRenderData(ref_ptr mng, - vector && renderData) + TrafficRenderData && renderData) { - if (renderData.empty()) - return; + m_renderData.emplace_back(move(renderData)); - size_t const startIndex = m_renderData.size(); - m_renderData.reserve(m_renderData.size() + renderData.size()); - move(renderData.begin(), renderData.end(), std::back_inserter(m_renderData)); - for (size_t i = startIndex; i < m_renderData.size(); i++) + ref_ptr program = mng->GetProgram(m_renderData.back().m_state.GetProgramIndex()); + program->Bind(); + m_renderData.back().m_bucket->GetBuffer()->Build(program); + + for (size_t j = 0; j < m_renderData.back().m_bucket->GetOverlayHandlesCount(); j++) { - ref_ptr program = mng->GetProgram(m_renderData[i].m_state.GetProgramIndex()); - program->Bind(); - m_renderData[i].m_bucket->GetBuffer()->Build(program); - for (size_t j = 0; j < m_renderData[i].m_bucket->GetOverlayHandlesCount(); j++) - { - TrafficHandle * handle = static_cast(m_renderData[i].m_bucket->GetOverlayHandle(j).get()); - m_handles.insert(make_pair(handle->GetSegmentId(), handle)); - } + TrafficHandle * handle = static_cast(m_renderData.back().m_bucket->GetOverlayHandle(j).get()); + m_handles.insert(make_pair(handle->GetSegmentId(), handle)); } } @@ -129,10 +123,27 @@ void TrafficRenderer::SetTexCoords(TrafficTexCoords && texCoords) m_texCoords = move(texCoords); } -void TrafficRenderer::Clear() +void TrafficRenderer::ClearGLDependentResources() { m_renderData.clear(); m_handles.clear(); + m_texCoords.clear(); +} + +void TrafficRenderer::Clear(MwmSet::MwmId const & mwmId) +{ + for (size_t i = 0; i < m_renderData.size();) + { + if (m_renderData[i].m_mwmId == mwmId) + { + swap(m_renderData[i], m_renderData.back()); + m_renderData.pop_back(); + } + else + { + ++i; + } + } } } // namespace df diff --git a/drape_frontend/traffic_renderer.hpp b/drape_frontend/traffic_renderer.hpp index e385d8231a..d7d38af220 100644 --- a/drape_frontend/traffic_renderer.hpp +++ b/drape_frontend/traffic_renderer.hpp @@ -21,7 +21,7 @@ public: TrafficRenderer() = default; void AddRenderData(ref_ptr mng, - vector && renderData); + TrafficRenderData && renderData); void SetTexCoords(TrafficTexCoords && texCoords); @@ -31,7 +31,8 @@ public: ref_ptr mng, dp::UniformValuesStorage const & commonUniforms); - void Clear(); + void ClearGLDependentResources(); + void Clear(MwmSet::MwmId const & mwmId); private: vector m_renderData; diff --git a/map/framework.cpp b/map/framework.cpp index d64b903274..a72d1492dc 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -1681,7 +1681,7 @@ void Framework::UpdateDrapeEngine(int width, int height) m_drapeApi.Invalidate(); - //TODO: update traffic data + m_trafficManager.OnRecover(); } } diff --git a/map/traffic_manager.cpp b/map/traffic_manager.cpp index 24238af36f..975034cec2 100644 --- a/map/traffic_manager.cpp +++ b/map/traffic_manager.cpp @@ -42,8 +42,19 @@ void TrafficManager::SetDrapeEngine(ref_ptr engine) m_drapeEngine = engine; } +void TrafficManager::OnRecover() +{ + m_requestTimings.clear(); + m_mwmIds.clear(); + + UpdateViewport(m_currentModelView); + UpdateMyPosition(m_currentPosition); +} + void TrafficManager::UpdateViewport(ScreenBase const & screen) { + m_currentModelView = screen; + if (!m_isEnabled) return; @@ -64,6 +75,8 @@ void TrafficManager::UpdateViewport(ScreenBase const & screen) void TrafficManager::UpdateMyPosition(MyPosition const & myPosition) { + m_currentPosition = myPosition; + if (!m_isEnabled) return; diff --git a/map/traffic_manager.hpp b/map/traffic_manager.hpp index 88f595b6c4..f2ca8dcda2 100644 --- a/map/traffic_manager.hpp +++ b/map/traffic_manager.hpp @@ -50,6 +50,8 @@ public: void UpdateViewport(ScreenBase const & screen); void UpdateMyPosition(MyPosition const & myPosition); + void OnRecover(); + void SetDrapeEngine(ref_ptr engine); private: @@ -70,7 +72,10 @@ private: GetMwmsByRectFn m_getMwmsByRectFn; ref_ptr m_drapeEngine; - m2::PointD m_myPosition; + + MyPosition m_currentPosition; + ScreenBase m_currentModelView; + set m_mwmIds; map> m_requestTimings;