forked from organicmaps/organicmaps
Bind every tile to sequence id, and remove active tile from tile cache only with less of equal sequence id
This commit is contained in:
parent
e23fb6bdf1
commit
b2202565dd
8 changed files with 94 additions and 70 deletions
|
@ -111,6 +111,7 @@ CoverageGenerator::~CoverageGenerator()
|
|||
|
||||
void CoverageGenerator::Cancel()
|
||||
{
|
||||
LOG(LDEBUG, ("UVRLOG : CoverageGenerator::Cancel"));
|
||||
m_queue.Cancel();
|
||||
}
|
||||
|
||||
|
@ -239,10 +240,12 @@ void CoverageGenerator::MergeTile(core::CommandsQueue::Environment const & env,
|
|||
{
|
||||
if (sequenceID < m_sequenceID)
|
||||
{
|
||||
m_tileRenderer->RemoveActiveTile(rectInfo);
|
||||
LOG(LDEBUG, ("UVRLOG : MergeTile fail. s=", rectInfo.m_tileScale, " x=", rectInfo.m_x, " y=", rectInfo.m_y, " SequenceID=", sequenceID, " m_SequenceID=", m_sequenceID));
|
||||
m_tileRenderer->RemoveActiveTile(rectInfo, sequenceID);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG(LDEBUG, ("UVRLOG : MergeTile s=", rectInfo.m_tileScale, " x=", rectInfo.m_x, " y=", rectInfo.m_y, " SequenceID=", sequenceID, " m_SequenceID=", m_sequenceID));
|
||||
m_currentCoverage->CopyInto(*m_workCoverage);
|
||||
m_workCoverage->SetSequenceID(sequenceID);
|
||||
m_workCoverage->Merge(rectInfo);
|
||||
|
|
|
@ -101,29 +101,10 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
|
|||
{
|
||||
ASSERT(m_tileRects.find(ri) != m_tileRects.end(), ());
|
||||
|
||||
TileCache & tileCache = m_tileRenderer->GetTileCache();
|
||||
TileSet & tileSet = m_tileRenderer->GetTileSet();
|
||||
Tile const * tile = m_tileRenderer->GetTile(ri);
|
||||
|
||||
Tile const * tile = 0;
|
||||
bool hasTile = false;
|
||||
|
||||
/// every code that works both with tileSet and tileCache
|
||||
/// should lock them in the same order to avoid deadlocks
|
||||
/// (unlocking should be done in reverse order)
|
||||
tileSet.Lock();
|
||||
tileCache.Lock();
|
||||
|
||||
hasTile = tileSet.HasTile(ri);
|
||||
|
||||
if (hasTile)
|
||||
if (tile != NULL)
|
||||
{
|
||||
ASSERT(tileCache.HasTile(ri), ());
|
||||
|
||||
tile = &tileCache.GetTile(ri);
|
||||
ASSERT(m_tiles.find(tile) == m_tiles.end(), ());
|
||||
|
||||
/// while in the TileSet, the tile is assumed to be locked
|
||||
|
||||
m_tiles.insert(tile);
|
||||
m_tileRects.erase(ri);
|
||||
m_newTileRects.erase(ri);
|
||||
|
@ -135,14 +116,6 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
|
|||
m_leafTilesToRender--;
|
||||
}
|
||||
|
||||
tileSet.RemoveTile(ri);
|
||||
}
|
||||
|
||||
tileCache.Unlock();
|
||||
tileSet.Unlock();
|
||||
|
||||
if (hasTile)
|
||||
{
|
||||
if (m_tiler.isLeaf(ri))
|
||||
{
|
||||
graphics::Overlay * tileOverlayCopy = tile->m_overlay->clone();
|
||||
|
@ -152,6 +125,8 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
|
|||
delete tileOverlayCopy;
|
||||
}
|
||||
}
|
||||
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,
|
||||
|
@ -239,6 +214,7 @@ bool ScreenCoverage::Cache(core::CommandsQueue::Environment const & env)
|
|||
|
||||
void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
||||
{
|
||||
LOG(LDEBUG, ("UVRLOG : Start ScreenCoverage::SetScreen. m_SequenceID=", GetSequenceID()));
|
||||
m_screen = screen;
|
||||
|
||||
m_newTileRects.clear();
|
||||
|
@ -326,6 +302,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
|||
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()));
|
||||
|
||||
Tiler::RectInfo cr[4] =
|
||||
{
|
||||
|
@ -356,7 +333,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
|||
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
|
||||
|
@ -397,7 +374,8 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
|||
|
||||
chain.addCommand(bind(&TileRenderer::RemoveActiveTile,
|
||||
m_tileRenderer,
|
||||
ri));
|
||||
ri,
|
||||
GetSequenceID()));
|
||||
|
||||
if (curNewTile == newRectsCount - 1)
|
||||
chain.addCommand(bind(&CoverageGenerator::AddFinishSequenceTask,
|
||||
|
|
|
@ -10,13 +10,15 @@ Tile::Tile(shared_ptr<graphics::gl::BaseTexture> const & renderTarget,
|
|||
ScreenBase const & tileScreen,
|
||||
Tiler::RectInfo const & rectInfo,
|
||||
double duration,
|
||||
bool isEmptyDrawing)
|
||||
bool isEmptyDrawing,
|
||||
int sequenceID)
|
||||
: m_renderTarget(renderTarget),
|
||||
m_overlay(overlay),
|
||||
m_tileScreen(tileScreen),
|
||||
m_rectInfo(rectInfo),
|
||||
m_duration(duration),
|
||||
m_isEmptyDrawing(isEmptyDrawing)
|
||||
m_isEmptyDrawing(isEmptyDrawing),
|
||||
m_sequenceID(sequenceID)
|
||||
{}
|
||||
|
||||
Tile::~Tile()
|
||||
|
|
|
@ -24,6 +24,7 @@ struct Tile
|
|||
Tiler::RectInfo m_rectInfo; //< taken from tiler
|
||||
double m_duration; //< how long does it take to render tile
|
||||
bool m_isEmptyDrawing; //< does this tile contains only coasts and oceans
|
||||
int m_sequenceID; // SequenceID in witch tile was rendered
|
||||
|
||||
Tile();
|
||||
|
||||
|
@ -32,7 +33,8 @@ struct Tile
|
|||
ScreenBase const & tileScreen,
|
||||
Tiler::RectInfo const & rectInfo,
|
||||
double duration,
|
||||
bool isEmptyDrawing);
|
||||
bool isEmptyDrawing,
|
||||
int sequenceID);
|
||||
|
||||
~Tile();
|
||||
};
|
||||
|
|
|
@ -18,6 +18,30 @@
|
|||
#include "../base/condition.hpp"
|
||||
#include "../base/shared_buffer_manager.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
class TileStructuresLockGuard
|
||||
{
|
||||
public:
|
||||
TileStructuresLockGuard(TileCache & tileCache, TileSet & tileSet)
|
||||
: m_tileCache(tileCache), m_tileSet(tileSet)
|
||||
{
|
||||
m_tileSet.Lock();
|
||||
m_tileCache.Lock();
|
||||
}
|
||||
|
||||
~TileStructuresLockGuard()
|
||||
{
|
||||
m_tileCache.Unlock();
|
||||
m_tileSet.Unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
TileCache & m_tileCache;
|
||||
TileSet & m_tileSet;
|
||||
};
|
||||
}
|
||||
|
||||
TileRenderer::TileRenderer(
|
||||
size_t tileSize,
|
||||
string const & skinName,
|
||||
|
@ -91,6 +115,7 @@ TileRenderer::~TileRenderer()
|
|||
{
|
||||
m_isExiting = true;
|
||||
|
||||
LOG(LDEBUG, ("UVRLOG : Cancel from ~TileRenderer"));
|
||||
m_queue.Cancel();
|
||||
|
||||
for (size_t i = 0; i < m_threadData.size(); ++i)
|
||||
|
@ -157,7 +182,12 @@ 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;
|
||||
|
@ -274,7 +304,8 @@ void TileRenderer::DrawTile(core::CommandsQueue::Environment const & env,
|
|||
frameScreen,
|
||||
rectInfo,
|
||||
0,
|
||||
paintEvent->isEmptyDrawing()));
|
||||
paintEvent->isEmptyDrawing(),
|
||||
sequenceID));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -309,9 +340,31 @@ TileCache & TileRenderer::GetTileCache()
|
|||
return m_tileCache;
|
||||
}
|
||||
|
||||
TileSet & TileRenderer::GetTileSet()
|
||||
Tile const * TileRenderer::GetTile(const Tiler::RectInfo & rectInfo)
|
||||
{
|
||||
return m_tileSet;
|
||||
TileStructuresLockGuard lock(m_tileCache, m_tileSet);
|
||||
|
||||
if (m_tileSet.HasTile(rectInfo))
|
||||
{
|
||||
ASSERT(!m_tileCache.HasTile(rectInfo), (""));
|
||||
Tile tile = m_tileSet.GetTile(rectInfo);
|
||||
|
||||
if (m_tileCache.CanFit() == 0)
|
||||
{
|
||||
LOG(LINFO, ("resizing tileCache to", m_tileCache.CacheSize() + 1, "elements"));
|
||||
m_tileCache.Resize(m_tileCache.CacheSize() + 1);
|
||||
}
|
||||
|
||||
m_tileCache.AddTile(rectInfo, TileCache::Entry(tile, m_resourceManager));
|
||||
m_tileCache.LockTile(rectInfo);
|
||||
|
||||
m_tileSet.RemoveTile(rectInfo);
|
||||
}
|
||||
|
||||
if (m_tileCache.HasTile(rectInfo))
|
||||
return &m_tileCache.GetTile(rectInfo);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void TileRenderer::WaitForEmptyAndFinished()
|
||||
|
@ -335,11 +388,7 @@ void TileRenderer::SetIsPaused(bool flag)
|
|||
|
||||
void TileRenderer::AddActiveTile(Tile const & tile)
|
||||
{
|
||||
/// every code that works both with tileSet and tileCache
|
||||
/// should lock them in the same order to avoid deadlocks
|
||||
/// (unlocking should be done in reverse order)
|
||||
m_tileSet.Lock();
|
||||
m_tileCache.Lock();
|
||||
TileStructuresLockGuard lock(m_tileCache, m_tileSet);
|
||||
|
||||
Tiler::RectInfo const & key = tile.m_rectInfo;
|
||||
|
||||
|
@ -347,39 +396,21 @@ void TileRenderer::AddActiveTile(Tile const & tile)
|
|||
m_resourceManager->texturePool(graphics::ERenderTargetTexture)->Free(tile.m_renderTarget);
|
||||
else
|
||||
{
|
||||
LOG(LDEBUG, ("UVRLOG : Add tile to set s=", key.m_tileScale, " x=", key.m_x, " y=", key.m_y, " m_SequenceID=", m_sequenceID));
|
||||
m_tileSet.AddTile(tile);
|
||||
|
||||
if (m_tileCache.CanFit() == 0)
|
||||
{
|
||||
LOG(LINFO, ("resizing tileCache to", m_tileCache.CacheSize() + 1, "elements"));
|
||||
m_tileCache.Resize(m_tileCache.CacheSize() + 1);
|
||||
}
|
||||
|
||||
m_tileCache.AddTile(key, TileCache::Entry(tile, m_resourceManager));
|
||||
m_tileCache.LockTile(key);
|
||||
}
|
||||
|
||||
m_tileCache.Unlock();
|
||||
m_tileSet.Unlock();
|
||||
}
|
||||
|
||||
void TileRenderer::RemoveActiveTile(Tiler::RectInfo const & rectInfo)
|
||||
void TileRenderer::RemoveActiveTile(Tiler::RectInfo const & rectInfo, int sequenceID)
|
||||
{
|
||||
/// every code that works both with tileSet and tileCache
|
||||
/// should lock them in the same order to avoid deadlocks
|
||||
/// (unlocking should be done in reverse order)
|
||||
m_tileSet.Lock();
|
||||
m_tileCache.Lock();
|
||||
TileStructuresLockGuard lock(m_tileCache, m_tileSet);
|
||||
|
||||
if (m_tileSet.HasTile(rectInfo))
|
||||
if (m_tileSet.HasTile(rectInfo) && m_tileSet.GetTileSequenceID(rectInfo) <= sequenceID)
|
||||
{
|
||||
ASSERT(m_tileCache.HasTile(rectInfo), ());
|
||||
m_tileCache.UnlockTile(rectInfo);
|
||||
ASSERT(!m_tileCache.HasTile(rectInfo), ("Tile cannot be in tileSet and tileCache at the same time"));
|
||||
LOG(LDEBUG, ("UVRLOG : Remove tile from set s=", rectInfo.m_tileScale, " x=", rectInfo.m_x, " y=", rectInfo.m_y, " m_SequenceID=", m_sequenceID));
|
||||
m_tileSet.RemoveTile(rectInfo);
|
||||
}
|
||||
|
||||
m_tileCache.Unlock();
|
||||
m_tileSet.Unlock();
|
||||
}
|
||||
|
||||
size_t TileRenderer::TileSize() const
|
||||
|
|
|
@ -103,8 +103,8 @@ public:
|
|||
core::CommandsQueue::Chain const & afterTileFns = core::CommandsQueue::Chain());
|
||||
/// get tile cache.
|
||||
TileCache & GetTileCache();
|
||||
/// get tile set
|
||||
TileSet & GetTileSet();
|
||||
/// get tile from render if tile already rendered, otherwise return NULL
|
||||
Tile const * GetTile(Tiler::RectInfo const & rectInfo);
|
||||
/// wait on a condition variable for an empty queue.
|
||||
void WaitForEmptyAndFinished();
|
||||
|
||||
|
@ -122,7 +122,7 @@ public:
|
|||
void AddActiveTile(Tile const & tile);
|
||||
/// remove tile from the TileSet.
|
||||
/// @param doUpdateCache shows, whether we should
|
||||
void RemoveActiveTile(Tiler::RectInfo const & rectInfo);
|
||||
void RemoveActiveTile(Tiler::RectInfo const & rectInfo, int sequenceID);
|
||||
|
||||
void SetIsPaused(bool flag);
|
||||
|
||||
|
|
|
@ -20,6 +20,12 @@ void TileSet::AddTile(Tile const & tile)
|
|||
m_tiles[tile.m_rectInfo] = tile;
|
||||
}
|
||||
|
||||
int TileSet::GetTileSequenceID(Tiler::RectInfo const & rectInfo)
|
||||
{
|
||||
ASSERT(HasTile(rectInfo), ());
|
||||
return m_tiles[rectInfo].m_sequenceID;
|
||||
}
|
||||
|
||||
void TileSet::RemoveTile(const Tiler::RectInfo &rectInfo)
|
||||
{
|
||||
m_tiles.erase(rectInfo);
|
||||
|
|
|
@ -24,6 +24,8 @@ public:
|
|||
bool HasTile(Tiler::RectInfo const & rectInfo);
|
||||
/// add tile to the set
|
||||
void AddTile(Tile const & tile);
|
||||
/// get sequenceID in witch tile was rendered
|
||||
int GetTileSequenceID(Tiler::RectInfo const & rectInfo);
|
||||
/// get tile from the set
|
||||
Tile const & GetTile(Tiler::RectInfo const & rectInfo);
|
||||
/// remove tile from the set
|
||||
|
|
Loading…
Add table
Reference in a new issue