Chromium Code Reviews| Index: src/gpu/GrAtlas.cpp |
| diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp |
| index c1d6d3d693c4f332907a996874d1f72ed7231cae..e6ff70c3eba01a82aa9ca5372f87145ba8cb7047 100644 |
| --- a/src/gpu/GrAtlas.cpp |
| +++ b/src/gpu/GrAtlas.cpp |
| @@ -44,9 +44,17 @@ |
| static int gCounter; |
| #endif |
| +// for testing |
| +#define FONT_CACHE_STATS 0 |
| +#if FONT_CACHE_STATS |
| +static int g_UploadCount = 0; |
| +#endif |
| + |
| GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY, GrMaskFormat format) { |
| 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); |
| @@ -62,7 +70,7 @@ GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY, GrMaskFormat format) { |
| } |
| GrAtlas::~GrAtlas() { |
| - fAtlasMgr->freePlot(fPlot.fX, fPlot.fY); |
| + fAtlasMgr->freePlot(fMaskFormat, fPlot.fX, fPlot.fY); |
| delete fRects; |
| @@ -72,6 +80,25 @@ GrAtlas::~GrAtlas() { |
| #endif |
| } |
| +bool GrAtlas::RemoveUnusedAtlases(GrAtlasMgr* atlasMgr, GrAtlas** startAtlas) { |
|
robertphillips
2013/08/05 15:11:40
// add comment here why a **?
|
| + GrAtlas** atlasRef = startAtlas; |
| + GrAtlas* atlas = *startAtlas; |
| + bool removed = false; |
| + while (NULL != atlas) { |
| + if (!atlas->used()) { |
| + *atlasRef = atlas->fNext; |
| + atlasMgr->deleteAtlas(atlas); |
| + atlas = *atlasRef; |
| + removed = true; |
| + } else { |
| + atlasRef = &atlas->fNext; |
| + atlas = atlas->fNext; |
| + } |
| + } |
| + |
| + return removed; |
| +} |
| + |
| static void adjustForPlot(GrIPoint16* loc, const GrIPoint16& plot) { |
| loc->fX += plot.fX * GR_ATLAS_WIDTH; |
| loc->fY += plot.fY * GR_ATLAS_HEIGHT; |
| @@ -122,6 +149,11 @@ bool GrAtlas::addSubImage(int width, int height, const void* image, |
| // now tell the caller to skip the top/left BORDER |
| loc->fX += BORDER; |
| loc->fY += BORDER; |
| + |
| +#if FONT_CACHE_STATS |
| + ++g_UploadCount; |
| +#endif |
| + |
| return true; |
| } |
| @@ -139,7 +171,11 @@ GrAtlasMgr::~GrAtlasMgr() { |
| GrSafeUnref(fTexture[i]); |
| } |
| delete fPlotMgr; |
| + |
| fGpu->unref(); |
| +#if FONT_CACHE_STATS |
| + GrPrintf("Num uploads: %d\n", g_UploadCount); |
| +#endif |
| } |
| static GrPixelConfig maskformat2pixelconfig(GrMaskFormat format) { |
| @@ -156,18 +192,23 @@ static GrPixelConfig maskformat2pixelconfig(GrMaskFormat format) { |
| return kUnknown_GrPixelConfig; |
| } |
| -GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas, |
| +GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas** atlas, |
| int width, int height, const void* image, |
| GrMaskFormat format, |
| GrIPoint16* loc) { |
| - GrAssert(NULL == atlas || atlas->getMaskFormat() == format); |
| + GrAssert(NULL == *atlas || (*atlas)->getMaskFormat() == format); |
| - if (atlas && atlas->addSubImage(width, height, image, loc)) { |
| - return atlas; |
| + // iterate through entire atlas list, see if we can find a hole |
| + GrAtlas* atlasIter = *atlas; |
| + while (atlasIter) { |
| + if (atlasIter->addSubImage(width, height, image, loc)) { |
| + return atlasIter; |
| + } |
| + atlasIter = atlasIter->fNext; |
| } |
| // If the above fails, then either we have no starting atlas, or the current |
| - // one is full. Either way we need to allocate a new atlas |
| + // atlas list is full. Either way we need to allocate a new atlas |
| GrIPoint16 plot; |
| if (!fPlotMgr->newPlot(&plot)) { |
| @@ -196,11 +237,14 @@ GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas* atlas, |
| return NULL; |
| } |
| - newAtlas->fNext = atlas; |
| + // new atlas, put at head |
| + newAtlas->fNext = *atlas; |
| + *atlas = newAtlas; |
| + |
| return newAtlas; |
| } |
| -void GrAtlasMgr::freePlot(int x, int y) { |
| +void GrAtlasMgr::freePlot(GrMaskFormat format, int x, int y) { |
| GrAssert(fPlotMgr->isBusy(x, y)); |
| fPlotMgr->freePlot(x, y); |
| } |