forked from organicmaps/organicmaps
using double buffering for dynamicPage in Skin. fixes issue on iPhone5.
This commit is contained in:
parent
be63171c2a
commit
56e06376d1
7 changed files with 132 additions and 39 deletions
|
@ -60,7 +60,7 @@ namespace yg
|
|||
float texX = style->m_texRect.minX() + 1.0f;
|
||||
float texY = style->m_texRect.minY() + 1.0f;
|
||||
|
||||
shared_ptr<BaseTexture> texture = skin()->getPage(style->m_pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> texture = skin()->page(style->m_pipelineID)->texture();
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
|
@ -105,7 +105,7 @@ namespace yg
|
|||
float texX = style->m_texRect.minX() + 1.0f;
|
||||
float texY = style->m_texRect.minY() + 1.0f;
|
||||
|
||||
shared_ptr<BaseTexture> texture = skin()->getPage(style->m_pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> texture = skin()->page(style->m_pipelineID)->texture();
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
|
|
|
@ -45,7 +45,7 @@ namespace yg
|
|||
{
|
||||
discardPipeline(i);
|
||||
freePipeline(i);
|
||||
if (m_skin->getPage(i)->type() != SkinPage::EStatic)
|
||||
if (m_skin->page(i)->type() != SkinPage::EStatic)
|
||||
freeTexture(i);
|
||||
}
|
||||
}
|
||||
|
@ -154,11 +154,11 @@ namespace yg
|
|||
{
|
||||
/// settings proper skin page type according to useGuiResources flag
|
||||
if (m_useGuiResources)
|
||||
for (size_t i = 0; i < m_skin->getPagesCount(); ++i)
|
||||
if (m_skin->getPage(i)->type() != SkinPage::EStatic)
|
||||
m_skin->getPage(i)->setType(SkinPage::ELightWeight);
|
||||
for (size_t i = 0; i < m_skin->pagesCount(); ++i)
|
||||
if (m_skin->page(i)->type() != SkinPage::EStatic)
|
||||
m_skin->page(i)->setType(SkinPage::ELightWeight);
|
||||
|
||||
m_pipelines.resize(m_skin->getPagesCount());
|
||||
m_pipelines.resize(m_skin->pagesCount());
|
||||
|
||||
m_skin->addClearPageFn(bind(&GeometryBatcher::flush, this, _1), 100);
|
||||
m_skin->addClearPageFn(bind(&GeometryBatcher::freeTexture, this, _1), 99);
|
||||
|
@ -170,7 +170,7 @@ namespace yg
|
|||
m_pipelines[i].m_currentIndex = 0;
|
||||
|
||||
m_pipelines[i].m_hasStorage = false;
|
||||
m_pipelines[i].m_type = skin->getPage(i)->type();
|
||||
m_pipelines[i].m_type = skin->page(i)->type();
|
||||
|
||||
m_pipelines[i].m_maxVertices = 0;
|
||||
m_pipelines[i].m_maxIndices = 0;
|
||||
|
@ -275,10 +275,27 @@ namespace yg
|
|||
{
|
||||
for (size_t i = m_pipelines.size(); i > 0; --i)
|
||||
{
|
||||
if ((pipelineID == -1) || ((i - 1) == (size_t)pipelineID))
|
||||
size_t id = i - 1;
|
||||
|
||||
if ((pipelineID == -1) || (id == (size_t)pipelineID))
|
||||
{
|
||||
flushPipeline(m_skin->getPage(i - 1), i - 1);
|
||||
reset(i - 1);
|
||||
if (flushPipeline(m_skin->page(id), id))
|
||||
{
|
||||
int nextPage = m_skin->nextPage(id);
|
||||
|
||||
if (nextPage != id)
|
||||
{
|
||||
// reserving texture in advance, before we'll
|
||||
// potentially return current texture into the pool.
|
||||
m_skin->page(nextPage)->checkTexture();
|
||||
}
|
||||
|
||||
m_skin->changePage(id);
|
||||
}
|
||||
|
||||
/// resetting geometry storage associated
|
||||
/// with the specified pipeline.
|
||||
reset(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -286,13 +303,13 @@ namespace yg
|
|||
|
||||
void GeometryBatcher::freeTexture(int pipelineID)
|
||||
{
|
||||
if (!m_skin->getPage(pipelineID)->hasTexture())
|
||||
if (!m_skin->page(pipelineID)->hasTexture())
|
||||
return;
|
||||
|
||||
shared_ptr<BaseTexture> texture = m_skin->getPage(pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> texture = m_skin->page(pipelineID)->texture();
|
||||
TTexturePool * texturePool = 0;
|
||||
|
||||
switch (m_skin->getPage(pipelineID)->type())
|
||||
switch (m_skin->page(pipelineID)->type())
|
||||
{
|
||||
case SkinPage::EPrimary:
|
||||
texturePool = resourceManager()->primaryTextures();
|
||||
|
@ -310,7 +327,7 @@ namespace yg
|
|||
|
||||
base_t::freeTexture(texture, texturePool);
|
||||
|
||||
m_skin->getPage(pipelineID)->resetTexture();
|
||||
m_skin->page(pipelineID)->resetTexture();
|
||||
}
|
||||
|
||||
void GeometryBatcher::unlockPipeline(int pipelineID)
|
||||
|
@ -327,7 +344,7 @@ namespace yg
|
|||
base_t::discardStorage(pipeline.m_storage);
|
||||
}
|
||||
|
||||
void GeometryBatcher::flushPipeline(shared_ptr<SkinPage> const & skinPage,
|
||||
bool GeometryBatcher::flushPipeline(shared_ptr<SkinPage> const & skinPage,
|
||||
int pipelineID)
|
||||
{
|
||||
GeometryPipeline & pipeline = m_pipelines[pipelineID];
|
||||
|
@ -365,7 +382,11 @@ namespace yg
|
|||
pipeline.m_indices = 0;
|
||||
pipeline.m_currentIndex = 0;
|
||||
pipeline.m_currentVertex = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GeometryBatcher::drawTexturedPolygon(
|
||||
|
@ -388,7 +409,7 @@ namespace yg
|
|||
float texMinY = ty0;
|
||||
float texMaxY = ty1;
|
||||
|
||||
shared_ptr<BaseTexture> const & texture = m_skin->getPage(pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> const & texture = m_skin->page(pipelineID)->texture();
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
|
@ -459,7 +480,7 @@ namespace yg
|
|||
float texMinY = ty0;
|
||||
float texMaxY = ty1;
|
||||
|
||||
shared_ptr<BaseTexture> const & texture = m_skin->getPage(pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> const & texture = m_skin->page(pipelineID)->texture();
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
|
|
|
@ -109,7 +109,7 @@ namespace yg
|
|||
void beginFrame();
|
||||
void endFrame();
|
||||
|
||||
void flushPipeline(shared_ptr<SkinPage> const & skinPage, int pipelineID);
|
||||
bool flushPipeline(shared_ptr<SkinPage> const & skinPage, int pipelineID);
|
||||
void unlockPipeline(int pipelineID);
|
||||
void discardPipeline(int pipelineID);
|
||||
|
||||
|
|
|
@ -95,7 +95,7 @@ namespace yg
|
|||
/// Length of the actual pattern data being tiling(without antialiasing zones).
|
||||
rawTileLen = 0;
|
||||
|
||||
shared_ptr<BaseTexture> texture = skin()->getPage(lineStyle->m_pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> texture = skin()->page(lineStyle->m_pipelineID)->texture();
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ namespace yg
|
|||
startVec = norm;
|
||||
}
|
||||
|
||||
shared_ptr<BaseTexture> texture = skin()->getPage(lineStyle->m_pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> texture = skin()->page(lineStyle->m_pipelineID)->texture();
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
|
@ -276,7 +276,7 @@ namespace yg
|
|||
nextPt + fDir - fNorm
|
||||
};
|
||||
|
||||
shared_ptr<BaseTexture> texture = skin()->getPage(lineStyle->m_pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> texture = skin()->page(lineStyle->m_pipelineID)->texture();
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
|
|
|
@ -110,7 +110,7 @@ namespace yg
|
|||
for (int i = 0; i < 4; ++i)
|
||||
rectPtsF[i] = m2::PointF(rectPts[i].x, rectPts[i].y);
|
||||
|
||||
shared_ptr<BaseTexture> texture = skin()->getPage(style->m_pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> texture = skin()->page(style->m_pipelineID)->texture();
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
|
@ -151,7 +151,7 @@ namespace yg
|
|||
m2::PointF(r.maxX(), r.maxY())
|
||||
};
|
||||
|
||||
shared_ptr<BaseTexture> texture = skin()->getPage(style->m_pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> texture = skin()->page(style->m_pipelineID)->texture();
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
|
@ -186,7 +186,7 @@ namespace yg
|
|||
return;
|
||||
}
|
||||
|
||||
shared_ptr<BaseTexture> texture = skin()->getPage(style->m_pipelineID)->texture();
|
||||
shared_ptr<BaseTexture> texture = skin()->page(style->m_pipelineID)->texture();
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
|
|
68
yg/skin.cpp
68
yg/skin.cpp
|
@ -25,8 +25,9 @@ namespace yg
|
|||
m_textPage = m_pages.size();
|
||||
addTextPages(1);
|
||||
|
||||
m_dynamicPage = m_pages.size();
|
||||
addDynamicPages(1);
|
||||
m_startDynamicPage = m_dynamicPage = m_pages.size();
|
||||
m_dynamicPagesCount = 2;
|
||||
addDynamicPages(m_dynamicPagesCount);
|
||||
}
|
||||
|
||||
void Skin::addTextPages(int count)
|
||||
|
@ -150,7 +151,8 @@ namespace yg
|
|||
|
||||
bool Skin::mapPenInfo(PenInfo const * penInfos, uint32_t * styleIDS, size_t count)
|
||||
{
|
||||
bool alreadyFlushed = false;
|
||||
int startDynamicPage = m_dynamicPage;
|
||||
int cycles = 0;
|
||||
|
||||
int i = 0;
|
||||
|
||||
|
@ -165,10 +167,17 @@ namespace yg
|
|||
{
|
||||
/// no room - flush the page
|
||||
flushDynamicPage();
|
||||
if (alreadyFlushed)
|
||||
return false; //<cycling
|
||||
|
||||
alreadyFlushed = true;
|
||||
if (startDynamicPage == m_dynamicPage)
|
||||
cycles += 1;
|
||||
|
||||
/// there could be maximum 2 cycles to
|
||||
/// pack the sequence as a whole.
|
||||
/// second cycle is necessary as the first one
|
||||
/// could possibly run on partially packed skin pages.
|
||||
if (cycles == 2)
|
||||
return false;
|
||||
|
||||
/// re-start packing
|
||||
i = 0;
|
||||
}
|
||||
|
@ -200,13 +209,13 @@ namespace yg
|
|||
return packID(m_textPage, m_pages[m_textPage]->mapGlyph(gk, glyphCache));
|
||||
}
|
||||
|
||||
shared_ptr<SkinPage> const & Skin::getPage(int i) const
|
||||
shared_ptr<SkinPage> const & Skin::page(int i) const
|
||||
{
|
||||
ASSERT(i < m_pages.size(), ());
|
||||
return m_pages[i];
|
||||
}
|
||||
|
||||
size_t Skin::getPagesCount() const
|
||||
size_t Skin::pagesCount() const
|
||||
{
|
||||
return m_pages.size();
|
||||
}
|
||||
|
@ -228,7 +237,7 @@ namespace yg
|
|||
|
||||
void Skin::clearPageHandles(uint8_t pipelineID)
|
||||
{
|
||||
getPage(pipelineID)->clearHandles();
|
||||
page(pipelineID)->clearHandles();
|
||||
}
|
||||
|
||||
/// This function is set to perform as a callback on texture or handles overflow
|
||||
|
@ -246,9 +255,33 @@ namespace yg
|
|||
flushTextPage();
|
||||
}
|
||||
|
||||
bool Skin::isDynamicPage(int i) const
|
||||
{
|
||||
return (i >= m_startDynamicPage) && (i < m_startDynamicPage + m_dynamicPagesCount);
|
||||
}
|
||||
|
||||
void Skin::flushDynamicPage()
|
||||
{
|
||||
callClearPageFns(m_dynamicPage);
|
||||
changeDynamicPage();
|
||||
}
|
||||
|
||||
int Skin::nextDynamicPage() const
|
||||
{
|
||||
if (m_dynamicPage == m_startDynamicPage + m_dynamicPagesCount - 1)
|
||||
return m_startDynamicPage;
|
||||
else
|
||||
return m_dynamicPage + 1;
|
||||
}
|
||||
|
||||
void Skin::changeDynamicPage()
|
||||
{
|
||||
m_dynamicPage = nextDynamicPage();
|
||||
}
|
||||
|
||||
bool Skin::isTextPage(int i) const
|
||||
{
|
||||
return i == m_textPage;
|
||||
}
|
||||
|
||||
void Skin::flushTextPage()
|
||||
|
@ -257,6 +290,23 @@ namespace yg
|
|||
callClearPageFns(m_textPage);
|
||||
}
|
||||
|
||||
int Skin::nextPage(int i) const
|
||||
{
|
||||
ASSERT(i < m_pages.size(), ());
|
||||
|
||||
if (isDynamicPage(i))
|
||||
return nextDynamicPage();
|
||||
|
||||
/// for static and text pages return same index as passed in.
|
||||
return i;
|
||||
}
|
||||
|
||||
void Skin::changePage(int i)
|
||||
{
|
||||
if (isDynamicPage(i))
|
||||
changeDynamicPage();
|
||||
}
|
||||
|
||||
uint32_t Skin::invalidHandle() const
|
||||
{
|
||||
return 0xFFFFFFFF;
|
||||
|
|
32
yg/skin.hpp
32
yg/skin.hpp
|
@ -44,11 +44,13 @@ namespace yg
|
|||
|
||||
TSkinPages m_pages;
|
||||
|
||||
uint8_t m_startDynamicPage;
|
||||
uint8_t m_dynamicPage;
|
||||
uint8_t m_dynamicPagesCount;
|
||||
|
||||
uint8_t m_textPage;
|
||||
|
||||
uint8_t m_startStaticPage;
|
||||
uint8_t m_currentStaticPage;
|
||||
uint8_t m_staticPagesCount;
|
||||
|
||||
shared_ptr<ResourceManager> m_resourceManager;
|
||||
|
@ -82,12 +84,19 @@ namespace yg
|
|||
void callOverflowFns(uint8_t pipelineID);
|
||||
|
||||
void clearPageHandles(uint8_t pipelineID);
|
||||
void onDynamicOverflow(uint8_t pipelineID);
|
||||
void onTextOverflow(uint8_t pipelineID);
|
||||
|
||||
bool isDynamicPage(int i) const;
|
||||
void flushDynamicPage();
|
||||
int nextDynamicPage() const;
|
||||
void changeDynamicPage();
|
||||
|
||||
void onDynamicOverflow(uint8_t pipelineID);
|
||||
|
||||
bool isTextPage(int i) const;
|
||||
void flushTextPage();
|
||||
|
||||
void onTextOverflow(uint8_t pipelineID);
|
||||
|
||||
public:
|
||||
|
||||
/// clean and destroy
|
||||
|
@ -117,10 +126,13 @@ namespace yg
|
|||
/// if not - pack and return id
|
||||
uint32_t mapCircleInfo(CircleInfo const & circleInfo);
|
||||
|
||||
/// adding function which will be called, when some SkinPage
|
||||
/// is getting cleared.
|
||||
void addClearPageFn(clearPageFn fn, int priority);
|
||||
|
||||
shared_ptr<SkinPage> const & getPage(int i) const;
|
||||
size_t getPagesCount() const;
|
||||
shared_ptr<SkinPage> const & page(int i) const;
|
||||
|
||||
size_t pagesCount() const;
|
||||
|
||||
uint32_t invalidHandle() const;
|
||||
uint32_t invalidPageHandle() const;
|
||||
|
@ -128,6 +140,16 @@ namespace yg
|
|||
uint8_t textPage() const;
|
||||
uint8_t dynamicPage() const;
|
||||
|
||||
/// change page for its "backbuffer" counterpart.
|
||||
/// this function is called after any rendering command
|
||||
/// issued to avoid the "GPU is waiting on texture used in
|
||||
/// rendering call" issue.
|
||||
/// @warning does nothing for static pages
|
||||
/// (pages loaded at skin creation time)
|
||||
/// and text pages.
|
||||
void changePage(int i);
|
||||
int nextPage(int i) const;
|
||||
|
||||
void clearHandles();
|
||||
|
||||
void memoryWarning();
|
||||
|
|
Loading…
Add table
Reference in a new issue