Index: src/gpu/GrLayerCache.h |
diff --git a/src/gpu/GrLayerCache.h b/src/gpu/GrLayerCache.h |
index 914d0d5a58c408206529a5b88e47f5f73a2019c1..a606681896621f935147cb85dbbc7561699d57a7 100644 |
--- a/src/gpu/GrLayerCache.h |
+++ b/src/gpu/GrLayerCache.h |
@@ -165,6 +165,7 @@ public: |
, fPaint(paint ? new SkPaint(*paint) : nullptr) |
, fFilter(nullptr) |
, fTexture(nullptr) |
+ , fAtlased(false) |
, fRect(SkIRect::MakeEmpty()) |
, fPlot(nullptr) |
, fUses(0) |
@@ -180,7 +181,9 @@ public: |
} |
~GrCachedLayer() { |
- SkSafeUnref(fTexture); |
+ if (!fAtlased) { |
+ SkSafeUnref(fTexture); |
+ } |
SkSafeUnref(fFilter); |
delete fPaint; |
} |
@@ -195,8 +198,15 @@ public: |
const SkIRect& srcIR() const { return fSrcIR; } |
const SkIRect& dstIR() const { return fDstIR; } |
int stop() const { return fStop; } |
- void setTexture(GrTexture* texture, const SkIRect& rect) { |
- SkRefCnt_SafeAssign(fTexture, texture); |
+ void setTexture(GrTexture* texture, const SkIRect& rect, bool atlased) { |
+ if (texture && !atlased) { |
+ texture->ref(); // non-atlased textures carry a ref |
+ } |
+ if (fTexture && !fAtlased) { |
+ fTexture->unref(); // non-atlased textures carry a ref |
+ } |
+ fTexture = texture; |
+ fAtlased = atlased; |
fRect = rect; |
if (!fTexture) { |
fLocked = false; |
@@ -216,7 +226,7 @@ public: |
} |
GrLayerAtlas::Plot* plot() { return fPlot; } |
- bool isAtlased() const { return SkToBool(fPlot); } |
+ bool isAtlased() const { SkASSERT(fAtlased == SkToBool(fPlot)); return fAtlased; } |
void setLocked(bool locked) { fLocked = locked; } |
bool locked() const { return fLocked; } |
@@ -252,6 +262,10 @@ private: |
// ref on a GrTexture for non-atlased textures. |
GrTexture* fTexture; |
+ // true if this layer is in the atlas (and 'fTexture' doesn't carry a ref) |
+ // and false if the layer is a free floater (and carries a ref). |
+ bool fAtlased; |
+ |
// For both atlased and non-atlased layers 'fRect' contains the bound of |
// the layer in whichever texture it resides. It is empty when 'fTexture' |
// is nullptr. |
@@ -285,10 +299,9 @@ private: |
// The GrLayerCache caches pre-computed saveLayers for later rendering. |
// Non-atlased layers are stored in their own GrTexture while the atlased |
// layers share a single GrTexture. |
-// Unlike the GrFontCache, the GrTexture atlas only has one GrAtlas (for 8888) |
-// and one GrPlot (for the entire atlas). As such, the GrLayerCache |
-// roughly combines the functionality of the GrFontCache and GrTextStrike |
-// classes. |
+// Unlike the GrFontCache, the GrLayerCache only has one atlas (for 8888). |
+// As such, the GrLayerCache roughly combines the functionality of the |
+// GrFontCache and GrTextStrike classes. |
class GrLayerCache { |
public: |
GrLayerCache(GrContext*); |
@@ -346,6 +359,9 @@ public: |
return width <= kPlotWidth && height <= kPlotHeight; |
} |
+ void begin(); |
+ void end(); |
+ |
#if !GR_CACHE_HOISTED_LAYERS |
void purgeAll(); |
#endif |
@@ -361,7 +377,7 @@ private: |
static const int kPlotHeight = kAtlasTextureHeight / kNumPlotsY; |
GrContext* fContext; // pointer back to owning context |
- SkAutoTDelete<GrLayerAtlas> fAtlas; // TODO: could lazily allocate |
+ SkAutoTDelete<GrLayerAtlas> fAtlas; // lazily allocated |
// We cache this information here (rather then, say, on the owning picture) |
// because we want to be able to clean it up as needed (e.g., if a picture |
@@ -397,9 +413,9 @@ private: |
void purgePlot(GrLayerAtlas::Plot* plot); |
- // Try to find a purgeable plot and clear it out. Return true if a plot |
+ // Either purge all un-locked plots or just one. Return true if >= 1 plot |
// was purged; false otherwise. |
- bool purgePlot(); |
+ bool purgePlots(bool justOne); |
void incPlotLock(int plotIdx) { ++fPlotLocks[plotIdx]; } |
void decPlotLock(int plotIdx) { |