Fixed memory consumption on zooming

This commit is contained in:
r.kuznetsov 2015-12-10 18:48:58 +03:00
parent 1c21b32533
commit a8ea9f0875
7 changed files with 54 additions and 31 deletions

View file

@ -119,7 +119,10 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
program->Bind();
bucket->GetBuffer()->Build(program);
if (!IsUserMarkLayer(key))
{
CheckTileGenerations(key);
m_tileTree->ProcessTile(key, GetCurrentZoomLevel(), state, move(bucket));
}
else
{
m_userMarkRenderGroups.emplace_back(make_unique_dp<UserMarkRenderGroup>(state, key, move(bucket)));
@ -510,26 +513,42 @@ void FrontendRenderer::OnActivateTile(TileKey const & tileKey)
void FrontendRenderer::OnRemoveTile(TileKey const & tileKey)
{
auto removePredicate = [&tileKey](drape_ptr<RenderGroup> const & group)
{
return group->GetTileKey() == tileKey;
};
RemoveRenderGroups(removePredicate);
}
void FrontendRenderer::RemoveRenderGroups(TRenderGroupRemovePredicate const & predicate)
{
ASSERT(predicate != nullptr, ());
m_overlayTree->ForceUpdate();
for(auto const & group : m_renderGroups)
{
if (group->GetTileKey() == tileKey)
if (predicate(group))
{
group->DeleteLater();
group->Disappear();
}
}
auto removePredicate = [&tileKey](drape_ptr<RenderGroup> const & group)
{
return group->GetTileKey() == tileKey;
};
m_deferredRenderGroups.erase(remove_if(m_deferredRenderGroups.begin(),
m_deferredRenderGroups.end(),
removePredicate),
predicate),
m_deferredRenderGroups.end());
}
void FrontendRenderer::CheckTileGenerations(TileKey const & tileKey)
{
auto removePredicate = [&tileKey](drape_ptr<RenderGroup> const & group)
{
return group->GetTileKey() == tileKey && group->GetTileKey().m_generation < tileKey.m_generation;
};
RemoveRenderGroups(removePredicate);
}
void FrontendRenderer::OnCompassTapped()
{
m_myPositionController->StopCompassFollow();
@ -1054,23 +1073,11 @@ void FrontendRenderer::UpdateScene(ScreenBase const & modelView)
TTilesCollection tiles;
ResolveTileKeys(modelView, tiles);
m_overlayTree->ForceUpdate();
auto removePredicate = [this](drape_ptr<RenderGroup> const & group)
{
return group->IsOverlay() && group->GetTileKey().m_zoomLevel > GetCurrentZoomLevel();
};
for (auto const & group : m_renderGroups)
{
if (removePredicate(group))
{
group->DeleteLater();
group->Disappear();
}
}
m_deferredRenderGroups.erase(remove_if(m_deferredRenderGroups.begin(),
m_deferredRenderGroups.end(),
removePredicate),
m_deferredRenderGroups.end());
RemoveRenderGroups(removePredicate);
m_requestedTiles->Set(modelView, move(tiles));
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,

View file

@ -194,6 +194,11 @@ private:
void OnActivateTile(TileKey const & tileKey);
void OnRemoveTile(TileKey const & tileKey);
using TRenderGroupRemovePredicate = function<bool(drape_ptr<RenderGroup> const &)>;
void RemoveRenderGroups(TRenderGroupRemovePredicate const & predicate);
void CheckTileGenerations(TileKey const & tileKey);
void OnCompassTapped();
FeatureID GetVisiblePOI(m2::PointD const & pixelPoint) const;

View file

@ -38,6 +38,7 @@ ReadManager::ReadManager(ref_ptr<ThreadsCommutator> commutator, MapDataProvider
, m_forceUpdate(true)
, myPool(64, ReadMWMTaskFactory(m_memIndex, m_model))
, m_counter(0)
, m_generationCounter(0)
{
}
@ -78,6 +79,7 @@ void ReadManager::UpdateCoverage(ScreenBase const & screen, TTilesCollection con
if (MustDropAllTiles(screen))
{
IncreaseCounter(static_cast<int>(tiles.size()));
m_generationCounter++;
for_each(m_tileInfos.begin(), m_tileInfos.end(), bind(&ReadManager::CancelTileInfo, this, _1));
m_tileInfos.clear();
@ -176,7 +178,8 @@ bool ReadManager::MustDropAllTiles(ScreenBase const & screen) const
void ReadManager::PushTaskBackForTileKey(TileKey const & tileKey, ref_ptr<dp::TextureManager> texMng)
{
shared_ptr<TileInfo> tileInfo(new TileInfo(make_unique_dp<EngineContext>(tileKey, m_commutator, texMng)));
shared_ptr<TileInfo> tileInfo(new TileInfo(make_unique_dp<EngineContext>(TileKey(tileKey, m_generationCounter),
m_commutator, texMng)));
m_tileInfos.insert(tileInfo);
ReadMWMTask * task = myPool.Get();
task->Init(tileInfo);

View file

@ -72,6 +72,7 @@ private:
int m_counter;
set<TileKey> m_finishedTiles;
mutex m_finishedTilesMutex;
uint64_t m_generationCounter;
void CancelTileInfo(shared_ptr<TileInfo> const & tileToCancel);
void ClearTileInfo(shared_ptr<TileInfo> const & tileToClear);

View file

@ -6,19 +6,24 @@ namespace df
{
TileKey::TileKey()
: m_x(-1), m_y(-1), m_zoomLevel(-1)
{
}
: m_x(-1), m_y(-1), m_zoomLevel(-1), m_generation(0)
{}
TileKey::TileKey(int x, int y, int zoomLevel)
: m_x(x), m_y(y), m_zoomLevel(zoomLevel)
{
}
: m_x(x), m_y(y), m_zoomLevel(zoomLevel), m_generation(0)
{}
TileKey::TileKey(TileKey const & key, uint64_t generation)
: m_x(key.m_x), m_y(key.m_y),
m_zoomLevel(key.m_zoomLevel),
m_generation(generation)
{}
bool TileKey::operator <(TileKey const & other) const
{
if (m_zoomLevel != other.m_zoomLevel)
return m_zoomLevel < other.m_zoomLevel;
if (m_y != other.m_y)
return m_y < other.m_y;
@ -47,7 +52,8 @@ m2::RectD TileKey::GetGlobalRect() const
string DebugPrint(TileKey const & key)
{
ostringstream out;
out << "[x = " << key.m_x << ", y = " << key.m_y << ", zoomLevel = " << key.m_zoomLevel << "]";
out << "[x = " << key.m_x << ", y = " << key.m_y << ", zoomLevel = "
<< key.m_zoomLevel << ", gen = " << key.m_generation << "]";
return out.str();
}

View file

@ -21,6 +21,7 @@ struct TileKey
{
TileKey();
TileKey(int x, int y, int zoomLevel);
TileKey(TileKey const & key, uint64_t generation);
bool operator < (TileKey const & other) const;
bool operator == (TileKey const & other) const;
@ -30,6 +31,7 @@ struct TileKey
int m_x;
int m_y;
int m_zoomLevel;
uint64_t m_generation;
};
string DebugPrint(TileKey const & key);

View file

@ -239,8 +239,7 @@ bool TileTree::ProcessNode(TNodePtr const & node, TileKey const & tileKey, int c
{
// skip unknown tiles and tiles from different zoom level
// A tile can get Unknown status if it becomes invalid before BR finished its processing
if (childNode->m_tileStatus == TileStatus::Unknown ||
childNode->m_tileKey.m_zoomLevel != zoomLevel)
if (childNode->m_tileStatus == TileStatus::Unknown || tileKey.m_zoomLevel != zoomLevel)
return false;
// remove all tiles below current
@ -251,14 +250,14 @@ bool TileTree::ProcessNode(TNodePtr const & node, TileKey const & tileKey, int c
{
childNode->m_tileStatus = TileStatus::Deferred;
if (m_deferRenderGroupHandler != nullptr)
m_deferRenderGroupHandler(childNode->m_tileKey, state, move(bucket));
m_deferRenderGroupHandler(tileKey, state, move(bucket));
childNode->m_isRemoved = false;
}
else
{
childNode->m_tileStatus = TileStatus::Rendered;
if (m_addRenderGroupHandler != nullptr)
m_addRenderGroupHandler(childNode->m_tileKey, state, move(bucket));
m_addRenderGroupHandler(tileKey, state, move(bucket));
childNode->m_isRemoved = false;
}