From f2f57c096dd621281e36ce11726d41a8384f3cfd Mon Sep 17 00:00:00 2001 From: ExMix Date: Wed, 5 Jun 2013 17:34:28 +0300 Subject: [PATCH] Remove ScreenCoverage as class. Now we hold one set of information about current coverage, and two display list to render. --- graphics/overlay.cpp | 20 +- graphics/overlay.hpp | 16 +- map/basic_tiling_render_policy.cpp | 31 +- map/basic_tiling_render_policy.hpp | 3 +- map/coverage_generator.cpp | 553 +++++++++++++++++++++++------ map/coverage_generator.hpp | 89 +++-- map/framework.cpp | 5 +- map/map.pro | 2 - map/render_policy.cpp | 4 +- map/render_policy.hpp | 2 +- map/screen_coverage.cpp | 505 -------------------------- map/screen_coverage.hpp | 139 -------- map/tile_renderer.cpp | 40 +-- map/tile_renderer.hpp | 6 - map/tiling_render_policy_mt.cpp | 2 - map/tiling_render_policy_st.cpp | 2 - 16 files changed, 557 insertions(+), 862 deletions(-) delete mode 100644 map/screen_coverage.cpp delete mode 100644 map/screen_coverage.hpp diff --git a/graphics/overlay.cpp b/graphics/overlay.cpp index 3ec44c951e..434f282d90 100644 --- a/graphics/overlay.cpp +++ b/graphics/overlay.cpp @@ -13,17 +13,6 @@ namespace graphics { - Overlay::Lock::Lock(shared_ptr overlay) - : m_overlay(overlay) - { - m_overlay->lock(); - } - - Overlay::Lock::~Lock() - { - m_overlay->unlock(); - } - bool betterOverlayElement(shared_ptr const & l, shared_ptr const & r) { @@ -143,6 +132,11 @@ namespace graphics offsetTree(m_tree, offs, rect); } + size_t Overlay::getElementsCount() const + { + return m_tree.GetSize(); + } + void Overlay::lock() { m_mutex.Lock(); @@ -242,13 +236,13 @@ namespace graphics } }; - void Overlay::selectOverlayElements(m2::RectD const & rect, list > & res) + void Overlay::selectOverlayElements(m2::RectD const & rect, list > & res) const { DoPreciseSelectByRect fn(rect, &res); m_tree.ForEachInRect(rect, fn); } - void Overlay::selectOverlayElements(m2::PointD const & pt, list > & res) + void Overlay::selectOverlayElements(m2::PointD const & pt, list > & res) const { DoPreciseSelectByPoint fn(pt, &res); m_tree.ForEachInRect(m2::RectD(pt - m2::PointD(1, 1), pt + m2::PointD(1, 1)), fn); diff --git a/graphics/overlay.hpp b/graphics/overlay.hpp index 3c5944b904..fcb59f5934 100644 --- a/graphics/overlay.hpp +++ b/graphics/overlay.hpp @@ -37,22 +37,12 @@ namespace graphics public: - class Lock - { - public: - Lock(shared_ptr overlay); - ~Lock(); - - private: - shared_ptr m_overlay; - }; - Overlay(); void draw(OverlayRenderer * r, math::Matrix const & m); - void selectOverlayElements(m2::PointD const & pt, list > & res); - void selectOverlayElements(m2::RectD const & rect, list > & res); + void selectOverlayElements(m2::PointD const & pt, list > & res) const; + void selectOverlayElements(m2::RectD const & rect, list > & res) const; void removeOverlayElement(shared_ptr const & oe, m2::RectD const & r); @@ -62,6 +52,8 @@ namespace graphics void offset(m2::PointD const & offs, m2::RectD const & rect); + size_t getElementsCount() const; + void lock(); void unlock(); diff --git a/map/basic_tiling_render_policy.cpp b/map/basic_tiling_render_policy.cpp index d1504becd7..b15d92bd99 100644 --- a/map/basic_tiling_render_policy.cpp +++ b/map/basic_tiling_render_policy.cpp @@ -6,7 +6,6 @@ #include "tile_renderer.hpp" #include "coverage_generator.hpp" -#include "screen_coverage.hpp" #include "queued_renderer.hpp" size_t BasicTilingRenderPolicy::CalculateTileSize(size_t screenWidth, size_t screenHeight) @@ -40,7 +39,8 @@ BasicTilingRenderPolicy::BasicTilingRenderPolicy(Params const & p, m_DrawScale(0), m_IsEmptyModel(false), m_IsNavigating(false), - m_WasAnimatingLastFrame(false) + m_WasAnimatingLastFrame(false), + m_DoRecreateCoverage(false) { m_TileSize = CalculateTileSize(p.m_screenWidth, p.m_screenHeight); @@ -96,9 +96,11 @@ void BasicTilingRenderPolicy::DrawFrame(shared_ptr const & e, Screen if (!m_IsNavigating && (!IsAnimating())) m_CoverageGenerator->CoverScreen(s, doForceUpdateFromGenerator + || m_DoRecreateCoverage || (doForceUpdate && doIntersectInvalidRect)); SetForceUpdate(false); + m_DoRecreateCoverage = false; /// rendering current coverage @@ -110,25 +112,17 @@ void BasicTilingRenderPolicy::DrawFrame(shared_ptr const & e, Screen FrameLock(); - ScreenCoverage * curCvg = m_CoverageGenerator->CurrentCoverage(); + m_CoverageGenerator->Draw(pDrawer->screen(), s); + m_DrawScale = m_CoverageGenerator->GetDrawScale(); - - if (curCvg) + if (!m_CoverageGenerator->IsEmptyDrawing() || !m_CoverageGenerator->IsPartialCoverage()) { - curCvg->Draw(pDrawer->screen(), s); - - m_DrawScale = curCvg->GetDrawScale(); - - if (!curCvg->IsEmptyDrawingCoverage() || !curCvg->IsPartialCoverage()) - { - m_IsEmptyModel = curCvg->IsEmptyDrawingCoverage() && curCvg->IsEmptyModelAtCoverageCenter(); - if (m_IsEmptyModel) - m_countryIndex = curCvg->GetCountryIndexAtCoverageCenter(); - } + m_IsEmptyModel = m_CoverageGenerator->IsEmptyDrawing() && m_CoverageGenerator->IsEmptyModelAtCenter(); + if (m_IsEmptyModel) + m_countryIndex = m_CoverageGenerator->GetCountryIndexAtCenter(); } pDrawer->endFrame(); - m_CoverageGenerator->FinishSequenceIfNeeded(); } void BasicTilingRenderPolicy::EndFrame(shared_ptr const & e, ScreenBase const & s) @@ -159,6 +153,7 @@ void BasicTilingRenderPolicy::ResumeBackgroundRendering() { m_TileRenderer->SetIsPaused(false); m_CoverageGenerator->Resume(); + m_DoRecreateCoverage = true; if (m_QueuedRenderer) m_QueuedRenderer->SetPartialExecution(GetPlatform().CpuCores(), false); } @@ -259,9 +254,9 @@ void BasicTilingRenderPolicy::FrameUnlock() m_CoverageGenerator->Unlock(); } -shared_ptr const BasicTilingRenderPolicy::FrameOverlay() const +graphics::Overlay * BasicTilingRenderPolicy::FrameOverlay() const { - return m_CoverageGenerator->CurrentCoverage()->GetOverlay(); + return m_CoverageGenerator->GetOverlay(); } int BasicTilingRenderPolicy::InsertBenchmarkFence() diff --git a/map/basic_tiling_render_policy.hpp b/map/basic_tiling_render_policy.hpp index 73922deb7d..b9e16dcb1f 100644 --- a/map/basic_tiling_render_policy.hpp +++ b/map/basic_tiling_render_policy.hpp @@ -40,6 +40,7 @@ protected: bool m_IsNavigating; bool m_WasAnimatingLastFrame; size_t m_TileSize; + bool m_DoRecreateCoverage; protected: @@ -80,7 +81,7 @@ public: void FrameLock(); void FrameUnlock(); - shared_ptr const FrameOverlay() const; + graphics::Overlay * FrameOverlay() const; /// benchmarking protocol int InsertBenchmarkFence(); diff --git a/map/coverage_generator.cpp b/map/coverage_generator.cpp index 187c9b6a17..1e82eae4d9 100644 --- a/map/coverage_generator.cpp +++ b/map/coverage_generator.cpp @@ -1,57 +1,49 @@ #include "../base/SRC_FIRST.hpp" #include "../platform/settings.hpp" +#include "../platform/platform.hpp" #include "coverage_generator.hpp" -#include "screen_coverage.hpp" #include "tile_renderer.hpp" #include "tile_set.hpp" #include "../graphics/opengl/gl_render_context.hpp" +#include "../graphics/display_list.hpp" #include "../base/logging.hpp" #include "../std/bind.hpp" -CoverageGenerator::CoverageGenerator( - TileRenderer * tileRenderer, - shared_ptr const & windowHandle, - shared_ptr const & primaryRC, - shared_ptr const & rm, - graphics::PacketsQueue * glQueue, - RenderPolicy::TCountryIndexFn const & countryIndexFn) - : m_queue(1), - m_tileRenderer(tileRenderer), - m_workCoverage(0), - m_currentCoverage(0), - m_windowHandle(windowHandle), - m_countryIndexFn(countryIndexFn), - m_glQueue(glQueue) +CoverageGenerator::CoverageGenerator(TileRenderer * tileRenderer, + shared_ptr const & windowHandle, + shared_ptr const & primaryRC, + shared_ptr const & rm, + graphics::PacketsQueue * glQueue, + RenderPolicy::TCountryIndexFn const & countryIndexFn) + : m_coverageInfo(tileRenderer) + , m_indexInfo(countryIndexFn) + , m_queue(1) + , m_windowHandle(windowHandle) { - m_resourceManager = rm; + shared_ptr renderContext; + if (!glQueue) + renderContext.reset(primaryRC->createShared()); - if (!m_glQueue) - m_renderContext.reset(primaryRC->createShared()); - - m_queue.AddInitCommand(bind(&CoverageGenerator::InitializeThreadGL, this)); - m_queue.AddFinCommand(bind(&CoverageGenerator::FinalizeThreadGL, this)); + m_queue.AddInitCommand(bind(&CoverageGenerator::InitializeThreadGL, this, renderContext, rm, glQueue)); + m_queue.AddFinCommand(bind(&CoverageGenerator::FinalizeThreadGL, this, renderContext, rm)); m_queue.Start(); Settings::Get("IsBenchmarking", m_benchmarkInfo.m_isBenchmarking); + + m_currentCoverage = new CachedCoverageInfo(); + m_backCoverage = new CachedCoverageInfo(); } CoverageGenerator::~CoverageGenerator() { LOG(LINFO, ("cancelling coverage thread")); m_queue.Cancel(); - - LOG(LINFO, ("deleting workCoverage")); - delete m_workCoverage; - m_workCoverage = 0; - - LOG(LINFO, ("deleting currentCoverage")); - delete m_currentCoverage; - m_currentCoverage = 0; + ClearCoverage(); } void CoverageGenerator::Shutdown() @@ -60,48 +52,40 @@ void CoverageGenerator::Shutdown() m_queue.Join(); } -ScreenCoverage * CoverageGenerator::CreateCoverage() -{ - graphics::Screen::Params params; - - params.m_resourceManager = m_resourceManager; - params.m_renderQueue = m_glQueue; - - params.m_doUnbindRT = false; - params.m_isSynchronized = false; - params.m_threadSlot = m_resourceManager->cacheThreadSlot(); - params.m_renderContext = m_renderContext; - params.m_storageType = graphics::EMediumStorage; - params.m_textureType = graphics::EMediumTexture; - - shared_ptr screen(new graphics::Screen(params)); - - ScreenCoverage * screenCoverage = new ScreenCoverage(m_tileRenderer, this, screen); - screenCoverage->SetBenchmarkingFlag(m_benchmarkInfo.m_isBenchmarking); - - return screenCoverage; -} - -void CoverageGenerator::InitializeThreadGL() +void CoverageGenerator::InitializeThreadGL(shared_ptr context, + shared_ptr resourceManager, + graphics::PacketsQueue * glQueue) { threads::MutexGuard g(m_stateInfo.m_mutex); LOG(LINFO, ("initializing CoverageGenerator on it's own thread.")); - if (m_renderContext) + if (context) { - m_renderContext->makeCurrent(); - m_renderContext->startThreadDrawing(m_resourceManager->cacheThreadSlot()); + context->makeCurrent(); + context->startThreadDrawing(resourceManager->cacheThreadSlot()); } - m_workCoverage = CreateCoverage(); - m_currentCoverage = CreateCoverage(); + graphics::Screen::Params params; + + params.m_resourceManager = resourceManager; + params.m_renderQueue = glQueue; + + params.m_doUnbindRT = false; + params.m_isSynchronized = false; + params.m_threadSlot = resourceManager->cacheThreadSlot(); + params.m_renderContext = context; + params.m_storageType = graphics::EMediumStorage; + params.m_textureType = graphics::EMediumTexture; + + m_cacheScreen.reset(new graphics::Screen(params)); } -void CoverageGenerator::FinalizeThreadGL() +void CoverageGenerator::FinalizeThreadGL(shared_ptr context, + shared_ptr resourceManager) { - if (m_renderContext) - m_renderContext->endThreadDrawing(m_resourceManager->cacheThreadSlot()); + if (context) + context->endThreadDrawing(resourceManager->cacheThreadSlot()); } void CoverageGenerator::Pause() @@ -158,16 +142,6 @@ void CoverageGenerator::FinishSequenceIfNeeded() m_queue.AddCommand(bind(&CoverageGenerator::BenchmarkInfo::TryFinishSequence, &m_benchmarkInfo)); } -void CoverageGenerator::DecrementTileCount(int sequenceID) -{ - m_queue.AddCommand(bind(&CoverageGenerator::BenchmarkInfo::DecrementTileCount, &m_benchmarkInfo, sequenceID)); -} - -ScreenCoverage * CoverageGenerator::CurrentCoverage() -{ - return m_currentCoverage; -} - void CoverageGenerator::Lock() { m_stateInfo.m_mutex.Lock(); @@ -178,16 +152,48 @@ void CoverageGenerator::Unlock() m_stateInfo.m_mutex.Unlock(); } -void CoverageGenerator::StartTileDrawingSession(int sequenceID, unsigned tileCount) +void CoverageGenerator::Draw(graphics::Screen * s, ScreenBase const & screen) { - ASSERT(m_benchmarkInfo.m_isBenchmarking, ("Only in benchmarking mode!")); - m_benchmarkInfo.m_benchmarkSequenceID = sequenceID; - m_benchmarkInfo.m_tilesCount = tileCount; + math::Matrix m = m_currentCoverage->m_screen.PtoGMatrix() * screen.GtoPMatrix(); + + ASSERT(m_currentCoverage, ()); + if (m_currentCoverage->m_mainElements) + s->drawDisplayList(m_currentCoverage->m_mainElements, m); + if (m_currentCoverage->m_sharpElements) + s->drawDisplayList(m_currentCoverage->m_sharpElements, m); + + if (m_benchmarkInfo.m_isBenchmarking) + FinishSequenceIfNeeded(); } storage::TIndex CoverageGenerator::GetCountryIndex(m2::PointD const & pt) const { - return m_countryIndexFn(pt); + return m_indexInfo.m_countryIndexFn(pt); +} + +storage::TIndex CoverageGenerator::GetCountryIndexAtCenter() const +{ + return m_indexInfo.m_countryIndex; +} + +graphics::Overlay * CoverageGenerator::GetOverlay() const +{ + return m_coverageInfo.m_overlay; +} + +bool CoverageGenerator::IsEmptyDrawing() const +{ + return (m_coverageInfo.m_renderLeafTilesCount <= 0) && m_coverageInfo.m_isEmptyDrawing; +} + +bool CoverageGenerator::IsEmptyModelAtCenter() const +{ + return m_indexInfo.m_countryIndex.IsValid(); +} + +bool CoverageGenerator::IsPartialCoverage() const +{ + return m_coverageInfo.m_hasTileCahceMiss; } bool CoverageGenerator::DoForceUpdate() const @@ -195,6 +201,11 @@ bool CoverageGenerator::DoForceUpdate() const return m_stateInfo.m_needForceUpdate; } +int CoverageGenerator::GetDrawScale() const +{ + return m_coverageInfo.m_tiler.tileScale(); +} + //////////////////////////////////////////////////// /// Benchmark support //////////////////////////////////////////////////// @@ -218,23 +229,24 @@ void CoverageGenerator::CoverScreenImpl(core::CommandsQueue::Environment const & if (sequenceID < m_stateInfo.m_sequenceID) return; - m_currentCoverage->CopyInto(*m_workCoverage, false); + m_stateInfo.m_currentScreen = screen; + m_backCoverage->m_screen = screen; + m_coverageInfo.m_tiler.seed(screen, screen.GlobalRect().GlobalCenter(), m_coverageInfo.m_tileRenderer->TileSize()); - m_workCoverage->SetSequenceID(sequenceID); - m_workCoverage->SetScreen(screen); + ComputeCoverTasks(); - if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage()) + if (!IsPartialCoverage() && IsEmptyDrawing()) { - m_workCoverage->ResetEmptyModelAtCoverageCenter(); + m_indexInfo.m_countryIndex = storage::TIndex(); CheckEmptyModel(sequenceID); } - bool shouldSwap = !m_stateInfo.m_isPause && m_workCoverage->Cache(env); + bool shouldSwap = !m_stateInfo.m_isPause && CacheCoverage(env); if (shouldSwap) { threads::MutexGuard g(m_stateInfo.m_mutex); - swap(m_currentCoverage, m_workCoverage); + swap(m_currentCoverage, m_backCoverage); } else { @@ -243,9 +255,6 @@ void CoverageGenerator::CoverScreenImpl(core::CommandsQueue::Environment const & } m_stateInfo.SetForceUpdate(!shouldSwap); - - m_workCoverage->Clear(); - m_windowHandle->invalidate(); } @@ -255,48 +264,65 @@ void CoverageGenerator::MergeTileImpl(core::CommandsQueue::Environment const & e { if (sequenceID < m_stateInfo.m_sequenceID) { - m_tileRenderer->RemoveActiveTile(rectInfo, sequenceID); + m_coverageInfo.m_tileRenderer->RemoveActiveTile(rectInfo, sequenceID); return; } - m_currentCoverage->CopyInto(*m_workCoverage, true); - m_workCoverage->SetSequenceID(sequenceID); - m_workCoverage->Merge(rectInfo); + m_backCoverage->m_screen = m_stateInfo.m_currentScreen; + MergeSingleTile(rectInfo); - if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage()) + if (!IsPartialCoverage() && IsEmptyDrawing()) { - m_workCoverage->ResetEmptyModelAtCoverageCenter(); + m_indexInfo.m_countryIndex = storage::TIndex(); CheckEmptyModel(sequenceID); } - bool shouldSwap = !m_stateInfo.m_isPause && m_workCoverage->Cache(env); + bool shouldSwap = !m_stateInfo.m_isPause && CacheCoverage(env); if (shouldSwap) { threads::MutexGuard g(m_stateInfo.m_mutex); - swap(m_currentCoverage, m_workCoverage); + swap(m_currentCoverage, m_backCoverage); m_benchmarkInfo.DecrementTileCount(sequenceID); } m_stateInfo.SetForceUpdate(!shouldSwap); - m_workCoverage->Clear(); - if (!m_benchmarkInfo.m_isBenchmarking) m_windowHandle->invalidate(); } void CoverageGenerator::InvalidateTilesImpl(m2::AnyRectD const & r, int startScale) { + TileCache & tileCache = m_coverageInfo.m_tileRenderer->GetTileCache(); + tileCache.Lock(); + { threads::MutexGuard g(m_stateInfo.m_mutex); - m_currentCoverage->RemoveTiles(r, startScale); + + buffer_vector toRemove; + + for (CoverageInfo::TTileSet::const_iterator it = m_coverageInfo.m_tiles.begin(); + it != m_coverageInfo.m_tiles.end(); + ++it) + { + Tiler::RectInfo const & ri = (*it)->m_rectInfo; + + if (r.IsIntersect(m2::AnyRectD(ri.m_rect)) && (ri.m_tileScale >= startScale)) + { + toRemove.push_back(*it); + tileCache.UnlockTile(ri); + } + } + + for (buffer_vector::const_iterator it = toRemove.begin(); + it != toRemove.end(); + ++it) + { + m_coverageInfo.m_tiles.erase(*it); + } } - TileCache & tileCache = m_tileRenderer->GetTileCache(); - - tileCache.Lock(); - /// here we should copy elements as we've delete some of them later set k = tileCache.Keys(); @@ -311,6 +337,8 @@ void CoverageGenerator::InvalidateTilesImpl(m2::AnyRectD const & r, int startSca } tileCache.Unlock(); + + MergeOverlay(); } void CoverageGenerator::CheckEmptyModelImpl(int sequenceID) @@ -318,11 +346,294 @@ void CoverageGenerator::CheckEmptyModelImpl(int sequenceID) if (sequenceID < m_stateInfo.m_sequenceID) return; - m_currentCoverage->CheckEmptyModelAtCoverageCenter(); + if (!IsPartialCoverage() && IsEmptyDrawing()) + { + m2::PointD const centerPt = m_stateInfo.m_currentScreen.GlobalRect().GetGlobalRect().Center(); + m_indexInfo.m_countryIndex = GetCountryIndex(centerPt); + } m_windowHandle->invalidate(); } +//////////////////////////////////////////////////////////// +/// Support methods +//////////////////////////////////////////////////////////// +void CoverageGenerator::ComputeCoverTasks() +{ + m_coverageInfo.m_isEmptyDrawing = true; + m_coverageInfo.m_renderLeafTilesCount = 0; + + vector allRects; + allRects.reserve(16); + buffer_vector newRects; + m_coverageInfo.m_tiler.tiles(allRects, GetPlatform().PreCachingDepth()); + + TileCache & tileCache = m_coverageInfo.m_tileRenderer->GetTileCache(); + tileCache.Lock(); + + int const step = GetPlatform().PreCachingDepth() - 1; + + CoverageInfo::TTileSet tiles; + for (size_t i = 0; i < allRects.size(); ++i) + { + Tiler::RectInfo const & ri = allRects[i]; + + if (!((ri.m_tileScale == m_coverageInfo.m_tiler.tileScale() - step) || + (ri.m_tileScale == m_coverageInfo.m_tiler.tileScale() ))) + { + continue; + } + + if (tileCache.HasTile(ri)) + { + tileCache.TouchTile(ri); + Tile const * tile = &tileCache.GetTile(ri); + ASSERT(tiles.find(tile) == tiles.end(), ()); + + if (m_coverageInfo.m_tiler.isLeaf(ri)) + m_coverageInfo.m_isEmptyDrawing &= tile->m_isEmptyDrawing; + + tiles.insert(tile); + } + else + { + newRects.push_back(ri); + if (m_coverageInfo.m_tiler.isLeaf(ri)) + ++m_coverageInfo.m_renderLeafTilesCount; + } + } + + m_coverageInfo.m_hasTileCahceMiss = !newRects.empty(); + + /// computing difference between current and previous coverage + /// tiles, that aren't in current coverage are unlocked to allow their deletion from TileCache + /// tiles, that are new to the current coverage are added into m_tiles and locked in TileCache + + size_t firstTileForAdd = 0; + buffer_vector diff_tiles; + diff_tiles.reserve(m_coverageInfo.m_tiles.size() + tiles.size()); + set_difference(m_coverageInfo.m_tiles.begin(), m_coverageInfo.m_tiles.end(), + tiles.begin(), tiles.end(), + back_inserter(diff_tiles), CoverageInfo::TTileSet::key_compare()); + + firstTileForAdd = diff_tiles.size(); + set_difference(tiles.begin(), tiles.end(), + m_coverageInfo.m_tiles.begin(), m_coverageInfo.m_tiles.end(), + back_inserter(diff_tiles), CoverageInfo::TTileSet::key_compare()); + + for (size_t i = 0; i < firstTileForAdd; ++i) + tileCache.UnlockTile(diff_tiles[i]->m_rectInfo); + + for (size_t i = firstTileForAdd; i < diff_tiles.size(); ++i) + tileCache.LockTile(diff_tiles[i]->m_rectInfo); + + tileCache.Unlock(); + + m_coverageInfo.m_tiles = tiles; + MergeOverlay(); + + /// clearing all old commands + m_coverageInfo.m_tileRenderer->ClearCommands(); + /// setting new sequenceID + m_coverageInfo.m_tileRenderer->SetSequenceID(m_stateInfo.m_sequenceID); + /// @todo After ClearCommands i think we have no commands to cancel. + m_coverageInfo.m_tileRenderer->CancelCommands(); + + m_benchmarkInfo.m_tilesCount = newRects.size(); + m_benchmarkInfo.m_benchmarkSequenceID = m_stateInfo.m_sequenceID; + + for (size_t i = 0; i < newRects.size(); ++i) + { + Tiler::RectInfo const & ri = newRects[i]; + + core::CommandsQueue::Chain chain; + + chain.addCommand(bind(&CoverageGenerator::MergeTile, + this, ri, m_stateInfo.m_sequenceID)); + + m_coverageInfo.m_tileRenderer->AddCommand(ri, m_stateInfo.m_sequenceID, chain); + } +} + +void CoverageGenerator::MergeOverlay() +{ + m_coverageInfo.m_overlay->lock(); + m_coverageInfo.m_overlay->clear(); + + for (CoverageInfo::TTileSet::const_iterator it = m_coverageInfo.m_tiles.begin(); + it != m_coverageInfo.m_tiles.end(); + ++it) + { + Tiler::RectInfo const & ri = (*it)->m_rectInfo; + if (m_coverageInfo.m_tiler.isLeaf(ri)) + m_coverageInfo.m_overlay->merge(*(*it)->m_overlay, + (*it)->m_tileScreen.PtoGMatrix() * m_stateInfo.m_currentScreen.GtoPMatrix()); + } + + m_coverageInfo.m_overlay->unlock(); +} + +void CoverageGenerator::MergeSingleTile(Tiler::RectInfo const & rectInfo) +{ + m_coverageInfo.m_tileRenderer->CacheActiveTile(rectInfo); + TileCache & tileCache = m_coverageInfo.m_tileRenderer->GetTileCache(); + tileCache.Lock(); + + Tile const * tile = NULL; + if (tileCache.HasTile(rectInfo)) + { + tileCache.LockTile(rectInfo); + tile = &tileCache.GetTile(rectInfo); + } + + if (tile != NULL) + { + m_coverageInfo.m_tiles.insert(tile); + + if (m_coverageInfo.m_tiler.isLeaf(rectInfo)) + { + m_coverageInfo.m_isEmptyDrawing &= tile->m_isEmptyDrawing; + m_coverageInfo.m_renderLeafTilesCount--; + } + } + + tileCache.Unlock(); + + if (tile != NULL && m_coverageInfo.m_tiler.isLeaf(rectInfo)) + { + m_coverageInfo.m_overlay->lock(); + m_coverageInfo.m_overlay->merge(*tile->m_overlay, + tile->m_tileScreen.PtoGMatrix() * m_stateInfo.m_currentScreen.GtoPMatrix()); + m_coverageInfo.m_overlay->unlock(); + } +} + +namespace +{ + bool SharpnessComparator(shared_ptr const & e1, + shared_ptr const & e2) + { + return e1->hasSharpGeometry() && (!e2->hasSharpGeometry()); + } +} + +bool CoverageGenerator::CacheCoverage(core::CommandsQueue::Environment const & env) +{ + delete m_backCoverage->m_mainElements; + delete m_backCoverage->m_sharpElements; + + m_backCoverage->m_mainElements = m_cacheScreen->createDisplayList(); + m_backCoverage->m_sharpElements = m_cacheScreen->createDisplayList(); + + m_cacheScreen->setEnvironment(&env); + + m_cacheScreen->beginFrame(); + m_cacheScreen->setDisplayList(m_backCoverage->m_mainElements); + + vector infos; + + for (CoverageInfo::TTileSet::const_iterator it = m_coverageInfo.m_tiles.begin(); + it != m_coverageInfo.m_tiles.end(); + ++it) + { + Tile const * tile = *it; + + size_t tileWidth = tile->m_renderTarget->width(); + size_t tileHeight = tile->m_renderTarget->height(); + + graphics::BlitInfo bi; + + bi.m_matrix = tile->m_tileScreen.PtoGMatrix() * m_stateInfo.m_currentScreen.GtoPMatrix(); + bi.m_srcRect = m2::RectI(0, 0, tileWidth - 2, tileHeight - 2); + bi.m_texRect = m2::RectU(1, 1, tileWidth - 1, tileHeight - 1); + bi.m_srcSurface = tile->m_renderTarget; + + infos.push_back(bi); + } + + if (!infos.empty()) + m_cacheScreen->blit(&infos[0], infos.size(), true, graphics::minDepth); + + math::Matrix idM = math::Identity(); + + m_coverageInfo.m_overlay->lock(); + + vector > overlayElements; + overlayElements.reserve(m_coverageInfo.m_overlay->getElementsCount()); + m_coverageInfo.m_overlay->forEach(MakeBackInsertFunctor(overlayElements)); + sort(overlayElements.begin(), overlayElements.end(), SharpnessComparator); + + unsigned currentElement = 0; + + for (; currentElement < overlayElements.size(); ++currentElement) + { + shared_ptr const & elem = overlayElements[currentElement]; + if (elem->hasSharpGeometry()) + break; + + elem->draw(m_cacheScreen.get(), idM); + } + + m_cacheScreen->applySharpStates(); + m_cacheScreen->setDisplayList(m_backCoverage->m_sharpElements); + + for (; currentElement < overlayElements.size(); ++currentElement) + overlayElements[currentElement]->draw(m_cacheScreen.get(), idM); + + m_coverageInfo.m_overlay->unlock(); + + m_cacheScreen->setDisplayList(0); + m_cacheScreen->applyStates(); + + m_cacheScreen->endFrame(); + + /// completing commands that was immediately executed + /// while recording of displayList(for example UnlockStorage) + + m_cacheScreen->completeCommands(); + + bool isCancelled = m_cacheScreen->isCancelled(); + + m_cacheScreen->setEnvironment(0); + + return !isCancelled; +} + +void CoverageGenerator::ClearCoverage() +{ + { + m_coverageInfo.m_overlay->lock(); + m_coverageInfo.m_overlay->clear(); + m_coverageInfo.m_overlay->unlock(); + } + + m_coverageInfo.m_isEmptyDrawing = false; + m_coverageInfo.m_renderLeafTilesCount = 0; + m_coverageInfo.m_hasTileCahceMiss = false; + m_indexInfo.m_countryIndex = storage::TIndex(); + + TileCache & tileCache = m_coverageInfo.m_tileRenderer->GetTileCache(); + + tileCache.Lock(); + + for (CoverageInfo::TTileSet::const_iterator it = m_coverageInfo.m_tiles.begin(); + it != m_coverageInfo.m_tiles.end(); + ++it) + { + Tiler::RectInfo const & ri = (*it)->m_rectInfo; + tileCache.UnlockTile(ri); + } + + tileCache.Unlock(); + + m_coverageInfo.m_tiles.clear(); + + delete m_currentCoverage; + m_currentCoverage = 0; + delete m_backCoverage; + m_backCoverage = 0; +} + //////////////////////////////////////////////////////////// /// BenchmarkInfo //////////////////////////////////////////////////////////// @@ -380,7 +691,7 @@ void CoverageGenerator::BenchmarkInfo::TryFinishSequence() } //////////////////////////////////////////////////////////// -/// BenchmarkInfo +/// StateInfo //////////////////////////////////////////////////////////// CoverageGenerator::StateInfo::StateInfo() : m_isPause(false) @@ -407,5 +718,41 @@ void CoverageGenerator::StateInfo::Pause() void CoverageGenerator::StateInfo::Resume() { m_isPause = false; - m_needForceUpdate = true; + m_needForceUpdate = false; +} + +//////////////////////////////////////////////////////////// +/// CoverageGenerator +//////////////////////////////////////////////////////////// +CoverageGenerator::CoverageInfo::CoverageInfo(TileRenderer *tileRenderer) + : m_tileRenderer(tileRenderer) + , m_overlay(new graphics::Overlay()) +{ + m_overlay->setCouldOverlap(false); +} + +CoverageGenerator::CoverageInfo::~CoverageInfo() +{ + delete m_overlay; +} + +//////////////////////////////////////////////////////////// +/// IndexInfo +//////////////////////////////////////////////////////////// +CoverageGenerator::IndexInfo::IndexInfo(RenderPolicy::TCountryIndexFn indexFn) + : m_countryIndexFn(indexFn) + , m_countryIndex() +{ +} + +CoverageGenerator::CachedCoverageInfo::CachedCoverageInfo() + : m_mainElements(NULL) + , m_sharpElements(NULL) +{ +} + +CoverageGenerator::CachedCoverageInfo::~CachedCoverageInfo() +{ + delete m_mainElements; + delete m_sharpElements; } diff --git a/map/coverage_generator.hpp b/map/coverage_generator.hpp index c1e374ea94..397e1175c8 100644 --- a/map/coverage_generator.hpp +++ b/map/coverage_generator.hpp @@ -39,8 +39,6 @@ namespace graphics /// newly rendered tile(p.e. merge it into current ScreenCoverage). class CoverageGenerator { - ScreenCoverage * CreateCoverage(); - public: CoverageGenerator(TileRenderer * tileRenderer, @@ -54,16 +52,19 @@ public: void Shutdown(); - void InitializeThreadGL(); - void FinalizeThreadGL(); + //@{ Called only on android, with Single thread policy + void InitializeThreadGL(shared_ptr context, + shared_ptr resourceManager, + graphics::PacketsQueue * glQueue); + void FinalizeThreadGL(shared_ptr context, + shared_ptr resourceManager); + //@} //@{ Add task to run on CoverageGenerator thread void InvalidateTiles(m2::AnyRectD const & rect, int startScale); void CoverScreen(ScreenBase const & screen, bool doForce); void MergeTile(Tiler::RectInfo const & rectInfo, int sequenceID); - void FinishSequenceIfNeeded(); - void DecrementTileCount(int sequenceID); void CheckEmptyModel(int sequenceID); //}@ @@ -72,11 +73,10 @@ public: void JoinBenchmarkFence(int fenceID); //}@ + void Draw(graphics::Screen * s, ScreenBase const & screen); + storage::TIndex GetCountryIndex(m2::PointD const & pt) const; - - ScreenCoverage * CurrentCoverage(); - - void StartTileDrawingSession(int sequenceID, unsigned tileCount); + storage::TIndex GetCountryIndexAtCenter() const; //@{ Frame lock void Lock(); @@ -86,8 +86,15 @@ public: void Pause(); void Resume(); + graphics::Overlay * GetOverlay() const; + + bool IsEmptyDrawing() const; + bool IsEmptyModelAtCenter() const; + bool IsPartialCoverage() const; bool DoForceUpdate() const; + int GetDrawScale() const; + private: void CoverScreenImpl(core::CommandsQueue::Environment const & env, ScreenBase const & screen, @@ -101,6 +108,15 @@ private: void CheckEmptyModelImpl(int sequenceID); +private: + void FinishSequenceIfNeeded(); + void ComputeCoverTasks(); + void MergeOverlay(); + void MergeSingleTile(Tiler::RectInfo const & rectInfo); + bool CacheCoverage(core::CommandsQueue::Environment const & env); + + void ClearCoverage(); + private: struct BenchmarkInfo { @@ -139,19 +155,46 @@ private: void Resume(); } m_stateInfo; + struct CoverageInfo + { + CoverageInfo(TileRenderer * tileRenderer); + ~CoverageInfo(); + + Tiler m_tiler; + TileRenderer * m_tileRenderer; + + typedef set TTileSet; + TTileSet m_tiles; + + graphics::Overlay * m_overlay; + + int m_renderLeafTilesCount; + bool m_hasTileCahceMiss; + bool m_isEmptyDrawing; + } m_coverageInfo; + + struct IndexInfo + { + IndexInfo(RenderPolicy::TCountryIndexFn indexFn); + + RenderPolicy::TCountryIndexFn m_countryIndexFn; + storage::TIndex m_countryIndex; + } m_indexInfo; + + struct CachedCoverageInfo + { + CachedCoverageInfo(); + ~CachedCoverageInfo(); + + graphics::DisplayList * m_mainElements; + graphics::DisplayList * m_sharpElements; + ScreenBase m_screen; + }; + + CachedCoverageInfo * m_currentCoverage; + CachedCoverageInfo * m_backCoverage; + core::CommandsQueue m_queue; - - TileRenderer * m_tileRenderer; - - shared_ptr m_resourceManager; - shared_ptr m_renderContext; - - ScreenCoverage * m_workCoverage; - ScreenCoverage * m_currentCoverage; - shared_ptr m_windowHandle; - - RenderPolicy::TCountryIndexFn m_countryIndexFn; - - graphics::PacketsQueue * m_glQueue; + shared_ptr m_cacheScreen; }; diff --git a/map/framework.cpp b/map/framework.cpp index 2be01cee67..dc9ae8d65c 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -1518,9 +1518,10 @@ bool Framework::GetVisiblePOI(m2::PointD const & pxPoint, m2::PointD & pxPivot, m2::RectD rect(pt.x - halfSize, pt.y - halfSize, pt.x + halfSize, pt.y + halfSize); { - shared_ptr frameOverlay = m_renderPolicy->FrameOverlay(); - graphics::Overlay::Lock guard(frameOverlay); + graphics::Overlay * frameOverlay = m_renderPolicy->FrameOverlay(); + frameOverlay->lock(); frameOverlay->selectOverlayElements(rect, candidates); + frameOverlay->unlock(); } shared_ptr elem = GetClosestToPivot(candidates, pt); diff --git a/map/map.pro b/map/map.pro index 46ce6a9011..25e5cf213c 100644 --- a/map/map.pro +++ b/map/map.pro @@ -31,7 +31,6 @@ HEADERS += \ tiler.hpp \ tile.hpp \ tile_cache.hpp \ - screen_coverage.hpp \ ruler.hpp \ measurement_utils.hpp \ simple_render_policy.hpp \ @@ -77,7 +76,6 @@ SOURCES += \ tiler.cpp \ tile_cache.cpp \ tile.cpp \ - screen_coverage.cpp \ ruler.cpp \ measurement_utils.cpp \ window_handle.cpp \ diff --git a/map/render_policy.cpp b/map/render_policy.cpp index 7e7e635eb4..5200d2ae4b 100644 --- a/map/render_policy.cpp +++ b/map/render_policy.cpp @@ -236,10 +236,10 @@ void RenderPolicy::FrameUnlock() LOG(LWARNING, ("unimplemented method called")); } -shared_ptr const RenderPolicy::FrameOverlay() const +graphics::Overlay * RenderPolicy::FrameOverlay() const { LOG(LWARNING, ("unimplemented method called")); - return shared_ptr(); + return NULL; } graphics::Color const RenderPolicy::GetBgColor() const diff --git a/map/render_policy.hpp b/map/render_policy.hpp index 7568b8e0e3..9899cc93db 100644 --- a/map/render_policy.hpp +++ b/map/render_policy.hpp @@ -162,7 +162,7 @@ public: /// Get current graphics::Overlay object. /// Access to this resource should be synchronized using /// FrameLock/FrameUnlock methods - virtual shared_ptr const FrameOverlay() const; + virtual graphics::Overlay * FrameOverlay() const; /// Benchmarking protocol virtual int InsertBenchmarkFence(); diff --git a/map/screen_coverage.cpp b/map/screen_coverage.cpp deleted file mode 100644 index f6d5b17d10..0000000000 --- a/map/screen_coverage.cpp +++ /dev/null @@ -1,505 +0,0 @@ -#include "../base/SRC_FIRST.hpp" - -#include "../platform/platform.hpp" - -#include "../std/bind.hpp" -#include "../std/set.hpp" -#include "../std/algorithm.hpp" - -#include "../indexer/scales.hpp" - -#include "../graphics/screen.hpp" -#include "../graphics/display_list.hpp" -#include "../graphics/opengl/base_texture.hpp" - -#include "screen_coverage.hpp" -#include "tile_renderer.hpp" -#include "window_handle.hpp" -#include "coverage_generator.hpp" - -ScreenCoverage::ScreenCoverage() - : m_sequenceID(numeric_limits::max()), - m_tileRenderer(NULL), - m_coverageGenerator(NULL), - m_overlay(new graphics::Overlay()), - m_isBenchmarking(false), - m_isEmptyDrawingCoverage(false), - m_isEmptyModelAtCoverageCenter(true), - m_leafTilesToRender(0) -{ - m_overlay->setCouldOverlap(false); -} - -ScreenCoverage::ScreenCoverage(TileRenderer * tileRenderer, - CoverageGenerator * coverageGenerator, - shared_ptr const & cacheScreen) - : m_sequenceID(numeric_limits::max()), - m_tileRenderer(tileRenderer), - m_coverageGenerator(coverageGenerator), - m_overlay(new graphics::Overlay()), - m_isBenchmarking(false), - m_isEmptyDrawingCoverage(false), - m_isEmptyModelAtCoverageCenter(true), - m_leafTilesToRender(0), - m_cacheScreen(cacheScreen) -{ - m_overlay->setCouldOverlap(false); -} - -void ScreenCoverage::CopyInto(ScreenCoverage & cvg, bool mergeOverlay) -{ - cvg.m_tileRenderer = m_tileRenderer; - cvg.m_tiler = m_tiler; - cvg.m_screen = m_screen; - cvg.m_coverageGenerator = m_coverageGenerator; - cvg.m_tileRects = m_tileRects; - cvg.m_newTileRects = m_newTileRects; - cvg.m_newLeafTileRects = m_newLeafTileRects; - cvg.m_isEmptyDrawingCoverage = m_isEmptyDrawingCoverage; - cvg.m_isEmptyModelAtCoverageCenter = m_isEmptyModelAtCoverageCenter; - cvg.m_leafTilesToRender = m_leafTilesToRender; - cvg.m_countryIndexAtCoverageCenter = m_countryIndexAtCoverageCenter; - - TileCache * tileCache = &m_tileRenderer->GetTileCache(); - - tileCache->Lock(); - - cvg.m_tiles = m_tiles; - - for (TTileSet::const_iterator it = cvg.m_tiles.begin(); it != cvg.m_tiles.end(); ++it) - { - Tiler::RectInfo const & ri = (*it)->m_rectInfo; - tileCache->LockTile(ri); - } - - tileCache->Unlock(); - if (mergeOverlay) - { - graphics::Overlay::Lock guard(cvg.m_overlay); - cvg.m_overlay->merge(*m_overlay); - } -} - -void ScreenCoverage::Clear() -{ - m_tileRects.clear(); - m_newTileRects.clear(); - m_newLeafTileRects.clear(); - { - graphics::Overlay::Lock guard(m_overlay); - m_overlay->clear(); - } - m_isEmptyDrawingCoverage = false; - m_isEmptyModelAtCoverageCenter = true; - m_leafTilesToRender = 0; - - TileCache * tileCache = &m_tileRenderer->GetTileCache(); - - tileCache->Lock(); - - for (TTileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - Tiler::RectInfo const & ri = (*it)->m_rectInfo; - tileCache->UnlockTile(ri); - } - - tileCache->Unlock(); - - m_tiles.clear(); -} - -void ScreenCoverage::Merge(Tiler::RectInfo const & ri) -{ - ASSERT(m_tileRects.find(ri) != m_tileRects.end(), ()); - - m_tileRenderer->CacheActiveTile(ri); - TileCache & tileCache = m_tileRenderer->GetTileCache(); - tileCache.Lock(); - - Tile const * tile = NULL; - if (tileCache.HasTile(ri)) - { - tileCache.LockTile(ri); - tile = &tileCache.GetTile(ri); - } - - if (tile != NULL) - { - m_tiles.insert(tile); - m_tileRects.erase(ri); - m_newTileRects.erase(ri); - m_newLeafTileRects.erase(ri); - - if (m_tiler.isLeaf(ri)) - { - m_isEmptyDrawingCoverage &= tile->m_isEmptyDrawing; - m_leafTilesToRender--; - } - } - - tileCache.Unlock(); - - if (tile != NULL && m_tiler.isLeaf(ri)) - { - graphics::Overlay::Lock guard(m_overlay); - m_overlay->merge(*tile->m_overlay, - tile->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix()); - } - - //else - // LOG(LDEBUG, ("UVRLOG : Tile not found s=", ri.m_tileScale, " x=", ri.m_x, " y=", ri.m_y)); -} - -void FilterElementsBySharpness(shared_ptr const & e, - vector > & v, - bool flag) -{ - if (e->hasSharpGeometry() == flag) - v.push_back(e); -} - -bool ScreenCoverage::Cache(core::CommandsQueue::Environment const & env) -{ - /// caching tiles blitting commands. - - m_primaryDL.reset(); - m_primaryDL.reset(m_cacheScreen->createDisplayList()); - - m_sharpTextDL.reset(); - m_sharpTextDL.reset(m_cacheScreen->createDisplayList()); - - m_cacheScreen->setEnvironment(&env); - - m_cacheScreen->beginFrame(); - m_cacheScreen->setDisplayList(m_primaryDL.get()); - - vector infos; - - for (TTileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - Tile const * tile = *it; - - size_t tileWidth = tile->m_renderTarget->width(); - size_t tileHeight = tile->m_renderTarget->height(); - - graphics::BlitInfo bi; - - bi.m_matrix = tile->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix(); - bi.m_srcRect = m2::RectI(0, 0, tileWidth - 2, tileHeight - 2); - bi.m_texRect = m2::RectU(1, 1, tileWidth - 1, tileHeight - 1); - bi.m_srcSurface = tile->m_renderTarget; - - infos.push_back(bi); - } - - if (!infos.empty()) - m_cacheScreen->blit(&infos[0], infos.size(), true, graphics::minDepth); - - math::Matrix idM = math::Identity(); - - // selecting and rendering non-sharp elements. - - { - graphics::Overlay::Lock guard(m_overlay); - vector > nonSharpElements; - m_overlay->forEach(bind(&FilterElementsBySharpness, _1, ref(nonSharpElements), false)); - - for (unsigned i = 0; i < nonSharpElements.size(); ++i) - nonSharpElements[i]->draw(m_cacheScreen.get(), idM); - - // selecting and rendering sharp elements - - vector > sharpElements; - m_overlay->forEach(bind(&FilterElementsBySharpness, _1, ref(sharpElements), true)); - - m_cacheScreen->applySharpStates(); - m_cacheScreen->setDisplayList(m_sharpTextDL.get()); - - for (unsigned i = 0; i < sharpElements.size(); ++i) - sharpElements[i]->draw(m_cacheScreen.get(), idM); - } /// Overlay lock - - m_cacheScreen->setDisplayList(0); - m_cacheScreen->applyStates(); - - m_cacheScreen->endFrame(); - - /// completing commands that was immediately executed - /// while recording of displayList(for example UnlockStorage) - - m_cacheScreen->completeCommands(); - - bool isCancelled = m_cacheScreen->isCancelled(); - - m_cacheScreen->setEnvironment(0); - - return !isCancelled; -} - -void ScreenCoverage::SetScreen(ScreenBase const & screen) -{ - //LOG(LDEBUG, ("UVRLOG : Start ScreenCoverage::SetScreen. m_SequenceID=", GetSequenceID())); - m_screen = screen; - - m_newTileRects.clear(); - - m_tiler.seed(m_screen, m_screen.GlobalRect().GlobalCenter(), m_tileRenderer->TileSize()); - - vector allRects; - vector newRects; - TTileSet tiles; - - m_tiler.tiles(allRects, GetPlatform().PreCachingDepth()); - - TileCache * tileCache = &m_tileRenderer->GetTileCache(); - - tileCache->Lock(); - - m_isEmptyDrawingCoverage = true; - m_isEmptyModelAtCoverageCenter = true; - m_leafTilesToRender = 0; - - for (size_t i = 0; i < allRects.size(); ++i) - { - Tiler::RectInfo const & ri = allRects[i]; - m_tileRects.insert(ri); - - if (tileCache->HasTile(ri)) - { - tileCache->TouchTile(ri); - Tile const * tile = &tileCache->GetTile(ri); - ASSERT(tiles.find(tile) == tiles.end(), ()); - - if (m_tiler.isLeaf(ri)) - m_isEmptyDrawingCoverage &= tile->m_isEmptyDrawing; - - tiles.insert(tile); - } - else - { - newRects.push_back(ri); - if (m_tiler.isLeaf(ri)) - ++m_leafTilesToRender; - } - } - - /// computing difference between current and previous coverage - /// tiles, that aren't in current coverage are unlocked to allow their deletion from TileCache - /// tiles, that are new to the current coverage are added into m_tiles and locked in TileCache - - size_t firstTileForAdd = 0; - buffer_vector diff_tiles; - diff_tiles.reserve(m_tiles.size() + tiles.size()); - set_difference(m_tiles.begin(), m_tiles.end(), tiles.begin(), tiles.end(), back_inserter(diff_tiles), TTileSet::key_compare()); - firstTileForAdd = diff_tiles.size(); - set_difference(tiles.begin(), tiles.end(), m_tiles.begin(), m_tiles.end(), back_inserter(diff_tiles), TTileSet::key_compare()); - - for (size_t i = 0; i < firstTileForAdd; ++i) - tileCache->UnlockTile(diff_tiles[i]->m_rectInfo); - - for (size_t i = firstTileForAdd; i < diff_tiles.size(); ++i) - tileCache->LockTile(diff_tiles[i]->m_rectInfo); - - tileCache->Unlock(); - - m_tiles = tiles; - - MergeOverlay(); - - vector firstClassTiles; - vector secondClassTiles; - - unsigned newRectsCount = newRects.size(); - - for (unsigned i = 0; i < newRectsCount; ++i) - { - Tiler::RectInfo nr = newRects[i]; - //LOG(LDEBUG, ("UVRLOG : NewRect add s=", nr.m_tileScale, " x=", nr.m_x, " y=", nr.m_y, " m_SequenceID=", GetSequenceID())); - - int const step = GetPlatform().PreCachingDepth() - 1; - - if ((nr.m_tileScale == m_tiler.tileScale() - step) - || (nr.m_tileScale == m_tiler.tileScale() )) - firstClassTiles.push_back(nr); - else - secondClassTiles.push_back(nr); - } - - /// clearing all old commands - m_tileRenderer->ClearCommands(); - /// setting new sequenceID - m_tileRenderer->SetSequenceID(GetSequenceID()); - //LOG(LDEBUG, ("UVRLOG : Cancel commands from set rect. m_SequenceID =", GetSequenceID())); - m_tileRenderer->CancelCommands(); - - // filtering out rects that are fully covered by its descedants - - int curNewTile = 0; - - if (m_isBenchmarking) - m_coverageGenerator->StartTileDrawingSession(GetSequenceID(), newRectsCount); - - // adding commands for tiles which aren't in cache - for (size_t i = 0; i < firstClassTiles.size(); ++i, ++curNewTile) - { - Tiler::RectInfo const & ri = firstClassTiles[i]; - - core::CommandsQueue::Chain chain; - - chain.addCommand(bind(&CoverageGenerator::MergeTile, - m_coverageGenerator, - ri, - GetSequenceID())); - - if (m_isBenchmarking) - { - chain.addCommand(bind(&CoverageGenerator::DecrementTileCount, - m_coverageGenerator, - GetSequenceID())); - } - - m_tileRenderer->AddCommand(ri, GetSequenceID(), - chain); - - if (m_tiler.isLeaf(ri)) - m_newLeafTileRects.insert(ri); - - m_newTileRects.insert(ri); - } - - for (size_t i = 0; i < secondClassTiles.size(); ++i, ++curNewTile) - { - Tiler::RectInfo const & ri = secondClassTiles[i]; - - core::CommandsQueue::Chain chain; - - chain.addCommand(bind(&TileRenderer::CacheActiveTile, - m_tileRenderer, - ri)); - - if (m_isBenchmarking) - { - chain.addCommand(bind(&CoverageGenerator::DecrementTileCount, - m_coverageGenerator, - GetSequenceID())); - } - - m_tileRenderer->AddCommand(ri, GetSequenceID(), chain); - } -} - -ScreenCoverage::~ScreenCoverage() -{ - Clear(); -} - -void ScreenCoverage::Draw(graphics::Screen * s, ScreenBase const & screen) -{ - math::Matrix m = m_screen.PtoGMatrix() * screen.GtoPMatrix(); - - if (m_primaryDL) - s->drawDisplayList(m_primaryDL.get(), m); - - if (m_sharpTextDL) - s->drawDisplayList(m_sharpTextDL.get(), m); -} - -shared_ptr const & ScreenCoverage::GetOverlay() const -{ - return m_overlay; -} - -int ScreenCoverage::GetDrawScale() const -{ - return m_tiler.tileScale(); -} - -bool ScreenCoverage::IsEmptyDrawingCoverage() const -{ - return (m_leafTilesToRender <= 0) && m_isEmptyDrawingCoverage; -} - -bool ScreenCoverage::IsEmptyModelAtCoverageCenter() const -{ - return m_isEmptyModelAtCoverageCenter; -} - -void ScreenCoverage::ResetEmptyModelAtCoverageCenter() -{ - m_isEmptyModelAtCoverageCenter = false; -} - -storage::TIndex ScreenCoverage::GetCountryIndexAtCoverageCenter() const -{ - return m_countryIndexAtCoverageCenter; -} - -void ScreenCoverage::CheckEmptyModelAtCoverageCenter() -{ - if (!IsPartialCoverage() && IsEmptyDrawingCoverage()) - { - m2::PointD const centerPt = m_screen.GlobalRect().GetGlobalRect().Center(); - m_countryIndexAtCoverageCenter = m_coverageGenerator->GetCountryIndex(centerPt); - m_isEmptyModelAtCoverageCenter = m_countryIndexAtCoverageCenter.IsValid(); - } -} - -bool ScreenCoverage::IsPartialCoverage() const -{ - return !m_newTileRects.empty(); -} - -void ScreenCoverage::SetSequenceID(int id) -{ - m_sequenceID = id; -} - -int ScreenCoverage::GetSequenceID() const -{ - return m_sequenceID; -} - -void ScreenCoverage::RemoveTiles(m2::AnyRectD const & r, int startScale) -{ - vector toRemove; - - for (TTileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - Tiler::RectInfo const & ri = (*it)->m_rectInfo; - - if (r.IsIntersect(m2::AnyRectD(ri.m_rect)) && (ri.m_tileScale >= startScale)) - toRemove.push_back(*it); - } - - TileCache * tileCache = &m_tileRenderer->GetTileCache(); - tileCache->Lock(); - - for (vector::const_iterator it = toRemove.begin(); it != toRemove.end(); ++it) - { - Tiler::RectInfo const & ri = (*it)->m_rectInfo; - tileCache->UnlockTile(ri); - m_tiles.erase(*it); - m_tileRects.erase(ri); - } - tileCache->Unlock(); - - MergeOverlay(); -} - -void ScreenCoverage::MergeOverlay() -{ - graphics::Overlay::Lock guard(m_overlay); - m_overlay->clear(); - - for (TTileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it) - { - Tiler::RectInfo const & ri = (*it)->m_rectInfo; - if (m_tiler.isLeaf(ri)) - m_overlay->merge(*(*it)->m_overlay, (*it)->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix()); - } -} - -void ScreenCoverage::SetBenchmarkingFlag(bool isBenchmarking) -{ - m_isBenchmarking = isBenchmarking; -} diff --git a/map/screen_coverage.hpp b/map/screen_coverage.hpp deleted file mode 100644 index 8077205fef..0000000000 --- a/map/screen_coverage.hpp +++ /dev/null @@ -1,139 +0,0 @@ -#pragma once - -#include "../base/mutex.hpp" - -#include "../geometry/screenbase.hpp" - -#include "../graphics/overlay.hpp" - -#include "tile.hpp" -#include "tiler.hpp" -#include "render_policy.hpp" - -class TileRenderer; - -namespace graphics -{ - namespace gl - { - class Screen; - } -} - -class CoverageGenerator; - -class ScreenCoverage -{ -private: - /// Unique ID of this screen coverage - int m_sequenceID; - /// Queue to put new rendering tasks in - TileRenderer * m_tileRenderer; - /// Coverage generator - CoverageGenerator * m_coverageGenerator; - /// Tiler to compute visible and predicted tiles - Tiler m_tiler; - /// Last covered screen - ScreenBase m_screen; - /// Container for a rects, that forms a set of tiles in the m_screen - typedef set TTileRectSet; - /// This set contains all rects that was returned by Tiler. - /// This includes already drawn rects, and rects which is not drawn yet. - TTileRectSet m_tileRects; - /// This set contains rects, which was send to TileRenderer to draw - TTileRectSet m_newTileRects; - /// Subset of newTileRects, only leaf rects that should be drawn - /// For quick check for Partial/NonPartial coverage - TTileRectSet m_newLeafTileRects; - /// Typedef for a set of tiles, that are visible for the m_screen - typedef set TTileSet; - /// This set contains all tiles that are found in the TileCache. - /// Tiles in this set are locked to prevent their deletion - /// from TileCache while drawing them - TTileSet m_tiles; - /// Overlay composed of overlays for visible tiles - shared_ptr m_overlay; - - /// State flags - bool m_isBenchmarking; - - /// Does the all leaf tiles in this coverage are empty? - bool m_isEmptyDrawingCoverage; - /// If the map model empty at the screen center? - bool m_isEmptyModelAtCoverageCenter; - /// Which country this coverage points to at its center? - /// It's valid only if m_isEmptyModelAtCoverageCenter is true - storage::TIndex m_countryIndexAtCoverageCenter; - /// How many "leaf" tiles we should render to cover the screen. - /// This is efficiently the size of newLeafTileRects and is cached for - /// quick check. - int m_leafTilesToRender; - /// Screen, which is used for caching of this ScreenCoverage into DisplayList - shared_ptr m_cacheScreen; - /// DisplayList which holds cached ScreenCoverage - shared_ptr m_primaryDL; - /// DisplayList to cache all straight texts. - /// They are drawn with different shader. - shared_ptr m_sharpTextDL; - - /// Direct copying is prohibited. - ScreenCoverage(ScreenCoverage const & src); - ScreenCoverage const & operator=(ScreenCoverage const & src); - - /// For each tile in m_tiles merge it's overlay into the big one. - void MergeOverlay(); - -public: - - /// Default Constructor - ScreenCoverage(); - /// Constructor - ScreenCoverage(TileRenderer * tileRenderer, - CoverageGenerator * coverageGenerator, - shared_ptr const & cacheScreen); - /// Destructor - ~ScreenCoverage(); - /// Copy all needed information into specified ScreenCoverage - void CopyInto(ScreenCoverage & cvg, bool mergeOverlay); - /// Make screen coverage empty - void Clear(); - /// set unique ID for all actions, used to compute this coverage - void SetSequenceID(int id); - /// get unique ID for all actions, used to compute this coverage - int GetSequenceID() const; - /// Is this screen coverage partial, which means that it contains non-drawn rects - bool IsPartialCoverage() const; - /// Is this screen coverage contains only empty tiles - bool IsEmptyDrawingCoverage() const; - /// Is the model empty at the screen center - bool IsEmptyModelAtCoverageCenter() const; - /// Reset IsEmptyModelAtCoverageCenter flag - void ResetEmptyModelAtCoverageCenter(); - /// What country is at this coverage center. - /// @warning check this flag only if IsEmptyModelAtCoverageCenter is true - storage::TIndex GetCountryIndexAtCoverageCenter() const; - /// Check, whether the model is empty at the center of the coverage. - void CheckEmptyModelAtCoverageCenter(); - /// Getter for Overlay - shared_ptr const & GetOverlay() const; - /// Cache coverage in display list - /// @return true - if the coverage was cached successfully, - /// false - otherwise(p.e. the caching was cancelled) - bool Cache(core::CommandsQueue::Environment const & env); - /// add rendered tile to coverage. Tile is locked, so make sure to unlock it in case it's not needed. - void Merge(Tiler::RectInfo const & ri); - /// recalculate screen coverage, using as much info from prev coverage as possible - void SetScreen(ScreenBase const & screen); - /// draw screen coverage - void Draw(graphics::Screen * s, ScreenBase const & currentScreen); - /// get draw scale for the tiles in the current coverage - /// Not all tiles in coverage could correspond to this value, - /// as there could be tiles from lower and higher level in the - /// coverage to provide a smooth scale transition experience - int GetDrawScale() const; - /// Unlock and remove tiles which intersect the specified rect - /// and deeper or equal than specified scale - void RemoveTiles(m2::AnyRectD const & r, int startScale); - - void SetBenchmarkingFlag(bool isBenchmarking); -}; diff --git a/map/tile_renderer.cpp b/map/tile_renderer.cpp index ab93bdbb6d..f586c3c978 100644 --- a/map/tile_renderer.cpp +++ b/map/tile_renderer.cpp @@ -44,27 +44,22 @@ namespace TileRenderer::TileRenderer( size_t tileSize, - string const & skinName, - graphics::EDensity density, unsigned executorsCount, graphics::Color const & bgColor, RenderPolicy::TRenderFn const & renderFn, shared_ptr const & primaryRC, shared_ptr const & rm, double visualScale, - graphics::PacketsQueue ** packetsQueues - ) : m_queue(executorsCount), - m_tileSize(tileSize), - m_renderFn(renderFn), - m_skinName(skinName), - m_density(density), - m_bgColor(bgColor), - m_sequenceID(0), - m_isExiting(false), - m_isPaused(false) + graphics::PacketsQueue ** packetsQueues) + : m_queue(executorsCount) + , m_tileSize(tileSize) + , m_renderFn(renderFn) + , m_bgColor(bgColor) + , m_sequenceID(0) + , m_isExiting(false) + , m_isPaused(false) { m_resourceManager = rm; - m_primaryContext = primaryRC; m_threadData.resize(m_queue.ExecutorsCount()); @@ -76,7 +71,7 @@ TileRenderer::TileRenderer( for (unsigned i = 0; i < m_threadData.size(); ++i) { if (!packetsQueues) - m_threadData[i].m_renderContext.reset(m_primaryContext->createShared()); + m_threadData[i].m_renderContext.reset(primaryRC->createShared()); Drawer::Params params; @@ -113,7 +108,6 @@ TileRenderer::~TileRenderer() { m_isExiting = true; - //LOG(LDEBUG, ("UVRLOG : Cancel from ~TileRenderer")); m_queue.Cancel(); for (size_t i = 0; i < m_threadData.size(); ++i) @@ -180,12 +174,7 @@ void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env, /// commands from the previous sequence are ignored if (sequenceID < m_sequenceID) - { - //LOG(LDEBUG, ("UVRLOG : tile not rendered. SequenceID=", sequenceID, " m_SequenceID", m_sequenceID)); return; - } - - //LOG(LDEBUG, ("UVRLOG : start render tile m_SequenceID=", m_sequenceID)); if (HasTile(rectInfo)) return; @@ -230,17 +219,6 @@ void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env, drawer->screen()->setClipRect(renderRect); drawer->clear(m_bgColor); -/* drawer->clear(graphics::Color(rand() % 32 + 128, rand() % 64 + 128, rand() % 32 + 128, 255)); - - std::stringstream out; - out << rectInfo.m_y << ", " << rectInfo.m_x << ", " << rectInfo.m_tileScale; - - drawer->screen()->drawText(graphics::FontDesc(12, graphics::Color(0, 0, 0, 255), true), - renderRect.Center(), - graphics::EPosCenter, - out.str(), - 0, - false);*/ frameScreen.SetFromRect(m2::AnyRectD(rectInfo.m_rect)); m2::RectD selectRect; diff --git a/map/tile_renderer.hpp b/map/tile_renderer.hpp index ef9cb7a987..2dc12ebb88 100644 --- a/map/tile_renderer.hpp +++ b/map/tile_renderer.hpp @@ -49,8 +49,6 @@ protected: buffer_vector m_threadData; - shared_ptr m_primaryContext; - TileCache m_tileCache; /// set of already rendered tiles, which are waiting @@ -60,8 +58,6 @@ protected: size_t m_tileSize; RenderPolicy::TRenderFn m_renderFn; - string m_skinName; - graphics::EDensity m_density; graphics::Color m_bgColor; int m_sequenceID; bool m_isExiting; @@ -86,8 +82,6 @@ public: /// constructor. TileRenderer(size_t tileSize, - string const & skinName, - graphics::EDensity density, unsigned tasksCount, graphics::Color const & bgColor, RenderPolicy::TRenderFn const & renderFn, diff --git a/map/tiling_render_policy_mt.cpp b/map/tiling_render_policy_mt.cpp index 58686366a3..8539d0046a 100644 --- a/map/tiling_render_policy_mt.cpp +++ b/map/tiling_render_policy_mt.cpp @@ -164,8 +164,6 @@ void TilingRenderPolicyMT::SetRenderFn(TRenderFn renderFn) string skinName = SkinName(); m_TileRenderer.reset(new TileRenderer(TileSize(), - skinName, - Density(), GetPlatform().CpuCores(), m_bgColor, renderFn, diff --git a/map/tiling_render_policy_st.cpp b/map/tiling_render_policy_st.cpp index f4056554e7..09c7e78176 100644 --- a/map/tiling_render_policy_st.cpp +++ b/map/tiling_render_policy_st.cpp @@ -198,8 +198,6 @@ void TilingRenderPolicyST::SetRenderFn(TRenderFn renderFn) queues[i] = m_QueuedRenderer->GetPacketsQueue(i); m_TileRenderer.reset(new TileRenderer(TileSize(), - skinName, - Density(), cpuCores, m_bgColor, renderFn,