checking for "true" model emptiness in TilingRenderPolicyXXX when all tiles are rendered "empty".

This commit is contained in:
rachytski 2012-04-10 19:00:02 +04:00 committed by Alex Zolotarev
parent ab02f8cee9
commit 4dea4ee38d
16 changed files with 101 additions and 26 deletions

View file

@ -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);
}

View file

@ -45,7 +45,7 @@ public:
RenderQueue & GetRenderQueue();
void SetRenderFn(TRenderFn renderFn);
void SetEmptyModelFn(TEmptyModelFn const & checkFn);
void SetEmptyModelFn(TEmptyModelFn checkFn);
bool NeedRedraw() const;
};

View file

@ -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();
}

View file

@ -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);
}

View file

@ -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();

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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);

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -173,5 +173,6 @@ void TilingRenderPolicyMT::SetRenderFn(TRenderFn renderFn)
m_windowHandle,
m_primaryRC,
m_resourceManager,
0));
0,
m_emptyModelFn));
}

View file

@ -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
));