diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrGpuResource.cpp | 11 | ||||
-rw-r--r-- | src/gpu/GrGpuResourceCacheAccess.h | 19 | ||||
-rw-r--r-- | src/gpu/GrResourceCache2.cpp | 52 | ||||
-rw-r--r-- | src/gpu/GrTexture.cpp | 2 |
4 files changed, 65 insertions, 19 deletions
diff --git a/src/gpu/GrGpuResource.cpp b/src/gpu/GrGpuResource.cpp index 3e9964f1a0..15d5888cc0 100644 --- a/src/gpu/GrGpuResource.cpp +++ b/src/gpu/GrGpuResource.cpp @@ -86,8 +86,8 @@ bool GrGpuResource::setContentKey(const GrContentKey& key) { // Currently this can only be called once and can't be called when the resource is scratch. SkASSERT(this->internalHasRef()); - // Wrapped resources can never have a key. - if (this->isWrapped()) { + // Wrapped and uncached resources can never have a content key. + if (!this->cacheAccess().isBudgeted()) { return false; } @@ -138,6 +138,13 @@ void GrGpuResource::makeBudgeted() { } } +void GrGpuResource::makeUnbudgeted() { + if (GrGpuResource::kCached_LifeCycle == fLifeCycle && !fContentKey.isValid()) { + fLifeCycle = kUncached_LifeCycle; + get_resource_cache2(fGpu)->resourceAccess().didChangeBudgetStatus(this); + } +} + uint32_t GrGpuResource::CreateUniqueID() { static int32_t gUniqueID = SK_InvalidUniqueID; uint32_t id; diff --git a/src/gpu/GrGpuResourceCacheAccess.h b/src/gpu/GrGpuResourceCacheAccess.h index 33fe1ad93a..474438fa9c 100644 --- a/src/gpu/GrGpuResourceCacheAccess.h +++ b/src/gpu/GrGpuResourceCacheAccess.h @@ -29,11 +29,12 @@ public: } /** - * Is the resource currently cached as scratch? This means it has a valid scratch key and does - * not have a content key. + * Is the resource currently cached as scratch? This means it is cached, has a valid scratch + * key, and does not have a content key. */ bool isScratch() const { - return !this->getContentKey().isValid() && fResource->fScratchKey.isValid(); + return !this->getContentKey().isValid() && fResource->fScratchKey.isValid() && + this->isBudgeted(); } /** @@ -62,7 +63,11 @@ public: /** * Does the resource count against the resource budget? */ - bool isBudgeted() const { return GrGpuResource::kCached_LifeCycle == fResource->fLifeCycle; } + bool isBudgeted() const { + bool ret = GrGpuResource::kCached_LifeCycle == fResource->fLifeCycle; + SkASSERT(ret || !this->getContentKey().isValid()); + return ret; + } /** * If the resource is uncached make it cached. Has no effect on resources that are wrapped or @@ -71,6 +76,12 @@ public: void makeBudgeted() { fResource->makeBudgeted(); } /** + * If the resource is cached make it uncached. Has no effect on resources that are wrapped or + * already uncached. Furthermore, resources with content keys cannot be made unbudgeted. + */ + void makeUnbudgeted() { fResource->makeUnbudgeted(); } + + /** * Called by the cache to delete the resource under normal circumstances. */ void release() { diff --git a/src/gpu/GrResourceCache2.cpp b/src/gpu/GrResourceCache2.cpp index 5f31bf010e..87c943ef12 100644 --- a/src/gpu/GrResourceCache2.cpp +++ b/src/gpu/GrResourceCache2.cpp @@ -257,23 +257,42 @@ void GrResourceCache2::notifyPurgable(GrGpuResource* resource) { return; } - // Purge the resource if we're over budget - bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes; - - // Also purge if the resource has neither a valid scratch key nor a content key. - bool noKey = !resource->cacheAccess().getScratchKey().isValid() && - !resource->cacheAccess().getContentKey().isValid(); - - // Only cached resources should ever have a key. - SkASSERT(noKey || resource->cacheAccess().isBudgeted()); + bool release = false; + + if (resource->cacheAccess().isWrapped()) { + release = true; + } else if (!resource->cacheAccess().isBudgeted()) { + // Check whether this resource could still be used as a scratch resource. + if (resource->cacheAccess().getScratchKey().isValid()) { + // We won't purge an existing resource to make room for this one. + bool underBudget = fBudgetedCount < fMaxCount && + fBudgetedBytes + resource->gpuMemorySize() <= fMaxBytes; + if (underBudget) { + resource->cacheAccess().makeBudgeted(); + } else { + release = true; + } + } else { + release = true; + } + } else { + // Purge the resource if we're over budget + bool overBudget = fBudgetedCount > fMaxCount || fBudgetedBytes > fMaxBytes; + + // Also purge if the resource has neither a valid scratch key nor a content key. + bool noKey = !resource->cacheAccess().getScratchKey().isValid() && + !resource->cacheAccess().getContentKey().isValid(); + if (overBudget || noKey) { + release = true; + } + } - if (overBudget || noKey) { + if (release) { SkDEBUGCODE(int beforeCount = fCount;) resource->cacheAccess().release(); // We should at least free this resource, perhaps dependent resources as well. SkASSERT(fCount < beforeCount); } - this->validate(); } @@ -389,6 +408,13 @@ void GrResourceCache2::purgeAllUnlocked() { #ifdef SK_DEBUG void GrResourceCache2::validate() const { + // Reduce the frequency of validations for large resource counts. + static SkRandom gRandom; + int mask = (SkNextPow2(fCount + 1) >> 5) - 1; + if (~mask && (gRandom.nextU() & mask)) { + return; + } + size_t bytes = 0; int count = 0; int budgetedCount = 0; @@ -414,7 +440,8 @@ void GrResourceCache2::validate() const { SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchKey())); SkASSERT(!resource->cacheAccess().isWrapped()); } else if (resource->cacheAccess().getScratchKey().isValid()) { - SkASSERT(resource->cacheAccess().getContentKey().isValid()); + SkASSERT(!resource->cacheAccess().isBudgeted() || + resource->cacheAccess().getContentKey().isValid()); ++couldBeScratch; SkASSERT(fScratchMap.countForKey(resource->cacheAccess().getScratchKey())); SkASSERT(!resource->cacheAccess().isWrapped()); @@ -424,6 +451,7 @@ void GrResourceCache2::validate() const { ++content; SkASSERT(fContentHash.find(contentKey) == resource); SkASSERT(!resource->cacheAccess().isWrapped()); + SkASSERT(resource->cacheAccess().isBudgeted()); } if (resource->cacheAccess().isBudgeted()) { diff --git a/src/gpu/GrTexture.cpp b/src/gpu/GrTexture.cpp index 30dbbb659a..6bd458674b 100644 --- a/src/gpu/GrTexture.cpp +++ b/src/gpu/GrTexture.cpp @@ -87,7 +87,7 @@ GrTexture::GrTexture(GrGpu* gpu, LifeCycle lifeCycle, const GrSurfaceDesc& desc) : INHERITED(gpu, lifeCycle, desc) , fMipMapsStatus(kNotAllocated_MipMapsStatus) { - if (kCached_LifeCycle == lifeCycle) { + if (kWrapped_LifeCycle != lifeCycle) { GrScratchKey key; GrTexturePriv::ComputeScratchKey(desc, &key); this->setScratchKey(key); |