From 4dea4ee38dc8e4602153d15eab4f07553f1d6cb9 Mon Sep 17 00:00:00 2001 From: rachytski Date: Tue, 10 Apr 2012 19:00:02 +0400 Subject: [PATCH] checking for "true" model emptiness in TilingRenderPolicyXXX when all tiles are rendered "empty". --- map/basic_render_policy.cpp | 3 ++- map/basic_render_policy.hpp | 2 +- map/basic_tiling_render_policy.cpp | 2 +- map/coverage_generator.cpp | 34 ++++++++++++++++++++++++++++-- map/coverage_generator.hpp | 9 +++++++- map/framework.cpp | 7 +++--- map/render_policy.cpp | 5 +++++ map/render_policy.hpp | 3 ++- map/render_queue.cpp | 5 +++++ map/render_queue.hpp | 3 +-- map/render_queue_routine.cpp | 5 +++++ map/render_queue_routine.hpp | 2 +- map/screen_coverage.cpp | 29 +++++++++++++++++++------ map/screen_coverage.hpp | 12 ++++++++--- map/tiling_render_policy_mt.cpp | 3 ++- map/tiling_render_policy_st.cpp | 3 ++- 16 files changed, 101 insertions(+), 26 deletions(-) diff --git a/map/basic_render_policy.cpp b/map/basic_render_policy.cpp index 6a77d172ed..70aac3bc68 100644 --- a/map/basic_render_policy.cpp +++ b/map/basic_render_policy.cpp @@ -25,8 +25,9 @@ void BasicRenderPolicy::SetRenderFn(TRenderFn renderFn) m_RenderQueue->initializeGL(m_primaryRC, m_resourceManager); } -void BasicRenderPolicy::SetEmptyModelFn(TEmptyModelFn const & checkFn) +void BasicRenderPolicy::SetEmptyModelFn(TEmptyModelFn checkFn) { + RenderPolicy::SetEmptyModelFn(checkFn); m_RenderQueue->SetEmptyModelFn(checkFn); } diff --git a/map/basic_render_policy.hpp b/map/basic_render_policy.hpp index 76375b8e61..33234722dd 100644 --- a/map/basic_render_policy.hpp +++ b/map/basic_render_policy.hpp @@ -45,7 +45,7 @@ public: RenderQueue & GetRenderQueue(); void SetRenderFn(TRenderFn renderFn); - void SetEmptyModelFn(TEmptyModelFn const & checkFn); + void SetEmptyModelFn(TEmptyModelFn checkFn); bool NeedRedraw() const; }; diff --git a/map/basic_tiling_render_policy.cpp b/map/basic_tiling_render_policy.cpp index 37d9ce432c..bb645d51b7 100644 --- a/map/basic_tiling_render_policy.cpp +++ b/map/basic_tiling_render_policy.cpp @@ -64,7 +64,7 @@ void BasicTilingRenderPolicy::DrawFrame(shared_ptr const & e, Screen m_DrawScale = curCvg->GetDrawScale(); if (!curCvg->IsEmptyDrawingCoverage() || !curCvg->IsPartialCoverage()) - m_IsEmptyModel = curCvg->IsEmptyDrawingCoverage(); + m_IsEmptyModel = curCvg->IsEmptyDrawingCoverage() && curCvg->IsEmptyModelAtCoverageCenter(); pDrawer->endFrame(); } diff --git a/map/coverage_generator.cpp b/map/coverage_generator.cpp index a11637231a..a4e4d92936 100644 --- a/map/coverage_generator.cpp +++ b/map/coverage_generator.cpp @@ -17,13 +17,15 @@ CoverageGenerator::CoverageGenerator( shared_ptr const & windowHandle, shared_ptr const & primaryRC, shared_ptr const & rm, - yg::gl::PacketsQueue * glQueue) + yg::gl::PacketsQueue * glQueue, + RenderPolicy::TEmptyModelFn emptyModelFn) : m_queue(1), m_tileRenderer(tileRenderer), m_workCoverage(0), m_currentCoverage(new ScreenCoverage(tileRenderer, this)), m_sequenceID(0), - m_windowHandle(windowHandle) + m_windowHandle(windowHandle), + m_emptyModelFn(emptyModelFn) { g_coverageGeneratorDestroyed = false; @@ -133,6 +135,10 @@ void CoverageGenerator::CoverScreen(ScreenBase const & screen, int sequenceID) m_workCoverage->SetSequenceID(sequenceID); m_workCoverage->SetResourceStyleCache(m_workStylesCache.get()); m_workCoverage->SetScreen(screen); + + if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage()) + AddCheckEmptyModelTask(sequenceID); + m_workCoverage->CacheInfoLayer(); { @@ -174,6 +180,10 @@ void CoverageGenerator::MergeTile(Tiler::RectInfo const & rectInfo, int sequence m_workCoverage->SetSequenceID(sequenceID); m_workCoverage->SetResourceStyleCache(m_workStylesCache.get()); m_workCoverage->Merge(rectInfo); + + if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage()) + AddCheckEmptyModelTask(sequenceID); + m_workCoverage->CacheInfoLayer(); { @@ -197,6 +207,21 @@ void CoverageGenerator::MergeTile(Tiler::RectInfo const & rectInfo, int sequence m_windowHandle->invalidate(); } +void CoverageGenerator::AddCheckEmptyModelTask(int sequenceID) +{ + m_queue.AddCommand(bind(&CoverageGenerator::CheckEmptyModel, this, sequenceID)); +} + +void CoverageGenerator::CheckEmptyModel(int sequenceID) +{ + if (sequenceID < m_sequenceID) + return; + + m_currentCoverage->CheckEmptyModelAtCoverageCenter(); + + m_windowHandle->invalidate(); +} + void CoverageGenerator::WaitForEmptyAndFinished() { m_queue.Join(); @@ -216,3 +241,8 @@ shared_ptr const & CoverageGenerator::resourceManager() con { return m_resourceManager; } + +bool CoverageGenerator::IsEmptyModelAtPoint(m2::PointD const & pt) const +{ + return m_emptyModelFn(pt); +} diff --git a/map/coverage_generator.hpp b/map/coverage_generator.hpp index e4b873dd30..78e0f1ae15 100644 --- a/map/coverage_generator.hpp +++ b/map/coverage_generator.hpp @@ -50,13 +50,16 @@ private: threads::Mutex m_mutex; + RenderPolicy::TEmptyModelFn m_emptyModelFn; + public: CoverageGenerator(TileRenderer * tileRenderer, shared_ptr const & windowHandle, shared_ptr const & primaryRC, shared_ptr const & rm, - yg::gl::PacketsQueue * glQueue); + yg::gl::PacketsQueue * glQueue, + RenderPolicy::TEmptyModelFn emptyModelFn); ~CoverageGenerator(); @@ -68,14 +71,18 @@ public: void AddCoverScreenTask(ScreenBase const & screen, bool doForce); void AddMergeTileTask(Tiler::RectInfo const & rectInfo, int sequenceID); + void AddCheckEmptyModelTask(int sequenceID); void CoverScreen(ScreenBase const & screen, int sequenceID); void MergeTile(Tiler::RectInfo const & rectInfo, int sequenceID); + void CheckEmptyModel(int sequenceID); void Cancel(); void WaitForEmptyAndFinished(); + bool IsEmptyModelAtPoint(m2::PointD const & pt) const; + ScreenCoverage & CurrentCoverage(); threads::Mutex & Mutex(); diff --git a/map/framework.cpp b/map/framework.cpp index 3a6ebf2fd3..d405be2cc3 100644 --- a/map/framework.cpp +++ b/map/framework.cpp @@ -535,16 +535,15 @@ void Framework::DrawModel(shared_ptr const & e, bool Framework::IsEmptyModel(m2::PointD const & pt) { // Correct, but slow version (check country polygon). - /* string const fName = GetSearchEngine()->GetCountryFile(pt); if (fName.empty()) return false; return !m_model.IsLoaded(fName); - */ - // Fast, but not strict-correct version (just check limit rect). - return !m_model.IsCountryLoaded(pt); + // *Upd* Doesn't work in many cases, as there are a lot of countries which has limit rect + // that even roughly doesn't correspond to the shape of the country. + // return !m_model.IsCountryLoaded(pt); } void Framework::BeginPaint(shared_ptr const & e) diff --git a/map/render_policy.cpp b/map/render_policy.cpp index 2bec92ecc9..8501831e74 100644 --- a/map/render_policy.cpp +++ b/map/render_policy.cpp @@ -130,6 +130,11 @@ void RenderPolicy::SetRenderFn(TRenderFn renderFn) m_renderFn = renderFn; } +void RenderPolicy::SetEmptyModelFn(TEmptyModelFn emptyModelFn) +{ + m_emptyModelFn = emptyModelFn; +} + bool RenderPolicy::DoForceUpdate() const { return m_doForceUpdate; diff --git a/map/render_policy.hpp b/map/render_policy.hpp index 349fd8e77c..061d54866a 100644 --- a/map/render_policy.hpp +++ b/map/render_policy.hpp @@ -46,6 +46,7 @@ protected: shared_ptr m_windowHandle; shared_ptr m_drawer; TRenderFn m_renderFn; + TEmptyModelFn m_emptyModelFn; bool m_doSupportRotation; bool m_doForceUpdate; m2::AnyRectD m_invalidRect; @@ -81,7 +82,7 @@ public: /// the start point of rendering in renderpolicy. virtual void SetRenderFn(TRenderFn renderFn); - virtual void SetEmptyModelFn(TEmptyModelFn const &) {} + virtual void SetEmptyModelFn(TEmptyModelFn emptyModelFn); bool DoSupportRotation() const; virtual bool IsTiling() const; diff --git a/map/render_queue.cpp b/map/render_queue.cpp index 1adcc97983..aa2c8e06ce 100644 --- a/map/render_queue.cpp +++ b/map/render_queue.cpp @@ -70,6 +70,11 @@ void RenderQueue::SetRedrawAll() m_renderState->m_doRepaintAll = true; } +void RenderQueue::SetEmptyModelFn(RenderQueueRoutine::TEmptyModelFn fn) +{ + m_routine->SetEmptyModelFn(fn); +} + void RenderQueue::AddWindowHandle(shared_ptr const & windowHandle) { m_routine->addWindowHandle(windowHandle); diff --git a/map/render_queue.hpp b/map/render_queue.hpp index bcb8baa0ca..34849b4505 100644 --- a/map/render_queue.hpp +++ b/map/render_queue.hpp @@ -54,8 +54,7 @@ public: void SetRedrawAll(); - template - inline void SetEmptyModelFn(TFn const & fn) { m_routine->SetEmptyModelFn(fn); } + void SetEmptyModelFn(RenderQueueRoutine::TEmptyModelFn fn); void SetVisualScale(double visualScale); diff --git a/map/render_queue_routine.cpp b/map/render_queue_routine.cpp index bc3da102e2..18df5482d3 100644 --- a/map/render_queue_routine.cpp +++ b/map/render_queue_routine.cpp @@ -81,6 +81,11 @@ void RenderQueueRoutine::onSize(int w, int h) m_newBackBuffer = m_resourceManager->createRenderTarget(texW, texH); } +void RenderQueueRoutine::SetEmptyModelFn(TEmptyModelFn checkFn) +{ + m_emptyModelFn = checkFn; +} + void RenderQueueRoutine::processResize(ScreenBase const & frameScreen) { if (m_renderState->m_isResized) diff --git a/map/render_queue_routine.hpp b/map/render_queue_routine.hpp index 3154d68a20..cc288d37c2 100644 --- a/map/render_queue_routine.hpp +++ b/map/render_queue_routine.hpp @@ -118,7 +118,7 @@ public: void onSize(int w, int h); - void SetEmptyModelFn(TEmptyModelFn const checkFn) { m_emptyModelFn = checkFn; } + void SetEmptyModelFn(TEmptyModelFn checkFn); /// Check, whether the resize command is queued, and resize accordingly. void processResize(ScreenBase const & frameScreen); diff --git a/map/screen_coverage.cpp b/map/screen_coverage.cpp index ab42ff89a6..9b4aea9ff9 100644 --- a/map/screen_coverage.cpp +++ b/map/screen_coverage.cpp @@ -20,7 +20,8 @@ ScreenCoverage::ScreenCoverage() : m_tiler(), m_infoLayer(new yg::InfoLayer()), m_isEmptyDrawingCoverage(false), - m_leavesCount(0), + m_isEmptyModelAtCoverageCenter(true), + m_leafTilesToRender(0), m_stylesCache(0) { m_infoLayer->setCouldOverlap(false); @@ -31,7 +32,8 @@ ScreenCoverage::ScreenCoverage(TileRenderer * tileRenderer, : m_tileRenderer(tileRenderer), m_infoLayer(new yg::InfoLayer()), m_isEmptyDrawingCoverage(false), - m_leavesCount(0), + m_isEmptyModelAtCoverageCenter(true), + m_leafTilesToRender(0), m_coverageGenerator(coverageGenerator), m_stylesCache(0) { @@ -50,7 +52,8 @@ ScreenCoverage * ScreenCoverage::Clone() res->m_newTileRects = m_newTileRects; res->m_newLeafTileRects = m_newLeafTileRects; res->m_isEmptyDrawingCoverage = m_isEmptyDrawingCoverage; - res->m_leavesCount = m_leavesCount; + res->m_isEmptyModelAtCoverageCenter = m_isEmptyModelAtCoverageCenter; + res->m_leafTilesToRender = m_leafTilesToRender; TileCache * tileCache = &m_tileRenderer->GetTileCache(); @@ -116,7 +119,7 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri) if (m_tiler.isLeaf(ri)) { m_isEmptyDrawingCoverage &= tile->m_isEmptyDrawing; - m_leavesCount--; + m_leafTilesToRender--; } } } @@ -180,7 +183,8 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen) tileCache->lock(); m_isEmptyDrawingCoverage = true; - m_leavesCount = 0; + m_isEmptyModelAtCoverageCenter = true; + m_leafTilesToRender = 0; for (unsigned i = 0; i < allRects.size(); ++i) { @@ -202,7 +206,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen) { newRects.push_back(ri); if (m_tiler.isLeaf(ri)) - ++m_leavesCount; + ++m_leafTilesToRender; } } @@ -369,7 +373,18 @@ int ScreenCoverage::GetDrawScale() const bool ScreenCoverage::IsEmptyDrawingCoverage() const { - return (m_leavesCount <= 0) && m_isEmptyDrawingCoverage; + return (m_leafTilesToRender <= 0) && m_isEmptyDrawingCoverage; +} + +bool ScreenCoverage::IsEmptyModelAtCoverageCenter() const +{ + return m_isEmptyModelAtCoverageCenter; +} + +void ScreenCoverage::CheckEmptyModelAtCoverageCenter() +{ + if (!IsPartialCoverage() && IsEmptyDrawingCoverage()) + m_isEmptyModelAtCoverageCenter = m_coverageGenerator->IsEmptyModelAtPoint(m_screen.GlobalRect().GetGlobalRect().Center()); } bool ScreenCoverage::IsPartialCoverage() const diff --git a/map/screen_coverage.hpp b/map/screen_coverage.hpp index 510e8774ca..da72217b6a 100644 --- a/map/screen_coverage.hpp +++ b/map/screen_coverage.hpp @@ -53,10 +53,12 @@ private: TileSet m_tiles; /// InfoLayer composed of infoLayers for visible tiles scoped_ptr m_infoLayer; - + /// Does this coverage holds only tiles that are empty bool m_isEmptyDrawingCoverage; - - int m_leavesCount; + /// Does the model empty at the screen center? + bool m_isEmptyModelAtCoverageCenter; + /// How many "leaf" tiles we should render to cover the screen + int m_leafTilesToRender; CoverageGenerator * m_coverageGenerator; yg::ResourceStyleCache * m_stylesCache; @@ -83,6 +85,10 @@ public: 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; + /// Check, whether the model is empty at the center of the coverage. + void CheckEmptyModelAtCoverageCenter(); /// Setters/Getters for current stylesCache void SetResourceStyleCache(yg::ResourceStyleCache * stylesCache); yg::ResourceStyleCache * GetResourceStyleCache() const; diff --git a/map/tiling_render_policy_mt.cpp b/map/tiling_render_policy_mt.cpp index 7489f28f4d..12bfa42d32 100644 --- a/map/tiling_render_policy_mt.cpp +++ b/map/tiling_render_policy_mt.cpp @@ -173,5 +173,6 @@ void TilingRenderPolicyMT::SetRenderFn(TRenderFn renderFn) m_windowHandle, m_primaryRC, m_resourceManager, - 0)); + 0, + m_emptyModelFn)); } diff --git a/map/tiling_render_policy_st.cpp b/map/tiling_render_policy_st.cpp index 69528bf089..142c003e6d 100644 --- a/map/tiling_render_policy_st.cpp +++ b/map/tiling_render_policy_st.cpp @@ -210,7 +210,8 @@ void TilingRenderPolicyST::SetRenderFn(TRenderFn renderFn) m_windowHandle, m_primaryRC, m_resourceManager, - m_QueuedRenderer->GetPacketsQueue(GetPlatform().CpuCores()) + m_QueuedRenderer->GetPacketsQueue(GetPlatform().CpuCores()), + m_emptyModelFn ));