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

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 reference to GrAtlasMgr 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
« no previous file with comments | « src/gpu/GrAtlas.h ('k') | src/gpu/GrBitmapTextContext.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrAtlas.cpp
diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp
index 646c213b8675a738aa190daeece4ebc2088f49ab..c2fcf46f687b5656a71f0c02ca6cf82ca4e2a727 100644
--- a/src/gpu/GrAtlas.cpp
+++ b/src/gpu/GrAtlas.cpp
@@ -35,10 +35,6 @@
///////////////////////////////////////////////////////////////////////////////
-#ifdef SK_DEBUG
- static int gCounter;
-#endif
-
// for testing
#define FONT_CACHE_STATS 0
#if FONT_CACHE_STATS
@@ -46,7 +42,6 @@ static int g_UploadCount = 0;
#endif
GrPlot::GrPlot() : fDrawToken(NULL, 0)
- , fNext(NULL)
, fTexture(NULL)
, fAtlasMgr(NULL)
, fBytesPerPixel(1)
@@ -94,6 +89,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) {
@@ -104,19 +104,17 @@ 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;
- GrPlot* currPlot = fPlots;
+ fPlotArray = SkNEW_ARRAY(GrPlot, (GR_PLOT_WIDTH*GR_PLOT_HEIGHT));
+
+ GrPlot* currPlot = fPlotArray;
for (int y = GR_PLOT_HEIGHT-1; y >= 0; --y) {
for (int x = GR_PLOT_WIDTH-1; x >= 0; --x) {
currPlot->fAtlasMgr = this;
currPlot->fOffset.set(x, y);
currPlot->fBytesPerPixel = bpp;
- // add to free list
- currPlot->fNext = fFreePlots;
- fFreePlots = currPlot;
-
+ // build LRU list
+ fPlotList.addToHead(currPlot);
++currPlot;
}
}
@@ -124,7 +122,7 @@ GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config) {
GrAtlasMgr::~GrAtlasMgr() {
SkSafeUnref(fTexture);
- SkDELETE_ARRAY(fPlots);
+ SkDELETE_ARRAY(fPlotArray);
fGpu->unref();
#if FONT_CACHE_STATS
@@ -132,25 +130,29 @@ GrAtlasMgr::~GrAtlasMgr() {
#endif
}
+void GrAtlasMgr::moveToHead(GrPlot* plot) {
+ if (fPlotList.head() == plot) {
+ return;
+ }
+
+ fPlotList.remove(plot);
+ fPlotList.addToHead(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)) {
+ this->moveToHead(plot);
+ 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 +166,53 @@ 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
+ GrPlotList::Iter plotIter;
+ plotIter.init(fPlotList, GrPlotList::Iter::kHead_IterStart);
+ GrPlot* plot;
+ while (NULL != (plot = plotIter.get())) {
+ // make sure texture is set for quick lookup
+ plot->fTexture = fTexture;
+ if (plot->addSubImage(width, height, image, loc)) {
+ this->moveToHead(plot);
+ // new plot for atlas, put at end of array
+ *(atlas->fPlots.append()) = plot;
+ return plot;
+ }
+ plotIter.next();
}
- // 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's not being used by the current draw
+GrPlot* GrAtlasMgr::getUnusedPlot() {
+ GrPlotList::Iter plotIter;
+ plotIter.init(fPlotList, GrPlotList::Iter::kTail_IterStart);
+ GrPlot* plot;
+ while (NULL != (plot = plotIter.get())) {
+ if (plot->drawToken().isIssued()) {
+ return plot;
+ }
+ plotIter.prev();
}
-}
-
-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 {
« no previous file with comments | « src/gpu/GrAtlas.h ('k') | src/gpu/GrBitmapTextContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698