Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(242)

Unified Diff: src/gpu/GrResourceCache.cpp

Issue 611383003: Revert of GrResourceCache2 manages scratch texture. (Closed) Base URL: https://skia.googlesource.com/skia.git@surfimpl
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrResourceCache.h ('k') | src/gpu/GrResourceCache2.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/gpu/GrResourceCache.cpp
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
index 12e959f198f11aa0287e1a9fe8afd605277d6fb3..e9be509569a09efef5d22d9ad9ffb5b84a722a73 100644
--- a/src/gpu/GrResourceCache.cpp
+++ b/src/gpu/GrResourceCache.cpp
@@ -82,10 +82,14 @@
#if GR_CACHE_STATS
fHighWaterEntryCount = 0;
fHighWaterEntryBytes = 0;
+ fHighWaterClientDetachedCount = 0;
+ fHighWaterClientDetachedBytes = 0;
#endif
fEntryCount = 0;
fEntryBytes = 0;
+ fClientDetachedCount = 0;
+ fClientDetachedBytes = 0;
fPurging = false;
@@ -132,26 +136,55 @@
}
}
-void GrResourceCache::internalDetach(GrResourceCacheEntry* entry) {
+void GrResourceCache::internalDetach(GrResourceCacheEntry* entry,
+ BudgetBehaviors behavior) {
fList.remove(entry);
- fEntryCount -= 1;
- fEntryBytes -= entry->fCachedSize;
-}
-
-void GrResourceCache::attachToHead(GrResourceCacheEntry* entry) {
+
+ // update our stats
+ if (kIgnore_BudgetBehavior == behavior) {
+ fClientDetachedCount += 1;
+ fClientDetachedBytes += entry->fCachedSize;
+
+#if GR_CACHE_STATS
+ if (fHighWaterClientDetachedCount < fClientDetachedCount) {
+ fHighWaterClientDetachedCount = fClientDetachedCount;
+ }
+ if (fHighWaterClientDetachedBytes < fClientDetachedBytes) {
+ fHighWaterClientDetachedBytes = fClientDetachedBytes;
+ }
+#endif
+
+ } else {
+ SkASSERT(kAccountFor_BudgetBehavior == behavior);
+
+ fEntryCount -= 1;
+ fEntryBytes -= entry->fCachedSize;
+ }
+}
+
+void GrResourceCache::attachToHead(GrResourceCacheEntry* entry,
+ BudgetBehaviors behavior) {
fList.addToHead(entry);
- fEntryCount += 1;
- fEntryBytes += entry->fCachedSize;
+ // update our stats
+ if (kIgnore_BudgetBehavior == behavior) {
+ fClientDetachedCount -= 1;
+ fClientDetachedBytes -= entry->fCachedSize;
+ } else {
+ SkASSERT(kAccountFor_BudgetBehavior == behavior);
+
+ fEntryCount += 1;
+ fEntryBytes += entry->fCachedSize;
#if GR_CACHE_STATS
- if (fHighWaterEntryCount < fEntryCount) {
- fHighWaterEntryCount = fEntryCount;
- }
- if (fHighWaterEntryBytes < fEntryBytes) {
- fHighWaterEntryBytes = fEntryBytes;
- }
-#endif
+ if (fHighWaterEntryCount < fEntryCount) {
+ fHighWaterEntryCount = fEntryCount;
+ }
+ if (fHighWaterEntryBytes < fEntryBytes) {
+ fHighWaterEntryBytes = fEntryBytes;
+ }
+#endif
+ }
}
// This functor just searches for an entry with only a single ref (from
@@ -160,40 +193,41 @@
class GrTFindUnreffedFunctor {
public:
bool operator()(const GrResourceCacheEntry* entry) const {
- return entry->resource()->isPurgable();
+ return entry->resource()->unique();
}
};
-
-void GrResourceCache::makeResourceMRU(GrGpuResource* resource) {
- GrResourceCacheEntry* entry = resource->getCacheEntry();
- if (entry) {
+GrGpuResource* GrResourceCache::find(const GrResourceKey& key, uint32_t ownershipFlags) {
+ GrAutoResourceCacheValidate atcv(this);
+
+ GrResourceCacheEntry* entry = NULL;
+
+ if (ownershipFlags & kNoOtherOwners_OwnershipFlag) {
+ GrTFindUnreffedFunctor functor;
+
+ entry = fCache.find<GrTFindUnreffedFunctor>(key, functor);
+ } else {
+ entry = fCache.find(key);
+ }
+
+ if (NULL == entry) {
+ return NULL;
+ }
+
+ if (ownershipFlags & kHide_OwnershipFlag) {
+ this->makeExclusive(entry);
+ } else {
+ // Make this resource MRU
this->internalDetach(entry);
this->attachToHead(entry);
}
-}
-
-GrGpuResource* GrResourceCache::find(const GrResourceKey& key) {
- GrAutoResourceCacheValidate atcv(this);
-
- GrResourceCacheEntry* entry = NULL;
-
- entry = fCache.find(key);
-
- if (NULL == entry) {
- return NULL;
- }
-
- // Make this resource MRU
- this->internalDetach(entry);
- this->attachToHead(entry);
-
- // GrResourceCache2 is responsible for scratch resources.
- SkASSERT(GrIORef::kNo_IsScratch == entry->resource()->fIsScratch);
+
return entry->fResource;
}
-void GrResourceCache::addResource(const GrResourceKey& key, GrGpuResource* resource) {
+void GrResourceCache::addResource(const GrResourceKey& key,
+ GrGpuResource* resource,
+ uint32_t ownershipFlags) {
SkASSERT(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.
@@ -207,15 +241,77 @@
this->attachToHead(entry);
fCache.insert(key, entry);
+
+ if (ownershipFlags & kHide_OwnershipFlag) {
+ this->makeExclusive(entry);
+ }
+
+}
+
+void GrResourceCache::makeExclusive(GrResourceCacheEntry* entry) {
+ GrAutoResourceCacheValidate atcv(this);
+
+ SkASSERT(!entry->fIsExclusive);
+ entry->fIsExclusive = 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);
+
+#ifdef SK_DEBUG
+ fExclusiveList.addToHead(entry);
+#endif
+}
+
+void GrResourceCache::removeInvalidResource(GrResourceCacheEntry* entry) {
+ // If the resource went invalid while it was detached then purge it
+ // This can happen when a 3D context was lost,
+ // the client called GrContext::abandonContext() to notify Gr,
+ // and then later an SkGpuDevice's destructor releases its backing
+ // texture (which was invalidated at contextDestroyed time).
+ // TODO: Safely delete the GrResourceCacheEntry as well.
+ fClientDetachedCount -= 1;
+ fEntryCount -= 1;
+ fClientDetachedBytes -= entry->fCachedSize;
+ fEntryBytes -= entry->fCachedSize;
+ entry->fCachedSize = 0;
+}
+
+void GrResourceCache::makeNonExclusive(GrResourceCacheEntry* entry) {
+ GrAutoResourceCacheValidate atcv(this);
+
+#ifdef SK_DEBUG
+ fExclusiveList.remove(entry);
+#endif
+
+ if (!entry->resource()->wasDestroyed()) {
+ // 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);
+
+ SkASSERT(entry->fIsExclusive);
+ entry->fIsExclusive = false;
+ } else {
+ this->removeInvalidResource(entry);
+ }
}
void GrResourceCache::didIncreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountInc) {
fEntryBytes += amountInc;
+ if (entry->fIsExclusive) {
+ fClientDetachedBytes += amountInc;
+ }
this->purgeAsNeeded();
}
void GrResourceCache::didDecreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountDec) {
fEntryBytes -= amountDec;
+ if (entry->fIsExclusive) {
+ fClientDetachedBytes -= amountDec;
+ }
#ifdef SK_DEBUG
this->validate();
#endif
@@ -263,6 +359,13 @@
fInvalidationInbox.poll(&invalidated);
for (int i = 0; i < invalidated.count(); i++) {
+ // We're somewhat missing an opportunity here. We could use the
+ // default find functor that gives us back resources whether we own
+ // them exclusively or not, and when they're not exclusively owned mark
+ // them for purging later when they do become exclusively owned.
+ //
+ // This is complicated and confusing. May try this in the future. For
+ // now, these resources are just LRU'd as if we never got the message.
while (GrResourceCacheEntry* entry = fCache.find(invalidated[i].key, GrTFindUnreffedFunctor())) {
this->deleteResource(entry);
}
@@ -270,7 +373,7 @@
}
void GrResourceCache::deleteResource(GrResourceCacheEntry* entry) {
- SkASSERT(entry->fResource->isPurgable());
+ SkASSERT(entry->fResource->unique());
// remove from our cache
fCache.remove(entry->key(), entry);
@@ -309,7 +412,7 @@
}
GrResourceCacheEntry* prev = iter.prev();
- if (entry->fResource->isPurgable()) {
+ if (entry->fResource->unique()) {
changed = true;
this->deleteResource(entry);
}
@@ -332,7 +435,14 @@
this->purgeAsNeeded();
#ifdef SK_DEBUG
+ SkASSERT(fExclusiveList.countEntries() == fClientDetachedCount);
+ SkASSERT(countBytes(fExclusiveList) == fClientDetachedBytes);
if (!fCache.count()) {
+ // Items may have been detached from the cache (such as the backing
+ // texture for an SkGpuDevice). The above purge would not have removed
+ // them.
+ SkASSERT(fEntryCount == fClientDetachedCount);
+ SkASSERT(fEntryBytes == fClientDetachedBytes);
SkASSERT(fList.isEmpty());
}
#endif
@@ -364,14 +474,25 @@
void GrResourceCache::validate() const {
fList.validate();
+ fExclusiveList.validate();
SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes));
- SkASSERT(fEntryCount == fCache.count());
+ SkASSERT(both_zero_or_nonzero(fClientDetachedCount, fClientDetachedBytes));
+ SkASSERT(fClientDetachedBytes <= fEntryBytes);
+ SkASSERT(fClientDetachedCount <= fEntryCount);
+ SkASSERT((fEntryCount - fClientDetachedCount) == fCache.count());
EntryList::Iter iter;
+ // check that the exclusively held entries are okay
+ const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fExclusiveList),
+ EntryList::Iter::kHead_IterStart);
+
+ for ( ; entry; entry = iter.next()) {
+ entry->validate();
+ }
+
// check that the shareable entries are okay
- const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fList),
- EntryList::Iter::kHead_IterStart);
+ entry = iter.init(const_cast<EntryList&>(fList), EntryList::Iter::kHead_IterStart);
int count = 0;
for ( ; entry; entry = iter.next()) {
@@ -379,11 +500,17 @@
SkASSERT(fCache.find(entry->key()));
count += 1;
}
- SkASSERT(count == fEntryCount);
-
- size_t bytes = this->countBytes(fList);
- SkASSERT(bytes == fEntryBytes);
- SkASSERT(fList.countEntries() == fEntryCount);
+ SkASSERT(count == fEntryCount - fClientDetachedCount);
+
+ size_t bytes = countBytes(fList);
+ SkASSERT(bytes == fEntryBytes - fClientDetachedBytes);
+
+ bytes = countBytes(fExclusiveList);
+ SkASSERT(bytes == fClientDetachedBytes);
+
+ SkASSERT(fList.countEntries() == fEntryCount - fClientDetachedCount);
+
+ SkASSERT(fExclusiveList.countEntries() == fClientDetachedCount);
}
#endif // SK_DEBUG
@@ -407,6 +534,10 @@
fEntryCount, locked, fHighWaterEntryCount);
SkDebugf("\t\tEntry Bytes: current %d high %d\n",
fEntryBytes, fHighWaterEntryBytes);
+ SkDebugf("\t\tDetached Entry Count: current %d high %d\n",
+ fClientDetachedCount, fHighWaterClientDetachedCount);
+ SkDebugf("\t\tDetached Bytes: current %d high %d\n",
+ fClientDetachedBytes, fHighWaterClientDetachedBytes);
}
#endif
« no previous file with comments | « src/gpu/GrResourceCache.h ('k') | src/gpu/GrResourceCache2.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698