Ganesh resource cache changes
https://codereview.appspot.com/6784051/
git-svn-id: http://skia.googlecode.com/svn/trunk@6211 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
index 89fce55..825b122 100644
--- a/src/gpu/GrResourceCache.cpp
+++ b/src/gpu/GrResourceCache.cpp
@@ -94,7 +94,7 @@
fCache.remove(entry->fKey, entry);
// remove from our llist
- this->internalDetach(entry, false);
+ this->internalDetach(entry);
delete entry;
}
@@ -121,11 +121,11 @@
}
void GrResourceCache::internalDetach(GrResourceEntry* entry,
- bool clientDetach) {
+ BudgetBehaviors behavior) {
fList.remove(entry);
// update our stats
- if (clientDetach) {
+ if (kIgnore_BudgetBehavior == behavior) {
fClientDetachedCount += 1;
fClientDetachedBytes += entry->resource()->sizeInBytes();
@@ -139,20 +139,24 @@
#endif
} else {
+ GrAssert(kAccountFor_BudgetBehavior == behavior);
+
fEntryCount -= 1;
fEntryBytes -= entry->resource()->sizeInBytes();
}
}
void GrResourceCache::attachToHead(GrResourceEntry* entry,
- bool clientReattach) {
+ BudgetBehaviors behavior) {
fList.addToHead(entry);
// update our stats
- if (clientReattach) {
+ if (kIgnore_BudgetBehavior == behavior) {
fClientDetachedCount -= 1;
fClientDetachedBytes -= entry->resource()->sizeInBytes();
} else {
+ GrAssert(kAccountFor_BudgetBehavior == behavior);
+
fEntryCount += 1;
fEntryBytes += entry->resource()->sizeInBytes();
@@ -167,16 +171,40 @@
}
}
-GrResource* GrResourceCache::find(const GrResourceKey& key) {
+// This functor just searches for an entry with only a single ref (from
+// the texture cache itself). Presumably in this situation no one else
+// is relying on the texture.
+class GrTFindUnreffedFunctor {
+public:
+ bool operator()(const GrResourceEntry* entry) const {
+ return 1 == entry->resource()->getRefCnt();
+ }
+};
+
+GrResource* GrResourceCache::find(const GrResourceKey& key, uint32_t ownershipFlags) {
GrAutoResourceCacheValidate atcv(this);
- GrResourceEntry* entry = fCache.find(key);
+ GrResourceEntry* entry = NULL;
+
+ if (ownershipFlags & kNoOtherOwners_OwnershipFlag) {
+ GrTFindUnreffedFunctor functor;
+
+ entry = fCache.find<GrTFindUnreffedFunctor>(key, functor);
+ } else {
+ entry = fCache.find(key);
+ }
+
if (NULL == entry) {
return NULL;
}
- this->internalDetach(entry, false);
- this->attachToHead(entry, false);
+ if (ownershipFlags & kHide_OwnershipFlag) {
+ this->makeExclusive(entry);
+ } else {
+ // Make this resource MRU
+ this->internalDetach(entry);
+ this->attachToHead(entry);
+ }
return entry->fResource;
}
@@ -185,7 +213,9 @@
return NULL != fCache.find(key);
}
-void GrResourceCache::create(const GrResourceKey& key, GrResource* resource) {
+void GrResourceCache::addResource(const GrResourceKey& key,
+ GrResource* resource,
+ uint32_t ownershipFlags) {
GrAssert(NULL == resource->getCacheEntry());
// we don't expect to create new resources during a purge. In theory
// this could cause purgeAsNeeded() into an infinite loop (e.g.
@@ -197,19 +227,26 @@
GrResourceEntry* entry = SkNEW_ARGS(GrResourceEntry, (key, resource));
resource->setCacheEntry(entry);
- this->attachToHead(entry, false);
+ this->attachToHead(entry);
fCache.insert(key, entry);
#if GR_DUMP_TEXTURE_UPLOAD
GrPrintf("--- add resource to cache %p, count=%d bytes= %d %d\n",
entry, fEntryCount, resource->sizeInBytes(), fEntryBytes);
#endif
+
+ if (ownershipFlags & kHide_OwnershipFlag) {
+ this->makeExclusive(entry);
+ }
+
}
void GrResourceCache::makeExclusive(GrResourceEntry* entry) {
GrAutoResourceCacheValidate atcv(this);
- this->internalDetach(entry, true);
+ // When scratch textures are detached (to hide them from future finds) they
+ // still count against the resource budget
+ this->internalDetach(entry, kIgnore_BudgetBehavior);
fCache.remove(entry->key(), entry);
#if GR_DEBUG
@@ -238,7 +275,10 @@
#endif
if (entry->resource()->isValid()) {
- attachToHead(entry, true);
+ // Since scratch textures still count against the cache budget even
+ // when they have been removed from the cache, re-adding them doesn't
+ // alter the budget information.
+ attachToHead(entry, kIgnore_BudgetBehavior);
fCache.insert(entry->key(), entry);
} else {
this->removeInvalidResource(entry);
@@ -290,7 +330,7 @@
fCache.remove(entry->key(), entry);
// remove from our llist
- this->internalDetach(entry, false);
+ this->internalDetach(entry);
#if GR_DUMP_TEXTURE_UPLOAD
GrPrintf("--- ~resource from cache %p [%d %d]\n",