1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 #include "GrGpuResource.h" 10 #include "GrResourceCache.h" 11 #include "GrGpu.h" 12 #include "GrGpuResourcePriv.h" 13 get_resource_cache(GrGpu * gpu)14static inline GrResourceCache* get_resource_cache(GrGpu* gpu) { 15 SkASSERT(gpu); 16 SkASSERT(gpu->getContext()); 17 SkASSERT(gpu->getContext()->getResourceCache()); 18 return gpu->getContext()->getResourceCache(); 19 } 20 GrGpuResource(GrGpu * gpu,LifeCycle lifeCycle)21GrGpuResource::GrGpuResource(GrGpu* gpu, LifeCycle lifeCycle) 22 : fGpu(gpu) 23 , fGpuMemorySize(kInvalidGpuMemorySize) 24 , fLifeCycle(lifeCycle) 25 , fUniqueID(CreateUniqueID()) { 26 SkDEBUGCODE(fCacheArrayIndex = -1); 27 } 28 registerWithCache()29void GrGpuResource::registerWithCache() { 30 get_resource_cache(fGpu)->resourceAccess().insertResource(this); 31 } 32 ~GrGpuResource()33GrGpuResource::~GrGpuResource() { 34 // The cache should have released or destroyed this resource. 35 SkASSERT(this->wasDestroyed()); 36 } 37 release()38void GrGpuResource::release() { 39 SkASSERT(fGpu); 40 this->onRelease(); 41 get_resource_cache(fGpu)->resourceAccess().removeResource(this); 42 fGpu = NULL; 43 fGpuMemorySize = 0; 44 } 45 abandon()46void GrGpuResource::abandon() { 47 SkASSERT(fGpu); 48 this->onAbandon(); 49 get_resource_cache(fGpu)->resourceAccess().removeResource(this); 50 fGpu = NULL; 51 fGpuMemorySize = 0; 52 } 53 setCustomData(const SkData * data)54const SkData* GrGpuResource::setCustomData(const SkData* data) { 55 SkSafeRef(data); 56 fData.reset(data); 57 return data; 58 } 59 getContext() const60const GrContext* GrGpuResource::getContext() const { 61 if (fGpu) { 62 return fGpu->getContext(); 63 } else { 64 return NULL; 65 } 66 } 67 getContext()68GrContext* GrGpuResource::getContext() { 69 if (fGpu) { 70 return fGpu->getContext(); 71 } else { 72 return NULL; 73 } 74 } 75 didChangeGpuMemorySize() const76void GrGpuResource::didChangeGpuMemorySize() const { 77 if (this->wasDestroyed()) { 78 return; 79 } 80 81 size_t oldSize = fGpuMemorySize; 82 SkASSERT(kInvalidGpuMemorySize != oldSize); 83 fGpuMemorySize = kInvalidGpuMemorySize; 84 get_resource_cache(fGpu)->resourceAccess().didChangeGpuMemorySize(this, oldSize); 85 } 86 removeUniqueKey()87void GrGpuResource::removeUniqueKey() { 88 SkASSERT(fUniqueKey.isValid()); 89 get_resource_cache(fGpu)->resourceAccess().removeUniqueKey(this); 90 } 91 setUniqueKey(const GrUniqueKey & key)92void GrGpuResource::setUniqueKey(const GrUniqueKey& key) { 93 SkASSERT(this->internalHasRef()); 94 SkASSERT(key.isValid()); 95 96 // Wrapped and uncached resources can never have a unique key. 97 if (!this->resourcePriv().isBudgeted()) { 98 return; 99 } 100 101 if (this->wasDestroyed()) { 102 return; 103 } 104 105 get_resource_cache(fGpu)->resourceAccess().changeUniqueKey(this, key); 106 } 107 notifyAllCntsAreZero(CntType lastCntTypeToReachZero) const108void GrGpuResource::notifyAllCntsAreZero(CntType lastCntTypeToReachZero) const { 109 if (this->wasDestroyed()) { 110 // We've already been removed from the cache. Goodbye cruel world! 111 SkDELETE(this); 112 return; 113 } 114 115 // We should have already handled this fully in notifyRefCntIsZero(). 116 SkASSERT(kRef_CntType != lastCntTypeToReachZero); 117 118 GrGpuResource* mutableThis = const_cast<GrGpuResource*>(this); 119 static const uint32_t kFlag = 120 GrResourceCache::ResourceAccess::kAllCntsReachedZero_RefNotificationFlag; 121 get_resource_cache(fGpu)->resourceAccess().notifyCntReachedZero(mutableThis, kFlag); 122 } 123 notifyRefCountIsZero() const124bool GrGpuResource::notifyRefCountIsZero() const { 125 if (this->wasDestroyed()) { 126 // handle this in notifyAllCntsAreZero(). 127 return true; 128 } 129 130 GrGpuResource* mutableThis = const_cast<GrGpuResource*>(this); 131 uint32_t flags = 132 GrResourceCache::ResourceAccess::kRefCntReachedZero_RefNotificationFlag; 133 if (!this->internalHasPendingIO()) { 134 flags |= GrResourceCache::ResourceAccess::kAllCntsReachedZero_RefNotificationFlag; 135 } 136 get_resource_cache(fGpu)->resourceAccess().notifyCntReachedZero(mutableThis, flags); 137 138 // There is no need to call our notifyAllCntsAreZero function at this point since we already 139 // told the cache about the state of cnts. 140 return false; 141 } 142 setScratchKey(const GrScratchKey & scratchKey)143void GrGpuResource::setScratchKey(const GrScratchKey& scratchKey) { 144 SkASSERT(!fScratchKey.isValid()); 145 SkASSERT(scratchKey.isValid()); 146 // Wrapped resources can never have a scratch key. 147 if (this->isWrapped()) { 148 return; 149 } 150 fScratchKey = scratchKey; 151 } 152 removeScratchKey()153void GrGpuResource::removeScratchKey() { 154 if (!this->wasDestroyed() && fScratchKey.isValid()) { 155 get_resource_cache(fGpu)->resourceAccess().willRemoveScratchKey(this); 156 fScratchKey.reset(); 157 } 158 } 159 makeBudgeted()160void GrGpuResource::makeBudgeted() { 161 if (GrGpuResource::kUncached_LifeCycle == fLifeCycle) { 162 fLifeCycle = kCached_LifeCycle; 163 get_resource_cache(fGpu)->resourceAccess().didChangeBudgetStatus(this); 164 } 165 } 166 makeUnbudgeted()167void GrGpuResource::makeUnbudgeted() { 168 if (GrGpuResource::kCached_LifeCycle == fLifeCycle && !fUniqueKey.isValid()) { 169 fLifeCycle = kUncached_LifeCycle; 170 get_resource_cache(fGpu)->resourceAccess().didChangeBudgetStatus(this); 171 } 172 } 173 CreateUniqueID()174uint32_t GrGpuResource::CreateUniqueID() { 175 static int32_t gUniqueID = SK_InvalidUniqueID; 176 uint32_t id; 177 do { 178 id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1); 179 } while (id == SK_InvalidUniqueID); 180 return id; 181 } 182