aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrResourceCache.cpp
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2014-11-13 13:19:10 -0800
committerGravatar Commit bot <commit-bot@chromium.org>2014-11-13 13:19:10 -0800
commit66a450f21a3da174b7eed89a1d5fc8591e8b6ee6 (patch)
tree97170b6b7e193001f9afbf6a99980dd355de2bda /src/gpu/GrResourceCache.cpp
parentbc97c9378bf8b89cc17280a2a04a5c3a9405e6ab (diff)
Replace GrResourceCache with GrResourceCache2.
Diffstat (limited to 'src/gpu/GrResourceCache.cpp')
-rw-r--r--src/gpu/GrResourceCache.cpp393
1 files changed, 0 insertions, 393 deletions
diff --git a/src/gpu/GrResourceCache.cpp b/src/gpu/GrResourceCache.cpp
deleted file mode 100644
index a73d11703d..0000000000
--- a/src/gpu/GrResourceCache.cpp
+++ /dev/null
@@ -1,393 +0,0 @@
-
-/*
- * Copyright 2010 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "GrResourceCache.h"
-#include "GrGpuResource.h"
-#include "GrGpuResourceCacheAccess.h"
-#include "GrTexturePriv.h"
-
-DECLARE_SKMESSAGEBUS_MESSAGE(GrResourceInvalidatedMessage);
-
-///////////////////////////////////////////////////////////////////////////////
-
-void GrGpuResource::didChangeGpuMemorySize() const {
- fGpuMemorySize = kInvalidGpuMemorySize;
- if (this->cacheAccess().isInCache()) {
- fCacheEntry->didChangeResourceSize();
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-GrResourceKey::ResourceType GrResourceKey::GenerateResourceType() {
- static int32_t gNextType = 0;
-
- int32_t type = sk_atomic_inc(&gNextType);
- if (type >= (1 << 8 * sizeof(ResourceType))) {
- SkFAIL("Too many Resource Types");
- }
-
- return static_cast<ResourceType>(type);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-GrResourceCacheEntry::GrResourceCacheEntry(GrResourceCache* resourceCache, GrGpuResource* resource)
- : fResourceCache(resourceCache),
- fResource(resource),
- fCachedSize(resource->gpuMemorySize()) {
- // we assume ownership of the resource, and will unref it when we die
- SkASSERT(resource);
- resource->ref();
-}
-
-GrResourceCacheEntry::~GrResourceCacheEntry() {
- // We're relying on having the cache entry to remove this from GrResourceCache2's content hash.
- // fResource->setCacheEntry(NULL);
- fResource->unref();
-}
-
-#ifdef SK_DEBUG
-void GrResourceCacheEntry::validate() const {
- SkASSERT(fResourceCache);
- SkASSERT(fResource);
- SkASSERT(fResource->cacheAccess().getCacheEntry() == this);
- SkASSERT(fResource->gpuMemorySize() == fCachedSize);
- fResource->validate();
-}
-#endif
-
-void GrResourceCacheEntry::didChangeResourceSize() {
- size_t oldSize = fCachedSize;
- fCachedSize = fResource->gpuMemorySize();
- if (fCachedSize > oldSize) {
- fResourceCache->didIncreaseResourceSize(this, fCachedSize - oldSize);
- } else if (fCachedSize < oldSize) {
- fResourceCache->didDecreaseResourceSize(this, oldSize - fCachedSize);
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-GrResourceCache::GrResourceCache(const GrDrawTargetCaps* caps, int maxCount, size_t maxBytes)
- : fMaxCount(maxCount)
- , fMaxBytes(maxBytes)
- , fCaps(SkRef(caps)) {
-#if GR_CACHE_STATS
- fHighWaterEntryCount = 0;
- fHighWaterEntryBytes = 0;
-#endif
-
- fEntryCount = 0;
- fEntryBytes = 0;
-
- fPurging = false;
-
- fOverbudgetCB = NULL;
- fOverbudgetData = NULL;
-}
-
-GrResourceCache::~GrResourceCache() {
- GrAutoResourceCacheValidate atcv(this);
-
- EntryList::Iter iter;
-
- // Unlike the removeAll, here we really remove everything, including locked resources.
- while (GrResourceCacheEntry* entry = fList.head()) {
- GrAutoResourceCacheValidate atcv(this);
-
- // remove from our llist
- this->internalDetach(entry);
-
- delete entry;
- }
-}
-
-void GrResourceCache::getLimits(int* maxResources, size_t* maxResourceBytes) const{
- if (maxResources) {
- *maxResources = fMaxCount;
- }
- if (maxResourceBytes) {
- *maxResourceBytes = fMaxBytes;
- }
-}
-
-void GrResourceCache::setLimits(int maxResources, size_t maxResourceBytes) {
- bool smaller = (maxResources < fMaxCount) || (maxResourceBytes < fMaxBytes);
-
- fMaxCount = maxResources;
- fMaxBytes = maxResourceBytes;
-
- if (smaller) {
- this->purgeAsNeeded();
- }
-}
-
-void GrResourceCache::internalDetach(GrResourceCacheEntry* entry) {
- fList.remove(entry);
- fEntryCount -= 1;
- fEntryBytes -= entry->fCachedSize;
-}
-
-void GrResourceCache::attachToHead(GrResourceCacheEntry* entry) {
- fList.addToHead(entry);
-
- fEntryCount += 1;
- fEntryBytes += entry->fCachedSize;
-
-#if GR_CACHE_STATS
- if (fHighWaterEntryCount < fEntryCount) {
- fHighWaterEntryCount = fEntryCount;
- }
- if (fHighWaterEntryBytes < fEntryBytes) {
- fHighWaterEntryBytes = fEntryBytes;
- }
-#endif
-}
-
-
-void GrResourceCache::makeResourceMRU(GrGpuResource* resource) {
- GrResourceCacheEntry* entry = resource->cacheAccess().getCacheEntry();
- if (entry) {
- this->internalDetach(entry);
- this->attachToHead(entry);
- }
-}
-
-void GrResourceCache::notifyPurgable(const GrGpuResource* resource) {
- // Remove scratch textures from the cache the moment they become purgeable if
- // scratch texture reuse is turned off.
- SkASSERT(resource->cacheAccess().getCacheEntry());
- if (resource->cacheAccess().isScratch()) {
- const GrResourceKey& key = resource->cacheAccess().getScratchKey();
- if (key.getResourceType() == GrTexturePriv::ResourceType() &&
- !fCaps->reuseScratchTextures() &&
- !(static_cast<const GrSurface*>(resource)->desc().fFlags & kRenderTarget_GrSurfaceFlag)) {
- this->deleteResource(resource->cacheAccess().getCacheEntry());
- }
- }
-}
-
-bool GrResourceCache::addResource(const GrResourceKey& key, GrGpuResource* resource) {
- if (NULL != resource->cacheAccess().getCacheEntry()) {
- return false;
- }
-
- if (key.isScratch()) {
- SkASSERT(resource->cacheAccess().isScratch());
- SkASSERT(key == resource->cacheAccess().getScratchKey());
- } else {
- if (!resource->cacheAccess().setContentKey(key)) {
- return false;
- }
- }
-
- // we don't expect to create new resources during a purge. In theory
- // this could cause purgeAsNeeded() into an infinite loop (e.g.
- // each resource destroyed creates and locks 2 resources and
- // unlocks 1 thereby causing a new purge).
- SkASSERT(!fPurging);
- GrAutoResourceCacheValidate atcv(this);
-
- GrResourceCacheEntry* entry = SkNEW_ARGS(GrResourceCacheEntry, (this, resource));
- resource->cacheAccess().setCacheEntry(entry);
-
- this->attachToHead(entry);
- this->purgeAsNeeded();
- return true;
-}
-
-void GrResourceCache::didIncreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountInc) {
- fEntryBytes += amountInc;
- this->purgeAsNeeded();
-}
-
-void GrResourceCache::didDecreaseResourceSize(const GrResourceCacheEntry* entry, size_t amountDec) {
- fEntryBytes -= amountDec;
-#ifdef SK_DEBUG
- this->validate();
-#endif
-}
-
-/**
- * Destroying a resource may potentially trigger the unlock of additional
- * resources which in turn will trigger a nested purge. We block the nested
- * purge using the fPurging variable. However, the initial purge will keep
- * looping until either all resources in the cache are unlocked or we've met
- * the budget. There is an assertion in createAndLock to check against a
- * resource's destructor inserting new resources into the cache. If these
- * new resources were unlocked before purgeAsNeeded completed it could
- * potentially make purgeAsNeeded loop infinitely.
- *
- * extraCount and extraBytes are added to the current resource totals to account
- * for incoming resources (e.g., GrContext is about to add 10MB split between
- * 10 textures).
- */
-void GrResourceCache::purgeAsNeeded(int extraCount, size_t extraBytes) {
- if (fPurging) {
- return;
- }
-
- fPurging = true;
-
- this->internalPurge(extraCount, extraBytes);
- if (((fEntryCount+extraCount) > fMaxCount ||
- (fEntryBytes+extraBytes) > fMaxBytes) &&
- fOverbudgetCB) {
- // Despite the purge we're still over budget. See if Ganesh can
- // release some resources and purge again.
- if ((*fOverbudgetCB)(fOverbudgetData)) {
- this->internalPurge(extraCount, extraBytes);
- }
- }
-
- fPurging = false;
-}
-
-void GrResourceCache::purgeInvalidated() {
- // TODO: Implement this in GrResourceCache2.
-}
-
-void GrResourceCache::deleteResource(GrResourceCacheEntry* entry) {
- SkASSERT(entry->fResource->isPurgable());
- // remove from our llist
- this->internalDetach(entry);
- delete entry;
-}
-
-void GrResourceCache::internalPurge(int extraCount, size_t extraBytes) {
- SkASSERT(fPurging);
-
- bool withinBudget = false;
- bool changed = false;
-
- // The purging process is repeated several times since one pass
- // may free up other resources
- do {
- EntryList::Iter iter;
-
- changed = false;
-
- // Note: the following code relies on the fact that the
- // doubly linked list doesn't invalidate its data/pointers
- // outside of the specific area where a deletion occurs (e.g.,
- // in internalDetach)
- GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart);
-
- while (entry) {
- GrAutoResourceCacheValidate atcv(this);
-
- if ((fEntryCount+extraCount) <= fMaxCount &&
- (fEntryBytes+extraBytes) <= fMaxBytes) {
- withinBudget = true;
- break;
- }
-
- GrResourceCacheEntry* prev = iter.prev();
- if (entry->fResource->isPurgable()) {
- changed = true;
- this->deleteResource(entry);
- }
- entry = prev;
- }
- } while (!withinBudget && changed);
-}
-
-void GrResourceCache::purgeAllUnlocked() {
- GrAutoResourceCacheValidate atcv(this);
-
- // we can have one GrCacheable holding a lock on another
- // so we don't want to just do a simple loop kicking each
- // entry out. Instead change the budget and purge.
-
- size_t savedMaxBytes = fMaxBytes;
- int savedMaxCount = fMaxCount;
- fMaxBytes = (size_t) -1;
- fMaxCount = 0;
- this->purgeAsNeeded();
-
- fMaxBytes = savedMaxBytes;
- fMaxCount = savedMaxCount;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-#ifdef SK_DEBUG
-size_t GrResourceCache::countBytes(const EntryList& list) {
- size_t bytes = 0;
-
- EntryList::Iter iter;
-
- const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(list),
- EntryList::Iter::kTail_IterStart);
-
- for ( ; entry; entry = iter.prev()) {
- bytes += entry->resource()->gpuMemorySize();
- }
- return bytes;
-}
-
-static bool both_zero_or_nonzero(int count, size_t bytes) {
- return (count == 0 && bytes == 0) || (count > 0 && bytes > 0);
-}
-
-void GrResourceCache::validate() const {
- fList.validate();
- SkASSERT(both_zero_or_nonzero(fEntryCount, fEntryBytes));
-
- EntryList::Iter iter;
-
- // check that the shareable entries are okay
- const GrResourceCacheEntry* entry = iter.init(const_cast<EntryList&>(fList),
- EntryList::Iter::kHead_IterStart);
-
- int count = 0;
- for ( ; entry; entry = iter.next()) {
- entry->validate();
- count += 1;
- }
- SkASSERT(count == fEntryCount);
-
- size_t bytes = this->countBytes(fList);
- SkASSERT(bytes == fEntryBytes);
- SkASSERT(fList.countEntries() == fEntryCount);
-}
-#endif // SK_DEBUG
-
-#if GR_CACHE_STATS
-
-void GrResourceCache::printStats() {
- int locked = 0;
- int scratch = 0;
-
- EntryList::Iter iter;
-
- GrResourceCacheEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart);
-
- for ( ; entry; entry = iter.prev()) {
- if (!entry->fResource->isPurgable()) {
- ++locked;
- }
- if (entry->fResource->cacheAccess().isScratch()) {
- ++scratch;
- }
- }
-
- float countUtilization = (100.f * fEntryCount) / fMaxCount;
- float byteUtilization = (100.f * fEntryBytes) / fMaxBytes;
-
- SkDebugf("Budget: %d items %d bytes\n", fMaxCount, fMaxBytes);
- SkDebugf("\t\tEntry Count: current %d (%d locked, %d scratch %.2g%% full), high %d\n",
- fEntryCount, locked, scratch, countUtilization, fHighWaterEntryCount);
- SkDebugf("\t\tEntry Bytes: current %d (%.2g%% full) high %d\n",
- fEntryBytes, byteUtilization, fHighWaterEntryBytes);
-}
-
-#endif
-
-///////////////////////////////////////////////////////////////////////////////