xref: /aosp_15_r20/external/skia/src/gpu/ganesh/GrGpuResource.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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 GrGpuResource_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define GrGpuResource_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkString.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypes.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkNoncopyable.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/gpu/ganesh/GrTypesPriv.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/GpuTypesPriv.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/ResourceKey.h"
18*c8dee2aaSAndroid Build Coastguard Worker 
19*c8dee2aaSAndroid Build Coastguard Worker #include <atomic>
20*c8dee2aaSAndroid Build Coastguard Worker #include <cstddef>
21*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
22*c8dee2aaSAndroid Build Coastguard Worker #include <string>
23*c8dee2aaSAndroid Build Coastguard Worker #include <string_view>
24*c8dee2aaSAndroid Build Coastguard Worker 
25*c8dee2aaSAndroid Build Coastguard Worker class GrDirectContext;
26*c8dee2aaSAndroid Build Coastguard Worker class GrGpu;
27*c8dee2aaSAndroid Build Coastguard Worker class GrResourceCache;
28*c8dee2aaSAndroid Build Coastguard Worker class GrSurface;
29*c8dee2aaSAndroid Build Coastguard Worker class SkTraceMemoryDump;
30*c8dee2aaSAndroid Build Coastguard Worker 
31*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu {
32*c8dee2aaSAndroid Build Coastguard Worker enum class Budgeted : bool;
33*c8dee2aaSAndroid Build Coastguard Worker }
34*c8dee2aaSAndroid Build Coastguard Worker 
35*c8dee2aaSAndroid Build Coastguard Worker /**
36*c8dee2aaSAndroid Build Coastguard Worker  * Base class for GrGpuResource. Provides the hooks for resources to interact with the cache.
37*c8dee2aaSAndroid Build Coastguard Worker  * Separated out as a base class to isolate the ref-cnting behavior and provide friendship without
38*c8dee2aaSAndroid Build Coastguard Worker  * exposing all of GrGpuResource.
39*c8dee2aaSAndroid Build Coastguard Worker  *
40*c8dee2aaSAndroid Build Coastguard Worker  * PRIOR to the last ref being removed DERIVED::notifyARefCntWillBeZero() will be called
41*c8dee2aaSAndroid Build Coastguard Worker  * (static poly morphism using CRTP). It is legal for additional ref's to be added
42*c8dee2aaSAndroid Build Coastguard Worker  * during this time. AFTER the ref count reaches zero DERIVED::notifyARefCntIsZero() will be
43*c8dee2aaSAndroid Build Coastguard Worker  * called.
44*c8dee2aaSAndroid Build Coastguard Worker  */
45*c8dee2aaSAndroid Build Coastguard Worker template <typename DERIVED> class GrIORef : public SkNoncopyable {
46*c8dee2aaSAndroid Build Coastguard Worker public:
unique()47*c8dee2aaSAndroid Build Coastguard Worker     bool unique() const { return fRefCnt == 1; }
48*c8dee2aaSAndroid Build Coastguard Worker 
ref()49*c8dee2aaSAndroid Build Coastguard Worker     void ref() const {
50*c8dee2aaSAndroid Build Coastguard Worker         // Only the cache should be able to add the first ref to a resource.
51*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(this->getRefCnt() > 0);
52*c8dee2aaSAndroid Build Coastguard Worker         // No barrier required.
53*c8dee2aaSAndroid Build Coastguard Worker         (void)fRefCnt.fetch_add(+1, std::memory_order_relaxed);
54*c8dee2aaSAndroid Build Coastguard Worker     }
55*c8dee2aaSAndroid Build Coastguard Worker 
56*c8dee2aaSAndroid Build Coastguard Worker     // This enum is used to notify the GrResourceCache which type of ref just dropped to zero.
57*c8dee2aaSAndroid Build Coastguard Worker     enum class LastRemovedRef {
58*c8dee2aaSAndroid Build Coastguard Worker         kMainRef,            // This refers to fRefCnt
59*c8dee2aaSAndroid Build Coastguard Worker         kCommandBufferUsage, // This refers to fCommandBufferUsageCnt
60*c8dee2aaSAndroid Build Coastguard Worker     };
61*c8dee2aaSAndroid Build Coastguard Worker 
unref()62*c8dee2aaSAndroid Build Coastguard Worker     void unref() const {
63*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(this->getRefCnt() > 0);
64*c8dee2aaSAndroid Build Coastguard Worker         if (1 == fRefCnt.fetch_add(-1, std::memory_order_acq_rel)) {
65*c8dee2aaSAndroid Build Coastguard Worker             this->notifyWillBeZero(LastRemovedRef::kMainRef);
66*c8dee2aaSAndroid Build Coastguard Worker         }
67*c8dee2aaSAndroid Build Coastguard Worker     }
68*c8dee2aaSAndroid Build Coastguard Worker 
refCommandBuffer()69*c8dee2aaSAndroid Build Coastguard Worker     void refCommandBuffer() const {
70*c8dee2aaSAndroid Build Coastguard Worker         // No barrier required.
71*c8dee2aaSAndroid Build Coastguard Worker         (void)fCommandBufferUsageCnt.fetch_add(+1, std::memory_order_relaxed);
72*c8dee2aaSAndroid Build Coastguard Worker     }
73*c8dee2aaSAndroid Build Coastguard Worker 
unrefCommandBuffer()74*c8dee2aaSAndroid Build Coastguard Worker     void unrefCommandBuffer() const {
75*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(!this->hasNoCommandBufferUsages());
76*c8dee2aaSAndroid Build Coastguard Worker         if (1 == fCommandBufferUsageCnt.fetch_add(-1, std::memory_order_acq_rel)) {
77*c8dee2aaSAndroid Build Coastguard Worker             this->notifyWillBeZero(LastRemovedRef::kCommandBufferUsage);
78*c8dee2aaSAndroid Build Coastguard Worker         }
79*c8dee2aaSAndroid Build Coastguard Worker     }
80*c8dee2aaSAndroid Build Coastguard Worker 
81*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
testingOnly_getRefCnt()82*c8dee2aaSAndroid Build Coastguard Worker     int32_t testingOnly_getRefCnt() const { return this->getRefCnt(); }
83*c8dee2aaSAndroid Build Coastguard Worker #endif
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker protected:
GrIORef()86*c8dee2aaSAndroid Build Coastguard Worker     GrIORef() : fRefCnt(1), fCommandBufferUsageCnt(0) {}
87*c8dee2aaSAndroid Build Coastguard Worker 
internalHasRef()88*c8dee2aaSAndroid Build Coastguard Worker     bool internalHasRef() const { return SkToBool(this->getRefCnt()); }
internalHasNoCommandBufferUsages()89*c8dee2aaSAndroid Build Coastguard Worker     bool internalHasNoCommandBufferUsages() const {
90*c8dee2aaSAndroid Build Coastguard Worker         return SkToBool(this->hasNoCommandBufferUsages());
91*c8dee2aaSAndroid Build Coastguard Worker     }
92*c8dee2aaSAndroid Build Coastguard Worker 
93*c8dee2aaSAndroid Build Coastguard Worker     // Privileged method that allows going from ref count = 0 to ref count = 1.
addInitialRef()94*c8dee2aaSAndroid Build Coastguard Worker     void addInitialRef() const {
95*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(fRefCnt >= 0);
96*c8dee2aaSAndroid Build Coastguard Worker         // No barrier required.
97*c8dee2aaSAndroid Build Coastguard Worker         (void)fRefCnt.fetch_add(+1, std::memory_order_relaxed);
98*c8dee2aaSAndroid Build Coastguard Worker     }
99*c8dee2aaSAndroid Build Coastguard Worker 
100*c8dee2aaSAndroid Build Coastguard Worker private:
notifyWillBeZero(LastRemovedRef removedRef)101*c8dee2aaSAndroid Build Coastguard Worker     void notifyWillBeZero(LastRemovedRef removedRef) const {
102*c8dee2aaSAndroid Build Coastguard Worker         static_cast<const DERIVED*>(this)->notifyARefCntIsZero(removedRef);
103*c8dee2aaSAndroid Build Coastguard Worker     }
104*c8dee2aaSAndroid Build Coastguard Worker 
getRefCnt()105*c8dee2aaSAndroid Build Coastguard Worker     int32_t getRefCnt() const { return fRefCnt.load(std::memory_order_relaxed); }
106*c8dee2aaSAndroid Build Coastguard Worker 
hasNoCommandBufferUsages()107*c8dee2aaSAndroid Build Coastguard Worker     bool hasNoCommandBufferUsages() const {
108*c8dee2aaSAndroid Build Coastguard Worker         if (0 == fCommandBufferUsageCnt.load(std::memory_order_acquire)) {
109*c8dee2aaSAndroid Build Coastguard Worker             // The acquire barrier is only really needed if we return true.  It
110*c8dee2aaSAndroid Build Coastguard Worker             // prevents code conditioned on the result of hasNoCommandBufferUsages() from running
111*c8dee2aaSAndroid Build Coastguard Worker             // until previous owners are all totally done calling removeCommandBufferUsage().
112*c8dee2aaSAndroid Build Coastguard Worker             return true;
113*c8dee2aaSAndroid Build Coastguard Worker         }
114*c8dee2aaSAndroid Build Coastguard Worker         return false;
115*c8dee2aaSAndroid Build Coastguard Worker     }
116*c8dee2aaSAndroid Build Coastguard Worker 
117*c8dee2aaSAndroid Build Coastguard Worker     mutable std::atomic<int32_t> fRefCnt;
118*c8dee2aaSAndroid Build Coastguard Worker     mutable std::atomic<int32_t> fCommandBufferUsageCnt;
119*c8dee2aaSAndroid Build Coastguard Worker 
120*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = SkNoncopyable;
121*c8dee2aaSAndroid Build Coastguard Worker };
122*c8dee2aaSAndroid Build Coastguard Worker 
123*c8dee2aaSAndroid Build Coastguard Worker /**
124*c8dee2aaSAndroid Build Coastguard Worker  * Base class for objects that can be kept in the GrResourceCache.
125*c8dee2aaSAndroid Build Coastguard Worker  */
126*c8dee2aaSAndroid Build Coastguard Worker class GrGpuResource : public GrIORef<GrGpuResource> {
127*c8dee2aaSAndroid Build Coastguard Worker public:
128*c8dee2aaSAndroid Build Coastguard Worker     /**
129*c8dee2aaSAndroid Build Coastguard Worker      * Tests whether a object has been abandoned or released. All objects will
130*c8dee2aaSAndroid Build Coastguard Worker      * be in this state after their creating GrContext is destroyed or has
131*c8dee2aaSAndroid Build Coastguard Worker      * contextLost called. It's up to the client to test wasDestroyed() before
132*c8dee2aaSAndroid Build Coastguard Worker      * attempting to use an object if it holds refs on objects across
133*c8dee2aaSAndroid Build Coastguard Worker      * ~GrContext, freeResources with the force flag, or contextLost.
134*c8dee2aaSAndroid Build Coastguard Worker      *
135*c8dee2aaSAndroid Build Coastguard Worker      * @return true if the object has been released or abandoned,
136*c8dee2aaSAndroid Build Coastguard Worker      *         false otherwise.
137*c8dee2aaSAndroid Build Coastguard Worker      */
wasDestroyed()138*c8dee2aaSAndroid Build Coastguard Worker     bool wasDestroyed() const { return nullptr == fGpu; }
139*c8dee2aaSAndroid Build Coastguard Worker 
140*c8dee2aaSAndroid Build Coastguard Worker     /**
141*c8dee2aaSAndroid Build Coastguard Worker      * Retrieves the context that owns the object. Note that it is possible for
142*c8dee2aaSAndroid Build Coastguard Worker      * this to return NULL. When objects have been release()ed or abandon()ed
143*c8dee2aaSAndroid Build Coastguard Worker      * they no longer have an owning context. Destroying a GrDirectContext
144*c8dee2aaSAndroid Build Coastguard Worker      * automatically releases all its resources.
145*c8dee2aaSAndroid Build Coastguard Worker      */
146*c8dee2aaSAndroid Build Coastguard Worker     const GrDirectContext* getContext() const;
147*c8dee2aaSAndroid Build Coastguard Worker     GrDirectContext* getContext();
148*c8dee2aaSAndroid Build Coastguard Worker 
149*c8dee2aaSAndroid Build Coastguard Worker     /**
150*c8dee2aaSAndroid Build Coastguard Worker      * Retrieves the amount of GPU memory used by this resource in bytes. It is
151*c8dee2aaSAndroid Build Coastguard Worker      * approximate since we aren't aware of additional padding or copies made
152*c8dee2aaSAndroid Build Coastguard Worker      * by the driver.
153*c8dee2aaSAndroid Build Coastguard Worker      *
154*c8dee2aaSAndroid Build Coastguard Worker      * @return the amount of GPU memory used in bytes
155*c8dee2aaSAndroid Build Coastguard Worker      */
gpuMemorySize()156*c8dee2aaSAndroid Build Coastguard Worker     size_t gpuMemorySize() const {
157*c8dee2aaSAndroid Build Coastguard Worker         if (kInvalidGpuMemorySize == fGpuMemorySize) {
158*c8dee2aaSAndroid Build Coastguard Worker             fGpuMemorySize = this->onGpuMemorySize();
159*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT(kInvalidGpuMemorySize != fGpuMemorySize);
160*c8dee2aaSAndroid Build Coastguard Worker         }
161*c8dee2aaSAndroid Build Coastguard Worker         return fGpuMemorySize;
162*c8dee2aaSAndroid Build Coastguard Worker     }
163*c8dee2aaSAndroid Build Coastguard Worker 
164*c8dee2aaSAndroid Build Coastguard Worker     class UniqueID {
165*c8dee2aaSAndroid Build Coastguard Worker     public:
166*c8dee2aaSAndroid Build Coastguard Worker         UniqueID() = default;
167*c8dee2aaSAndroid Build Coastguard Worker 
UniqueID(uint32_t id)168*c8dee2aaSAndroid Build Coastguard Worker         explicit UniqueID(uint32_t id) : fID(id) {}
169*c8dee2aaSAndroid Build Coastguard Worker 
asUInt()170*c8dee2aaSAndroid Build Coastguard Worker         uint32_t asUInt() const { return fID; }
171*c8dee2aaSAndroid Build Coastguard Worker 
172*c8dee2aaSAndroid Build Coastguard Worker         bool operator==(const UniqueID& other) const { return fID == other.fID; }
173*c8dee2aaSAndroid Build Coastguard Worker         bool operator!=(const UniqueID& other) const { return !(*this == other); }
174*c8dee2aaSAndroid Build Coastguard Worker 
makeInvalid()175*c8dee2aaSAndroid Build Coastguard Worker         void makeInvalid() { fID = SK_InvalidUniqueID; }
isInvalid()176*c8dee2aaSAndroid Build Coastguard Worker         bool isInvalid() const { return  fID == SK_InvalidUniqueID; }
177*c8dee2aaSAndroid Build Coastguard Worker 
178*c8dee2aaSAndroid Build Coastguard Worker     protected:
179*c8dee2aaSAndroid Build Coastguard Worker         uint32_t fID = SK_InvalidUniqueID;
180*c8dee2aaSAndroid Build Coastguard Worker     };
181*c8dee2aaSAndroid Build Coastguard Worker 
182*c8dee2aaSAndroid Build Coastguard Worker     /**
183*c8dee2aaSAndroid Build Coastguard Worker      * Gets an id that is unique for this GrGpuResource object. It is static in that it does
184*c8dee2aaSAndroid Build Coastguard Worker      * not change when the content of the GrGpuResource object changes. This will never return
185*c8dee2aaSAndroid Build Coastguard Worker      * 0.
186*c8dee2aaSAndroid Build Coastguard Worker      */
uniqueID()187*c8dee2aaSAndroid Build Coastguard Worker     UniqueID uniqueID() const { return fUniqueID; }
188*c8dee2aaSAndroid Build Coastguard Worker 
189*c8dee2aaSAndroid Build Coastguard Worker     /** Returns the current unique key for the resource. It will be invalid if the resource has no
190*c8dee2aaSAndroid Build Coastguard Worker         associated unique key. */
getUniqueKey()191*c8dee2aaSAndroid Build Coastguard Worker     const skgpu::UniqueKey& getUniqueKey() const { return fUniqueKey; }
192*c8dee2aaSAndroid Build Coastguard Worker 
getLabel()193*c8dee2aaSAndroid Build Coastguard Worker     std::string getLabel() const { return fLabel; }
194*c8dee2aaSAndroid Build Coastguard Worker 
setLabel(std::string_view label)195*c8dee2aaSAndroid Build Coastguard Worker     void setLabel(std::string_view label) {
196*c8dee2aaSAndroid Build Coastguard Worker         fLabel = label;
197*c8dee2aaSAndroid Build Coastguard Worker         this->onSetLabel();
198*c8dee2aaSAndroid Build Coastguard Worker     }
199*c8dee2aaSAndroid Build Coastguard Worker 
200*c8dee2aaSAndroid Build Coastguard Worker     /**
201*c8dee2aaSAndroid Build Coastguard Worker      * Internal-only helper class used for manipulations of the resource by the cache.
202*c8dee2aaSAndroid Build Coastguard Worker      */
203*c8dee2aaSAndroid Build Coastguard Worker     class CacheAccess;
204*c8dee2aaSAndroid Build Coastguard Worker     inline CacheAccess cacheAccess();
205*c8dee2aaSAndroid Build Coastguard Worker     inline const CacheAccess cacheAccess() const;  // NOLINT(readability-const-return-type)
206*c8dee2aaSAndroid Build Coastguard Worker 
207*c8dee2aaSAndroid Build Coastguard Worker     /**
208*c8dee2aaSAndroid Build Coastguard Worker      * Internal-only helper class used for manipulations of the resource by GrSurfaceProxy.
209*c8dee2aaSAndroid Build Coastguard Worker      */
210*c8dee2aaSAndroid Build Coastguard Worker     class ProxyAccess;
211*c8dee2aaSAndroid Build Coastguard Worker     inline ProxyAccess proxyAccess();
212*c8dee2aaSAndroid Build Coastguard Worker 
213*c8dee2aaSAndroid Build Coastguard Worker     /**
214*c8dee2aaSAndroid Build Coastguard Worker      * Internal-only helper class used for manipulations of the resource by internal code.
215*c8dee2aaSAndroid Build Coastguard Worker      */
216*c8dee2aaSAndroid Build Coastguard Worker     class ResourcePriv;
217*c8dee2aaSAndroid Build Coastguard Worker     inline ResourcePriv resourcePriv();
218*c8dee2aaSAndroid Build Coastguard Worker     inline const ResourcePriv resourcePriv() const;  // NOLINT(readability-const-return-type)
219*c8dee2aaSAndroid Build Coastguard Worker 
220*c8dee2aaSAndroid Build Coastguard Worker     /**
221*c8dee2aaSAndroid Build Coastguard Worker      * Dumps memory usage information for this GrGpuResource to traceMemoryDump.
222*c8dee2aaSAndroid Build Coastguard Worker      * Typically, subclasses should not need to override this, and should only
223*c8dee2aaSAndroid Build Coastguard Worker      * need to override setMemoryBacking.
224*c8dee2aaSAndroid Build Coastguard Worker      **/
225*c8dee2aaSAndroid Build Coastguard Worker     virtual void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
226*c8dee2aaSAndroid Build Coastguard Worker 
227*c8dee2aaSAndroid Build Coastguard Worker     /**
228*c8dee2aaSAndroid Build Coastguard Worker      * Describes the type of gpu resource that is represented by the implementing
229*c8dee2aaSAndroid Build Coastguard Worker      * class (e.g. texture, buffer object, stencil).  This data is used for diagnostic
230*c8dee2aaSAndroid Build Coastguard Worker      * purposes by dumpMemoryStatistics().
231*c8dee2aaSAndroid Build Coastguard Worker      *
232*c8dee2aaSAndroid Build Coastguard Worker      * The value returned is expected to be long lived and will not be copied by the caller.
233*c8dee2aaSAndroid Build Coastguard Worker      */
234*c8dee2aaSAndroid Build Coastguard Worker     virtual const char* getResourceType() const = 0;
235*c8dee2aaSAndroid Build Coastguard Worker 
236*c8dee2aaSAndroid Build Coastguard Worker     static uint32_t CreateUniqueID();
237*c8dee2aaSAndroid Build Coastguard Worker 
238*c8dee2aaSAndroid Build Coastguard Worker #if defined(GPU_TEST_UTILS)
asSurface()239*c8dee2aaSAndroid Build Coastguard Worker     virtual const GrSurface* asSurface() const { return nullptr; }
240*c8dee2aaSAndroid Build Coastguard Worker #endif
241*c8dee2aaSAndroid Build Coastguard Worker 
242*c8dee2aaSAndroid Build Coastguard Worker protected:
243*c8dee2aaSAndroid Build Coastguard Worker     // This must be called by every non-wrapped GrGpuObject. It should be called once the object is
244*c8dee2aaSAndroid Build Coastguard Worker     // fully initialized (i.e. only from the constructors of the final class).
245*c8dee2aaSAndroid Build Coastguard Worker     void registerWithCache(skgpu::Budgeted);
246*c8dee2aaSAndroid Build Coastguard Worker 
247*c8dee2aaSAndroid Build Coastguard Worker     // This must be called by every GrGpuObject that references any wrapped backend objects. It
248*c8dee2aaSAndroid Build Coastguard Worker     // should be called once the object is fully initialized (i.e. only from the constructors of the
249*c8dee2aaSAndroid Build Coastguard Worker     // final class).
250*c8dee2aaSAndroid Build Coastguard Worker     void registerWithCacheWrapped(GrWrapCacheable);
251*c8dee2aaSAndroid Build Coastguard Worker 
252*c8dee2aaSAndroid Build Coastguard Worker     GrGpuResource(GrGpu*, std::string_view label);
253*c8dee2aaSAndroid Build Coastguard Worker     virtual ~GrGpuResource();
254*c8dee2aaSAndroid Build Coastguard Worker 
getGpu()255*c8dee2aaSAndroid Build Coastguard Worker     GrGpu* getGpu() const { return fGpu; }
256*c8dee2aaSAndroid Build Coastguard Worker 
257*c8dee2aaSAndroid Build Coastguard Worker     /** Overridden to free GPU resources in the backend API. */
onRelease()258*c8dee2aaSAndroid Build Coastguard Worker     virtual void onRelease() { }
259*c8dee2aaSAndroid Build Coastguard Worker     /** Overridden to abandon any internal handles, ptrs, etc to backend API resources.
260*c8dee2aaSAndroid Build Coastguard Worker         This may be called when the underlying 3D context is no longer valid and so no
261*c8dee2aaSAndroid Build Coastguard Worker         backend API calls should be made. */
onAbandon()262*c8dee2aaSAndroid Build Coastguard Worker     virtual void onAbandon() { }
263*c8dee2aaSAndroid Build Coastguard Worker 
264*c8dee2aaSAndroid Build Coastguard Worker     /**
265*c8dee2aaSAndroid Build Coastguard Worker      * Allows subclasses to add additional backing information to the SkTraceMemoryDump.
266*c8dee2aaSAndroid Build Coastguard Worker      **/
setMemoryBacking(SkTraceMemoryDump *,const SkString &)267*c8dee2aaSAndroid Build Coastguard Worker     virtual void setMemoryBacking(SkTraceMemoryDump*, const SkString&) const {}
268*c8dee2aaSAndroid Build Coastguard Worker 
269*c8dee2aaSAndroid Build Coastguard Worker     /**
270*c8dee2aaSAndroid Build Coastguard Worker      * Returns a string that uniquely identifies this resource.
271*c8dee2aaSAndroid Build Coastguard Worker      */
272*c8dee2aaSAndroid Build Coastguard Worker     SkString getResourceName() const;
273*c8dee2aaSAndroid Build Coastguard Worker 
274*c8dee2aaSAndroid Build Coastguard Worker     /**
275*c8dee2aaSAndroid Build Coastguard Worker      * A helper for subclasses that override dumpMemoryStatistics(). This method using a format
276*c8dee2aaSAndroid Build Coastguard Worker      * consistent with the default implementation of dumpMemoryStatistics() but allows the caller
277*c8dee2aaSAndroid Build Coastguard Worker      * to customize various inputs.
278*c8dee2aaSAndroid Build Coastguard Worker      */
279*c8dee2aaSAndroid Build Coastguard Worker     void dumpMemoryStatisticsPriv(SkTraceMemoryDump* traceMemoryDump, const SkString& resourceName,
280*c8dee2aaSAndroid Build Coastguard Worker                                   const char* type, size_t size) const;
281*c8dee2aaSAndroid Build Coastguard Worker 
282*c8dee2aaSAndroid Build Coastguard Worker 
283*c8dee2aaSAndroid Build Coastguard Worker private:
284*c8dee2aaSAndroid Build Coastguard Worker     bool isPurgeable() const;
285*c8dee2aaSAndroid Build Coastguard Worker     bool hasRef() const;
286*c8dee2aaSAndroid Build Coastguard Worker     bool hasNoCommandBufferUsages() const;
287*c8dee2aaSAndroid Build Coastguard Worker 
288*c8dee2aaSAndroid Build Coastguard Worker     /**
289*c8dee2aaSAndroid Build Coastguard Worker      * Called by the registerWithCache if the resource is available to be used as scratch.
290*c8dee2aaSAndroid Build Coastguard Worker      * Resource subclasses should override this if the instances should be recycled as scratch
291*c8dee2aaSAndroid Build Coastguard Worker      * resources and populate the scratchKey with the key.
292*c8dee2aaSAndroid Build Coastguard Worker      * By default resources are not recycled as scratch.
293*c8dee2aaSAndroid Build Coastguard Worker      **/
computeScratchKey(skgpu::ScratchKey *)294*c8dee2aaSAndroid Build Coastguard Worker     virtual void computeScratchKey(skgpu::ScratchKey*) const {}
295*c8dee2aaSAndroid Build Coastguard Worker 
296*c8dee2aaSAndroid Build Coastguard Worker     /**
297*c8dee2aaSAndroid Build Coastguard Worker      * Removes references to objects in the underlying 3D API without freeing them.
298*c8dee2aaSAndroid Build Coastguard Worker      * Called by CacheAccess.
299*c8dee2aaSAndroid Build Coastguard Worker      */
300*c8dee2aaSAndroid Build Coastguard Worker     void abandon();
301*c8dee2aaSAndroid Build Coastguard Worker 
302*c8dee2aaSAndroid Build Coastguard Worker     /**
303*c8dee2aaSAndroid Build Coastguard Worker      * Frees the object in the underlying 3D API. Called by CacheAccess.
304*c8dee2aaSAndroid Build Coastguard Worker      */
305*c8dee2aaSAndroid Build Coastguard Worker     void release();
306*c8dee2aaSAndroid Build Coastguard Worker 
307*c8dee2aaSAndroid Build Coastguard Worker     virtual size_t onGpuMemorySize() const = 0;
308*c8dee2aaSAndroid Build Coastguard Worker 
309*c8dee2aaSAndroid Build Coastguard Worker     virtual void onSetLabel() = 0;
310*c8dee2aaSAndroid Build Coastguard Worker 
311*c8dee2aaSAndroid Build Coastguard Worker     // See comments in CacheAccess and ResourcePriv.
312*c8dee2aaSAndroid Build Coastguard Worker     void setUniqueKey(const skgpu::UniqueKey&);
313*c8dee2aaSAndroid Build Coastguard Worker     void removeUniqueKey();
314*c8dee2aaSAndroid Build Coastguard Worker     void notifyARefCntIsZero(LastRemovedRef removedRef) const;
315*c8dee2aaSAndroid Build Coastguard Worker     void removeScratchKey();
316*c8dee2aaSAndroid Build Coastguard Worker     void makeBudgeted();
317*c8dee2aaSAndroid Build Coastguard Worker     void makeUnbudgeted();
318*c8dee2aaSAndroid Build Coastguard Worker 
319*c8dee2aaSAndroid Build Coastguard Worker #ifdef SK_DEBUG
320*c8dee2aaSAndroid Build Coastguard Worker     friend class GrGpu;  // for assert in GrGpu to access getGpu
321*c8dee2aaSAndroid Build Coastguard Worker #endif
322*c8dee2aaSAndroid Build Coastguard Worker 
323*c8dee2aaSAndroid Build Coastguard Worker     // An index into a heap when this resource is purgeable or an array when not. This is maintained
324*c8dee2aaSAndroid Build Coastguard Worker     // by the cache.
325*c8dee2aaSAndroid Build Coastguard Worker     int fCacheArrayIndex;
326*c8dee2aaSAndroid Build Coastguard Worker     // This value reflects how recently this resource was accessed in the cache. This is maintained
327*c8dee2aaSAndroid Build Coastguard Worker     // by the cache.
328*c8dee2aaSAndroid Build Coastguard Worker     uint32_t fTimestamp;
329*c8dee2aaSAndroid Build Coastguard Worker     skgpu::StdSteadyClock::time_point fTimeWhenBecamePurgeable;
330*c8dee2aaSAndroid Build Coastguard Worker 
331*c8dee2aaSAndroid Build Coastguard Worker     static const size_t kInvalidGpuMemorySize = ~static_cast<size_t>(0);
332*c8dee2aaSAndroid Build Coastguard Worker     skgpu::ScratchKey fScratchKey;
333*c8dee2aaSAndroid Build Coastguard Worker     skgpu::UniqueKey fUniqueKey;
334*c8dee2aaSAndroid Build Coastguard Worker 
335*c8dee2aaSAndroid Build Coastguard Worker     // This is not ref'ed but abandon() or release() will be called before the GrGpu object
336*c8dee2aaSAndroid Build Coastguard Worker     // is destroyed. Those calls will set this to NULL.
337*c8dee2aaSAndroid Build Coastguard Worker     GrGpu* fGpu;
338*c8dee2aaSAndroid Build Coastguard Worker     mutable size_t fGpuMemorySize = kInvalidGpuMemorySize;
339*c8dee2aaSAndroid Build Coastguard Worker 
340*c8dee2aaSAndroid Build Coastguard Worker     GrBudgetedType fBudgetedType = GrBudgetedType::kUnbudgetedUncacheable;
341*c8dee2aaSAndroid Build Coastguard Worker     bool fRefsWrappedObjects = false;
342*c8dee2aaSAndroid Build Coastguard Worker     const UniqueID fUniqueID;
343*c8dee2aaSAndroid Build Coastguard Worker     std::string fLabel;
344*c8dee2aaSAndroid Build Coastguard Worker 
345*c8dee2aaSAndroid Build Coastguard Worker     using INHERITED = GrIORef<GrGpuResource>;
346*c8dee2aaSAndroid Build Coastguard Worker     friend class GrIORef<GrGpuResource>; // to access notifyRefCntWillBeZero and
347*c8dee2aaSAndroid Build Coastguard Worker                                          // notifyARefCntIsZero.
348*c8dee2aaSAndroid Build Coastguard Worker };
349*c8dee2aaSAndroid Build Coastguard Worker 
350*c8dee2aaSAndroid Build Coastguard Worker class GrGpuResource::ProxyAccess {
351*c8dee2aaSAndroid Build Coastguard Worker private:
ProxyAccess(GrGpuResource * resource)352*c8dee2aaSAndroid Build Coastguard Worker     ProxyAccess(GrGpuResource* resource) : fResource(resource) {}
353*c8dee2aaSAndroid Build Coastguard Worker 
354*c8dee2aaSAndroid Build Coastguard Worker     /** Proxies are allowed to take a resource from no refs to one ref. */
355*c8dee2aaSAndroid Build Coastguard Worker     void ref(GrResourceCache* cache);
356*c8dee2aaSAndroid Build Coastguard Worker 
357*c8dee2aaSAndroid Build Coastguard Worker     // No taking addresses of this type.
358*c8dee2aaSAndroid Build Coastguard Worker     const CacheAccess* operator&() const = delete;
359*c8dee2aaSAndroid Build Coastguard Worker     CacheAccess* operator&() = delete;
360*c8dee2aaSAndroid Build Coastguard Worker 
361*c8dee2aaSAndroid Build Coastguard Worker     GrGpuResource* fResource;
362*c8dee2aaSAndroid Build Coastguard Worker 
363*c8dee2aaSAndroid Build Coastguard Worker     friend class GrGpuResource;
364*c8dee2aaSAndroid Build Coastguard Worker     friend class GrSurfaceProxy;
365*c8dee2aaSAndroid Build Coastguard Worker };
366*c8dee2aaSAndroid Build Coastguard Worker 
proxyAccess()367*c8dee2aaSAndroid Build Coastguard Worker inline GrGpuResource::ProxyAccess GrGpuResource::proxyAccess() { return ProxyAccess(this); }
368*c8dee2aaSAndroid Build Coastguard Worker 
369*c8dee2aaSAndroid Build Coastguard Worker #endif
370