1 /* 2 * Copyright 2014 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef GrGpuResourceCacheAccess_DEFINED 9 #define GrGpuResourceCacheAccess_DEFINED 10 11 #include "src/gpu/GrGpuResource.h" 12 #include "src/gpu/GrGpuResourcePriv.h" 13 14 namespace skiatest { 15 class Reporter; 16 } // namespace skiatest 17 18 /** 19 * This class allows GrResourceCache increased privileged access to GrGpuResource objects. 20 */ 21 class GrGpuResource::CacheAccess { 22 private: 23 /** The cache is allowed to go from no refs to 1 ref. */ ref()24 void ref() { fResource->addInitialRef(); } 25 26 /** 27 * Is the resource currently cached as scratch? This means it is cached, has a valid scratch 28 * key, and does not have a unique key. 29 */ isScratch()30 bool isScratch() const { 31 return !fResource->getUniqueKey().isValid() && fResource->fScratchKey.isValid() && 32 GrBudgetedType::kBudgeted == fResource->resourcePriv().budgetedType(); 33 } 34 isUsableAsScratch()35 bool isUsableAsScratch() const { 36 return this->isScratch() && !fResource->internalHasRef(); 37 } 38 39 /** 40 * Called by the cache to delete the resource under normal circumstances. 41 */ release()42 void release() { 43 fResource->release(); 44 if (!fResource->hasRef() && fResource->hasNoCommandBufferUsages()) { 45 delete fResource; 46 fResource = nullptr; 47 } 48 } 49 50 /** 51 * Called by the cache to delete the resource when the backend 3D context is no longer valid. 52 */ abandon()53 void abandon() { 54 fResource->abandon(); 55 if (!fResource->hasRef() && fResource->hasNoCommandBufferUsages()) { 56 delete fResource; 57 } 58 } 59 60 /** Called by the cache to assign a new unique key. */ setUniqueKey(const GrUniqueKey & key)61 void setUniqueKey(const GrUniqueKey& key) { fResource->fUniqueKey = key; } 62 63 /** Is the resource ref'ed */ hasRef()64 bool hasRef() const { return fResource->hasRef(); } hasRefOrCommandBufferUsage()65 bool hasRefOrCommandBufferUsage() const { 66 return this->hasRef() || !fResource->hasNoCommandBufferUsages(); 67 } 68 69 /** Called by the cache to make the unique key invalid. */ removeUniqueKey()70 void removeUniqueKey() { fResource->fUniqueKey.reset(); } 71 timestamp()72 uint32_t timestamp() const { return fResource->fTimestamp; } setTimestamp(uint32_t ts)73 void setTimestamp(uint32_t ts) { fResource->fTimestamp = ts; } 74 setTimeWhenResourceBecomePurgeable()75 void setTimeWhenResourceBecomePurgeable() { 76 SkASSERT(fResource->isPurgeable()); 77 fResource->fTimeWhenBecamePurgeable = GrStdSteadyClock::now(); 78 } 79 /** 80 * Called by the cache to determine whether this resource should be purged based on the length 81 * of time it has been available for purging. 82 */ timeWhenResourceBecamePurgeable()83 GrStdSteadyClock::time_point timeWhenResourceBecamePurgeable() { 84 SkASSERT(fResource->isPurgeable()); 85 return fResource->fTimeWhenBecamePurgeable; 86 } 87 accessCacheIndex()88 int* accessCacheIndex() const { return &fResource->fCacheArrayIndex; } 89 CacheAccess(GrGpuResource * resource)90 CacheAccess(GrGpuResource* resource) : fResource(resource) {} CacheAccess(const CacheAccess & that)91 CacheAccess(const CacheAccess& that) : fResource(that.fResource) {} 92 CacheAccess& operator=(const CacheAccess&) = delete; 93 94 // No taking addresses of this type. 95 const CacheAccess* operator&() const = delete; 96 CacheAccess* operator&() = delete; 97 98 GrGpuResource* fResource; 99 100 friend class GrGpuResource; // to construct/copy this type. 101 friend class GrResourceCache; // to use this type 102 friend void test_unbudgeted_to_scratch(skiatest::Reporter* reporter); // for unit testing 103 }; 104 cacheAccess()105inline GrGpuResource::CacheAccess GrGpuResource::cacheAccess() { return CacheAccess(this); } 106 cacheAccess()107inline const GrGpuResource::CacheAccess GrGpuResource::cacheAccess() const { // NOLINT(readability-const-return-type) 108 return CacheAccess(const_cast<GrGpuResource*>(this)); 109 } 110 111 #endif 112