Remove ScreenCoverage as class. Now we hold one set of information about current coverage, and two display list to render.

This commit is contained in:
ExMix 2013-06-05 17:34:28 +03:00 committed by Alex Zolotarev
parent e78f051c16
commit f2f57c096d
16 changed files with 557 additions and 862 deletions

View file

@ -13,17 +13,6 @@
namespace graphics
{
Overlay::Lock::Lock(shared_ptr<Overlay> overlay)
: m_overlay(overlay)
{
m_overlay->lock();
}
Overlay::Lock::~Lock()
{
m_overlay->unlock();
}
bool betterOverlayElement(shared_ptr<OverlayElement> const & l,
shared_ptr<OverlayElement> 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<shared_ptr<OverlayElement> > & res)
void Overlay::selectOverlayElements(m2::RectD const & rect, list<shared_ptr<OverlayElement> > & res) const
{
DoPreciseSelectByRect fn(rect, &res);
m_tree.ForEachInRect(rect, fn);
}
void Overlay::selectOverlayElements(m2::PointD const & pt, list<shared_ptr<OverlayElement> > & res)
void Overlay::selectOverlayElements(m2::PointD const & pt, list<shared_ptr<OverlayElement> > & res) const
{
DoPreciseSelectByPoint fn(pt, &res);
m_tree.ForEachInRect(m2::RectD(pt - m2::PointD(1, 1), pt + m2::PointD(1, 1)), fn);

View file

@ -37,22 +37,12 @@ namespace graphics
public:
class Lock
{
public:
Lock(shared_ptr<Overlay> overlay);
~Lock();
private:
shared_ptr<Overlay> m_overlay;
};
Overlay();
void draw(OverlayRenderer * r, math::Matrix<double, 3, 3> const & m);
void selectOverlayElements(m2::PointD const & pt, list<shared_ptr<OverlayElement> > & res);
void selectOverlayElements(m2::RectD const & rect, list<shared_ptr<OverlayElement> > & res);
void selectOverlayElements(m2::PointD const & pt, list<shared_ptr<OverlayElement> > & res) const;
void selectOverlayElements(m2::RectD const & rect, list<shared_ptr<OverlayElement> > & res) const;
void removeOverlayElement(shared_ptr<OverlayElement> 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();

View file

@ -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<PaintEvent> 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<PaintEvent> 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<PaintEvent> 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<graphics::Overlay> const BasicTilingRenderPolicy::FrameOverlay() const
graphics::Overlay * BasicTilingRenderPolicy::FrameOverlay() const
{
return m_CoverageGenerator->CurrentCoverage()->GetOverlay();
return m_CoverageGenerator->GetOverlay();
}
int BasicTilingRenderPolicy::InsertBenchmarkFence()

View file

@ -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<graphics::Overlay> const FrameOverlay() const;
graphics::Overlay * FrameOverlay() const;
/// benchmarking protocol
int InsertBenchmarkFence();

View file

@ -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<WindowHandle> const & windowHandle,
shared_ptr<graphics::RenderContext> const & primaryRC,
shared_ptr<graphics::ResourceManager> 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<WindowHandle> const & windowHandle,
shared_ptr<graphics::RenderContext> const & primaryRC,
shared_ptr<graphics::ResourceManager> 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<graphics::RenderContext> 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<graphics::Screen> 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<graphics::RenderContext> context,
shared_ptr<graphics::ResourceManager> 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<graphics::RenderContext> context,
shared_ptr<graphics::ResourceManager> 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<double, 3, 3> 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<Tile const *, 8> 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<Tile const *, 8>::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<Tiler::RectInfo> 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<Tiler::RectInfo> allRects;
allRects.reserve(16);
buffer_vector<Tiler::RectInfo, 8> 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<const Tile *, 64> 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<graphics::OverlayElement> const & e1,
shared_ptr<graphics::OverlayElement> 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<graphics::BlitInfo> 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<double, 3, 3> idM = math::Identity<double, 3>();
m_coverageInfo.m_overlay->lock();
vector<shared_ptr<graphics::OverlayElement> > 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<graphics::OverlayElement> 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;
}

View file

@ -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<graphics::RenderContext> context,
shared_ptr<graphics::ResourceManager> resourceManager,
graphics::PacketsQueue * glQueue);
void FinalizeThreadGL(shared_ptr<graphics::RenderContext> context,
shared_ptr<graphics::ResourceManager> 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<Tile const *, LessRectInfo> 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<graphics::ResourceManager> m_resourceManager;
shared_ptr<graphics::RenderContext> m_renderContext;
ScreenCoverage * m_workCoverage;
ScreenCoverage * m_currentCoverage;
shared_ptr<WindowHandle> m_windowHandle;
RenderPolicy::TCountryIndexFn m_countryIndexFn;
graphics::PacketsQueue * m_glQueue;
shared_ptr<graphics::Screen> m_cacheScreen;
};

View file

@ -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<graphics::Overlay> 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<ElementT> elem = GetClosestToPivot(candidates, pt);

View file

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

View file

@ -236,10 +236,10 @@ void RenderPolicy::FrameUnlock()
LOG(LWARNING, ("unimplemented method called"));
}
shared_ptr<graphics::Overlay> const RenderPolicy::FrameOverlay() const
graphics::Overlay * RenderPolicy::FrameOverlay() const
{
LOG(LWARNING, ("unimplemented method called"));
return shared_ptr<graphics::Overlay>();
return NULL;
}
graphics::Color const RenderPolicy::GetBgColor() const

View file

@ -162,7 +162,7 @@ public:
/// Get current graphics::Overlay object.
/// Access to this resource should be synchronized using
/// FrameLock/FrameUnlock methods
virtual shared_ptr<graphics::Overlay> const FrameOverlay() const;
virtual graphics::Overlay * FrameOverlay() const;
/// Benchmarking protocol
virtual int InsertBenchmarkFence();

View file

@ -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<int>::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<graphics::Screen> const & cacheScreen)
: m_sequenceID(numeric_limits<int>::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<graphics::OverlayElement> const & e,
vector<shared_ptr<graphics::OverlayElement> > & 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<graphics::BlitInfo> 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<double, 3, 3> idM = math::Identity<double, 3>();
// selecting and rendering non-sharp elements.
{
graphics::Overlay::Lock guard(m_overlay);
vector<shared_ptr<graphics::OverlayElement> > 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<shared_ptr<graphics::OverlayElement> > 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<Tiler::RectInfo> allRects;
vector<Tiler::RectInfo> 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<const Tile *, 64> 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<Tiler::RectInfo> firstClassTiles;
vector<Tiler::RectInfo> 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<double, 3, 3> 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<graphics::Overlay> 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<Tile const*> 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<Tile const *>::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;
}

View file

@ -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<Tiler::RectInfo> 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<Tile const *, LessRectInfo> 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<graphics::Overlay> 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<graphics::Screen> m_cacheScreen;
/// DisplayList which holds cached ScreenCoverage
shared_ptr<graphics::DisplayList> m_primaryDL;
/// DisplayList to cache all straight texts.
/// They are drawn with different shader.
shared_ptr<graphics::DisplayList> 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<graphics::Screen> 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<graphics::Overlay> 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);
};

View file

@ -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<graphics::RenderContext> const & primaryRC,
shared_ptr<graphics::ResourceManager> 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;

View file

@ -49,8 +49,6 @@ protected:
buffer_vector<ThreadData, 4> m_threadData;
shared_ptr<graphics::RenderContext> 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,

View file

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

View file

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