Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1023)

Unified Diff: src/gpu/GrAtlas.cpp

Issue 177463003: New approach for GPU font atlas (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Remove unnecessary method declarations. Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/gpu/GrAtlas.cpp
diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp
index 646c213b8675a738aa190daeece4ebc2088f49ab..775bd1285a626e0c702681f11827135e5205fb5d 100644
--- a/src/gpu/GrAtlas.cpp
+++ b/src/gpu/GrAtlas.cpp
@@ -46,6 +46,7 @@ static int g_UploadCount = 0;
#endif
GrPlot::GrPlot() : fDrawToken(NULL, 0)
+ , fPrev(NULL)
, fNext(NULL)
, fTexture(NULL)
, fAtlasMgr(NULL)
@@ -94,6 +95,11 @@ bool GrPlot::addSubImage(int width, int height, const void* image,
return true;
}
+void GrPlot::resetRects() {
+ SkASSERT(NULL != fRects);
+ fRects->reset();
+}
+
///////////////////////////////////////////////////////////////////////////////
GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config) {
@@ -105,7 +111,9 @@ GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config) {
// set up allocated plots
size_t bpp = GrBytesPerPixel(fPixelConfig);
fPlots = SkNEW_ARRAY(GrPlot, (GR_PLOT_WIDTH*GR_PLOT_HEIGHT));
- fFreePlots = NULL;
+ fHead = NULL;
+ fTail = NULL;
+
GrPlot* currPlot = fPlots;
for (int y = GR_PLOT_HEIGHT-1; y >= 0; --y) {
for (int x = GR_PLOT_WIDTH-1; x >= 0; --x) {
@@ -113,10 +121,16 @@ GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config) {
currPlot->fOffset.set(x, y);
currPlot->fBytesPerPixel = bpp;
- // add to free list
- currPlot->fNext = fFreePlots;
- fFreePlots = currPlot;
-
+ // build LRU list
+ if (fHead == NULL) {
+ currPlot->fPrev = NULL;
+ currPlot->fNext = NULL;
+ fHead = fTail = currPlot;
+ } else {
+ currPlot->fNext = fHead;
+ fHead->fPrev = currPlot;
+ fHead = currPlot;
+ }
++currPlot;
}
}
@@ -132,25 +146,42 @@ GrAtlasMgr::~GrAtlasMgr() {
#endif
}
+void GrAtlasMgr::moveToHead(GrPlot* plot) {
+ if (NULL == plot || NULL == plot->fPrev) {
bsalomon 2014/02/28 16:28:53 I wonder if we should be using SkTInternalLList
jvanverth1 2014/02/28 19:55:27 Done.
+ SkASSERT(plot == fHead);
+ return;
+ }
+
+ if (plot == fTail) {
+ fTail = plot->fPrev;
+ } else {
+ plot->fNext->fPrev = plot->fPrev;
+ }
+
+ plot->fPrev->fNext = plot->fNext;
+ plot->fNext = fHead;
+ fHead->fPrev = plot;
+ fHead = plot;
+ plot->fPrev = NULL;
+ SkASSERT(plot == fHead);
+ SkASSERT(plot->fPrev == NULL);
+ SkASSERT(plot->fNext->fPrev == plot);
+}
+
GrPlot* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
int width, int height, const void* image,
GrIPoint16* loc) {
- // iterate through entire plot list, see if we can find a hole
- GrPlot* plotIter = atlas->fPlots;
- while (plotIter) {
- if (plotIter->addSubImage(width, height, image, loc)) {
- return plotIter;
+ // iterate through entire plot list for this atlas, see if we can find a hole
+ // last one was most recently added and probably most empty
+ for (int i = atlas->fPlots.count()-1; i >= 0; --i) {
+ GrPlot* plot = atlas->fPlots[i];
+ if (plot->addSubImage(width, height, image, loc)) {
+ moveToHead(plot);
bsalomon 2014/02/28 16:28:53 this->
jvanverth1 2014/02/28 19:55:27 Done.
+ return plot;
}
- plotIter = plotIter->fNext;
- }
-
- // If the above fails, then either we have no starting plot, or the current
- // plot list is full. Either way we need to allocate a new plot
- GrPlot* newPlot = this->allocPlot();
- if (NULL == newPlot) {
- return NULL;
}
+ // before we get a new plot, make sure we have a backing texture
if (NULL == fTexture) {
// TODO: Update this to use the cache rather than directly creating a texture.
GrTextureDesc desc;
@@ -164,77 +195,49 @@ GrPlot* GrAtlasMgr::addToAtlas(GrAtlas* atlas,
return NULL;
}
}
- // be sure to set texture for fast lookup
- newPlot->fTexture = fTexture;
- if (!newPlot->addSubImage(width, height, image, loc)) {
- this->freePlot(newPlot);
- return NULL;
+ // now look through all allocated plots for one we can share, in MRU order
+ GrPlot* plotIter = fHead;
+ while (plotIter) {
+ // make sure texture is set for quick lookup
+ plotIter->fTexture = fTexture;
+ if (plotIter->addSubImage(width, height, image, loc)) {
+ moveToHead(plotIter);
+ // new plot for atlas, put at end of array
+ *(atlas->fPlots.append()) = plotIter;
+ return plotIter;
+ }
+ plotIter = plotIter->fNext;
}
- // new plot, put at head
- newPlot->fNext = atlas->fPlots;
- atlas->fPlots = newPlot;
-
- return newPlot;
+ // If the above fails, then the current plot list has no room
+ return NULL;
}
-bool GrAtlasMgr::removeUnusedPlots(GrAtlas* atlas) {
-
- // GrPlot** is used so that the head element can be easily
- // modified when the first element is deleted
- GrPlot** plotRef = &atlas->fPlots;
- GrPlot* plot = atlas->fPlots;
- bool removed = false;
- while (NULL != plot) {
- if (plot->drawToken().isIssued()) {
- *plotRef = plot->fNext;
- this->freePlot(plot);
- plot = *plotRef;
- removed = true;
- } else {
- plotRef = &plot->fNext;
- plot = plot->fNext;
+bool GrAtlasMgr::removePlot(GrAtlas* atlas, const GrPlot* plot) {
+ // iterate through plot list for this atlas
+ int count = atlas->fPlots.count();
+ for (int i = 0; i < count; ++i) {
+ if (plot == atlas->fPlots[i]) {
+ atlas->fPlots.remove(i);
+ return true;
}
}
- return removed;
-}
-
-void GrAtlasMgr::deletePlotList(GrPlot* plot) {
- while (NULL != plot) {
- GrPlot* next = plot->fNext;
- this->freePlot(plot);
- plot = next;
- }
+ return false;
}
-GrPlot* GrAtlasMgr::allocPlot() {
- if (NULL == fFreePlots) {
- return NULL;
- } else {
- GrPlot* alloc = fFreePlots;
- fFreePlots = alloc->fNext;
-#ifdef SK_DEBUG
-// GrPrintf(" GrPlot %p [%d %d] %d\n", this, alloc->fOffset.fX, alloc->fOffset.fY, gCounter);
- gCounter += 1;
-#endif
- return alloc;
+// get a plot that only contains drawn content
+GrPlot* GrAtlasMgr::getUnusedPlot() {
+ GrPlot* plotIter = fTail;
+ while (plotIter) {
+ if (plotIter->drawToken().isIssued()) {
+ return plotIter;
+ }
+ plotIter = plotIter->fPrev;
}
-}
-
-void GrAtlasMgr::freePlot(GrPlot* plot) {
- SkASSERT(this == plot->fAtlasMgr);
-
- plot->fRects->reset();
- plot->fNext = fFreePlots;
- fFreePlots = plot;
-
-#ifdef SK_DEBUG
- --gCounter;
-// GrPrintf("~GrPlot %p [%d %d] %d\n", this, plot->fOffset.fX, plot->fOffset.fY, gCounter);
-#endif
+ return NULL;
}
SkISize GrAtlas::getSize() const {
« src/gpu/GrAtlas.h ('K') | « src/gpu/GrAtlas.h ('k') | src/gpu/GrBitmapTextContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698