forked from organicmaps/organicmaps
Coverage generator simplification
This commit is contained in:
parent
6fd1389ec7
commit
e78f051c16
7 changed files with 376 additions and 360 deletions
|
@ -39,7 +39,6 @@ BasicTilingRenderPolicy::BasicTilingRenderPolicy(Params const & p,
|
|||
: RenderPolicy(p, GetPlatform().IsPro(), GetPlatform().CpuCores() + 2),
|
||||
m_DrawScale(0),
|
||||
m_IsEmptyModel(false),
|
||||
m_DoRecreateCoverage(false),
|
||||
m_IsNavigating(false),
|
||||
m_WasAnimatingLastFrame(false)
|
||||
{
|
||||
|
@ -95,13 +94,11 @@ void BasicTilingRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & e, Screen
|
|||
m_CoverageGenerator->InvalidateTiles(GetInvalidRect(), scales::GetUpperWorldScale() + 1);
|
||||
|
||||
if (!m_IsNavigating && (!IsAnimating()))
|
||||
m_CoverageGenerator->AddCoverScreenTask(s,
|
||||
doForceUpdateFromGenerator
|
||||
|| m_DoRecreateCoverage
|
||||
|| (doForceUpdate && doIntersectInvalidRect));
|
||||
m_CoverageGenerator->CoverScreen(s,
|
||||
doForceUpdateFromGenerator
|
||||
|| (doForceUpdate && doIntersectInvalidRect));
|
||||
|
||||
SetForceUpdate(false);
|
||||
m_DoRecreateCoverage = false;
|
||||
|
||||
/// rendering current coverage
|
||||
|
||||
|
@ -111,7 +108,7 @@ void BasicTilingRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & e, Screen
|
|||
|
||||
pDrawer->screen()->clear(m_bgColor);
|
||||
|
||||
m_CoverageGenerator->Mutex().Lock();
|
||||
FrameLock();
|
||||
|
||||
ScreenCoverage * curCvg = m_CoverageGenerator->CurrentCoverage();
|
||||
|
||||
|
@ -131,12 +128,12 @@ void BasicTilingRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & e, Screen
|
|||
}
|
||||
|
||||
pDrawer->endFrame();
|
||||
m_CoverageGenerator->AddFinishSequenceTaskIfNeeded();
|
||||
m_CoverageGenerator->FinishSequenceIfNeeded();
|
||||
}
|
||||
|
||||
void BasicTilingRenderPolicy::EndFrame(shared_ptr<PaintEvent> const & e, ScreenBase const & s)
|
||||
{
|
||||
m_CoverageGenerator->Mutex().Unlock();
|
||||
FrameUnlock();
|
||||
|
||||
if (m_QueuedRenderer)
|
||||
m_QueuedRenderer->EndFrame();
|
||||
|
@ -153,8 +150,7 @@ void BasicTilingRenderPolicy::PauseBackgroundRendering()
|
|||
{
|
||||
m_TileRenderer->SetIsPaused(true);
|
||||
m_TileRenderer->CancelCommands();
|
||||
m_CoverageGenerator->SetIsPaused(true);
|
||||
m_CoverageGenerator->CancelCommands();
|
||||
m_CoverageGenerator->Pause();
|
||||
if (m_QueuedRenderer)
|
||||
m_QueuedRenderer->SetPartialExecution(GetPlatform().CpuCores(), true);
|
||||
}
|
||||
|
@ -162,8 +158,7 @@ void BasicTilingRenderPolicy::PauseBackgroundRendering()
|
|||
void BasicTilingRenderPolicy::ResumeBackgroundRendering()
|
||||
{
|
||||
m_TileRenderer->SetIsPaused(false);
|
||||
m_CoverageGenerator->SetIsPaused(false);
|
||||
m_DoRecreateCoverage = true;
|
||||
m_CoverageGenerator->Resume();
|
||||
if (m_QueuedRenderer)
|
||||
m_QueuedRenderer->SetPartialExecution(GetPlatform().CpuCores(), false);
|
||||
}
|
||||
|
@ -256,12 +251,12 @@ size_t BasicTilingRenderPolicy::TileSize() const
|
|||
|
||||
void BasicTilingRenderPolicy::FrameLock()
|
||||
{
|
||||
m_CoverageGenerator->Mutex().Lock();
|
||||
m_CoverageGenerator->Lock();
|
||||
}
|
||||
|
||||
void BasicTilingRenderPolicy::FrameUnlock()
|
||||
{
|
||||
m_CoverageGenerator->Mutex().Unlock();
|
||||
m_CoverageGenerator->Unlock();
|
||||
}
|
||||
|
||||
shared_ptr<graphics::Overlay> const BasicTilingRenderPolicy::FrameOverlay() const
|
||||
|
|
|
@ -37,7 +37,6 @@ protected:
|
|||
int m_DrawScale;
|
||||
bool m_IsEmptyModel;
|
||||
storage::TIndex m_countryIndex;
|
||||
bool m_DoRecreateCoverage;
|
||||
bool m_IsNavigating;
|
||||
bool m_WasAnimatingLastFrame;
|
||||
size_t m_TileSize;
|
||||
|
|
|
@ -12,11 +12,7 @@
|
|||
|
||||
#include "../std/bind.hpp"
|
||||
|
||||
bool g_coverageGeneratorDestroyed = false;
|
||||
|
||||
CoverageGenerator::CoverageGenerator(
|
||||
string const & skinName,
|
||||
graphics::EDensity density,
|
||||
TileRenderer * tileRenderer,
|
||||
shared_ptr<WindowHandle> const & windowHandle,
|
||||
shared_ptr<graphics::RenderContext> const & primaryRC,
|
||||
|
@ -27,20 +23,10 @@ CoverageGenerator::CoverageGenerator(
|
|||
m_tileRenderer(tileRenderer),
|
||||
m_workCoverage(0),
|
||||
m_currentCoverage(0),
|
||||
m_sequenceID(0),
|
||||
m_windowHandle(windowHandle),
|
||||
m_countryIndexFn(countryIndexFn),
|
||||
m_glQueue(glQueue),
|
||||
m_skinName(skinName),
|
||||
m_density(density),
|
||||
m_fenceManager(2),
|
||||
m_currentFenceID(-1),
|
||||
m_doForceUpdate(false),
|
||||
m_isPaused(false),
|
||||
m_isBenchmarking(false)
|
||||
m_glQueue(glQueue)
|
||||
{
|
||||
g_coverageGeneratorDestroyed = false;
|
||||
|
||||
m_resourceManager = rm;
|
||||
|
||||
if (!m_glQueue)
|
||||
|
@ -51,7 +37,27 @@ CoverageGenerator::CoverageGenerator(
|
|||
|
||||
m_queue.Start();
|
||||
|
||||
Settings::Get("IsBenchmarking", m_isBenchmarking);
|
||||
Settings::Get("IsBenchmarking", m_benchmarkInfo.m_isBenchmarking);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
void CoverageGenerator::Shutdown()
|
||||
{
|
||||
m_stateInfo.SetSequenceID(numeric_limits<int>::max());
|
||||
m_queue.Join();
|
||||
}
|
||||
|
||||
ScreenCoverage * CoverageGenerator::CreateCoverage()
|
||||
|
@ -71,14 +77,14 @@ ScreenCoverage * CoverageGenerator::CreateCoverage()
|
|||
shared_ptr<graphics::Screen> screen(new graphics::Screen(params));
|
||||
|
||||
ScreenCoverage * screenCoverage = new ScreenCoverage(m_tileRenderer, this, screen);
|
||||
screenCoverage->SetBenchmarkingFlag(m_isBenchmarking);
|
||||
screenCoverage->SetBenchmarkingFlag(m_benchmarkInfo.m_isBenchmarking);
|
||||
|
||||
return screenCoverage;
|
||||
}
|
||||
|
||||
void CoverageGenerator::InitializeThreadGL()
|
||||
{
|
||||
threads::MutexGuard g(m_mutex);
|
||||
threads::MutexGuard g(m_stateInfo.m_mutex);
|
||||
|
||||
LOG(LINFO, ("initializing CoverageGenerator on it's own thread."));
|
||||
|
||||
|
@ -98,32 +104,192 @@ void CoverageGenerator::FinalizeThreadGL()
|
|||
m_renderContext->endThreadDrawing(m_resourceManager->cacheThreadSlot());
|
||||
}
|
||||
|
||||
CoverageGenerator::~CoverageGenerator()
|
||||
void CoverageGenerator::Pause()
|
||||
{
|
||||
LOG(LINFO, ("cancelling coverage thread"));
|
||||
Cancel();
|
||||
|
||||
LOG(LINFO, ("deleting workCoverage"));
|
||||
delete m_workCoverage;
|
||||
m_workCoverage = 0;
|
||||
|
||||
LOG(LINFO, ("deleting currentCoverage"));
|
||||
delete m_currentCoverage;
|
||||
m_currentCoverage = 0;
|
||||
|
||||
g_coverageGeneratorDestroyed = true;
|
||||
m_stateInfo.Pause();
|
||||
m_queue.CancelCommands();
|
||||
}
|
||||
|
||||
void CoverageGenerator::Cancel()
|
||||
void CoverageGenerator::Resume()
|
||||
{
|
||||
//LOG(LDEBUG, ("UVRLOG : CoverageGenerator::Cancel"));
|
||||
m_queue.Cancel();
|
||||
m_stateInfo.Resume();
|
||||
}
|
||||
|
||||
void CoverageGenerator::InvalidateTiles(m2::AnyRectD const & r, int startScale)
|
||||
{
|
||||
if (m_stateInfo.m_sequenceID == numeric_limits<int>::max())
|
||||
return;
|
||||
|
||||
/// this automatically will skip the previous CoverScreen commands
|
||||
/// and MergeTiles commands from previously generated ScreenCoverages
|
||||
++m_stateInfo.m_sequenceID;
|
||||
|
||||
m_queue.AddCommand(bind(&CoverageGenerator::InvalidateTilesImpl, this, r, startScale));
|
||||
}
|
||||
|
||||
void CoverageGenerator::CoverScreen(ScreenBase const & screen, bool doForce)
|
||||
{
|
||||
if ((screen == m_stateInfo.m_currentScreen) && (!doForce))
|
||||
return;
|
||||
|
||||
if (m_stateInfo.m_sequenceID == numeric_limits<int>::max())
|
||||
return;
|
||||
|
||||
m_stateInfo.m_currentScreen = screen;
|
||||
|
||||
++m_stateInfo.m_sequenceID;
|
||||
|
||||
m_queue.AddCommand(bind(&CoverageGenerator::CoverScreenImpl, this, _1, screen, m_stateInfo.m_sequenceID));
|
||||
}
|
||||
|
||||
void CoverageGenerator::MergeTile(Tiler::RectInfo const & rectInfo,
|
||||
int sequenceID)
|
||||
{
|
||||
m_queue.AddCommand(bind(&CoverageGenerator::MergeTileImpl, this, _1, rectInfo, sequenceID));
|
||||
}
|
||||
|
||||
void CoverageGenerator::CheckEmptyModel(int sequenceID)
|
||||
{
|
||||
m_queue.AddCommand(bind(&CoverageGenerator::CheckEmptyModelImpl, this, sequenceID));
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void CoverageGenerator::Unlock()
|
||||
{
|
||||
m_stateInfo.m_mutex.Unlock();
|
||||
}
|
||||
|
||||
void CoverageGenerator::StartTileDrawingSession(int sequenceID, unsigned tileCount)
|
||||
{
|
||||
ASSERT(m_benchmarkInfo.m_isBenchmarking, ("Only in benchmarking mode!"));
|
||||
m_benchmarkInfo.m_benchmarkSequenceID = sequenceID;
|
||||
m_benchmarkInfo.m_tilesCount = tileCount;
|
||||
}
|
||||
|
||||
storage::TIndex CoverageGenerator::GetCountryIndex(m2::PointD const & pt) const
|
||||
{
|
||||
return m_countryIndexFn(pt);
|
||||
}
|
||||
|
||||
bool CoverageGenerator::DoForceUpdate() const
|
||||
{
|
||||
return m_stateInfo.m_needForceUpdate;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
/// Benchmark support
|
||||
////////////////////////////////////////////////////
|
||||
int CoverageGenerator::InsertBenchmarkFence()
|
||||
{
|
||||
return m_benchmarkInfo.InsertBenchmarkFence();
|
||||
}
|
||||
|
||||
void CoverageGenerator::JoinBenchmarkFence(int fenceID)
|
||||
{
|
||||
m_benchmarkInfo.JoinBenchmarkFence(fenceID);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
/// On Coverage generator thread methods
|
||||
////////////////////////////////////////////////////
|
||||
void CoverageGenerator::CoverScreenImpl(core::CommandsQueue::Environment const & env,
|
||||
ScreenBase const & screen,
|
||||
int sequenceID)
|
||||
{
|
||||
if (sequenceID < m_stateInfo.m_sequenceID)
|
||||
return;
|
||||
|
||||
m_currentCoverage->CopyInto(*m_workCoverage, false);
|
||||
|
||||
m_workCoverage->SetSequenceID(sequenceID);
|
||||
m_workCoverage->SetScreen(screen);
|
||||
|
||||
if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage())
|
||||
{
|
||||
m_workCoverage->ResetEmptyModelAtCoverageCenter();
|
||||
CheckEmptyModel(sequenceID);
|
||||
}
|
||||
|
||||
bool shouldSwap = !m_stateInfo.m_isPause && m_workCoverage->Cache(env);
|
||||
|
||||
if (shouldSwap)
|
||||
{
|
||||
threads::MutexGuard g(m_stateInfo.m_mutex);
|
||||
swap(m_currentCoverage, m_workCoverage);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// we should skip all the following MergeTile commands
|
||||
++m_stateInfo.m_sequenceID;
|
||||
}
|
||||
|
||||
m_stateInfo.SetForceUpdate(!shouldSwap);
|
||||
|
||||
m_workCoverage->Clear();
|
||||
|
||||
m_windowHandle->invalidate();
|
||||
}
|
||||
|
||||
void CoverageGenerator::MergeTileImpl(core::CommandsQueue::Environment const & env,
|
||||
Tiler::RectInfo const & rectInfo,
|
||||
int sequenceID)
|
||||
{
|
||||
if (sequenceID < m_stateInfo.m_sequenceID)
|
||||
{
|
||||
m_tileRenderer->RemoveActiveTile(rectInfo, sequenceID);
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentCoverage->CopyInto(*m_workCoverage, true);
|
||||
m_workCoverage->SetSequenceID(sequenceID);
|
||||
m_workCoverage->Merge(rectInfo);
|
||||
|
||||
if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage())
|
||||
{
|
||||
m_workCoverage->ResetEmptyModelAtCoverageCenter();
|
||||
CheckEmptyModel(sequenceID);
|
||||
}
|
||||
|
||||
bool shouldSwap = !m_stateInfo.m_isPause && m_workCoverage->Cache(env);
|
||||
|
||||
if (shouldSwap)
|
||||
{
|
||||
threads::MutexGuard g(m_stateInfo.m_mutex);
|
||||
swap(m_currentCoverage, m_workCoverage);
|
||||
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)
|
||||
{
|
||||
{
|
||||
threads::MutexGuard g(m_mutex);
|
||||
threads::MutexGuard g(m_stateInfo.m_mutex);
|
||||
m_currentCoverage->RemoveTiles(r, startScale);
|
||||
}
|
||||
|
||||
|
@ -147,147 +313,9 @@ void CoverageGenerator::InvalidateTilesImpl(m2::AnyRectD const & r, int startSca
|
|||
tileCache.Unlock();
|
||||
}
|
||||
|
||||
void CoverageGenerator::InvalidateTiles(m2::AnyRectD const & r, int startScale)
|
||||
void CoverageGenerator::CheckEmptyModelImpl(int sequenceID)
|
||||
{
|
||||
if (m_sequenceID == numeric_limits<int>::max())
|
||||
return;
|
||||
|
||||
/// this automatically will skip the previous CoverScreen commands
|
||||
/// and MergeTiles commands from previously generated ScreenCoverages
|
||||
++m_sequenceID;
|
||||
|
||||
m_queue.AddCommand(bind(&CoverageGenerator::InvalidateTilesImpl, this, r, startScale));
|
||||
}
|
||||
|
||||
void CoverageGenerator::AddCoverScreenTask(ScreenBase const & screen, bool doForce)
|
||||
{
|
||||
if ((screen == m_currentScreen) && (!doForce))
|
||||
return;
|
||||
|
||||
if (m_sequenceID == numeric_limits<int>::max())
|
||||
return;
|
||||
|
||||
m_currentScreen = screen;
|
||||
|
||||
++m_sequenceID;
|
||||
|
||||
m_queue.AddCommand(bind(&CoverageGenerator::CoverScreen, this, _1, screen, m_sequenceID));
|
||||
}
|
||||
|
||||
int CoverageGenerator::InsertBenchmarkFence()
|
||||
{
|
||||
ASSERT(m_isBenchmarking, ("Only in benchmarking mode!"));
|
||||
m_currentFenceID = m_fenceManager.insertFence();
|
||||
return m_currentFenceID;
|
||||
}
|
||||
|
||||
void CoverageGenerator::JoinBenchmarkFence(int fenceID)
|
||||
{
|
||||
ASSERT(m_isBenchmarking, ("Only in benchmarking mode!"));
|
||||
CHECK(fenceID == m_currentFenceID, ("InsertBenchmarkFence without corresponding SignalBenchmarkFence detected"));
|
||||
m_fenceManager.joinFence(fenceID);
|
||||
}
|
||||
|
||||
void CoverageGenerator::SignalBenchmarkFence()
|
||||
{
|
||||
ASSERT(m_isBenchmarking, ("Only in benchmarking mode!"));
|
||||
if (m_currentFenceID != -1)
|
||||
m_fenceManager.signalFence(m_currentFenceID);
|
||||
}
|
||||
|
||||
void CoverageGenerator::CoverScreen(core::CommandsQueue::Environment const & env,
|
||||
ScreenBase const & screen,
|
||||
int sequenceID)
|
||||
{
|
||||
if (sequenceID < m_sequenceID)
|
||||
return;
|
||||
|
||||
m_currentCoverage->CopyInto(*m_workCoverage, false);
|
||||
|
||||
m_workCoverage->SetSequenceID(sequenceID);
|
||||
m_workCoverage->SetScreen(screen);
|
||||
|
||||
if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage())
|
||||
{
|
||||
m_workCoverage->ResetEmptyModelAtCoverageCenter();
|
||||
AddCheckEmptyModelTask(sequenceID);
|
||||
}
|
||||
|
||||
bool shouldSwap = !m_isPaused && m_workCoverage->Cache(env);
|
||||
|
||||
if (shouldSwap)
|
||||
{
|
||||
threads::MutexGuard g(m_mutex);
|
||||
swap(m_currentCoverage, m_workCoverage);
|
||||
}
|
||||
else
|
||||
{
|
||||
/// we should skip all the following MergeTile commands
|
||||
++m_sequenceID;
|
||||
}
|
||||
|
||||
m_doForceUpdate = !shouldSwap;
|
||||
|
||||
m_workCoverage->Clear();
|
||||
|
||||
m_windowHandle->invalidate();
|
||||
}
|
||||
|
||||
void CoverageGenerator::AddMergeTileTask(Tiler::RectInfo const & rectInfo,
|
||||
int sequenceID)
|
||||
{
|
||||
if (g_coverageGeneratorDestroyed)
|
||||
return;
|
||||
|
||||
m_queue.AddCommand(bind(&CoverageGenerator::MergeTile, this, _1, rectInfo, sequenceID));
|
||||
}
|
||||
|
||||
void CoverageGenerator::MergeTile(core::CommandsQueue::Environment const & env,
|
||||
Tiler::RectInfo const & rectInfo,
|
||||
int sequenceID)
|
||||
{
|
||||
if (sequenceID < m_sequenceID)
|
||||
{
|
||||
//LOG(LDEBUG, ("UVRLOG : MergeTile fail. s=", rectInfo.m_tileScale, " x=", rectInfo.m_x, " y=", rectInfo.m_y, " SequenceID=", sequenceID, " m_SequenceID=", m_sequenceID));
|
||||
m_tileRenderer->RemoveActiveTile(rectInfo, sequenceID);
|
||||
return;
|
||||
}
|
||||
|
||||
//LOG(LDEBUG, ("UVRLOG : MergeTile s=", rectInfo.m_tileScale, " x=", rectInfo.m_x, " y=", rectInfo.m_y, " SequenceID=", sequenceID, " m_SequenceID=", m_sequenceID));
|
||||
m_currentCoverage->CopyInto(*m_workCoverage, true);
|
||||
m_workCoverage->SetSequenceID(sequenceID);
|
||||
m_workCoverage->Merge(rectInfo);
|
||||
|
||||
if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage())
|
||||
{
|
||||
m_workCoverage->ResetEmptyModelAtCoverageCenter();
|
||||
AddCheckEmptyModelTask(sequenceID);
|
||||
}
|
||||
|
||||
bool shouldSwap = !m_isPaused && m_workCoverage->Cache(env);
|
||||
|
||||
if (shouldSwap)
|
||||
{
|
||||
threads::MutexGuard g(m_mutex);
|
||||
swap(m_currentCoverage, m_workCoverage);
|
||||
}
|
||||
|
||||
m_doForceUpdate = !shouldSwap;
|
||||
|
||||
m_workCoverage->Clear();
|
||||
|
||||
if (!m_isBenchmarking)
|
||||
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)
|
||||
if (sequenceID < m_stateInfo.m_sequenceID)
|
||||
return;
|
||||
|
||||
m_currentCoverage->CheckEmptyModelAtCoverageCenter();
|
||||
|
@ -295,89 +323,89 @@ void CoverageGenerator::CheckEmptyModel(int sequenceID)
|
|||
m_windowHandle->invalidate();
|
||||
}
|
||||
|
||||
void CoverageGenerator::AddFinishSequenceTaskIfNeeded()
|
||||
////////////////////////////////////////////////////////////
|
||||
/// BenchmarkInfo
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
CoverageGenerator::BenchmarkInfo::BenchmarkInfo()
|
||||
: m_benchmarkSequenceID(numeric_limits<int>::max())
|
||||
, m_tilesCount(-1)
|
||||
, m_fenceManager(2)
|
||||
, m_currentFenceID(-1)
|
||||
, m_isBenchmarking(false)
|
||||
{
|
||||
if (g_coverageGeneratorDestroyed)
|
||||
}
|
||||
|
||||
void CoverageGenerator::BenchmarkInfo::DecrementTileCount(int sequenceID)
|
||||
{
|
||||
if (!m_isBenchmarking)
|
||||
return;
|
||||
|
||||
if (m_benchmarkBarrier.m_tilesCount == 0)
|
||||
if (sequenceID < m_benchmarkSequenceID)
|
||||
{
|
||||
// this instruction based on idea that up to this point all tiles is rendered, all threads
|
||||
// expect gui thread in wait state, and no one can modify m_tilesCount expect gui thread.
|
||||
// If banchmarking engine change logic, may be m_tilesCount need to be guard by some sync primitive
|
||||
m_benchmarkBarrier.m_tilesCount = -1;
|
||||
m_queue.AddCommand(bind(&CoverageGenerator::FinishSequence, this));
|
||||
m_tilesCount = -1;
|
||||
return;
|
||||
}
|
||||
m_tilesCount -= 1;
|
||||
}
|
||||
|
||||
int CoverageGenerator::BenchmarkInfo::InsertBenchmarkFence()
|
||||
{
|
||||
ASSERT(m_isBenchmarking, ("Only for benchmark mode"));
|
||||
m_currentFenceID = m_fenceManager.insertFence();
|
||||
return m_currentFenceID;
|
||||
}
|
||||
|
||||
void CoverageGenerator::BenchmarkInfo::JoinBenchmarkFence(int fenceID)
|
||||
{
|
||||
ASSERT(m_isBenchmarking, ("Only for benchmark mode"));
|
||||
CHECK(fenceID == m_currentFenceID, ("InsertBenchmarkFence without corresponding SignalBenchmarkFence detected"));
|
||||
m_fenceManager.joinFence(fenceID);
|
||||
}
|
||||
|
||||
void CoverageGenerator::BenchmarkInfo::SignalBenchmarkFence()
|
||||
{
|
||||
ASSERT(m_isBenchmarking, ("Only for benchmark mode"));
|
||||
if (m_currentFenceID != -1)
|
||||
m_fenceManager.signalFence(m_currentFenceID);
|
||||
}
|
||||
|
||||
void CoverageGenerator::BenchmarkInfo::TryFinishSequence()
|
||||
{
|
||||
if (m_tilesCount == 0)
|
||||
{
|
||||
m_tilesCount = -1;
|
||||
SignalBenchmarkFence();
|
||||
}
|
||||
}
|
||||
|
||||
void CoverageGenerator::FinishSequence()
|
||||
////////////////////////////////////////////////////////////
|
||||
/// BenchmarkInfo
|
||||
////////////////////////////////////////////////////////////
|
||||
CoverageGenerator::StateInfo::StateInfo()
|
||||
: m_isPause(false)
|
||||
, m_needForceUpdate(false)
|
||||
, m_sequenceID(0)
|
||||
{
|
||||
SignalBenchmarkFence();
|
||||
}
|
||||
|
||||
void CoverageGenerator::AddDecrementTileCountTask(int sequenceID)
|
||||
{
|
||||
if (g_coverageGeneratorDestroyed)
|
||||
return;
|
||||
|
||||
m_queue.AddCommand(bind(&CoverageGenerator::DecrementTileCounter, this, sequenceID));
|
||||
}
|
||||
|
||||
void CoverageGenerator::DecrementTileCounter(int sequenceID)
|
||||
{
|
||||
ASSERT(m_isBenchmarking, ("Only in benchmarking mode!"));
|
||||
m_benchmarkBarrier.DecrementTileCounter(sequenceID);
|
||||
m_windowHandle->invalidate();
|
||||
}
|
||||
|
||||
void CoverageGenerator::WaitForEmptyAndFinished()
|
||||
{
|
||||
m_queue.Join();
|
||||
}
|
||||
|
||||
ScreenCoverage * CoverageGenerator::CurrentCoverage()
|
||||
{
|
||||
return m_currentCoverage;
|
||||
}
|
||||
|
||||
threads::Mutex & CoverageGenerator::Mutex()
|
||||
{
|
||||
return m_mutex;
|
||||
}
|
||||
|
||||
void CoverageGenerator::SetSequenceID(int sequenceID)
|
||||
void CoverageGenerator::StateInfo::SetSequenceID(int sequenceID)
|
||||
{
|
||||
m_sequenceID = sequenceID;
|
||||
}
|
||||
|
||||
void CoverageGenerator::StartTileDrawingSession(int sequenceID, unsigned tileCount)
|
||||
void CoverageGenerator::StateInfo::SetForceUpdate(bool needForceUpdate)
|
||||
{
|
||||
ASSERT(m_isBenchmarking, ("Only in benchmarking mode!"));
|
||||
m_benchmarkBarrier.m_sequenceID = sequenceID;
|
||||
m_benchmarkBarrier.m_tilesCount = tileCount;
|
||||
m_needForceUpdate = needForceUpdate;
|
||||
}
|
||||
|
||||
shared_ptr<graphics::ResourceManager> const & CoverageGenerator::resourceManager() const
|
||||
void CoverageGenerator::StateInfo::Pause()
|
||||
{
|
||||
return m_resourceManager;
|
||||
m_isPause = true;
|
||||
}
|
||||
|
||||
storage::TIndex CoverageGenerator::GetCountryIndex(m2::PointD const & pt) const
|
||||
void CoverageGenerator::StateInfo::Resume()
|
||||
{
|
||||
return m_countryIndexFn(pt);
|
||||
}
|
||||
|
||||
void CoverageGenerator::CancelCommands()
|
||||
{
|
||||
m_queue.CancelCommands();
|
||||
}
|
||||
|
||||
void CoverageGenerator::SetIsPaused(bool flag)
|
||||
{
|
||||
m_isPaused = flag;
|
||||
}
|
||||
|
||||
bool CoverageGenerator::DoForceUpdate() const
|
||||
{
|
||||
return m_doForceUpdate;
|
||||
m_isPause = false;
|
||||
m_needForceUpdate = true;
|
||||
}
|
||||
|
|
|
@ -39,25 +39,105 @@ namespace graphics
|
|||
/// newly rendered tile(p.e. merge it into current ScreenCoverage).
|
||||
class CoverageGenerator
|
||||
{
|
||||
ScreenCoverage * CreateCoverage();
|
||||
|
||||
public:
|
||||
|
||||
CoverageGenerator(TileRenderer * tileRenderer,
|
||||
shared_ptr<WindowHandle> const & windowHandle,
|
||||
shared_ptr<graphics::RenderContext> const & primaryRC,
|
||||
shared_ptr<graphics::ResourceManager> const & rm,
|
||||
graphics::PacketsQueue * glQueue,
|
||||
RenderPolicy::TCountryIndexFn const & countryIndexFn);
|
||||
|
||||
~CoverageGenerator();
|
||||
|
||||
void Shutdown();
|
||||
|
||||
void InitializeThreadGL();
|
||||
void FinalizeThreadGL();
|
||||
|
||||
//@{ 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);
|
||||
//}@
|
||||
|
||||
//@{ Benchmark support
|
||||
int InsertBenchmarkFence();
|
||||
void JoinBenchmarkFence(int fenceID);
|
||||
//}@
|
||||
|
||||
storage::TIndex GetCountryIndex(m2::PointD const & pt) const;
|
||||
|
||||
ScreenCoverage * CurrentCoverage();
|
||||
|
||||
void StartTileDrawingSession(int sequenceID, unsigned tileCount);
|
||||
|
||||
//@{ Frame lock
|
||||
void Lock();
|
||||
void Unlock();
|
||||
//}@
|
||||
|
||||
void Pause();
|
||||
void Resume();
|
||||
|
||||
bool DoForceUpdate() const;
|
||||
|
||||
private:
|
||||
struct BenchmarkRenderingBarier
|
||||
void CoverScreenImpl(core::CommandsQueue::Environment const & env,
|
||||
ScreenBase const & screen,
|
||||
int sequenceID);
|
||||
|
||||
void MergeTileImpl(core::CommandsQueue::Environment const & env,
|
||||
Tiler::RectInfo const & rectInfo,
|
||||
int sequenceID);
|
||||
|
||||
void InvalidateTilesImpl(m2::AnyRectD const & rect, int startScale);
|
||||
|
||||
void CheckEmptyModelImpl(int sequenceID);
|
||||
|
||||
private:
|
||||
struct BenchmarkInfo
|
||||
{
|
||||
BenchmarkRenderingBarier()
|
||||
: m_sequenceID(-1), m_tilesCount(-1)
|
||||
{
|
||||
}
|
||||
int m_benchmarkSequenceID;
|
||||
int m_tilesCount;
|
||||
|
||||
FenceManager m_fenceManager;
|
||||
int m_currentFenceID;
|
||||
|
||||
bool m_isBenchmarking;
|
||||
|
||||
BenchmarkInfo();
|
||||
|
||||
void DecrementTileCount(int sequenceID);
|
||||
|
||||
int InsertBenchmarkFence();
|
||||
void JoinBenchmarkFence(int fenceID);
|
||||
void SignalBenchmarkFence();
|
||||
void TryFinishSequence();
|
||||
} m_benchmarkInfo;
|
||||
|
||||
struct StateInfo
|
||||
{
|
||||
bool m_isPause;
|
||||
bool m_needForceUpdate;
|
||||
int m_sequenceID;
|
||||
unsigned m_tilesCount;
|
||||
ScreenBase m_currentScreen;
|
||||
threads::Mutex m_mutex;
|
||||
|
||||
void DecrementTileCounter(int sequenceID)
|
||||
{
|
||||
if (sequenceID == m_sequenceID)
|
||||
--m_tilesCount;
|
||||
}
|
||||
};
|
||||
StateInfo();
|
||||
|
||||
BenchmarkRenderingBarier m_benchmarkBarrier;
|
||||
void SetSequenceID(int sequenceID);
|
||||
void SetForceUpdate(bool needForceUpdate);
|
||||
|
||||
void Pause();
|
||||
void Resume();
|
||||
} m_stateInfo;
|
||||
|
||||
core::CommandsQueue m_queue;
|
||||
|
||||
|
@ -69,90 +149,9 @@ private:
|
|||
ScreenCoverage * m_workCoverage;
|
||||
ScreenCoverage * m_currentCoverage;
|
||||
|
||||
ScreenBase m_currentScreen;
|
||||
int m_sequenceID;
|
||||
|
||||
shared_ptr<WindowHandle> m_windowHandle;
|
||||
|
||||
threads::Mutex m_mutex;
|
||||
|
||||
RenderPolicy::TCountryIndexFn m_countryIndexFn;
|
||||
|
||||
graphics::PacketsQueue * m_glQueue;
|
||||
string m_skinName;
|
||||
graphics::EDensity m_density;
|
||||
|
||||
FenceManager m_fenceManager;
|
||||
int m_currentFenceID;
|
||||
|
||||
bool m_doForceUpdate;
|
||||
bool m_isPaused;
|
||||
bool m_isBenchmarking;
|
||||
|
||||
ScreenCoverage * CreateCoverage();
|
||||
|
||||
public:
|
||||
|
||||
CoverageGenerator(string const & skinName,
|
||||
graphics::EDensity density,
|
||||
TileRenderer * tileRenderer,
|
||||
shared_ptr<WindowHandle> const & windowHandle,
|
||||
shared_ptr<graphics::RenderContext> const & primaryRC,
|
||||
shared_ptr<graphics::ResourceManager> const & rm,
|
||||
graphics::PacketsQueue * glQueue,
|
||||
RenderPolicy::TCountryIndexFn const & countryIndexFn);
|
||||
|
||||
~CoverageGenerator();
|
||||
|
||||
void InitializeThreadGL();
|
||||
void FinalizeThreadGL();
|
||||
|
||||
void InvalidateTiles(m2::AnyRectD const & rect, int startScale);
|
||||
void InvalidateTilesImpl(m2::AnyRectD const & rect, int startScale);
|
||||
|
||||
void AddCoverScreenTask(ScreenBase const & screen, bool doForce);
|
||||
void AddMergeTileTask(Tiler::RectInfo const & rectInfo,
|
||||
int sequenceID);
|
||||
|
||||
void AddCheckEmptyModelTask(int sequenceID);
|
||||
void AddFinishSequenceTaskIfNeeded();
|
||||
|
||||
void AddDecrementTileCountTask(int sequenceID);
|
||||
void DecrementTileCounter(int sequenceID);
|
||||
|
||||
void CoverScreen(core::CommandsQueue::Environment const & env,
|
||||
ScreenBase const & screen,
|
||||
int sequenceID);
|
||||
|
||||
void MergeTile(core::CommandsQueue::Environment const & env,
|
||||
Tiler::RectInfo const & rectInfo,
|
||||
int sequenceID);
|
||||
|
||||
void CheckEmptyModel(int sequenceID);
|
||||
|
||||
void FinishSequence();
|
||||
|
||||
void Cancel();
|
||||
|
||||
void WaitForEmptyAndFinished();
|
||||
|
||||
storage::TIndex GetCountryIndex(m2::PointD const & pt) const;
|
||||
|
||||
ScreenCoverage * CurrentCoverage();
|
||||
|
||||
int InsertBenchmarkFence();
|
||||
void JoinBenchmarkFence(int fenceID);
|
||||
void SignalBenchmarkFence();
|
||||
|
||||
bool DoForceUpdate() const;
|
||||
|
||||
void SetSequenceID(int sequenceID);
|
||||
void StartTileDrawingSession(int sequenceID, unsigned tileCount);
|
||||
|
||||
threads::Mutex & Mutex();
|
||||
|
||||
shared_ptr<graphics::ResourceManager> const & resourceManager() const;
|
||||
|
||||
void SetIsPaused(bool flag);
|
||||
void CancelCommands();
|
||||
};
|
||||
|
|
|
@ -346,14 +346,14 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
|||
|
||||
core::CommandsQueue::Chain chain;
|
||||
|
||||
chain.addCommand(bind(&CoverageGenerator::AddMergeTileTask,
|
||||
chain.addCommand(bind(&CoverageGenerator::MergeTile,
|
||||
m_coverageGenerator,
|
||||
ri,
|
||||
GetSequenceID()));
|
||||
|
||||
if (m_isBenchmarking)
|
||||
{
|
||||
chain.addCommand(bind(&CoverageGenerator::AddDecrementTileCountTask,
|
||||
chain.addCommand(bind(&CoverageGenerator::DecrementTileCount,
|
||||
m_coverageGenerator,
|
||||
GetSequenceID()));
|
||||
}
|
||||
|
@ -379,7 +379,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
|||
|
||||
if (m_isBenchmarking)
|
||||
{
|
||||
chain.addCommand(bind(&CoverageGenerator::AddDecrementTileCountTask,
|
||||
chain.addCommand(bind(&CoverageGenerator::DecrementTileCount,
|
||||
m_coverageGenerator,
|
||||
GetSequenceID()));
|
||||
}
|
||||
|
|
|
@ -174,9 +174,7 @@ void TilingRenderPolicyMT::SetRenderFn(TRenderFn renderFn)
|
|||
VisualScale(),
|
||||
0));
|
||||
|
||||
m_CoverageGenerator.reset(new CoverageGenerator(skinName,
|
||||
Density(),
|
||||
m_TileRenderer.get(),
|
||||
m_CoverageGenerator.reset(new CoverageGenerator(m_TileRenderer.get(),
|
||||
m_windowHandle,
|
||||
m_primaryRC,
|
||||
m_resourceManager,
|
||||
|
|
|
@ -160,8 +160,7 @@ TilingRenderPolicyST::~TilingRenderPolicyST()
|
|||
m_QueuedRenderer->PrepareQueueCancellation(cpuCores);
|
||||
|
||||
/// now we should process all commands to collect them into queues
|
||||
m_CoverageGenerator->SetSequenceID(numeric_limits<int>::max());
|
||||
m_CoverageGenerator->WaitForEmptyAndFinished();
|
||||
m_CoverageGenerator->Shutdown();
|
||||
|
||||
m_QueuedRenderer->CancelQueuedCommands(cpuCores);
|
||||
|
||||
|
@ -214,9 +213,7 @@ void TilingRenderPolicyST::SetRenderFn(TRenderFn renderFn)
|
|||
/// CoverageGenerator rendering queue could execute commands partially
|
||||
/// as there are no render-to-texture calls.
|
||||
// m_QueuedRenderer->SetPartialExecution(cpuCores, true);
|
||||
m_CoverageGenerator.reset(new CoverageGenerator(skinName,
|
||||
Density(),
|
||||
m_TileRenderer.get(),
|
||||
m_CoverageGenerator.reset(new CoverageGenerator(m_TileRenderer.get(),
|
||||
m_windowHandle,
|
||||
m_primaryRC,
|
||||
m_resourceManager,
|
||||
|
|
Loading…
Add table
Reference in a new issue