Change Atlas recycling to track current flush count and recycle if Atlas not used in current flush.
BUG= R=bsalomon@google.com, robertphillips@google.com Author: jvanverth@google.com Review URL: https://chromiumcodereview.appspot.com/23120004 git-svn-id: http://skia.googlecode.com/svn/trunk@10777 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
2276c01920
commit
a8916ffd90
@ -840,6 +840,7 @@ public:
|
||||
GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType,
|
||||
GrPathRendererChain::StencilSupport* stencilSupport = NULL);
|
||||
|
||||
|
||||
#if GR_CACHE_STATS
|
||||
void printCacheStats() const;
|
||||
#endif
|
||||
|
@ -50,10 +50,10 @@
|
||||
static int g_UploadCount = 0;
|
||||
#endif
|
||||
|
||||
GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY, GrMaskFormat format) {
|
||||
GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY, GrMaskFormat format) :
|
||||
fDrawToken(NULL, 0) {
|
||||
fAtlasMgr = mgr; // just a pointer, not an owner
|
||||
fNext = NULL;
|
||||
fUsed = false;
|
||||
|
||||
fTexture = mgr->getTexture(format); // we're not an owner, just a pointer
|
||||
fPlot.set(plotX, plotY);
|
||||
@ -87,7 +87,7 @@ bool GrAtlas::RemoveUnusedAtlases(GrAtlasMgr* atlasMgr, GrAtlas** startAtlas) {
|
||||
GrAtlas* atlas = *startAtlas;
|
||||
bool removed = false;
|
||||
while (NULL != atlas) {
|
||||
if (!atlas->used()) {
|
||||
if (atlas->drawToken().isIssued()) {
|
||||
*atlasRef = atlas->fNext;
|
||||
atlasMgr->deleteAtlas(atlas);
|
||||
atlas = *atlasRef;
|
||||
@ -189,7 +189,7 @@ static GrPixelConfig maskformat2pixelconfig(GrMaskFormat format) {
|
||||
case kA888_GrMaskFormat:
|
||||
return kSkia8888_GrPixelConfig;
|
||||
default:
|
||||
GrAssert(!"unknown maskformat");
|
||||
SkASSERT(!"unknown maskformat");
|
||||
}
|
||||
return kUnknown_GrPixelConfig;
|
||||
}
|
||||
@ -217,8 +217,8 @@ GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas** atlas,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GrAssert(0 == kA8_GrMaskFormat);
|
||||
GrAssert(1 == kA565_GrMaskFormat);
|
||||
SkASSERT(0 == kA8_GrMaskFormat);
|
||||
SkASSERT(1 == kA565_GrMaskFormat);
|
||||
if (NULL == fTexture[format]) {
|
||||
// TODO: Update this to use the cache rather than directly creating a texture.
|
||||
GrTextureDesc desc;
|
||||
@ -247,6 +247,6 @@ GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas** atlas,
|
||||
}
|
||||
|
||||
void GrAtlasMgr::freePlot(GrMaskFormat format, int x, int y) {
|
||||
GrAssert(fPlotMgr->isBusy(x, y));
|
||||
SkASSERT(fPlotMgr->isBusy(x, y));
|
||||
fPlotMgr->freePlot(x, y);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "GrPoint.h"
|
||||
#include "GrTexture.h"
|
||||
#include "GrDrawTarget.h"
|
||||
|
||||
class GrGpu;
|
||||
class GrRectanizer;
|
||||
@ -36,32 +37,25 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
static void MarkAllUnused(GrAtlas* atlas) {
|
||||
while (NULL != atlas) {
|
||||
atlas->fUsed = false;
|
||||
atlas = atlas->fNext;
|
||||
}
|
||||
}
|
||||
|
||||
static bool RemoveUnusedAtlases(GrAtlasMgr* atlasMgr, GrAtlas** startAtlas);
|
||||
|
||||
bool used() const { return fUsed; }
|
||||
void setUsed(bool used) { fUsed = used; }
|
||||
GrDrawTarget::DrawToken drawToken() const { return fDrawToken; }
|
||||
void setDrawToken(GrDrawTarget::DrawToken draw) { fDrawToken = draw; }
|
||||
|
||||
private:
|
||||
GrAtlas(GrAtlasMgr*, int plotX, int plotY, GrMaskFormat format);
|
||||
~GrAtlas(); // does not try to delete the fNext field
|
||||
|
||||
GrAtlas* fNext;
|
||||
|
||||
// for recycling
|
||||
bool fUsed;
|
||||
GrDrawTarget::DrawToken fDrawToken;
|
||||
|
||||
GrTexture* fTexture;
|
||||
GrRectanizer* fRects;
|
||||
GrAtlasMgr* fAtlasMgr;
|
||||
GrIPoint16 fPlot;
|
||||
GrMaskFormat fMaskFormat;
|
||||
GrAtlas* fNext;
|
||||
|
||||
GrTexture* fTexture;
|
||||
GrRectanizer* fRects;
|
||||
GrAtlasMgr* fAtlasMgr;
|
||||
GrIPoint16 fPlot;
|
||||
GrMaskFormat fMaskFormat;
|
||||
|
||||
friend class GrAtlasMgr;
|
||||
};
|
||||
|
@ -621,6 +621,23 @@ public:
|
||||
GrDrawTarget* fTarget;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Draw execution tracking (for font atlases and other resources)
|
||||
class DrawToken {
|
||||
public:
|
||||
DrawToken(GrDrawTarget* drawTarget, uint32_t drawID) :
|
||||
fDrawTarget(drawTarget), fDrawID(drawID) {}
|
||||
|
||||
bool isIssued() { return NULL != fDrawTarget && fDrawTarget->isIssued(fDrawID); }
|
||||
|
||||
private:
|
||||
GrDrawTarget* fDrawTarget;
|
||||
uint32_t fDrawID; // this may wrap, but we're doing direct comparison
|
||||
// so that should be okay
|
||||
};
|
||||
|
||||
virtual DrawToken getCurrentDrawToken() { return DrawToken(this, 0); }
|
||||
|
||||
protected:
|
||||
|
||||
enum GeometrySrcType {
|
||||
@ -839,6 +856,9 @@ private:
|
||||
// but couldn't be made. Otherwise, returns true.
|
||||
bool setupDstReadIfNecessary(DrawInfo* info);
|
||||
|
||||
// Check to see if this set of draw commands has been sent out
|
||||
virtual bool isIssued(uint32_t drawID) { return true; }
|
||||
|
||||
enum {
|
||||
kPreallocGeoSrcStateStackCnt = 4,
|
||||
};
|
||||
|
@ -27,7 +27,8 @@ GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrGpu* gpu,
|
||||
, fClipProxyState(kUnknown_ClipProxyState)
|
||||
, fVertexPool(*vertexPool)
|
||||
, fIndexPool(*indexPool)
|
||||
, fFlushing(false) {
|
||||
, fFlushing(false)
|
||||
, fDrawID(0) {
|
||||
|
||||
fDstGpu->ref();
|
||||
fCaps.reset(SkRef(fDstGpu->caps()));
|
||||
@ -536,6 +537,7 @@ void GrInOrderDrawBuffer::flush() {
|
||||
fDstGpu->setDrawState(prevDrawState);
|
||||
prevDrawState->unref();
|
||||
this->reset();
|
||||
++fDrawID;
|
||||
}
|
||||
|
||||
bool GrInOrderDrawBuffer::onCopySurface(GrSurface* dst,
|
||||
|
@ -66,6 +66,9 @@ public:
|
||||
*/
|
||||
void flush();
|
||||
|
||||
// tracking for draws
|
||||
virtual DrawToken getCurrentDrawToken() { return DrawToken(this, fDrawID); }
|
||||
|
||||
// overrides from GrDrawTarget
|
||||
virtual bool geometryHints(int* vertexCount,
|
||||
int* indexCount) const SK_OVERRIDE;
|
||||
@ -75,7 +78,6 @@ public:
|
||||
|
||||
virtual void initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) SK_OVERRIDE;
|
||||
|
||||
|
||||
protected:
|
||||
virtual void clipWillBeSet(const GrClipData* newClip) SK_OVERRIDE;
|
||||
|
||||
@ -222,7 +224,10 @@ private:
|
||||
};
|
||||
SkSTArray<kGeoPoolStatePreAllocCnt, GeometryPoolState> fGeoPoolStateStack;
|
||||
|
||||
virtual bool isIssued(uint32_t drawID) { return drawID != fDrawID; }
|
||||
|
||||
bool fFlushing;
|
||||
uint32_t fDrawID;
|
||||
|
||||
typedef GrDrawTarget INHERITED;
|
||||
};
|
||||
|
@ -148,14 +148,15 @@ void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
|
||||
}
|
||||
}
|
||||
|
||||
GrDrawTarget::DrawToken drawToken = fDrawTarget->getCurrentDrawToken();
|
||||
if (NULL == glyph->fAtlas) {
|
||||
if (fStrike->getGlyphAtlas(glyph, scaler)) {
|
||||
if (fStrike->getGlyphAtlas(glyph, scaler, drawToken)) {
|
||||
goto HAS_ATLAS;
|
||||
}
|
||||
|
||||
// try to clear out an unused atlas before we flush
|
||||
fContext->getFontCache()->freeAtlasExceptFor(fStrike);
|
||||
if (fStrike->getGlyphAtlas(glyph, scaler)) {
|
||||
if (fStrike->getGlyphAtlas(glyph, scaler, drawToken)) {
|
||||
goto HAS_ATLAS;
|
||||
}
|
||||
|
||||
@ -165,7 +166,8 @@ void GrTextContext::drawPackedGlyph(GrGlyph::PackedID packed,
|
||||
|
||||
// try to purge
|
||||
fContext->getFontCache()->purgeExceptFor(fStrike);
|
||||
if (fStrike->getGlyphAtlas(glyph, scaler)) {
|
||||
// need to use new flush count here
|
||||
if (fStrike->getGlyphAtlas(glyph, scaler, drawToken)) {
|
||||
goto HAS_ATLAS;
|
||||
}
|
||||
|
||||
|
@ -86,9 +86,6 @@ void GrFontCache::purgeExceptFor(GrTextStrike* preserveStrike) {
|
||||
fCache.removeAt(index, strikeToPurge->fFontScalerKey->getHash());
|
||||
this->detachStrikeFromList(strikeToPurge);
|
||||
delete strikeToPurge;
|
||||
} else {
|
||||
// for the remaining strikes, we just mark them unused
|
||||
GrAtlas::MarkAllUnused(strikeToPurge->fAtlas);
|
||||
}
|
||||
}
|
||||
#if FONT_CACHE_STATS
|
||||
@ -185,7 +182,7 @@ GrTextStrike::GrTextStrike(GrFontCache* cache, const GrKey* key,
|
||||
static void free_glyph(GrGlyph*& glyph) { glyph->free(); }
|
||||
|
||||
static void invalidate_glyph(GrGlyph*& glyph) {
|
||||
if (glyph->fAtlas && !glyph->fAtlas->used()) {
|
||||
if (glyph->fAtlas && glyph->fAtlas->drawToken().isIssued()) {
|
||||
glyph->fAtlas = NULL;
|
||||
}
|
||||
}
|
||||
@ -217,11 +214,10 @@ GrGlyph* GrTextStrike::generateGlyph(GrGlyph::PackedID packed,
|
||||
bool GrTextStrike::removeUnusedAtlases() {
|
||||
fCache.getArray().visitAll(invalidate_glyph);
|
||||
return GrAtlas::RemoveUnusedAtlases(fAtlasMgr, &fAtlas);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
|
||||
bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler,
|
||||
GrDrawTarget::DrawToken currentDrawToken) {
|
||||
#if 0 // testing hack to force us to flush our cache often
|
||||
static int gCounter;
|
||||
if ((++gCounter % 10) == 0) return false;
|
||||
@ -231,7 +227,7 @@ bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
|
||||
GrAssert(scaler);
|
||||
GrAssert(fCache.contains(glyph));
|
||||
if (glyph->fAtlas) {
|
||||
glyph->fAtlas->setUsed(true);
|
||||
glyph->fAtlas->setDrawToken(currentDrawToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -256,6 +252,6 @@ bool GrTextStrike::getGlyphAtlas(GrGlyph* glyph, GrFontScaler* scaler) {
|
||||
}
|
||||
|
||||
glyph->fAtlas = atlas;
|
||||
atlas->setUsed(true);
|
||||
atlas->setDrawToken(currentDrawToken);
|
||||
return true;
|
||||
}
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "GrTHashCache.h"
|
||||
#include "GrPoint.h"
|
||||
#include "GrGlyph.h"
|
||||
#include "GrDrawTarget.h"
|
||||
|
||||
class GrAtlasMgr;
|
||||
class GrFontCache;
|
||||
@ -37,7 +38,7 @@ public:
|
||||
GrMaskFormat getMaskFormat() const { return fMaskFormat; }
|
||||
|
||||
inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
|
||||
bool getGlyphAtlas(GrGlyph*, GrFontScaler*);
|
||||
bool getGlyphAtlas(GrGlyph*, GrFontScaler*, GrDrawTarget::DrawToken currentDrawToken);
|
||||
|
||||
// testing
|
||||
int countGlyphs() const { return fCache.getArray().count(); }
|
||||
|
Loading…
Reference in New Issue
Block a user