aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrAtlas.cpp
diff options
context:
space:
mode:
authorGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-09-27 19:39:38 +0000
committerGravatar commit-bot@chromium.org <commit-bot@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81>2013-09-27 19:39:38 +0000
commit7d330eb19cd3c9278abce68ca0e3efabf2ec8f87 (patch)
tree7bf9cd9bfc7bea76a09f8fcd8bef5568c30a8928 /src/gpu/GrAtlas.cpp
parent3e292aa398dc40f5188bc4f0b36c8916ac552308 (diff)
GrAtlas cleanup: Split out GrPlot and GrAtlas
This breaks up GrAtlas into the head of the list (GrAtlas) and the list elements (GrPlot). It also moves all of the GrPlot management code into GrAtlasMgr. It adds a simple pool allocator for GrPlots and removes use of GrPlotMgr. R=bsalomon@google.com, robertphillips@google.com Author: jvanverth@google.com Review URL: https://codereview.chromium.org/24981004 git-svn-id: http://skia.googlecode.com/svn/trunk@11508 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/gpu/GrAtlas.cpp')
-rw-r--r--src/gpu/GrAtlas.cpp196
1 files changed, 113 insertions, 83 deletions
diff --git a/src/gpu/GrAtlas.cpp b/src/gpu/GrAtlas.cpp
index b3340a02d9..e33ec6519e 100644
--- a/src/gpu/GrAtlas.cpp
+++ b/src/gpu/GrAtlas.cpp
@@ -6,13 +6,10 @@
* found in the LICENSE file.
*/
-
-
#include "GrAtlas.h"
#include "GrContext.h"
#include "GrGpu.h"
#include "GrRectanizer.h"
-#include "GrPlotMgr.h"
#if 0
#define GR_PLOT_WIDTH 8
@@ -50,70 +47,34 @@
static int g_UploadCount = 0;
#endif
-GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY, int bpp) :
- fDrawToken(NULL, 0) {
- fAtlasMgr = mgr; // just a pointer, not an owner
- fNext = NULL;
-
- fTexture = mgr->getTexture(); // we're not an owner, just a pointer
- fPlot.set(plotX, plotY);
-
+GrPlot::GrPlot() : fDrawToken(NULL, 0)
+ , fNext(NULL)
+ , fTexture(NULL)
+ , fAtlasMgr(NULL)
+ , fBytesPerPixel(1)
+{
fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH - BORDER,
GR_ATLAS_HEIGHT - BORDER);
-
- fBytesPerPixel = bpp;
-
-#ifdef SK_DEBUG
-// GrPrintf(" GrAtlas %p [%d %d] %d\n", this, plotX, plotY, gCounter);
- gCounter += 1;
-#endif
+ fOffset.set(0, 0);
}
-GrAtlas::~GrAtlas() {
- fAtlasMgr->freePlot(fPlot.fX, fPlot.fY);
-
+GrPlot::~GrPlot() {
delete fRects;
-
-#ifdef SK_DEBUG
- --gCounter;
-// GrPrintf("~GrAtlas %p [%d %d] %d\n", this, fPlot.fX, fPlot.fY, gCounter);
-#endif
}
-bool GrAtlas::RemoveUnusedAtlases(GrAtlasMgr* atlasMgr, GrAtlas** startAtlas) {
- // GrAtlas** is used so that a pointer to the head element can be passed in and
- // modified when the first element is deleted
- GrAtlas** atlasRef = startAtlas;
- GrAtlas* atlas = *startAtlas;
- bool removed = false;
- while (NULL != atlas) {
- if (atlas->drawToken().isIssued()) {
- *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;
+static void adjust_for_offset(GrIPoint16* loc, const GrIPoint16& offset) {
+ loc->fX += offset.fX * GR_ATLAS_WIDTH;
+ loc->fY += offset.fY * GR_ATLAS_HEIGHT;
}
-static uint8_t* zerofill(uint8_t* ptr, int count) {
+static uint8_t* zero_fill(uint8_t* ptr, int count) {
while (--count >= 0) {
*ptr++ = 0;
}
return ptr;
}
-bool GrAtlas::addSubImage(int width, int height, const void* image,
+bool GrPlot::addSubImage(int width, int height, const void* image,
GrIPoint16* loc) {
if (!fRects->addRect(width + BORDER, height + BORDER, loc)) {
return false;
@@ -128,16 +89,16 @@ bool GrAtlas::addSubImage(int width, int height, const void* image,
sk_bzero(dst, dstRB); // zero top row
dst += dstRB;
for (int y = 0; y < height; y++) {
- dst = zerofill(dst, fBytesPerPixel); // zero left edge
+ dst = zero_fill(dst, fBytesPerPixel); // zero left edge
memcpy(dst, image, width * fBytesPerPixel);
dst += width * fBytesPerPixel;
- dst = zerofill(dst, fBytesPerPixel); // zero right edge
+ dst = zero_fill(dst, fBytesPerPixel); // zero right edge
image = (const void*)((const char*)image + width * fBytesPerPixel);
}
sk_bzero(dst, dstRB); // zero bottom row
image = storage.get();
}
- adjustForPlot(loc, fPlot);
+ adjust_for_offset(loc, fOffset);
GrContext* context = fTexture->getContext();
// We pass the flag that does not force a flush. We assume our caller is
// smart and hasn't referenced the part of the texture we're about to update
@@ -165,12 +126,30 @@ GrAtlasMgr::GrAtlasMgr(GrGpu* gpu, GrPixelConfig config) {
fPixelConfig = config;
gpu->ref();
fTexture = NULL;
- fPlotMgr = SkNEW_ARGS(GrPlotMgr, (GR_PLOT_WIDTH, GR_PLOT_HEIGHT));
+
+ // set up allocated plots
+ int bpp = GrBytesPerPixel(fPixelConfig);
+ fPlots = SkNEW_ARRAY(GrPlot, (GR_PLOT_WIDTH*GR_PLOT_HEIGHT));
+ fFreePlots = NULL;
+ GrPlot* currPlot = fPlots;
+ 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;
+
+ ++currPlot;
+ }
+ }
}
GrAtlasMgr::~GrAtlasMgr() {
SkSafeUnref(fTexture);
- delete fPlotMgr;
+ SkDELETE_ARRAY(fPlots);
fGpu->unref();
#if FONT_CACHE_STATS
@@ -178,23 +157,22 @@ GrAtlasMgr::~GrAtlasMgr() {
#endif
}
-GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas** atlas,
- int width, int height, const void* image,
- GrIPoint16* loc) {
- // 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;
+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;
}
- atlasIter = atlasIter->fNext;
+ plotIter = plotIter->fNext;
}
- // If the above fails, then either we have no starting atlas, or the current
- // atlas list is full. Either way we need to allocate a new atlas
-
- GrIPoint16 plot;
- if (!fPlotMgr->newPlot(&plot)) {
+ // 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;
}
@@ -211,22 +189,74 @@ GrAtlas* GrAtlasMgr::addToAtlas(GrAtlas** atlas,
return NULL;
}
}
-
- int bpp = GrBytesPerPixel(fPixelConfig);
- GrAtlas* newAtlas = SkNEW_ARGS(GrAtlas, (this, plot.fX, plot.fY, bpp));
- if (!newAtlas->addSubImage(width, height, image, loc)) {
- delete newAtlas;
+ // be sure to set texture for fast lookup
+ newPlot->fTexture = fTexture;
+
+ if (!newPlot->addSubImage(width, height, image, loc)) {
+ this->freePlot(newPlot);
return NULL;
}
- // new atlas, put at head
- newAtlas->fNext = *atlas;
- *atlas = newAtlas;
+ // new plot, put at head
+ newPlot->fNext = atlas->fPlots;
+ atlas->fPlots = newPlot;
- return newAtlas;
+ return newPlot;
+}
+
+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;
+ }
+ }
+
+ return removed;
}
-void GrAtlasMgr::freePlot(int x, int y) {
- SkASSERT(fPlotMgr->isBusy(x, y));
- fPlotMgr->freePlot(x, y);
+void GrAtlasMgr::deletePlotList(GrPlot* plot) {
+ while (NULL != plot) {
+ GrPlot* next = plot->fNext;
+ this->freePlot(plot);
+ plot = next;
+ }
+}
+
+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;
+ }
+
+}
+
+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
}