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