forked from organicmaps/organicmaps
checking for "true" model emptiness in TilingRenderPolicyXXX when all tiles are rendered "empty".
This commit is contained in:
parent
ab02f8cee9
commit
4dea4ee38d
16 changed files with 101 additions and 26 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@ public:
|
|||
RenderQueue & GetRenderQueue();
|
||||
|
||||
void SetRenderFn(TRenderFn renderFn);
|
||||
void SetEmptyModelFn(TEmptyModelFn const & checkFn);
|
||||
void SetEmptyModelFn(TEmptyModelFn checkFn);
|
||||
|
||||
bool NeedRedraw() const;
|
||||
};
|
||||
|
|
|
@ -64,7 +64,7 @@ void BasicTilingRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & e, Screen
|
|||
m_DrawScale = curCvg->GetDrawScale();
|
||||
|
||||
if (!curCvg->IsEmptyDrawingCoverage() || !curCvg->IsPartialCoverage())
|
||||
m_IsEmptyModel = curCvg->IsEmptyDrawingCoverage();
|
||||
m_IsEmptyModel = curCvg->IsEmptyDrawingCoverage() && curCvg->IsEmptyModelAtCoverageCenter();
|
||||
|
||||
pDrawer->endFrame();
|
||||
}
|
||||
|
|
|
@ -17,13 +17,15 @@ CoverageGenerator::CoverageGenerator(
|
|||
shared_ptr<WindowHandle> const & windowHandle,
|
||||
shared_ptr<yg::gl::RenderContext> const & primaryRC,
|
||||
shared_ptr<yg::ResourceManager> 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<yg::ResourceManager> const & CoverageGenerator::resourceManager() con
|
|||
{
|
||||
return m_resourceManager;
|
||||
}
|
||||
|
||||
bool CoverageGenerator::IsEmptyModelAtPoint(m2::PointD const & pt) const
|
||||
{
|
||||
return m_emptyModelFn(pt);
|
||||
}
|
||||
|
|
|
@ -50,13 +50,16 @@ private:
|
|||
|
||||
threads::Mutex m_mutex;
|
||||
|
||||
RenderPolicy::TEmptyModelFn m_emptyModelFn;
|
||||
|
||||
public:
|
||||
|
||||
CoverageGenerator(TileRenderer * tileRenderer,
|
||||
shared_ptr<WindowHandle> const & windowHandle,
|
||||
shared_ptr<yg::gl::RenderContext> const & primaryRC,
|
||||
shared_ptr<yg::ResourceManager> 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();
|
||||
|
|
|
@ -535,16 +535,15 @@ void Framework::DrawModel(shared_ptr<PaintEvent> 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<PaintEvent> const & e)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -46,6 +46,7 @@ protected:
|
|||
shared_ptr<WindowHandle> m_windowHandle;
|
||||
shared_ptr<DrawerYG> 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;
|
||||
|
|
|
@ -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<WindowHandle> const & windowHandle)
|
||||
{
|
||||
m_routine->addWindowHandle(windowHandle);
|
||||
|
|
|
@ -54,8 +54,7 @@ public:
|
|||
|
||||
void SetRedrawAll();
|
||||
|
||||
template <class TFn>
|
||||
inline void SetEmptyModelFn(TFn const & fn) { m_routine->SetEmptyModelFn(fn); }
|
||||
void SetEmptyModelFn(RenderQueueRoutine::TEmptyModelFn fn);
|
||||
|
||||
void SetVisualScale(double visualScale);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -53,10 +53,12 @@ private:
|
|||
TileSet m_tiles;
|
||||
/// InfoLayer composed of infoLayers for visible tiles
|
||||
scoped_ptr<yg::InfoLayer> 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;
|
||||
|
|
|
@ -173,5 +173,6 @@ void TilingRenderPolicyMT::SetRenderFn(TRenderFn renderFn)
|
|||
m_windowHandle,
|
||||
m_primaryRC,
|
||||
m_resourceManager,
|
||||
0));
|
||||
0,
|
||||
m_emptyModelFn));
|
||||
}
|
||||
|
|
|
@ -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
|
||||
));
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue