moved ScreenCoverage rendering completely onto displayList without ResourceStyleCache.

This commit is contained in:
rachytski 2012-04-20 16:56:10 +04:00 committed by Alex Zolotarev
parent 255836e728
commit 8f700f3cdb
8 changed files with 153 additions and 190 deletions

View file

@ -75,11 +75,6 @@ void BasicTilingRenderPolicy::DrawFrame(shared_ptr<PaintEvent> const & e, Screen
void BasicTilingRenderPolicy::EndFrame(shared_ptr<PaintEvent> const & e, ScreenBase const & s)
{
ScreenCoverage * curCvg = &m_CoverageGenerator->CurrentCoverage();
DrawerYG * pDrawer = e->drawer();
curCvg->EndFrame(pDrawer->screen().get());
m_CoverageGenerator->Mutex().Unlock();
if (m_QueuedRenderer)

View file

@ -24,54 +24,51 @@ CoverageGenerator::CoverageGenerator(
RenderPolicy::TEmptyModelFn emptyModelFn)
: m_queue(1),
m_tileRenderer(tileRenderer),
m_workCoverage(0),
m_currentCoverage(new ScreenCoverage(tileRenderer, this)),
m_sequenceID(0),
m_windowHandle(windowHandle),
m_emptyModelFn(emptyModelFn)
m_emptyModelFn(emptyModelFn),
m_glQueue(glQueue),
m_skinName(skinName)
{
g_coverageGeneratorDestroyed = false;
m_resourceManager = rm;
if (!glQueue)
if (!m_glQueue)
m_renderContext = primaryRC->createShared();
m_currentStylesCache.reset(new yg::ResourceStyleCache(rm,
rm->cacheThreadGlyphCacheID(),
glQueue));
m_workStylesCache.reset(new yg::ResourceStyleCache(rm,
rm->cacheThreadGlyphCacheID(),
glQueue));
m_params.m_resourceManager = m_resourceManager;
m_params.m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer());
if (glQueue)
m_params.m_renderQueue = glQueue;
m_params.m_doUnbindRT = false;
m_params.m_isSynchronized = false;
m_params.m_glyphCacheID = m_resourceManager->cacheThreadGlyphCacheID();
m_cacheSkin.reset(loadSkin(m_resourceManager,
skinName,
2,
2));
m_queue.AddInitCommand(bind(&CoverageGenerator::InitializeThreadGL, this));
m_queue.AddFinCommand(bind(&CoverageGenerator::FinalizeThreadGL, this));
m_queue.Start();
}
ScreenCoverage * CoverageGenerator::CreateCoverage()
{
yg::gl::Screen::Params params;
params.m_resourceManager = m_resourceManager;
params.m_renderQueue = m_glQueue;
params.m_doUnbindRT = false;
params.m_isSynchronized = false;
params.m_glyphCacheID = m_resourceManager->cacheThreadGlyphCacheID();
shared_ptr<yg::gl::Screen> screen(new yg::gl::Screen(params));
shared_ptr<yg::Skin> skin(loadSkin(m_resourceManager, m_skinName, 2, 2));
screen->setSkin(skin);
return new ScreenCoverage(m_tileRenderer, this, screen);
}
void CoverageGenerator::InitializeThreadGL()
{
if (m_renderContext)
m_renderContext->makeCurrent();
m_cacheScreen.reset(new yg::gl::Screen(m_params));
m_cacheScreen->setSkin(m_cacheSkin);
m_workCoverage = CreateCoverage();
m_currentCoverage = CreateCoverage();
}
void CoverageGenerator::FinalizeThreadGL()
@ -85,14 +82,13 @@ CoverageGenerator::~CoverageGenerator()
LOG(LINFO, ("cancelling coverage thread"));
Cancel();
LOG(LINFO, ("deleting cacheScreen"));
m_cacheScreen.reset();
LOG(LINFO, ("deleting workCoverage"));
delete m_workCoverage;
m_workCoverage = 0;
LOG(LINFO, ("deleting currentCoverage"));
delete m_currentCoverage;
m_currentCoverage = 0;
g_coverageGeneratorDestroyed = true;
}
@ -159,34 +155,22 @@ void CoverageGenerator::CoverScreen(ScreenBase const & screen, int sequenceID)
if (sequenceID < m_sequenceID)
return;
ASSERT(m_workCoverage == 0, ());
m_currentCoverage->CopyInto(*m_workCoverage);
m_workCoverage = m_currentCoverage->Clone();
m_workCoverage->SetSequenceID(sequenceID);
m_workCoverage->SetResourceStyleCache(m_workStylesCache.get());
m_workCoverage->SetScreen(screen);
if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage())
AddCheckEmptyModelTask(sequenceID);
m_workCoverage->Cache(m_cacheScreen.get());
m_workCoverage->Cache();
{
threads::MutexGuard g(m_mutex);
/// test that m_workCoverage->InfoLayer doesn't have
/// the same elements as m_currentCoverage->InfoLayer
ASSERT(!m_workCoverage->GetInfoLayer()->checkHasEquals(m_currentCoverage->GetInfoLayer()), ());
ASSERT(m_workCoverage->GetInfoLayer()->checkCached(m_workStylesCache.get()), ());
swap(m_currentCoverage, m_workCoverage);
swap(m_currentStylesCache, m_workStylesCache);
ASSERT(m_currentCoverage->GetResourceStyleCache() == m_currentStylesCache.get(), ());
}
delete m_workCoverage;
m_workCoverage = 0;
m_workCoverage->Clear();
m_windowHandle->invalidate();
}
@ -208,35 +192,21 @@ void CoverageGenerator::MergeTile(Tiler::RectInfo const & rectInfo, int sequence
return;
}
ASSERT(m_workCoverage == 0, ());
m_workCoverage = m_currentCoverage->Clone();
m_currentCoverage->CopyInto(*m_workCoverage);
m_workCoverage->SetSequenceID(sequenceID);
m_workCoverage->SetResourceStyleCache(m_workStylesCache.get());
m_workCoverage->Merge(rectInfo);
if (!m_workCoverage->IsPartialCoverage() && m_workCoverage->IsEmptyDrawingCoverage())
AddCheckEmptyModelTask(sequenceID);
m_workCoverage->Cache(m_cacheScreen.get());
m_workCoverage->Cache();
{
threads::MutexGuard g(m_mutex);
/// test that m_workCoverage->InfoLayer doesn't have
/// the same elements as m_currentCoverage->InfoLayer
ASSERT(!m_workCoverage->GetInfoLayer()->checkHasEquals(m_currentCoverage->GetInfoLayer()), ());
ASSERT(m_workCoverage->GetInfoLayer()->checkCached(m_workStylesCache.get()), ());
swap(m_currentCoverage, m_workCoverage);
swap(m_currentStylesCache, m_workStylesCache);
ASSERT(m_currentCoverage->GetResourceStyleCache() == m_currentStylesCache.get(), ());
}
/// we should delete workCoverage
delete m_workCoverage;
m_workCoverage = 0;
m_workCoverage->Clear();
m_windowHandle->invalidate();
}

View file

@ -46,9 +46,6 @@ private:
ScreenCoverage * m_workCoverage;
ScreenCoverage * m_currentCoverage;
shared_ptr<yg::ResourceStyleCache> m_workStylesCache;
shared_ptr<yg::ResourceStyleCache> m_currentStylesCache;
ScreenBase m_currentScreen;
int m_sequenceID;
@ -58,10 +55,10 @@ private:
RenderPolicy::TEmptyModelFn m_emptyModelFn;
/// screen for caching ScreenCoverage
yg::gl::Screen::Params m_cacheParams;
shared_ptr<yg::gl::Screen> m_cacheScreen;
shared_ptr<yg::Skin> m_cacheSkin;
yg::gl::PacketsQueue * m_glQueue;
string m_skinName;
ScreenCoverage * CreateCoverage();
public:

View file

@ -22,47 +22,45 @@ ScreenCoverage::ScreenCoverage()
m_infoLayer(new yg::InfoLayer()),
m_isEmptyDrawingCoverage(false),
m_isEmptyModelAtCoverageCenter(true),
m_leafTilesToRender(0),
m_stylesCache(0)
m_leafTilesToRender(0)
{
m_infoLayer->setCouldOverlap(false);
}
ScreenCoverage::ScreenCoverage(TileRenderer * tileRenderer,
CoverageGenerator * coverageGenerator)
CoverageGenerator * coverageGenerator,
shared_ptr<yg::gl::Screen> const & cacheScreen)
: m_tileRenderer(tileRenderer),
m_coverageGenerator(coverageGenerator),
m_infoLayer(new yg::InfoLayer()),
m_isEmptyDrawingCoverage(false),
m_isEmptyModelAtCoverageCenter(true),
m_leafTilesToRender(0),
m_coverageGenerator(coverageGenerator),
m_stylesCache(0)
m_cacheScreen(cacheScreen)
{
m_infoLayer->setCouldOverlap(false);
}
ScreenCoverage * ScreenCoverage::Clone()
void ScreenCoverage::CopyInto(ScreenCoverage & cvg)
{
ScreenCoverage * res = new ScreenCoverage();
res->m_tileRenderer = m_tileRenderer;
res->m_tiler = m_tiler;
res->m_screen = m_screen;
res->m_coverageGenerator = m_coverageGenerator;
res->m_tileRects = m_tileRects;
res->m_newTileRects = m_newTileRects;
res->m_newLeafTileRects = m_newLeafTileRects;
res->m_isEmptyDrawingCoverage = m_isEmptyDrawingCoverage;
res->m_isEmptyModelAtCoverageCenter = m_isEmptyModelAtCoverageCenter;
res->m_leafTilesToRender = m_leafTilesToRender;
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;
TileCache * tileCache = &m_tileRenderer->GetTileCache();
tileCache->Lock();
res->m_tiles = m_tiles;
cvg.m_tiles = m_tiles;
for (TTileSet::const_iterator it = res->m_tiles.begin(); it != res->m_tiles.end(); ++it)
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);
@ -70,22 +68,32 @@ ScreenCoverage * ScreenCoverage::Clone()
tileCache->Unlock();
res->m_infoLayer.reset();
res->m_infoLayer.reset(m_infoLayer->clone());
res->m_stylesCache = 0;
res->m_displayList.reset();
return res;
cvg.m_infoLayer.reset(m_infoLayer->clone());
}
void ScreenCoverage::SetResourceStyleCache(yg::ResourceStyleCache * stylesCache)
void ScreenCoverage::Clear()
{
m_stylesCache = stylesCache;
}
m_tileRects.clear();
m_newTileRects.clear();
m_newLeafTileRects.clear();
m_infoLayer->clear();
m_isEmptyDrawingCoverage = false;
m_isEmptyModelAtCoverageCenter = true;
m_leafTilesToRender = 0;
yg::ResourceStyleCache * ScreenCoverage::GetResourceStyleCache() const
{
return m_stylesCache;
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)
@ -145,15 +153,15 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
}
}
void ScreenCoverage::Cache(yg::gl::Screen *screen)
void ScreenCoverage::Cache()
{
/// caching tiles blitting commands.
m_displayList.reset();
m_displayList.reset(screen->createDisplayList());
m_displayList.reset(m_cacheScreen->createDisplayList());
screen->beginFrame();
screen->setDisplayList(m_displayList.get());
m_cacheScreen->beginFrame();
m_cacheScreen->setDisplayList(m_displayList.get());
vector<yg::gl::BlitInfo> infos;
@ -175,46 +183,17 @@ void ScreenCoverage::Cache(yg::gl::Screen *screen)
}
if (!infos.empty())
screen->blit(&infos[0], infos.size(), true);
m_cacheScreen->blit(&infos[0], infos.size(), true);
screen->setDisplayList(0);
screen->endFrame();
m_infoLayer->draw(m_cacheScreen.get(), math::Identity<double, 3>());
/// caching InfoLayer into texture
if (!m_stylesCache)
{
LOG(LWARNING, ("no styles cache"));
return;
}
m_infoLayer->cache(m_stylesCache);
/// asserting, that all visible elements is cached
ASSERT(m_infoLayer->checkCached(m_stylesCache), ());
m_stylesCache->upload();
/// and then into display list
screen->beginFrame();
screen->setAdditionalSkinPage(m_stylesCache->cachePage());
screen->setDisplayList(m_displayList.get());
m_infoLayer->draw(screen, math::Identity<double, 3>());
screen->setDisplayList(0);
screen->clearAdditionalSkinPage();
screen->endFrame();
m_cacheScreen->setDisplayList(0);
m_cacheScreen->endFrame();
/// completing commands that was immediately executed
/// while recording of displayList(for example UnlockStorage)
screen->completeCommands();
}
void ScreenCoverage::Remove(Tile const *)
{
m_cacheScreen->completeCommands();
}
void ScreenCoverage::SetScreen(ScreenBase const & screen)
@ -376,17 +355,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
ScreenCoverage::~ScreenCoverage()
{
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();
Clear();
}
void ScreenCoverage::Draw(yg::gl::Screen * s, ScreenBase const & screen)
@ -400,11 +369,6 @@ yg::InfoLayer * ScreenCoverage::GetInfoLayer() const
return m_infoLayer.get();
}
void ScreenCoverage::EndFrame(yg::gl::Screen *s)
{
s->clearAdditionalSkinPage();
}
int ScreenCoverage::GetDrawScale() const
{
return min(m_tiler.tileScale(), scales::GetUpperScale());

View file

@ -26,54 +26,71 @@ 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;
/// All rects, including rects which corresponds to a tiles in m_tiles
/// 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;
/// Only rects, that should be drawn
/// This set contains rects, which was send to TileRenderer to draw
TTileRectSet m_newTileRects;
/// Only leaf rects, that should be drawn
/// 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;
/// InfoLayer composed of infoLayers for visible tiles
scoped_ptr<yg::InfoLayer> m_infoLayer;
/// Does this coverage holds only tiles that are empty
/// State flags
/// Does the all leaf tiles in this coverage are empty?
bool m_isEmptyDrawingCoverage;
/// Does the model empty at the screen center?
/// If the map model empty at the screen center?
bool m_isEmptyModelAtCoverageCenter;
/// How many "leaf" tiles we should render to cover the screen
/// 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;
CoverageGenerator * m_coverageGenerator;
yg::ResourceStyleCache * m_stylesCache;
/// Screen, which is used for caching of this ScreenCoverage into DisplayList
shared_ptr<yg::gl::Screen> m_cacheScreen;
/// DisplayList which holds cached ScreenCoverage
shared_ptr<yg::gl::DisplayList> m_displayList;
/// Direct copying is prohibited.
ScreenCoverage(ScreenCoverage const & src);
ScreenCoverage const & operator=(ScreenCoverage const & src);
/// For each tile in m_tiles merge it's infoLayer into the big one.
void MergeInfoLayer();
public:
/// Default Constructor
ScreenCoverage();
~ScreenCoverage();
/// Constructor
ScreenCoverage(TileRenderer * tileRenderer,
CoverageGenerator * coverageGenerator);
ScreenCoverage * Clone();
CoverageGenerator * coverageGenerator,
shared_ptr<yg::gl::Screen> const & cacheScreen);
/// Destructor
~ScreenCoverage();
/// Copy all needed information into specified ScreenCoverage
void CopyInto(ScreenCoverage & cvg);
/// 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
@ -86,23 +103,16 @@ public:
bool IsEmptyModelAtCoverageCenter() const;
/// Check, whether the model is empty at the center of the coverage.
void CheckEmptyModelAtCoverageCenter();
/// Setters/Getters for current stylesCache
void SetResourceStyleCache(yg::ResourceStyleCache * stylesCache);
yg::ResourceStyleCache * GetResourceStyleCache() const;
/// Getter for InfoLayer
yg::InfoLayer * GetInfoLayer() const;
/// Cache entire coverage in display list
void Cache(yg::gl::Screen * screen);
/// Cache coverage in display list
void Cache();
/// 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);
/// remove tile from coverage
void Remove(Tile const * tile);
/// recalculate screen coverage, using as much info from prev coverage as possible
void SetScreen(ScreenBase const & screen);
/// draw screen coverage
void Draw(yg::gl::Screen * s, ScreenBase const & currentScreen);
/// perform end frame
void EndFrame(yg::gl::Screen * s);
/// 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

View file

@ -32,6 +32,18 @@ TilingRenderPolicyMT::TilingRenderPolicyMT(VideoTimer * videoTimer,
false,
true);
rmp.m_fontTexturesParams = yg::ResourceManager::TexturePoolParams(256,
256,
1,
rmp.m_texFormat,
true,
true,
true,
1,
"primaryTexture",
true,
true);
rmp.m_primaryStoragesParams = yg::ResourceManager::StoragePoolParams(50000 * sizeof(yg::gl::Vertex),
sizeof(yg::gl::Vertex),
100000 * sizeof(unsigned short),

View file

@ -35,6 +35,18 @@ TilingRenderPolicyST::TilingRenderPolicyST(VideoTimer * videoTimer,
true,
true);
rmp.m_fontTexturesParams = yg::ResourceManager::TexturePoolParams(256,
256,
1,
rmp.m_texFormat,
true,
true,
true,
1,
"primaryTexture",
true,
true);
rmp.m_primaryStoragesParams = yg::ResourceManager::StoragePoolParams(6000 * sizeof(yg::gl::Vertex),
sizeof(yg::gl::Vertex),
9000 * sizeof(unsigned short),

View file

@ -53,10 +53,13 @@ namespace yg
{
m_isRendering = true;
m_frameBuffer->setRenderTarget(m_renderTarget);
m_frameBuffer->setDepthBuffer(m_depthBuffer);
if (m_frameBuffer)
{
m_frameBuffer->setRenderTarget(m_renderTarget);
m_frameBuffer->setDepthBuffer(m_depthBuffer);
processCommand(make_shared_ptr(new ChangeFrameBuffer(m_frameBuffer)));
processCommand(make_shared_ptr(new ChangeFrameBuffer(m_frameBuffer)));
}
// checkStatus();
}