Notify immediately that tile reading finished.

This commit is contained in:
Daria Volvenkova 2016-03-11 13:44:50 +03:00 committed by Sergey Yershov
parent 15d4d854d2
commit 6b4ee29d1a
7 changed files with 129 additions and 89 deletions

View file

@ -140,25 +140,25 @@ void BackendRenderer::AcceptMessage(ref_ptr<Message> message)
m_batchersPool->ReleaseBatcher(msg->GetKey());
break;
}
case Message::FinishTileRead:
{
ref_ptr<FinishTileReadMessage> msg = message;
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<FinishTileReadMessage>(msg->MoveTiles(),
msg->GetTileRequestGeneration()),
MessagePriority::Normal);
break;
}
case Message::FinishReading:
{
ref_ptr<FinishReadingMessage> msg = message;
if (msg->IsEnableFlushOverlays())
TOverlaysRenderData overlays;
overlays.swap(m_overlays);
if (!overlays.empty())
{
TOverlaysRenderData overlays;
overlays.swap(m_overlays);
if (!overlays.empty())
{
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<FlushOverlaysMessage>(move(overlays)),
MessagePriority::Normal);
}
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<FlushOverlaysMessage>(move(overlays)),
MessagePriority::Normal);
}
m_commutator->PostMessage(ThreadsCommutator::RenderThread,
make_unique_dp<FinishReadingMessage>(move(msg->MoveTiles()),
msg->GetTileRequestGeneration()),
MessagePriority::Normal);
break;
}
case Message::MapShapeReaded:

View file

@ -195,6 +195,42 @@ void FrontendRenderer::AfterDrawFrame()
#endif
void FrontendRenderer::UpdateFeaturesWaitingStatus()
{
m2::RectD const & screenRect = m_userEventStream.GetCurrentScreen().ClipRect();
vector<m2::RectD> notFinishedTileRects;
notFinishedTileRects.reserve(m_notFinishedTiles.size());
for (auto const & tileKey : m_notFinishedTiles)
notFinishedTileRects.push_back(tileKey.GetGlobalRect());
for (RenderLayer & layer : m_layers)
{
for (auto & group : layer.m_renderGroups)
{
if (group->IsFeaturesWaiting())
{
m2::RectD const tileRect = group->GetTileKey().GetGlobalRect();
bool waitTileFeatures = false;
if (!notFinishedTileRects.empty() && tileRect.IsIntersect(screenRect))
{
for (auto const & notFinishedRect : notFinishedTileRects)
{
if (notFinishedRect.IsIntersect(tileRect))
{
waitTileFeatures = true;
break;
}
}
}
layer.m_isDirty |= group->UpdateFeaturesWaitingStatus(waitTileFeatures, m_currentZoomLevel,
make_ref(m_overlayTree), m_bucketsToDelete);
}
}
}
}
void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
{
switch (message->GetType())
@ -243,19 +279,29 @@ void FrontendRenderer::AcceptMessage(ref_ptr<Message> message)
break;
}
case Message::FinishReading:
case Message::FinishTileRead:
{
ref_ptr<FinishReadingMessage> msg = message;
ref_ptr<FinishTileReadMessage> msg = message;
bool const isLastRequest = m_tileRequestGeneration == msg->GetTileRequestGeneration();
if (!isLastRequest)
break;
bool changed = false;
for (auto const & tileKey : msg->GetTiles())
{
if (CheckTileGenerations(tileKey) && isLastRequest)
if (CheckTileGenerations(tileKey))
{
auto it = m_notFinishedTiles.find(tileKey);
if (it != m_notFinishedTiles.end())
{
m_notFinishedTiles.erase(it);
changed = true;
}
}
}
if (changed)
UpdateFeaturesWaitingStatus();
break;
}
@ -856,37 +902,6 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView)
BeforeDrawFrame();
#endif
m2::RectD const & screenRect = modelView.ClipRect();
vector<m2::RectD> notFinishedTileRects;
notFinishedTileRects.reserve(m_notFinishedTiles.size());
for (auto const & tileKey : m_notFinishedTiles)
notFinishedTileRects.push_back(tileKey.GetGlobalRect());
for (RenderLayer & layer : m_layers)
{
for (auto & group : layer.m_renderGroups)
{
if (group->IsFeaturesWaiting())
{
m2::RectD const tileRect = group->GetTileKey().GetGlobalRect();
bool waitTileFeatures = false;
if (!notFinishedTileRects.empty() && tileRect.IsIntersect(screenRect))
{
for (auto const & notFinishedRect : notFinishedTileRects)
{
if (notFinishedRect.IsIntersect(tileRect))
{
waitTileFeatures = true;
break;
}
}
}
layer.m_isDirty |= group->UpdateFeaturesWaitingStatus(waitTileFeatures, m_currentZoomLevel,
make_ref(m_overlayTree), m_bucketsToDelete);
}
}
}
bool const isPerspective = modelView.isPerspective();
GLFunctions::glEnable(gl_const::GLDepthTest);
@ -1196,8 +1211,12 @@ void FrontendRenderer::CheckPerspectiveMinScale()
void FrontendRenderer::ResolveZoomLevel(ScreenBase const & screen)
{
int const prevZoomLevel = m_currentZoomLevel;
m_currentZoomLevel = GetDrawTileScale(screen);
if (prevZoomLevel != m_currentZoomLevel)
UpdateFeaturesWaitingStatus();
CheckIsometryMinScale(screen);
CheckPerspectiveMinScale();
}

View file

@ -216,6 +216,7 @@ private:
double rotationAngle, double angleFOV);
void InvalidateRect(m2::RectD const & gRect);
bool CheckTileGenerations(TileKey const & tileKey);
void UpdateFeaturesWaitingStatus();
void OnCompassTapped();

View file

@ -12,6 +12,7 @@ public:
TileReadStarted,
TileReadEnded,
FinishReading,
FinishTileRead,
FlushTile,
FlushOverlays,
MapShapeReaded,

View file

@ -90,23 +90,27 @@ private:
class FinishReadingMessage : public Message
{
public:
template<typename T> FinishReadingMessage(T && tiles, uint64_t tileRequestGeneration, bool enableFlushOverlays = true)
FinishReadingMessage() = default;
Type GetType() const override { return Message::FinishReading; }
};
class FinishTileReadMessage : public Message
{
public:
template<typename T> FinishTileReadMessage(T && tiles, uint64_t tileRequestGeneration)
: m_tiles(forward<T>(tiles))
, m_tileRequestGeneration(tileRequestGeneration)
, m_enableFlushOverlays(enableFlushOverlays)
{}
Type GetType() const override { return Message::FinishReading; }
Type GetType() const override { return Message::FinishTileRead; }
TTilesCollection const & GetTiles() const { return m_tiles; }
TTilesCollection && MoveTiles() { return move(m_tiles); }
uint64_t GetTileRequestGeneration() const { return m_tileRequestGeneration; }
bool IsEnableFlushOverlays() const { return m_enableFlushOverlays; }
private:
TTilesCollection m_tiles;
uint64_t m_tileRequestGeneration;
bool m_enableFlushOverlays;
};
class FlushRenderBucketMessage : public BaseTileMessage

View file

@ -60,9 +60,7 @@ void ReadManager::OnTaskFinished(threads::IRoutine * task)
{
lock_guard<mutex> lock(m_finishedTilesMutex);
// add finished tile to collection
if (!task->IsCancelled())
m_finishedTiles.emplace(t->GetTileKey());
m_activeTiles.erase(t->GetTileKey());
// decrement counter
ASSERT(m_counter > 0, ());
@ -70,9 +68,17 @@ void ReadManager::OnTaskFinished(threads::IRoutine * task)
if (m_counter == 0)
{
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<FinishReadingMessage>(m_finishedTiles, m_tileRequestGeneration),
make_unique_dp<FinishReadingMessage>(),
MessagePriority::Normal);
}
if (!task->IsCancelled())
{
TTilesCollection tiles;
tiles.emplace(t->GetTileKey());
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<FinishTileReadMessage>(move(tiles), m_tileRequestGeneration),
MessagePriority::Normal);
m_finishedTiles.clear();
}
}
@ -94,11 +100,12 @@ void ReadManager::UpdateCoverage(ScreenBase const & screen, bool is3dBuildings,
{
m_modeChanged = false;
for_each(m_tileInfos.begin(), m_tileInfos.end(), bind(&ReadManager::CancelTileInfo, this, _1));
m_tileInfos.clear();
IncreaseCounter(static_cast<int>(tiles.size()), tileRequestGeneration);
m_generationCounter++;
for_each(m_tileInfos.begin(), m_tileInfos.end(), bind(&ReadManager::CancelTileInfo, this, _1));
m_tileInfos.clear();
for_each(tiles.begin(), tiles.end(), bind(&ReadManager::PushTaskBackForTileKey, this, _1, texMng));
}
else
@ -112,6 +119,8 @@ void ReadManager::UpdateCoverage(ScreenBase const & screen, bool is3dBuildings,
tiles.begin(), tiles.end(),
back_inserter(outdatedTiles), LessCoverageCell());
for_each(outdatedTiles.begin(), outdatedTiles.end(), bind(&ReadManager::ClearTileInfo, this, _1));
// Find rects that go in into viewport.
buffer_vector<TileKey, 8> newTiles;
#ifdef _MSC_VER
@ -130,9 +139,8 @@ void ReadManager::UpdateCoverage(ScreenBase const & screen, bool is3dBuildings,
outdatedTiles.begin(), outdatedTiles.end(),
back_inserter(readyTiles), LessCoverageCell());
IncreaseCounter(static_cast<int>(newTiles.size()), tileRequestGeneration, &readyTiles);
for_each(outdatedTiles.begin(), outdatedTiles.end(), bind(&ReadManager::ClearTileInfo, this, _1));
IncreaseCounter(static_cast<int>(newTiles.size()), tileRequestGeneration);
CheckFinishedTiles(readyTiles);
for_each(newTiles.begin(), newTiles.end(), bind(&ReadManager::PushTaskBackForTileKey, this, _1, texMng));
}
@ -188,7 +196,7 @@ bool ReadManager::CheckTileKey(TileKey const & tileKey) const
size_t ReadManager::ReadCount()
{
return max(static_cast<int>(GetPlatform().CpuCores()) - 2, 1);
return max(static_cast<int>(GetPlatform().CpuCores()) - 2, 2);
}
bool ReadManager::MustDropAllTiles(ScreenBase const & screen) const
@ -205,16 +213,34 @@ void ReadManager::PushTaskBackForTileKey(TileKey const & tileKey, ref_ptr<dp::Te
tileInfo->Set3dBuildings(m_need3dBuildings && m_allow3dBuildings);
m_tileInfos.insert(tileInfo);
ReadMWMTask * task = myPool.Get();
task->Init(tileInfo);
{
lock_guard<mutex> lock(m_finishedTilesMutex);
m_activeTiles.insert(tileKey);
}
m_pool->PushBack(task);
}
void ReadManager::PushTaskFront(shared_ptr<TileInfo> const & tileToReread)
void ReadManager::CheckFinishedTiles(TTileInfoCollection const & requestedTiles)
{
tileToReread->Set3dBuildings(m_need3dBuildings && m_allow3dBuildings);
ReadMWMTask * task = myPool.Get();
task->Init(tileToReread);
m_pool->PushFront(task);
if (requestedTiles.empty())
return;
TTilesCollection finishedTiles;
lock_guard<mutex> lock(m_finishedTilesMutex);
for (auto const & tile : requestedTiles)
if (m_activeTiles.find(tile->GetTileKey()) == m_activeTiles.end())
finishedTiles.emplace(tile->GetTileKey());
if (!finishedTiles.empty())
{
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<FinishTileReadMessage>(move(finishedTiles), m_tileRequestGeneration),
MessagePriority::Normal);
}
}
void ReadManager::CancelTileInfo(shared_ptr<TileInfo> const & tileToCancel)
@ -228,27 +254,17 @@ void ReadManager::ClearTileInfo(shared_ptr<TileInfo> const & tileToClear)
m_tileInfos.erase(tileToClear);
}
void ReadManager::IncreaseCounter(int value, uint64_t tileRequestGeneration,
TTileInfoCollection * readyTiles)
void ReadManager::IncreaseCounter(int value, uint64_t tileRequestGeneration)
{
lock_guard<mutex> lock(m_finishedTilesMutex);
m_counter += value;
m_tileRequestGeneration = tileRequestGeneration;
if (readyTiles != nullptr)
if (m_counter == 0)
{
bool const enableFlushOverlays = !m_finishedTiles.empty();
for (shared_ptr<TileInfo> & tile : *readyTiles)
m_finishedTiles.emplace(tile->GetTileKey());
if (m_counter == 0)
{
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<FinishReadingMessage>(m_finishedTiles, m_tileRequestGeneration,
enableFlushOverlays),
MessagePriority::Normal);
m_finishedTiles.clear();
}
m_commutator->PostMessage(ThreadsCommutator::ResourceUploadThread,
make_unique_dp<FinishReadingMessage>(),
MessagePriority::Normal);
}
}

View file

@ -45,7 +45,6 @@ private:
bool MustDropAllTiles(ScreenBase const & screen) const;
void PushTaskBackForTileKey(TileKey const & tileKey, ref_ptr<dp::TextureManager> texMng);
void PushTaskFront(shared_ptr<TileInfo> const & tileToReread);
private:
ref_ptr<ThreadsCommutator> m_commutator;
@ -74,17 +73,17 @@ private:
ObjectPool<ReadMWMTask, ReadMWMTaskFactory> myPool;
int m_counter;
set<TileKey> m_finishedTiles;
mutex m_finishedTilesMutex;
uint64_t m_generationCounter;
uint64_t m_tileRequestGeneration;
using TTileInfoCollection = buffer_vector<shared_ptr<TileInfo>, 8>;
TTilesCollection m_activeTiles;
void CancelTileInfo(shared_ptr<TileInfo> const & tileToCancel);
void ClearTileInfo(shared_ptr<TileInfo> const & tileToClear);
void IncreaseCounter(int value, uint64_t tileRequestGeneration,
TTileInfoCollection * readyTiles = nullptr);
void IncreaseCounter(int value, uint64_t tileRequestGeneration);
void CheckFinishedTiles(TTileInfoCollection const & requestedTiles);
};
} // namespace df