aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrLayerCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/GrLayerCache.cpp')
-rw-r--r--src/gpu/GrLayerCache.cpp87
1 files changed, 73 insertions, 14 deletions
diff --git a/src/gpu/GrLayerCache.cpp b/src/gpu/GrLayerCache.cpp
index 9688cac650..ff26750df7 100644
--- a/src/gpu/GrLayerCache.cpp
+++ b/src/gpu/GrLayerCache.cpp
@@ -41,8 +41,33 @@ private:
int fLayerID;
};
+/**
+ * PictureKey just wraps a picture's unique ID for GrTHashTable. It is used to
+ * look up a picture's GrPictureInfo (i.e., its GrPlot usage).
+ */
+class GrLayerCache::PictureKey {
+public:
+ PictureKey(uint32_t pictureID) : fPictureID(pictureID) { }
+
+ uint32_t pictureID() const { return fPictureID; }
+
+ uint32_t getHash() const { return fPictureID; }
+
+ static bool LessThan(const GrPictureInfo& pictInfo, const PictureKey& key) {
+ return pictInfo.fPictureID < key.pictureID();
+ }
+
+ static bool Equals(const GrPictureInfo& pictInfo, const PictureKey& key) {
+ return pictInfo.fPictureID == key.pictureID();
+
+ }
+
+private:
+ uint32_t fPictureID;
+};
+
#ifdef SK_DEBUG
-void GrCachedLayer::validate(GrTexture* backingTexture) const {
+void GrCachedLayer::validate(const GrTexture* backingTexture) const {
SkASSERT(SK_InvalidGenID != fPictureID);
SkASSERT(-1 != fLayerID);
@@ -55,6 +80,14 @@ void GrCachedLayer::validate(GrTexture* backingTexture) const {
}
} else {
SkASSERT(fRect.isEmpty());
+ SkASSERT(NULL == fPlot);
+ }
+
+ if (NULL != fPlot) {
+ // If a layer has a plot (i.e., is atlased) then it must point to
+ // the backing texture. Additionally, its rect should be non-empty.
+ SkASSERT(NULL != fTexture && backingTexture == fTexture);
+ SkASSERT(!fRect.isEmpty());
}
}
@@ -72,9 +105,13 @@ public:
fLayer->validate(fBackingTexture);
}
}
+ void setBackingTexture(GrTexture* backingTexture) {
+ SkASSERT(NULL == fBackingTexture || fBackingTexture == backingTexture);
+ fBackingTexture = backingTexture;
+ }
private:
- GrTexture* fBackingTexture;
+ const GrTexture* fBackingTexture;
const GrCachedLayer* fLayer;
};
#endif
@@ -106,7 +143,7 @@ void GrLayerCache::initAtlas() {
SkISize textureSize = SkISize::Make(kAtlasTextureWidth, kAtlasTextureHeight);
fAtlas.reset(SkNEW_ARGS(GrAtlas, (fContext->getGpu(), kSkia8888_GrPixelConfig,
kRenderTarget_GrTextureFlagBit,
- textureSize, 1, 1, false)));
+ textureSize, kNumPlotsX, kNumPlotsY, false)));
}
void GrLayerCache::freeAll() {
@@ -165,14 +202,26 @@ bool GrLayerCache::lock(GrCachedLayer* layer, const GrTextureDesc& desc) {
}
#if USE_ATLAS
- SkIPoint16 loc;
- GrPlot* plot = fAtlas->addToAtlas(&fPlotUsage, desc.fWidth, desc.fHeight, NULL, &loc);
- if (NULL != plot) {
- GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY,
- SkToS16(desc.fWidth), SkToS16(desc.fHeight));
- layer->setTexture(fAtlas->getTexture(), bounds);
- layer->setAtlased(true);
- return false;
+ {
+ GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(layer->pictureID()));
+ if (NULL == pictInfo) {
+ pictInfo = SkNEW_ARGS(GrPictureInfo, (layer->pictureID()));
+ fPictureHash.insert(PictureKey(layer->pictureID()), pictInfo);
+ }
+
+ SkIPoint16 loc;
+ GrPlot* plot = fAtlas->addToAtlas(&pictInfo->fPlotUsage,
+ desc.fWidth, desc.fHeight,
+ NULL, &loc);
+ // addToAtlas can allocate the backing texture
+ SkDEBUGCODE(avl.setBackingTexture(fAtlas->getTexture()));
+ if (NULL != plot) {
+ GrIRect16 bounds = GrIRect16::MakeXYWH(loc.fX, loc.fY,
+ SkToS16(desc.fWidth), SkToS16(desc.fHeight));
+ layer->setTexture(fAtlas->getTexture(), bounds);
+ layer->setPlot(plot);
+ return false;
+ }
}
#endif
@@ -192,9 +241,13 @@ void GrLayerCache::unlock(GrCachedLayer* layer) {
}
if (layer->isAtlased()) {
- // The atlas doesn't currently use a scratch texture (and we would have
- // to free up space differently anyways)
- // TODO: unlock atlas space when a recycling rectanizer is available
+ SkASSERT(layer->texture() == fAtlas->getTexture());
+
+ GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(layer->pictureID()));
+ SkASSERT(NULL != pictInfo);
+ pictInfo->fPlotUsage.isEmpty(); // just to silence compiler warnings for the time being
+
+ // TODO: purging from atlas goes here
} else {
fContext->unlockScratchTexture(layer->texture());
layer->setTexture(NULL, GrIRect16::MakeEmpty());
@@ -247,4 +300,10 @@ void GrLayerCache::purge(const SkPicture* picture) {
fLayerHash.remove(key, toBeRemoved[i]);
SkDELETE(toBeRemoved[i]);
}
+
+ GrPictureInfo* pictInfo = fPictureHash.find(PictureKey(picture->uniqueID()));
+ if (NULL != pictInfo) {
+ fPictureHash.remove(PictureKey(picture->uniqueID()), pictInfo);
+ SkDELETE(pictInfo);
+ }
}