forked from organicmaps/organicmaps
fixed dropped-out texts in TilingRenderPolicyXXX
This commit is contained in:
parent
16164acc38
commit
2f4015193b
6 changed files with 188 additions and 57 deletions
|
@ -94,20 +94,28 @@ void CoverageGenerator::CoverScreen(ScreenBase const & screen, int sequenceID)
|
|||
if (sequenceID < m_sequenceID)
|
||||
return;
|
||||
|
||||
ASSERT(m_workCoverage == 0, ());
|
||||
|
||||
m_workCoverage = m_currentCoverage->Clone();
|
||||
m_workCoverage->SetStylesCache(m_workStylesCache.get());
|
||||
m_workCoverage->SetScreen(screen);
|
||||
|
||||
ScreenCoverage * oldCoverage = m_currentCoverage;
|
||||
m_workCoverage->CacheInfoLayer();
|
||||
|
||||
{
|
||||
threads::MutexGuard g(m_mutex);
|
||||
m_currentCoverage->SetStylesCache(0);
|
||||
m_currentCoverage = m_workCoverage;
|
||||
|
||||
/// 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->GetStylesCache() == m_currentStylesCache.get(), ());
|
||||
}
|
||||
|
||||
delete oldCoverage;
|
||||
delete m_workCoverage;
|
||||
m_workCoverage = 0;
|
||||
|
||||
m_windowHandle->invalidate();
|
||||
|
@ -123,21 +131,29 @@ void CoverageGenerator::AddMergeTileTask(Tiler::RectInfo const & rectInfo)
|
|||
|
||||
void CoverageGenerator::MergeTile(Tiler::RectInfo const & rectInfo)
|
||||
{
|
||||
ASSERT(m_workCoverage == 0, ());
|
||||
|
||||
m_workCoverage = m_currentCoverage->Clone();
|
||||
m_workCoverage->SetStylesCache(m_workStylesCache.get());
|
||||
|
||||
m_workCoverage->Merge(rectInfo);
|
||||
|
||||
ScreenCoverage * oldCoverage = m_currentCoverage;
|
||||
m_workCoverage->CacheInfoLayer();
|
||||
|
||||
{
|
||||
threads::MutexGuard g(m_mutex);
|
||||
m_currentCoverage->SetStylesCache(0);
|
||||
m_currentCoverage = m_workCoverage;
|
||||
|
||||
/// 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->GetStylesCache() == m_currentStylesCache.get(), ());
|
||||
}
|
||||
|
||||
delete oldCoverage;
|
||||
/// we should delete workCoverage
|
||||
delete m_workCoverage;
|
||||
m_workCoverage = 0;
|
||||
|
||||
m_windowHandle->invalidate();
|
||||
|
|
|
@ -13,8 +13,13 @@
|
|||
#include "coverage_generator.hpp"
|
||||
|
||||
ScreenCoverage::ScreenCoverage()
|
||||
: m_tiler(0, 0), m_stylesCache(0)
|
||||
{}
|
||||
: m_tiler(0, 0),
|
||||
m_drawScale(0),
|
||||
m_stylesCache(0),
|
||||
m_infoLayer(new yg::InfoLayer())
|
||||
{
|
||||
m_infoLayer->setCouldOverlap(false);
|
||||
}
|
||||
|
||||
ScreenCoverage::ScreenCoverage(TileRenderer * tileRenderer,
|
||||
CoverageGenerator * coverageGenerator,
|
||||
|
@ -23,9 +28,11 @@ ScreenCoverage::ScreenCoverage(TileRenderer * tileRenderer,
|
|||
: m_tileRenderer(tileRenderer),
|
||||
m_tiler(tileSize, scaleEtalonSize),
|
||||
m_coverageGenerator(coverageGenerator),
|
||||
m_infoLayer(new yg::InfoLayer()),
|
||||
m_drawScale(0),
|
||||
m_stylesCache(0)
|
||||
{
|
||||
m_infoLayer.setCouldOverlap(false);
|
||||
m_infoLayer->setCouldOverlap(false);
|
||||
}
|
||||
|
||||
ScreenCoverage * ScreenCoverage::Clone()
|
||||
|
@ -53,7 +60,8 @@ ScreenCoverage * ScreenCoverage::Clone()
|
|||
|
||||
tileCache->writeUnlock();
|
||||
|
||||
res->m_infoLayer = m_infoLayer;
|
||||
res->m_infoLayer.reset();
|
||||
res->m_infoLayer.reset(m_infoLayer->clone());
|
||||
res->m_stylesCache = 0;
|
||||
|
||||
return res;
|
||||
|
@ -64,6 +72,11 @@ void ScreenCoverage::SetStylesCache(yg::StylesCache * stylesCache)
|
|||
m_stylesCache = stylesCache;
|
||||
}
|
||||
|
||||
yg::StylesCache * ScreenCoverage::GetStylesCache() const
|
||||
{
|
||||
return m_stylesCache;
|
||||
}
|
||||
|
||||
void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
|
||||
{
|
||||
if (m_tileRects.find(ri) == m_tileRects.end())
|
||||
|
@ -98,19 +111,31 @@ void ScreenCoverage::Merge(Tiler::RectInfo const & ri)
|
|||
|
||||
if (addTile)
|
||||
{
|
||||
m_infoLayer.merge(*tile->m_infoLayer.get(),
|
||||
tile->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix());
|
||||
yg::InfoLayer * tileInfoLayerCopy = tile->m_infoLayer->clone();
|
||||
|
||||
if (!m_stylesCache)
|
||||
LOG(LWARNING, ("no styles cache"));
|
||||
else
|
||||
{
|
||||
m_infoLayer.cache(m_stylesCache);
|
||||
m_stylesCache->upload();
|
||||
}
|
||||
m_infoLayer->merge(*tileInfoLayerCopy,
|
||||
tile->m_tileScreen.PtoGMatrix() * m_screen.GtoPMatrix());
|
||||
|
||||
delete tileInfoLayerCopy;
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenCoverage::CacheInfoLayer()
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
void ScreenCoverage::Remove(Tile const *)
|
||||
{
|
||||
}
|
||||
|
@ -144,7 +169,7 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
|||
else
|
||||
CHECK(drawScale == allRects[i].m_drawScale, (drawScale, allRects[i].m_drawScale));
|
||||
|
||||
m_drawScale = drawScale;
|
||||
m_drawScale = drawScale == -1 ? 0 : drawScale;
|
||||
|
||||
for (unsigned i = 0; i < allRects.size(); ++i)
|
||||
{
|
||||
|
@ -192,16 +217,13 @@ void ScreenCoverage::SetScreen(ScreenBase const & screen)
|
|||
|
||||
m_tiles = tiles;
|
||||
|
||||
m_infoLayer.clear();
|
||||
for (TileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it)
|
||||
m_infoLayer.merge(*((*it)->m_infoLayer.get()), (*it)->m_tileScreen.PtoGMatrix() * screen.GtoPMatrix());
|
||||
m_infoLayer->clear();
|
||||
|
||||
if (!m_stylesCache)
|
||||
LOG(LWARNING, ("no styles cache"));
|
||||
else
|
||||
for (TileSet::const_iterator it = m_tiles.begin(); it != m_tiles.end(); ++it)
|
||||
{
|
||||
m_infoLayer.cache(m_stylesCache);
|
||||
m_stylesCache->upload();
|
||||
yg::InfoLayer * tileInfoLayerCopy = (*it)->m_infoLayer->clone();
|
||||
m_infoLayer->merge(*tileInfoLayerCopy, (*it)->m_tileScreen.PtoGMatrix() * screen.GtoPMatrix());
|
||||
delete tileInfoLayerCopy;
|
||||
}
|
||||
|
||||
/// clearing all old commands
|
||||
|
@ -256,9 +278,19 @@ void ScreenCoverage::Draw(yg::gl::Screen * s, ScreenBase const & screen)
|
|||
s->blit(&infos[0], infos.size(), true);
|
||||
|
||||
if (m_stylesCache)
|
||||
{
|
||||
ASSERT(m_infoLayer->checkCached(m_stylesCache), ());
|
||||
s->setAdditionalSkinPage(m_stylesCache->cachePage());
|
||||
}
|
||||
else
|
||||
LOG(LINFO, ("no styles cache"));
|
||||
|
||||
m_infoLayer.draw(s, m_screen.PtoGMatrix() * screen.GtoPMatrix());
|
||||
m_infoLayer->draw(s, m_screen.PtoGMatrix() * screen.GtoPMatrix());
|
||||
}
|
||||
|
||||
yg::InfoLayer * ScreenCoverage::GetInfoLayer() const
|
||||
{
|
||||
return m_infoLayer.get();
|
||||
}
|
||||
|
||||
void ScreenCoverage::EndFrame(yg::gl::Screen *s)
|
||||
|
|
|
@ -43,7 +43,7 @@ private:
|
|||
TileRectSet m_tileRects; //< rects, that forms a set of tiles in current rect.
|
||||
|
||||
TileSet m_tiles; //< set of tiles, that are visible for the m_screen
|
||||
yg::InfoLayer m_infoLayer; //< composite infoLayers for visible tiles
|
||||
scoped_ptr<yg::InfoLayer> m_infoLayer; //< composite infoLayers for visible tiles
|
||||
|
||||
//< scales, which are used in the tiles, drawn in the current screen.
|
||||
int m_drawScale;
|
||||
|
@ -64,7 +64,13 @@ public:
|
|||
size_t scaleEtalonSize);
|
||||
|
||||
ScreenCoverage * Clone();
|
||||
|
||||
void SetStylesCache(yg::StylesCache * stylesCache);
|
||||
yg::StylesCache * GetStylesCache() const;
|
||||
|
||||
yg::InfoLayer * GetInfoLayer() const;
|
||||
|
||||
void CacheInfoLayer();
|
||||
|
||||
/// 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);
|
||||
|
|
|
@ -38,6 +38,26 @@ namespace yg
|
|||
: m_couldOverlap(true)
|
||||
{}
|
||||
|
||||
InfoLayer::InfoLayer(InfoLayer const & src)
|
||||
{
|
||||
m_couldOverlap = src.m_couldOverlap;
|
||||
|
||||
vector<shared_ptr<OverlayElement> > elems;
|
||||
src.m_tree.ForEach(MakeBackInsertFunctor(elems));
|
||||
|
||||
math::Matrix<double, 3, 3> id = math::Identity<double, 3>();
|
||||
|
||||
for (unsigned i = 0; i < elems.size(); ++i)
|
||||
{
|
||||
shared_ptr<OverlayElement> e(elems[i]->clone(id));
|
||||
|
||||
e->setIsVisible(true);
|
||||
e->setIsNeedRedraw(true);
|
||||
|
||||
processOverlayElement(e);
|
||||
}
|
||||
}
|
||||
|
||||
void InfoLayer::setCouldOverlap(bool flag)
|
||||
{
|
||||
m_couldOverlap = flag;
|
||||
|
@ -214,22 +234,29 @@ namespace yg
|
|||
|
||||
sort(v.begin(), v.end(), &greater_priority);
|
||||
|
||||
/// making all elements visible
|
||||
|
||||
for (unsigned i = 0; i < v.size(); ++i)
|
||||
v[i]->setIsNeedRedraw(true);
|
||||
|
||||
/// caching on StylesCache::m_maxPagesCount at most
|
||||
/// collecting all the unpacked rects from all elements
|
||||
|
||||
vector<m2::PointU> sizes;
|
||||
sizes.reserve(100);
|
||||
|
||||
/// some glyphs will be counted twice(probably a lot of them).
|
||||
/// that way we'll actually waste a lot of texture space.
|
||||
|
||||
for (unsigned i = 0; i < v.size(); ++i)
|
||||
v[i]->getNonPackedRects(stylesCache, sizes);
|
||||
|
||||
if (sizes.empty())
|
||||
return;
|
||||
|
||||
/// if there are enough room to cache all the elements
|
||||
if (stylesCache->hasRoom(&sizes[0], sizes.size()))
|
||||
{
|
||||
/// cache them
|
||||
for (unsigned i = 0; i < v.size(); ++i)
|
||||
v[i]->map(stylesCache);
|
||||
}
|
||||
|
@ -255,12 +282,16 @@ namespace yg
|
|||
}
|
||||
}
|
||||
|
||||
if (v.size() - pos > 1)
|
||||
if (v.size() - pos >= 1)
|
||||
LOG(LINFO, ("making ", v.size() - pos, "elements invisible"));
|
||||
|
||||
/// making all uncached elements invisible
|
||||
/// partially uncached elements should be invisible
|
||||
for (; pos < v.size(); ++pos)
|
||||
v[pos]->setIsNeedRedraw(false);
|
||||
{
|
||||
sizes.clear();
|
||||
v[pos]->getNonPackedRects(stylesCache, sizes);
|
||||
v[pos]->setIsNeedRedraw(sizes.empty());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -307,5 +338,43 @@ namespace yg
|
|||
|
||||
// LOG(LINFO, ("clipped out", clippedCnt, "elements,", elemCnt, "elements total"));
|
||||
}
|
||||
|
||||
bool InfoLayer::checkHasEquals(InfoLayer const * l) const
|
||||
{
|
||||
vector<shared_ptr<OverlayElement> > v0;
|
||||
m_tree.ForEach(MakeBackInsertFunctor(v0));
|
||||
|
||||
sort(v0.begin(), v0.end());
|
||||
|
||||
vector<shared_ptr<OverlayElement> > v1;
|
||||
l->m_tree.ForEach(MakeBackInsertFunctor(v1));
|
||||
|
||||
sort(v1.begin(), v1.end());
|
||||
|
||||
vector<shared_ptr<OverlayElement> > res;
|
||||
|
||||
set_intersection(v0.begin(), v0.end(), v1.begin(), v1.end(), back_inserter(res));
|
||||
|
||||
return !res.empty();
|
||||
}
|
||||
|
||||
bool InfoLayer::checkCached(StylesCache * s) const
|
||||
{
|
||||
vector<shared_ptr<OverlayElement> > v;
|
||||
m_tree.ForEach(MakeBackInsertFunctor(v));
|
||||
|
||||
for (unsigned i = 0; i < v.size(); ++i)
|
||||
if (v[i]->isNeedRedraw())
|
||||
if (!v[i]->find(s))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
InfoLayer * InfoLayer::clone() const
|
||||
{
|
||||
InfoLayer * res = new InfoLayer(*this);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -32,9 +32,12 @@ namespace yg
|
|||
void addOverlayElement(shared_ptr<OverlayElement> const & oe);
|
||||
void replaceOverlayElement(shared_ptr<OverlayElement> const & oe);
|
||||
|
||||
friend class InfoLayer;
|
||||
|
||||
public:
|
||||
|
||||
InfoLayer();
|
||||
InfoLayer(InfoLayer const & src);
|
||||
|
||||
void draw(gl::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m);
|
||||
|
||||
|
@ -53,5 +56,10 @@ namespace yg
|
|||
void merge(InfoLayer const & infoLayer, math::Matrix<double, 3, 3> const & m);
|
||||
|
||||
void clip(m2::RectI const & r);
|
||||
|
||||
bool checkHasEquals(InfoLayer const * l) const;
|
||||
bool checkCached(StylesCache * s) const;
|
||||
|
||||
InfoLayer * clone() const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -140,18 +140,18 @@ namespace yg
|
|||
{
|
||||
GlyphLayoutElem const & elem = layout.entries()[i];
|
||||
|
||||
GlyphKey glyphKey(elem.m_sym,
|
||||
desc.m_size,
|
||||
desc.m_isMasked,
|
||||
desc.m_isMasked ? desc.m_maskColor : desc.m_color);
|
||||
GlyphKey gk(elem.m_sym,
|
||||
desc.m_size,
|
||||
desc.m_isMasked,
|
||||
desc.m_isMasked ? desc.m_maskColor : desc.m_color);
|
||||
|
||||
bool packed = skinPage->findGlyph(glyphKey) != 0x00FFFFFF;
|
||||
bool packed = skinPage->findGlyph(gk) != 0x00FFFFFF;
|
||||
|
||||
if (!packed)
|
||||
{
|
||||
if (skinPage->hasRoom(glyphKey, glyphCache))
|
||||
if (skinPage->hasRoom(gk, glyphCache))
|
||||
{
|
||||
skinPage->mapGlyph(glyphKey, glyphCache);
|
||||
skinPage->mapGlyph(gk, glyphCache);
|
||||
packed = true;
|
||||
}
|
||||
}
|
||||
|
@ -171,12 +171,12 @@ namespace yg
|
|||
{
|
||||
GlyphLayoutElem const & elem = layout.entries()[i];
|
||||
|
||||
GlyphKey glyphKey(elem.m_sym,
|
||||
desc.m_size,
|
||||
desc.m_isMasked,
|
||||
desc.m_isMasked ? desc.m_maskColor : desc.m_color);
|
||||
GlyphKey gk(elem.m_sym,
|
||||
desc.m_size,
|
||||
desc.m_isMasked,
|
||||
desc.m_isMasked ? desc.m_maskColor : desc.m_color);
|
||||
|
||||
if (skinPage->findGlyph(glyphKey) == 0x00FFFFFF)
|
||||
if (skinPage->findGlyph(gk) == 0x00FFFFFF)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -198,14 +198,14 @@ namespace yg
|
|||
{
|
||||
GlyphLayoutElem const & elem = layout.entries()[i];
|
||||
|
||||
GlyphKey glyphKey(elem.m_sym,
|
||||
desc.m_size,
|
||||
desc.m_isMasked,
|
||||
desc.m_isMasked ? desc.m_maskColor : desc.m_color);
|
||||
GlyphKey gk(elem.m_sym,
|
||||
desc.m_size,
|
||||
desc.m_isMasked,
|
||||
desc.m_isMasked ? desc.m_maskColor : desc.m_color);
|
||||
|
||||
if (skinPage->findGlyph(glyphKey) == 0x00FFFFFF)
|
||||
if (skinPage->findGlyph(gk) == 0x00FFFFFF)
|
||||
{
|
||||
shared_ptr<GlyphInfo> gi = glyphCache->getGlyphInfo(glyphKey);
|
||||
shared_ptr<GlyphInfo> gi = glyphCache->getGlyphInfo(gk);
|
||||
v.push_back(m2::PointU(gi->m_metrics.m_width + 4, gi->m_metrics.m_height + 4));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue