1fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot/* 2fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Copyright 2014 Google Inc. 3fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * 4fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * Use of this source code is governed by a BSD-style license that can be 5fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot * found in the LICENSE file. 6fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot */ 7fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 8fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 9fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrResourceCache.h" 10fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 11fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrCaps.h" 12fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrGpuResourceCacheAccess.h" 13fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrProxyProvider.h" 14fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTexture.h" 15fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTextureProxyCacheAccess.h" 16fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "GrTracing.h" 17fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkGr.h" 18fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkMessageBus.h" 19fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkOpts.h" 20fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#include "SkTSort.h" 21fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 22fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDECLARE_SKMESSAGEBUS_MESSAGE(GrUniqueKeyInvalidatedMessage); 23fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 24fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotDECLARE_SKMESSAGEBUS_MESSAGE(GrGpuResourceFreedMessage); 25fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 26fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot////////////////////////////////////////////////////////////////////////////// 27fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 28fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrScratchKey::ResourceType GrScratchKey::GenerateResourceType() { 29fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static int32_t gType = INHERITED::kInvalidDomain + 1; 30fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 31fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int32_t type = sk_atomic_inc(&gType); 32fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (type > SK_MaxU16) { 33fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ABORT("Too many Resource Types"); 34fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 35fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 36fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return static_cast<ResourceType>(type); 37fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 38fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 39fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrUniqueKey::Domain GrUniqueKey::GenerateDomain() { 40fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static int32_t gDomain = INHERITED::kInvalidDomain + 1; 41fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 42fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int32_t domain = sk_atomic_inc(&gDomain); 43fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (domain > SK_MaxU16) { 44fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SK_ABORT("Too many GrUniqueKey Domains"); 45fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 46fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 47fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return static_cast<Domain>(domain); 48fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 49fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 50fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotuint32_t GrResourceKeyHash(const uint32_t* data, size_t size) { 51fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return SkOpts::hash(data, size); 52fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 53fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 54fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot////////////////////////////////////////////////////////////////////////////// 55fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 56fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrResourceCache::AutoValidate : ::SkNoncopyable { 57fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 58fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot AutoValidate(GrResourceCache* cache) : fCache(cache) { cache->validate(); } 59fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ~AutoValidate() { fCache->validate(); } 60fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 61fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrResourceCache* fCache; 62fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 63fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 64fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ////////////////////////////////////////////////////////////////////////////// 65fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 66fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 67fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrResourceCache::GrResourceCache(const GrCaps* caps, uint32_t contextUniqueID) 68fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot : fProxyProvider(nullptr) 69fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fTimestamp(0) 70fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fMaxCount(kDefaultMaxCount) 71fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fMaxBytes(kDefaultMaxSize) 72fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fMaxUnusedFlushes(kDefaultMaxUnusedFlushes) 73fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_CACHE_STATS 74fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fHighWaterCount(0) 75fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fHighWaterBytes(0) 76fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fBudgetedHighWaterCount(0) 77fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fBudgetedHighWaterBytes(0) 78fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 79fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fBytes(0) 80fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fBudgetedCount(0) 81fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fBudgetedBytes(0) 82fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fPurgeableBytes(0) 83fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fRequestFlush(false) 84fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fExternalFlushCnt(0) 85fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fContextUniqueID(contextUniqueID) 86fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot , fPreferVRAMUseOverFlushes(caps->preferVRAMUseOverFlushes()) { 87fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE(fCount = 0;) 88fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE(fNewlyPurgeableResourceForValidation = nullptr;) 89fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 90fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 91fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrResourceCache::~GrResourceCache() { 92fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->releaseAll(); 93fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 94fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 95fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::setLimits(int count, size_t bytes, int maxUnusedFlushes) { 96fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxCount = count; 97fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxBytes = bytes; 98fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxUnusedFlushes = maxUnusedFlushes; 99fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->purgeAsNeeded(); 100fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 101fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 102fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::insertResource(GrGpuResource* resource) { 103fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource); 104fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!this->isInCache(resource)); 105fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!resource->wasDestroyed()); 106fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!resource->isPurgeable()); 107fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 108fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We must set the timestamp before adding to the array in case the timestamp wraps and we wind 109fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // up iterating over all the resources that already have timestamps. 110fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().setTimestamp(this->getNextTimestamp()); 111fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 112fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addToNonpurgeableArray(resource); 113fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 114fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size = resource->gpuMemorySize(); 115fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE(++fCount;) 116fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBytes += size; 117fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_CACHE_STATS 118fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fHighWaterCount = SkTMax(this->getResourceCount(), fHighWaterCount); 119fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); 120fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 121fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { 122fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fBudgetedCount; 123fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes += size; 124fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TRACE_COUNTER2("skia.gpu.cache", "skia budget", "used", 125fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); 126fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_CACHE_STATS 127fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount); 128fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes); 129fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 130fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 131fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->resourcePriv().getScratchKey().isValid() && 132fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot !resource->getUniqueKey().isValid()) { 133fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!resource->resourcePriv().refsWrappedObjects()); 134fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); 135fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 136fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 137fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->purgeAsNeeded(); 138fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 139fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 140fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::removeResource(GrGpuResource* resource) { 141fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 142fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->isInCache(resource)); 143fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 144fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size = resource->gpuMemorySize(); 145fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->isPurgeable()) { 146fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableQueue.remove(resource); 147fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableBytes -= size; 148fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 149fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->removeFromNonpurgeableArray(resource); 150fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 151fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 152fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE(--fCount;) 153fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBytes -= size; 154fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { 155fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot --fBudgetedCount; 156fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes -= size; 157fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TRACE_COUNTER2("skia.gpu.cache", "skia budget", "used", 158fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); 159fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 160fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 161fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->resourcePriv().getScratchKey().isValid() && 162fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot !resource->getUniqueKey().isValid()) { 163fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); 164fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 165fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->getUniqueKey().isValid()) { 166fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUniqueHash.remove(resource->getUniqueKey()); 167fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 168fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 169fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 170fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 171fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::abandonAll() { 172fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot AutoValidate av(this); 173fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 174fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (fNonpurgeableResources.count()) { 175fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* back = *(fNonpurgeableResources.end() - 1); 176fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!back->wasDestroyed()); 177fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot back->cacheAccess().abandon(); 178fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 179fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 180fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (fPurgeableQueue.count()) { 181fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* top = fPurgeableQueue.peek(); 182fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!top->wasDestroyed()); 183fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot top->cacheAccess().abandon(); 184fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 185fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 186fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fScratchMap.count()); 187fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fUniqueHash.count()); 188fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fCount); 189fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!this->getResourceCount()); 190fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fBytes); 191fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fBudgetedCount); 192fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fBudgetedBytes); 193fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fPurgeableBytes); 194fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 195fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 196fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::releaseAll() { 197fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot AutoValidate av(this); 198fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 199fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->processFreedGpuResources(); 200fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 201fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fProxyProvider); // better have called setProxyProvider 202fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We must remove the uniqueKeys from the proxies here. While they possess a uniqueKey 203fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // they also have a raw pointer back to this class (which is presumably going away)! 204fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fProxyProvider->removeAllUniqueKeys(); 205fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 206fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while(fNonpurgeableResources.count()) { 207fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* back = *(fNonpurgeableResources.end() - 1); 208fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!back->wasDestroyed()); 209fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot back->cacheAccess().release(); 210fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 211fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 212fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (fPurgeableQueue.count()) { 213fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* top = fPurgeableQueue.peek(); 214fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!top->wasDestroyed()); 215fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot top->cacheAccess().release(); 216fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 217fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 218fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fScratchMap.count()); 219fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fUniqueHash.count()); 220fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fCount); 221fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!this->getResourceCount()); 222fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fBytes); 223fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fBudgetedCount); 224fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fBudgetedBytes); 225fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fPurgeableBytes); 226fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 227fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 228fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotclass GrResourceCache::AvailableForScratchUse { 229fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotpublic: 230fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot AvailableForScratchUse(bool rejectPendingIO) : fRejectPendingIO(rejectPendingIO) { } 231fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 232fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool operator()(const GrGpuResource* resource) const { 233fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!resource->getUniqueKey().isValid() && 234fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->resourcePriv().getScratchKey().isValid()); 235fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->internalHasRef() || !resource->cacheAccess().isScratch()) { 236fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 237fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 238fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return !fRejectPendingIO || !resource->internalHasPendingIO(); 239fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 240fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 241fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotprivate: 242fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool fRejectPendingIO; 243fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot}; 244fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 245fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team RobotGrGpuResource* GrResourceCache::findAndRefScratchResource(const GrScratchKey& scratchKey, 246fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t resourceSize, 247fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint32_t flags) { 248fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(scratchKey.isValid()); 249fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 250fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* resource; 251fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (flags & (kPreferNoPendingIO_ScratchFlag | kRequireNoPendingIO_ScratchFlag)) { 252fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource = fScratchMap.find(scratchKey, AvailableForScratchUse(true)); 253fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource) { 254fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->refAndMakeResourceMRU(resource); 255fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 256fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return resource; 257fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (flags & kRequireNoPendingIO_ScratchFlag) { 258fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 259fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 260fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We would prefer to consume more available VRAM rather than flushing 261fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // immediately, but on ANGLE this can lead to starving of the GPU. 262fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fPreferVRAMUseOverFlushes && this->wouldFit(resourceSize)) { 263fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // kPrefer is specified, we didn't find a resource without pending io, 264fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // but there is still space in our budget for the resource so force 265fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the caller to allocate a new resource. 266fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return nullptr; 267fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 268fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 269fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource = fScratchMap.find(scratchKey, AvailableForScratchUse(false)); 270fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource) { 271fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->refAndMakeResourceMRU(resource); 272fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 273fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 274fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return resource; 275fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 276fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 277fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::willRemoveScratchKey(const GrGpuResource* resource) { 278fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource->resourcePriv().getScratchKey().isValid()); 279fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!resource->getUniqueKey().isValid()) { 280fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); 281fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 282fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 283fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 284fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::removeUniqueKey(GrGpuResource* resource) { 285fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Someone has a ref to this resource in order to have removed the key. When the ref count 286fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // reaches zero we will get a ref cnt notification and figure out what to do with it. 287fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->getUniqueKey().isValid()) { 288fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); 289fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUniqueHash.remove(resource->getUniqueKey()); 290fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 291fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().removeUniqueKey(); 292fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 293fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->resourcePriv().getScratchKey().isValid()) { 294fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fScratchMap.insert(resource->resourcePriv().getScratchKey(), resource); 295fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 296fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 297fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 298fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 299fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 300fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::changeUniqueKey(GrGpuResource* resource, const GrUniqueKey& newKey) { 301fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource); 302fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->isInCache(resource)); 303fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 304fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // If another resource has the new key, remove its key then install the key on this resource. 305fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (newKey.isValid()) { 306fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (GrGpuResource* old = fUniqueHash.find(newKey)) { 307fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // If the old resource using the key is purgeable and is unreachable, then remove it. 308fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!old->resourcePriv().getScratchKey().isValid() && old->isPurgeable()) { 309fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot old->cacheAccess().release(); 310fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 311fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->removeUniqueKey(old); 312fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 313fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 314fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(nullptr == fUniqueHash.find(newKey)); 315fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 316fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Remove the entry for this resource if it already has a unique key. 317fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->getUniqueKey().isValid()) { 318fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource == fUniqueHash.find(resource->getUniqueKey())); 319fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUniqueHash.remove(resource->getUniqueKey()); 320fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(nullptr == fUniqueHash.find(resource->getUniqueKey())); 321fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 322fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // 'resource' didn't have a valid unique key before so it is switching sides. Remove it 323fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // from the ScratchMap 324fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->resourcePriv().getScratchKey().isValid()) { 325fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fScratchMap.remove(resource->resourcePriv().getScratchKey(), resource); 326fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 327fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 328fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 329fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().setUniqueKey(newKey); 330fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUniqueHash.add(resource); 331fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 332fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->removeUniqueKey(resource); 333fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 334fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 335fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 336fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 337fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 338fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::refAndMakeResourceMRU(GrGpuResource* resource) { 339fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource); 340fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->isInCache(resource)); 341fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 342fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->isPurgeable()) { 343fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // It's about to become unpurgeable. 344fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableBytes -= resource->gpuMemorySize(); 345fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableQueue.remove(resource); 346fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->addToNonpurgeableArray(resource); 347fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 348fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->ref(); 349fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 350fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().setTimestamp(this->getNextTimestamp()); 351fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 352fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 353fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 354fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::notifyCntReachedZero(GrGpuResource* resource, uint32_t flags) { 355fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource); 356fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!resource->wasDestroyed()); 357fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(flags); 358fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->isInCache(resource)); 359fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This resource should always be in the nonpurgeable array when this function is called. It 360fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // will be moved to the queue if it is newly purgeable. 361fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fNonpurgeableResources[*resource->cacheAccess().accessCacheIndex()] == resource); 362fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 363fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkToBool(ResourceAccess::kRefCntReachedZero_RefNotificationFlag & flags)) { 364fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG 365fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // When the timestamp overflows validate() is called. validate() checks that resources in 366fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the nonpurgeable array are indeed not purgeable. However, the movement from the array to 367fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // the purgeable queue happens just below in this function. So we mark it as an exception. 368fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->isPurgeable()) { 369fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fNewlyPurgeableResourceForValidation = resource; 370fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 371fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 372fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().setTimestamp(this->getNextTimestamp()); 373fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE(fNewlyPurgeableResourceForValidation = nullptr); 374fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 375fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 376fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!SkToBool(ResourceAccess::kAllCntsReachedZero_RefNotificationFlag & flags)) { 377fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!resource->isPurgeable()); 378fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 379fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 380fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 381fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource->isPurgeable()); 382fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->removeFromNonpurgeableArray(resource); 383fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableQueue.insert(resource); 384fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().setFlushCntWhenResourceBecamePurgeable(fExternalFlushCnt); 385fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().setTimeWhenResourceBecomePurgeable(); 386fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableBytes += resource->gpuMemorySize(); 387fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 388fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkBudgeted::kNo == resource->resourcePriv().isBudgeted()) { 389fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Check whether this resource could still be used as a scratch resource. 390fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!resource->resourcePriv().refsWrappedObjects() && 391fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->resourcePriv().getScratchKey().isValid()) { 392fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We won't purge an existing resource to make room for this one. 393fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fBudgetedCount < fMaxCount && 394fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes + resource->gpuMemorySize() <= fMaxBytes) { 395fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->resourcePriv().makeBudgeted(); 396fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 397fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 398fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 399fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 400fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Purge the resource immediately if we're over budget 401fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Also purge if the resource has neither a valid scratch key nor a unique key. 402fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool noKey = !resource->resourcePriv().getScratchKey().isValid() && 403fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot !resource->getUniqueKey().isValid(); 404fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!this->overBudget() && !noKey) { 405fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 406fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 407fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 408fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 409fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE(int beforeCount = this->getResourceCount();) 410fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().release(); 411fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We should at least free this resource, perhaps dependent resources as well. 412fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->getResourceCount() < beforeCount); 413fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 414fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 415fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 416fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::didChangeGpuMemorySize(const GrGpuResource* resource, size_t oldSize) { 417fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // SkASSERT(!fPurging); GrPathRange increases size during flush. :( 418fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource); 419fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->isInCache(resource)); 420fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 421fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ptrdiff_t delta = resource->gpuMemorySize() - oldSize; 422fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 423fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBytes += delta; 424fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_CACHE_STATS 425fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fHighWaterBytes = SkTMax(fBytes, fHighWaterBytes); 426fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 427fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { 428fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes += delta; 429fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TRACE_COUNTER2("skia.gpu.cache", "skia budget", "used", 430fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); 431fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_CACHE_STATS 432fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes); 433fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 434fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 435fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 436fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->purgeAsNeeded(); 437fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 438fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 439fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 440fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::didChangeBudgetStatus(GrGpuResource* resource) { 441fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource); 442fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(this->isInCache(resource)); 443fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 444fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t size = resource->gpuMemorySize(); 445fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 446fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { 447fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fBudgetedCount; 448fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes += size; 449fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_CACHE_STATS 450fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedHighWaterBytes = SkTMax(fBudgetedBytes, fBudgetedHighWaterBytes); 451fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedHighWaterCount = SkTMax(fBudgetedCount, fBudgetedHighWaterCount); 452fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 453fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->purgeAsNeeded(); 454fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 455fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot --fBudgetedCount; 456fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes -= size; 457fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 458fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot TRACE_COUNTER2("skia.gpu.cache", "skia budget", "used", 459fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes, "free", fMaxBytes - fBudgetedBytes); 460fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 461fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 462fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 463fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 464fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::purgeAsNeeded() { 465fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray<GrUniqueKeyInvalidatedMessage> invalidKeyMsgs; 466fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fInvalidUniqueKeyInbox.poll(&invalidKeyMsgs); 467fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (invalidKeyMsgs.count()) { 468fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->processInvalidUniqueKeys(invalidKeyMsgs); 469fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 470fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 471fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->processFreedGpuResources(); 472fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 473fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (fMaxUnusedFlushes > 0) { 474fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We want to know how many complete flushes have occurred without the resource being used. 475fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // If the resource was tagged when fExternalFlushCnt was N then this means it became 476fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // purgeable during activity that became the N+1th flush. So when the flush count is N+2 477fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // it has sat in the purgeable queue for one entire flush. 478fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint32_t oldestAllowedFlushCnt = fExternalFlushCnt - fMaxUnusedFlushes - 1; 479fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // check for underflow 480fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (oldestAllowedFlushCnt < fExternalFlushCnt) { 481fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (fPurgeableQueue.count()) { 482fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint32_t flushWhenResourceBecamePurgeable = 483fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableQueue.peek()->cacheAccess().flushCntWhenResourceBecamePurgeable(); 484fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (oldestAllowedFlushCnt < flushWhenResourceBecamePurgeable) { 485fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Resources were given both LRU timestamps and tagged with a flush cnt when 486fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // they first became purgeable. The LRU timestamp won't change again until the 487fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // resource is made non-purgeable again. So, at this point all the remaining 488fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // resources in the timestamp-sorted queue will have a flush count >= to this 489fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // one. 490fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 491fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 492fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* resource = fPurgeableQueue.peek(); 493fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource->isPurgeable()); 494fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().release(); 495fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 496fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 497fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 498fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 499fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool stillOverbudget = this->overBudget(); 500fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (stillOverbudget && fPurgeableQueue.count()) { 501fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* resource = fPurgeableQueue.peek(); 502fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource->isPurgeable()); 503fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().release(); 504fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stillOverbudget = this->overBudget(); 505fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 506fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 507fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 508fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 509fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (stillOverbudget) { 510fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Set this so that GrDrawingManager will issue a flush to free up resources with pending 511fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // IO that we were unable to purge in this pass. 512fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fRequestFlush = true; 513fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 514fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 515fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 516fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::purgeAllUnlocked() { 517fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // We could disable maintaining the heap property here, but it would add a lot of complexity. 518fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Moreover, this is rarely called. 519fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (fPurgeableQueue.count()) { 520fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* resource = fPurgeableQueue.peek(); 521fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource->isPurgeable()); 522fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().release(); 523fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 524fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 525fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 526fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 527fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 528fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::purgeResourcesNotUsedSince(GrStdSteadyClock::time_point purgeTime) { 529fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (fPurgeableQueue.count()) { 530fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrStdSteadyClock::time_point resourceTime = 531fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableQueue.peek()->cacheAccess().timeWhenResourceBecamePurgeable(); 532fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resourceTime >= purgeTime) { 533fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Resources were given both LRU timestamps and tagged with a frame number when 534fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // they first became purgeable. The LRU timestamp won't change again until the 535fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // resource is made non-purgeable again. So, at this point all the remaining 536fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // resources in the timestamp-sorted queue will have a frame number >= to this 537fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // one. 538fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 539fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 540fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* resource = fPurgeableQueue.peek(); 541fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource->isPurgeable()); 542fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->cacheAccess().release(); 543fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 544fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 545fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 546fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources) { 547fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 548fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const size_t tmpByteBudget = SkTMax((size_t)0, fBytes - bytesToPurge); 549fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot bool stillOverbudget = tmpByteBudget < fBytes; 550fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 551fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (preferScratchResources && bytesToPurge < fPurgeableBytes) { 552fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Sort the queue 553fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableQueue.sort(); 554fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 555fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Make a list of the scratch resources to delete 556fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTDArray<GrGpuResource*> scratchResources; 557fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t scratchByteCount = 0; 558fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fPurgeableQueue.count() && stillOverbudget; i++) { 559fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* resource = fPurgeableQueue.at(i); 560fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource->isPurgeable()); 561fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!resource->getUniqueKey().isValid()) { 562fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *scratchResources.append() = resource; 563fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot scratchByteCount += resource->gpuMemorySize(); 564fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stillOverbudget = tmpByteBudget < fBytes - scratchByteCount; 565fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 566fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 567fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 568fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Delete the scratch resources. This must be done as a separate pass 569fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // to avoid messing up the sorted order of the queue 570fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < scratchResources.count(); i++) { 571fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot scratchResources.getAt(i)->cacheAccess().release(); 572fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 573fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stillOverbudget = tmpByteBudget < fBytes; 574fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 575fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 576fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 577fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 578fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Purge any remaining resources in LRU order 579fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (stillOverbudget) { 580fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const size_t cachedByteCount = fMaxBytes; 581fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxBytes = tmpByteBudget; 582fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->purgeAsNeeded(); 583fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fMaxBytes = cachedByteCount; 584fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 585fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 586fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 587fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::processInvalidUniqueKeys( 588fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const SkTArray<GrUniqueKeyInvalidatedMessage>& msgs) { 589fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fProxyProvider); // better have called setProxyProvider 590fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 591fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < msgs.count(); ++i) { 592fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fProxyProvider->processInvalidProxyUniqueKey(msgs[i].key()); 593fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 594fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* resource = this->findAndRefUniqueResource(msgs[i].key()); 595fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource) { 596fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->resourcePriv().removeUniqueKey(); 597fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->unref(); // If this resource is now purgeable, the cache will be notified. 598fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 599fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 600fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 601fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 602fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::insertCrossContextGpuResource(GrGpuResource* resource) { 603fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->ref(); 604fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 605fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 606fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::processFreedGpuResources() { 607fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTArray<GrGpuResourceFreedMessage> msgs; 608fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fFreedGpuResourceInbox.poll(&msgs); 609fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < msgs.count(); ++i) { 610fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (msgs[i].fOwningUniqueID == fContextUniqueID) { 611fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot msgs[i].fResource->unref(); 612fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 613fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 614fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 615fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 616fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::addToNonpurgeableArray(GrGpuResource* resource) { 617fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int index = fNonpurgeableResources.count(); 618fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *fNonpurgeableResources.append() = resource; 619fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *resource->cacheAccess().accessCacheIndex() = index; 620fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 621fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 622fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::removeFromNonpurgeableArray(GrGpuResource* resource) { 623fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int* index = resource->cacheAccess().accessCacheIndex(); 624fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Fill the whole we will create in the array with the tail object, adjust its index, and 625fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // then pop the array 626fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot GrGpuResource* tail = *(fNonpurgeableResources.end() - 1); 627fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fNonpurgeableResources[*index] == resource); 628fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fNonpurgeableResources[*index] = tail; 629fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *tail->cacheAccess().accessCacheIndex() = *index; 630fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fNonpurgeableResources.pop(); 631fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGCODE(*index = -1); 632fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 633fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 634fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotuint32_t GrResourceCache::getNextTimestamp() { 635fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // If we wrap then all the existing resources will appear older than any resources that get 636fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // a timestamp after the wrap. 637fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (0 == fTimestamp) { 638fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int count = this->getResourceCount(); 639fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (count) { 640fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Reset all the timestamps. We sort the resources by timestamp and then assign 641fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // sequential timestamps beginning with 0. This is O(n*lg(n)) but it should be extremely 642fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // rare. 643fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTDArray<GrGpuResource*> sortedPurgeableResources; 644fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sortedPurgeableResources.setReserve(fPurgeableQueue.count()); 645fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 646fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (fPurgeableQueue.count()) { 647fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *sortedPurgeableResources.append() = fPurgeableQueue.peek(); 648fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableQueue.pop(); 649fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 650fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 651fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkTQSort(fNonpurgeableResources.begin(), fNonpurgeableResources.end() - 1, 652fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot CompareTimestamp); 653fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 654fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Pick resources out of the purgeable and non-purgeable arrays based on lowest 655fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // timestamp and assign new timestamps. 656fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int currP = 0; 657fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int currNP = 0; 658fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (currP < sortedPurgeableResources.count() && 659fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot currNP < fNonpurgeableResources.count()) { 660fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint32_t tsP = sortedPurgeableResources[currP]->cacheAccess().timestamp(); 661fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uint32_t tsNP = fNonpurgeableResources[currNP]->cacheAccess().timestamp(); 662fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(tsP != tsNP); 663fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (tsP < tsNP) { 664fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sortedPurgeableResources[currP++]->cacheAccess().setTimestamp(fTimestamp++); 665fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else { 666fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Correct the index in the nonpurgeable array stored on the resource post-sort. 667fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *fNonpurgeableResources[currNP]->cacheAccess().accessCacheIndex() = currNP; 668fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fNonpurgeableResources[currNP++]->cacheAccess().setTimestamp(fTimestamp++); 669fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 670fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 671fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 672fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // The above loop ended when we hit the end of one array. Finish the other one. 673fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (currP < sortedPurgeableResources.count()) { 674fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot sortedPurgeableResources[currP++]->cacheAccess().setTimestamp(fTimestamp++); 675fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 676fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot while (currNP < fNonpurgeableResources.count()) { 677fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot *fNonpurgeableResources[currNP]->cacheAccess().accessCacheIndex() = currNP; 678fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fNonpurgeableResources[currNP++]->cacheAccess().setTimestamp(fTimestamp++); 679fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 680fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 681fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Rebuild the queue. 682fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < sortedPurgeableResources.count(); ++i) { 683fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableQueue.insert(sortedPurgeableResources[i]); 684fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 685fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 686fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->validate(); 687fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(count == this->getResourceCount()); 688fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 689fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // count should be the next timestamp we return. 690fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fTimestamp == SkToU32(count)); 691fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 692fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 693fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return fTimestamp++; 694fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 695fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 696fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::notifyFlushOccurred(FlushType type) { 697fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot switch (type) { 698fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case FlushType::kCacheRequested: 699fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fRequestFlush); 700fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fRequestFlush = false; 701fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 702fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot case FlushType::kExternal: 703fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fExternalFlushCnt; 704fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (0 == fExternalFlushCnt) { 705fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // When this wraps just reset all the purgeable resources' last used flush state. 706fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fPurgeableQueue.count(); ++i) { 707fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableQueue.at(i)->cacheAccess().setFlushCntWhenResourceBecamePurgeable(0); 708fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 709fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 710fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot break; 711fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 712fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot this->purgeAsNeeded(); 713fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 714fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 715fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const { 716fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fNonpurgeableResources.count(); ++i) { 717fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fNonpurgeableResources[i]->dumpMemoryStatistics(traceMemoryDump); 718fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 719fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fPurgeableQueue.count(); ++i) { 720fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fPurgeableQueue.at(i)->dumpMemoryStatistics(traceMemoryDump); 721fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 722fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 723fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 724fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#ifdef SK_DEBUG 725fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotvoid GrResourceCache::validate() const { 726fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // Reduce the frequency of validations for large resource counts. 727fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot static SkRandom gRandom; 728fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int mask = (SkNextPow2(fCount + 1) >> 5) - 1; 729fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (~mask && (gRandom.nextU() & mask)) { 730fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return; 731fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 732fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 733fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot struct Stats { 734fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t fBytes; 735fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fBudgetedCount; 736fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t fBudgetedBytes; 737fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fLocked; 738fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fScratch; 739fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fCouldBeScratch; 740fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int fContent; 741fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const ScratchMap* fScratchMap; 742fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const UniqueHash* fUniqueHash; 743fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 744fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Stats(const GrResourceCache* cache) { 745fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot memset(this, 0, sizeof(*this)); 746fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fScratchMap = &cache->fScratchMap; 747fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fUniqueHash = &cache->fUniqueHash; 748fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 749fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 750fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot void update(GrGpuResource* resource) { 751fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBytes += resource->gpuMemorySize(); 752fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 753fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!resource->isPurgeable()) { 754fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fLocked; 755fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 756fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 757fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrScratchKey& scratchKey = resource->resourcePriv().getScratchKey(); 758fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrUniqueKey& uniqueKey = resource->getUniqueKey(); 759fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 760fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (resource->cacheAccess().isScratch()) { 761fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!uniqueKey.isValid()); 762fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fScratch; 763fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fScratchMap->countForKey(scratchKey)); 764fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!resource->resourcePriv().refsWrappedObjects()); 765fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } else if (scratchKey.isValid()) { 766fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(SkBudgeted::kNo == resource->resourcePriv().isBudgeted() || 767fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot uniqueKey.isValid()); 768fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (!uniqueKey.isValid()) { 769fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fCouldBeScratch; 770fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fScratchMap->countForKey(scratchKey)); 771fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 772fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!resource->resourcePriv().refsWrappedObjects()); 773fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 774fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (uniqueKey.isValid()) { 775fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fContent; 776fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fUniqueHash->find(uniqueKey) == resource); 777fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(SkBudgeted::kYes == resource->resourcePriv().isBudgeted() || 778fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot resource->resourcePriv().refsWrappedObjects()); 779fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 780fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (scratchKey.isValid()) { 781fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fScratchMap->has(resource, scratchKey)); 782fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 783fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 784fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 785fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (SkBudgeted::kYes == resource->resourcePriv().isBudgeted()) { 786fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ++fBudgetedCount; 787fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fBudgetedBytes += resource->gpuMemorySize(); 788fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 789fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 790fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot }; 791fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 792fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot { 793fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot ScratchMap::ConstIter iter(&fScratchMap); 794fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 795fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int count = 0; 796fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for ( ; !iter.done(); ++iter) { 797fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot const GrGpuResource* resource = *iter; 798fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(resource->resourcePriv().getScratchKey().isValid()); 799fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!resource->getUniqueKey().isValid()); 800fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot count++; 801fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 802fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(count == fScratchMap.count()); // ensure the iterator is working correctly 803fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 804fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 805fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot Stats stats(this); 806fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot size_t purgeableBytes = 0; 807fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 808fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fNonpurgeableResources.count(); ++i) { 809fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fNonpurgeableResources[i]->isPurgeable() || 810fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot fNewlyPurgeableResourceForValidation == fNonpurgeableResources[i]); 811fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(*fNonpurgeableResources[i]->cacheAccess().accessCacheIndex() == i); 812fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fNonpurgeableResources[i]->wasDestroyed()); 813fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stats.update(fNonpurgeableResources[i]); 814fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 815fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot for (int i = 0; i < fPurgeableQueue.count(); ++i) { 816fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fPurgeableQueue.at(i)->isPurgeable()); 817fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(*fPurgeableQueue.at(i)->cacheAccess().accessCacheIndex() == i); 818fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(!fPurgeableQueue.at(i)->wasDestroyed()); 819fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot stats.update(fPurgeableQueue.at(i)); 820fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot purgeableBytes += fPurgeableQueue.at(i)->gpuMemorySize(); 821fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 822fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 823fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fCount == this->getResourceCount()); 824fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fBudgetedCount <= fCount); 825fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fBudgetedBytes <= fBytes); 826fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(stats.fBytes == fBytes); 827fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(stats.fBudgetedBytes == fBudgetedBytes); 828fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(stats.fBudgetedCount == fBudgetedCount); 829fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(purgeableBytes == fPurgeableBytes); 830fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#if GR_CACHE_STATS 831fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fBudgetedHighWaterCount <= fHighWaterCount); 832fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fBudgetedHighWaterBytes <= fHighWaterBytes); 833fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fBytes <= fHighWaterBytes); 834fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fCount <= fHighWaterCount); 835fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fBudgetedBytes <= fBudgetedHighWaterBytes); 836fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(fBudgetedCount <= fBudgetedHighWaterCount); 837fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 838fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(stats.fContent == fUniqueHash.count()); 839fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkASSERT(stats.fScratch + stats.fCouldBeScratch == fScratchMap.count()); 840fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 841fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // This assertion is not currently valid because we can be in recursive notifyCntReachedZero() 842fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // calls. This will be fixed when subresource registration is explicit. 843fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // bool overBudget = budgetedBytes > fMaxBytes || budgetedCount > fMaxCount; 844fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot // SkASSERT(!overBudget || locked == count || fPurging); 845fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 846fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 847fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robotbool GrResourceCache::isInCache(const GrGpuResource* resource) const { 848fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot int index = *resource->cacheAccess().accessCacheIndex(); 849fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (index < 0) { 850fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 851fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 852fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (index < fPurgeableQueue.count() && fPurgeableQueue.at(index) == resource) { 853fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 854fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 855fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot if (index < fNonpurgeableResources.count() && fNonpurgeableResources[index] == resource) { 856fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return true; 857fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot } 858fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot SkDEBUGFAIL("Resource index should be -1 or the resource should be in the cache."); 859fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot return false; 860fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot} 861fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot 862fe17456d5e528078ce69b5f15cf7adf1fab963fandroid-build-team Robot#endif 863