aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrLayerCache.cpp
diff options
context:
space:
mode:
authorGravatar robertphillips <robertphillips@google.com>2014-07-17 08:26:44 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2014-07-17 08:26:44 -0700
commit261b8a98dc7378989ba8fa9c06b728e89162862b (patch)
tree05a4ed0b8d35af3af35ab51c68b6bad0b6f6375e /src/gpu/GrLayerCache.cpp
parenta8f774549e35b743afae35e3436f73e8849e869d (diff)
Make GrLayerCache use multiple plots in its atlas
Until we have a recycling Rectanizer the atlas purging must occur at the GrPlot level. This CL breaks the atlas into four plots to give some room for purging (without trashing the entire atlas). This is calved off of (Add atlased layer purging - https://codereview.chromium.org/367073002/) R=jvanverth@google.com Author: robertphillips@google.com Review URL: https://codereview.chromium.org/397873004
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);
+ }
}