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