forked from organicmaps/organicmaps
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:
parent
e78f051c16
commit
f2f57c096d
16 changed files with 557 additions and 862 deletions
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
};
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue