added CoverageGenerator pausing and Coverage caching command cancellation for smoother GUI performance.

This commit is contained in:
rachytski 2012-09-22 23:45:57 +03:00 committed by Alex Zolotarev
parent d03e167bc0
commit 89adf0faef
12 changed files with 125 additions and 16 deletions

View file

@ -89,12 +89,16 @@ void BasicTilingRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & e, Screen
bool doForceUpdate = DoForceUpdate();
bool doIntersectInvalidRect = GetInvalidRect().IsIntersect(s.GlobalRect());
bool doForceUpdateFromGenerator = m_CoverageGenerator->DoForceUpdate();
if (doForceUpdate)
m_CoverageGenerator->InvalidateTiles(GetInvalidRect(), scales::GetUpperWorldScale() + 1);
if (!m_IsNavigating && (!IsAnimating()))
m_CoverageGenerator->AddCoverScreenTask(s,
m_DoRecreateCoverage || (doForceUpdate && doIntersectInvalidRect));
doForceUpdateFromGenerator
|| m_DoRecreateCoverage
|| (doForceUpdate && doIntersectInvalidRect));
SetForceUpdate(false);
m_DoRecreateCoverage = false;
@ -144,6 +148,8 @@ void BasicTilingRenderPolicy::PauseBackgroundRendering()
{
m_TileRenderer->SetIsPaused(true);
m_TileRenderer->CancelCommands();
m_CoverageGenerator->SetIsPaused(true);
m_CoverageGenerator->CancelCommands();
if (m_QueuedRenderer)
m_QueuedRenderer->SetPartialExecution(GetPlatform().CpuCores(), true);
}
@ -151,6 +157,7 @@ void BasicTilingRenderPolicy::PauseBackgroundRendering()
void BasicTilingRenderPolicy::ResumeBackgroundRendering()
{
m_TileRenderer->SetIsPaused(false);
m_CoverageGenerator->SetIsPaused(false);
m_DoRecreateCoverage = true;
if (m_QueuedRenderer)
m_QueuedRenderer->SetPartialExecution(GetPlatform().CpuCores(), false);

View file

@ -30,7 +30,9 @@ CoverageGenerator::CoverageGenerator(
m_glQueue(glQueue),
m_skinName(skinName),
m_fenceManager(2),
m_currentFenceID(-1)
m_currentFenceID(-1),
m_doForceUpdate(false),
m_isPaused(false)
{
g_coverageGeneratorDestroyed = false;
@ -151,7 +153,7 @@ void CoverageGenerator::AddCoverScreenTask(ScreenBase const & screen, bool doFor
++m_sequenceID;
m_queue.AddCommand(bind(&CoverageGenerator::CoverScreen, this, screen, m_sequenceID));
m_queue.AddCommand(bind(&CoverageGenerator::CoverScreen, this, _1, screen, m_sequenceID));
}
int CoverageGenerator::InsertBenchmarkFence()
@ -172,7 +174,9 @@ void CoverageGenerator::SignalBenchmarkFence()
m_fenceManager.signalFence(m_currentFenceID);
}
void CoverageGenerator::CoverScreen(ScreenBase const & screen, int sequenceID)
void CoverageGenerator::CoverScreen(core::CommandsQueue::Environment const & env,
ScreenBase const & screen,
int sequenceID)
{
if (sequenceID < m_sequenceID)
return;
@ -188,13 +192,16 @@ void CoverageGenerator::CoverScreen(ScreenBase const & screen, int sequenceID)
AddCheckEmptyModelTask(sequenceID);
}
m_workCoverage->Cache();
bool shouldSwap = !m_isPaused && m_workCoverage->Cache(env);
if (shouldSwap)
{
threads::MutexGuard g(m_mutex);
swap(m_currentCoverage, m_workCoverage);
}
m_doForceUpdate = !shouldSwap;
m_workCoverage->Clear();
m_windowHandle->invalidate();
@ -206,10 +213,12 @@ void CoverageGenerator::AddMergeTileTask(Tiler::RectInfo const & rectInfo,
if (g_coverageGeneratorDestroyed)
return;
m_queue.AddCommand(bind(&CoverageGenerator::MergeTile, this, rectInfo, sequenceID));
m_queue.AddCommand(bind(&CoverageGenerator::MergeTile, this, _1, rectInfo, sequenceID));
}
void CoverageGenerator::MergeTile(Tiler::RectInfo const & rectInfo, int sequenceID)
void CoverageGenerator::MergeTile(core::CommandsQueue::Environment const & env,
Tiler::RectInfo const & rectInfo,
int sequenceID)
{
if (sequenceID < m_sequenceID)
{
@ -227,13 +236,16 @@ void CoverageGenerator::MergeTile(Tiler::RectInfo const & rectInfo, int sequence
AddCheckEmptyModelTask(sequenceID);
}
m_workCoverage->Cache();
bool shouldSwap = !m_isPaused && m_workCoverage->Cache(env);
if (shouldSwap)
{
threads::MutexGuard g(m_mutex);
swap(m_currentCoverage, m_workCoverage);
}
m_doForceUpdate = !shouldSwap;
m_workCoverage->Clear();
m_windowHandle->invalidate();
@ -302,3 +314,18 @@ string CoverageGenerator::GetCountryName(m2::PointD const & pt) const
{
return m_countryNameFn(pt);
}
void CoverageGenerator::CancelCommands()
{
m_queue.CancelCommands();
}
void CoverageGenerator::SetIsPaused(bool flag)
{
m_isPaused = flag;
}
bool CoverageGenerator::DoForceUpdate() const
{
return m_doForceUpdate;
}

View file

@ -66,6 +66,9 @@ private:
FenceManager m_fenceManager;
int m_currentFenceID;
bool m_doForceUpdate;
bool m_isPaused;
ScreenCoverage * CreateCoverage();
public:
@ -93,9 +96,16 @@ public:
void AddCheckEmptyModelTask(int sequenceID);
void AddFinishSequenceTask(int sequenceID);
void CoverScreen(ScreenBase const & screen, int sequenceID);
void MergeTile(Tiler::RectInfo const & rectInfo, int sequenceID);
void CoverScreen(core::CommandsQueue::Environment const & env,
ScreenBase const & screen,
int sequenceID);
void MergeTile(core::CommandsQueue::Environment const & env,
Tiler::RectInfo const & rectInfo,
int sequenceID);
void CheckEmptyModel(int sequenceID);
void FinishSequence(int sequenceID);
void Cancel();
@ -110,9 +120,14 @@ public:
void JoinBenchmarkFence(int fenceID);
void SignalBenchmarkFence();
bool DoForceUpdate() const;
void SetSequenceID(int sequenceID);
threads::Mutex & Mutex();
shared_ptr<yg::ResourceManager> const & resourceManager() const;
void SetIsPaused(bool flag);
void CancelCommands();
};

View file

@ -10,6 +10,7 @@
#include "../yg/screen.hpp"
#include "../yg/display_list.hpp"
#include "../yg/skin.hpp"
#include "../yg/base_texture.hpp"
#include "screen_coverage.hpp"
@ -154,13 +155,15 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
}
}
void ScreenCoverage::Cache()
bool ScreenCoverage::Cache(core::CommandsQueue::Environment const & env)
{
/// caching tiles blitting commands.
m_displayList.reset();
m_displayList.reset(m_cacheScreen->createDisplayList());
m_cacheScreen->setEnvironment(&env);
m_cacheScreen->beginFrame();
m_cacheScreen->setDisplayList(m_displayList.get());
@ -195,6 +198,12 @@ void ScreenCoverage::Cache()
/// 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)

View file

@ -113,7 +113,9 @@ public:
/// Getter for Overlay
shared_ptr<yg::Overlay> const & GetOverlay() const;
/// Cache coverage in display list
void Cache();
/// @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

View file

@ -274,6 +274,14 @@ namespace yg
}
}
/// is the rendering was cancelled, there possibly could
/// be "ghost" render styles which are present in internal
/// skin structures, but aren't rendered onto skin texture.
/// so we are clearing the whole skin, to ensure that they
/// are gone(slightly heavy, but very simple solution).
if (isCancelled())
m_skin->clearHandles();
base_t::endFrame();
}

View file

@ -89,6 +89,9 @@ namespace yg
shared_ptr<BaseTexture> const & texture,
bool shouldAddCheckPoint)
{
if (isCancelled())
return;
vector<shared_ptr<ResourceStyle> > v;
v.reserve(end - start);
copy(&uploadQueue[0] + start, &uploadQueue[0] + end, back_inserter(v));
@ -185,6 +188,9 @@ namespace yg
size_t indicesOffs,
unsigned primType)
{
if (isCancelled())
return;
shared_ptr<DrawGeometry> command(new DrawGeometry());
command->m_texture = texture;

View file

@ -1,6 +1,7 @@
#include "../base/SRC_FIRST.hpp"
#include "overlay.hpp"
#include "overlay_renderer.hpp"
#include "text_element.hpp"
#include "../base/logging.hpp"
@ -28,9 +29,17 @@ namespace yg
return elem->roughBoundRect();
}
void DrawIfNotCancelled(gl::OverlayRenderer * r,
shared_ptr<OverlayElement> const & e,
math::Matrix<double, 3, 3> const & m)
{
if (!r->isCancelled())
e->draw(r, m);
}
void Overlay::draw(gl::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m)
{
m_tree.ForEach(bind(&OverlayElement::draw, _1, r, cref(m)));
m_tree.ForEach(bind(&DrawIfNotCancelled, r, _1, cref(m)));
}
Overlay::Overlay()

View file

@ -27,7 +27,8 @@ namespace yg
m_isSynchronized(params.m_isSynchronized),
m_isRendering(false),
m_width(0),
m_height(0)
m_height(0),
m_env(0)
{
m_frameBuffer = params.m_frameBuffer;
m_resourceManager = params.m_resourceManager;
@ -287,5 +288,18 @@ namespace yg
if (m_renderQueue)
m_renderQueue->completeCommands();
}
void Renderer::setEnvironment(core::CommandsQueue::Environment const * env)
{
m_env = env;
}
bool Renderer::isCancelled() const
{
if (m_env)
return m_env->isCancelled();
else
return false;
}
}
}

View file

@ -5,6 +5,7 @@
#include "resource_manager.hpp"
#include "../base/threaded_list.hpp"
#include "../base/commands_queue.hpp"
#include "../std/function.hpp"
#include "../std/shared_ptr.hpp"
#include "../geometry/rect2d.hpp"
@ -102,6 +103,8 @@ namespace yg
unsigned int m_width;
unsigned int m_height;
core::CommandsQueue::Environment const * m_env;
public:
static const yg::Color s_bgColor;
@ -151,6 +154,9 @@ namespace yg
void addFramePoint();
void completeCommands();
void setEnvironment(core::CommandsQueue::Environment const * env);
bool isCancelled() const;
};
}
}

View file

@ -354,6 +354,12 @@ namespace yg
m_additionalPages[0]->setPipelineID(0 + m_pages.size());
}
void Skin::clearHandles()
{
for (unsigned i = 0; i < m_pages.size(); ++i)
m_pages[i]->clear();
}
void Skin::clearAdditionalPage()
{
m_additionalPages.clear();

View file

@ -57,8 +57,6 @@ namespace yg
bool m_fillAlpha;
void clearHandles();
Skin(shared_ptr<ResourceManager> const & resourceManager,
TSkinPages const & pages);
@ -141,6 +139,8 @@ namespace yg
void setAdditionalPage(shared_ptr<SkinPage> const & pages);
void clearAdditionalPage();
void clearHandles();
void memoryWarning();
void enterBackground();
void enterForeground();