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 GrResourceCache_DEFINED
9 #define GrResourceCache_DEFINED
10
11 #include <set>
12 #include <stack>
13 #include <unordered_set>
14
15 #include "include/core/SkRefCnt.h"
16 #include "include/core/SkTypes.h"
17 #include "include/gpu/ganesh/GrDirectContext.h"
18 #include "include/private/base/SkDebug.h"
19 #include "include/private/base/SkTArray.h"
20 #include "include/private/base/SkTDArray.h"
21 #include "include/private/base/SkTo.h"
22 #include "include/private/gpu/ganesh/GrTypesPriv.h"
23 #include "src/base/SkTDPQueue.h"
24 #include "src/core/SkMessageBus.h"
25 #include "src/core/SkTDynamicHash.h"
26 #include "src/core/SkTMultiMap.h"
27 #include "src/gpu/GpuTypesPriv.h"
28 #include "src/gpu/ResourceKey.h"
29 #include "src/gpu/ganesh/GrGpuResource.h"
30 #include "src/gpu/ganesh/GrGpuResourceCacheAccess.h"
31 #include "src/gpu/ganesh/GrGpuResourcePriv.h"
32
33 #include <cstddef>
34 #include <cstdint>
35 #include <functional>
36 #include <type_traits>
37 #include <unordered_map>
38 #include <utility>
39
40 class GrProxyProvider;
41 class GrSurface;
42 class GrThreadSafeCache;
43 class SkString;
44 class SkTraceMemoryDump;
45 enum class GrPurgeResourceOptions;
46 namespace skgpu {
47 class SingleOwner;
48 }
49
50 /**
51 * Manages the lifetime of all GrGpuResource instances.
52 *
53 * Resources may have optionally have two types of keys:
54 * 1) A scratch key. This is for resources whose allocations are cached but not their contents.
55 * Multiple resources can share the same scratch key. This is so a caller can have two
56 * resource instances with the same properties (e.g. multipass rendering that ping-pongs
57 * between two temporary surfaces). The scratch key is set at resource creation time and
58 * should never change. Resources need not have a scratch key.
59 * 2) A unique key. This key's meaning is specific to the domain that created the key. Only one
60 * resource may have a given unique key. The unique key can be set, cleared, or changed
61 * anytime after resource creation.
62 *
63 * A unique key always takes precedence over a scratch key when a resource has both types of keys.
64 * If a resource has neither key type then it will be deleted as soon as the last reference to it
65 * is dropped.
66 */
67 class GrResourceCache {
68 public:
69 GrResourceCache(skgpu::SingleOwner* owner,
70 GrDirectContext::DirectContextID owningContextID,
71 uint32_t familyID);
72 ~GrResourceCache();
73
74 /**
75 * This is used to safely return a resource to the cache when the owner may be on another
76 * thread from GrDirectContext. If the context still exists then using this method ensures that
77 * the resource is received by the cache for processing (recycling or destruction) on the
78 * context's thread.
79 *
80 * This is templated as it is rather than simply taking sk_sp<GrGpuResource> in order to enforce
81 * that the caller passes an rvalue. If the caller doesn't move its ref into this function
82 * then it will retain ownership, defeating the purpose. (Note that sk_sp<GrGpuResource>&&
83 * doesn't work either because calling with sk_sp<GrSpecificResource> will create a temporary
84 * sk_sp<GrGpuResource> which is an rvalue).
85 */
86 template<typename T>
87 static std::enable_if_t<std::is_base_of_v<GrGpuResource, T>, void>
ReturnResourceFromThread(sk_sp<T> && resource,GrDirectContext::DirectContextID id)88 ReturnResourceFromThread(sk_sp<T>&& resource, GrDirectContext::DirectContextID id) {
89 UnrefResourceMessage msg(std::move(resource), id);
90 UnrefResourceMessage::Bus::Post(std::move(msg));
91 }
92
93 // Default maximum number of bytes of gpu memory of budgeted resources in the cache.
94 static const size_t kDefaultMaxSize = 256 * (1 << 20);
95
96 /** Used to access functionality needed by GrGpuResource for lifetime management. */
97 class ResourceAccess;
98 ResourceAccess resourceAccess();
99
100 /**
101 * Get current resource tag for gpu cache recycle.
102 */
103 GrGpuResourceTag getCurrentGrResourceTag() const;
104
105 /**
106 * Set current resourcetag for gpu cache recycle.
107 */
108 void setCurrentGrResourceTag(const GrGpuResourceTag& tag);
109
110 /**
111 * Pop resource tag.
112 */
113 void popGrResourceTag();
114
115 /** Unique ID of the owning GrContext. */
contextUniqueID()116 uint32_t contextUniqueID() const { return fContextUniqueID; }
117
118 /** Sets the max gpu memory byte size of the cache. */
119 void setLimit(size_t bytes);
120
121 /**
122 * Returns the number of resources.
123 */
getResourceCount()124 int getResourceCount() const {
125 return fPurgeableQueue.count() + fNonpurgeableResources.size();
126 }
127
128 /**
129 * Returns the number of resources that count against the budget.
130 */
getBudgetedResourceCount()131 int getBudgetedResourceCount() const { return fBudgetedCount; }
132
133 /**
134 * Returns the number of bytes consumed by resources.
135 */
getResourceBytes()136 size_t getResourceBytes() const { return fBytes; }
137
138 #ifdef SKIA_DFX_FOR_RECORD_VKIMAGE
139 void dumpAllResource(std::stringstream& dump) const;
140 #endif
141
142 #ifdef SKIA_DFX_FOR_OHOS
addAllocImageBytes(size_t bytes)143 void addAllocImageBytes(size_t bytes) { fAllocImageBytes += bytes; }
removeAllocImageBytes(size_t bytes)144 void removeAllocImageBytes(size_t bytes) { fAllocImageBytes -= bytes; }
addAllocBufferBytes(size_t bytes)145 void addAllocBufferBytes(size_t bytes) { fAllocBufferBytes += bytes; }
removeAllocBufferBytes(size_t bytes)146 void removeAllocBufferBytes(size_t bytes) { fAllocBufferBytes -= bytes; }
147 #endif
148
149 /**
150 * Returns the number of bytes held by unlocked resources which are available for purging.
151 */
getPurgeableBytes()152 size_t getPurgeableBytes() const { return fPurgeableBytes; }
153
154 /**
155 * Returns the number of bytes consumed by budgeted resources.
156 */
getBudgetedResourceBytes()157 size_t getBudgetedResourceBytes() const { return fBudgetedBytes; }
158
159 /**
160 * Returns the number of bytes consumed by cached resources.
161 */
getMaxResourceBytes()162 size_t getMaxResourceBytes() const { return fMaxBytes; }
163
164 /**
165 * Abandons the backend API resources owned by all GrGpuResource objects and removes them from
166 * the cache.
167 */
168 void abandonAll();
169
170 /**
171 * Releases the backend API resources owned by all GrGpuResource objects and removes them from
172 * the cache.
173 */
174 void releaseAll();
175
176 /**
177 * Release GrGpuResource objects and removes them from the cache by tag.
178 */
179 void releaseByTag(const GrGpuResourceTag& tag);
180 /**
181 * Get all GrGpuResource tags.
182 */
183 std::set<GrGpuResourceTag> getAllGrGpuResourceTag() const;
184
185 /**
186 * Find a resource that matches a scratch key.
187 */
188 GrGpuResource* findAndRefScratchResource(const skgpu::ScratchKey& scratchKey);
189
190 #ifdef SK_DEBUG
191 // This is not particularly fast and only used for validation, so debug only.
countScratchEntriesForKey(const skgpu::ScratchKey & scratchKey)192 int countScratchEntriesForKey(const skgpu::ScratchKey& scratchKey) const {
193 return fScratchMap.countForKey(scratchKey);
194 }
195 #endif
196
197 /**
198 * Find a resource that matches a unique key.
199 */
findAndRefUniqueResource(const skgpu::UniqueKey & key)200 GrGpuResource* findAndRefUniqueResource(const skgpu::UniqueKey& key) {
201 GrGpuResource* resource = fUniqueHash.find(key);
202 if (resource) {
203 this->refAndMakeResourceMRU(resource);
204 }
205 return resource;
206 }
207
208 /**
209 * Query whether a unique key exists in the cache.
210 */
hasUniqueKey(const skgpu::UniqueKey & key)211 bool hasUniqueKey(const skgpu::UniqueKey& key) const {
212 return SkToBool(fUniqueHash.find(key));
213 }
214
215 /** Purges resources to become under budget and processes resources with invalidated unique
216 keys. */
217 void purgeAsNeeded();
218
219 // Purge unlocked resources. If 'opts' is kScratchResourcesOnly, the purgeable resources
220 // containing persistent data are spared. If it is kAllResources then all purgeable resources
221 // will be deleted.
purgeUnlockedResources(GrPurgeResourceOptions opts)222 void purgeUnlockedResources(GrPurgeResourceOptions opts) {
223 this->purgeUnlockedResources(/*purgeTime=*/nullptr, opts);
224 }
225
226 void purgeUnlockedResourcesByTag(bool scratchResourceOnly, const GrGpuResourceTag& tag);
227 void purgeUnlockedResourcesByPid(bool scratchResourceOnly, const std::set<int>& exitedPidSet);
228
229 // Purge unlocked resources not used since the passed point in time. If 'opts' is
230 // kScratchResourcesOnly, the purgeable resources containing persistent data are spared.
231 // If it is kAllResources then all purgeable resources older than 'purgeTime' will be deleted.
purgeResourcesNotUsedSince(skgpu::StdSteadyClock::time_point purgeTime,GrPurgeResourceOptions opts)232 void purgeResourcesNotUsedSince(skgpu::StdSteadyClock::time_point purgeTime,
233 GrPurgeResourceOptions opts) {
234 this->purgeUnlockedResources(&purgeTime, opts);
235 }
236
237 /** If it's possible to purge enough resources to get the provided amount of budget
238 headroom, do so and return true. If it's not possible, do nothing and return false.
239 */
240 bool purgeToMakeHeadroom(size_t desiredHeadroomBytes);
241
overBudget()242 bool overBudget() const { return fBudgetedBytes > fMaxBytes; }
243
244 /**
245 * Purge unlocked resources from the cache until the the provided byte count has been reached
246 * or we have purged all unlocked resources. The default policy is to purge in LRU order, but
247 * can be overridden to prefer purging scratch resources (in LRU order) prior to purging other
248 * resource types.
249 *
250 * @param maxBytesToPurge the desired number of bytes to be purged.
251 * @param preferScratchResources If true scratch resources will be purged prior to other
252 * resource types.
253 */
254 void purgeUnlockedResources(size_t bytesToPurge, bool preferScratchResources);
255
256 /** Returns true if the cache would like a flush to occur in order to make more resources
257 purgeable. */
258 bool requestsFlush() const;
259
260 #if GR_CACHE_STATS
261 struct Stats {
262 int fTotal;
263 int fNumPurgeable;
264 int fNumNonPurgeable;
265
266 int fScratch;
267 int fWrapped;
268 size_t fUnbudgetedSize;
269
StatsStats270 Stats() { this->reset(); }
271
resetStats272 void reset() {
273 fTotal = 0;
274 fNumPurgeable = 0;
275 fNumNonPurgeable = 0;
276 fScratch = 0;
277 fWrapped = 0;
278 fUnbudgetedSize = 0;
279 }
280
updateStats281 void update(GrGpuResource* resource) {
282 if (resource->cacheAccess().isScratch()) {
283 ++fScratch;
284 }
285 if (resource->resourcePriv().refsWrappedObjects()) {
286 ++fWrapped;
287 }
288 if (GrBudgetedType::kBudgeted != resource->resourcePriv().budgetedType()) {
289 fUnbudgetedSize += resource->gpuMemorySize();
290 }
291 }
292 };
293
294 void getStats(Stats*) const;
295
296 #if defined(GPU_TEST_UTILS)
297 void dumpStats(SkString*) const;
298
299 void dumpStatsKeyValuePairs(
300 skia_private::TArray<SkString>* keys, skia_private::TArray<double>* value) const;
301 #endif
302
303 #endif // GR_CACHE_STATS
304
305 #if defined(GPU_TEST_UTILS)
306 int countUniqueKeysWithTag(const char* tag) const;
307
308 void changeTimestamp(uint32_t newTimestamp);
309
310 void visitSurfaces(const std::function<void(const GrSurface*, bool purgeable)>&) const;
311 #endif
312
313 // Enumerates all cached resources and dumps their details to traceMemoryDump.
314 void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump) const;
315 void dumpMemoryStatistics(SkTraceMemoryDump* traceMemoryDump, GrGpuResourceTag& tag) const;
316
setProxyProvider(GrProxyProvider * proxyProvider)317 void setProxyProvider(GrProxyProvider* proxyProvider) { fProxyProvider = proxyProvider; }
setThreadSafeCache(GrThreadSafeCache * threadSafeCache)318 void setThreadSafeCache(GrThreadSafeCache* threadSafeCache) {
319 fThreadSafeCache = threadSafeCache;
320 }
321
322 std::set<GrGpuResourceTag> getAllGrGpuResourceTags() const; // Get the tag of all GPU resources
323
324 // OH ISSUE: get the memory information of the updated pid.
325 void getUpdatedMemoryMap(std::unordered_map<int32_t, size_t> &out);
326
327 // OH ISSUE: check whether the PID is abnormal.
328 bool isPidAbnormal() const;
329
330 // OH ISSUE: change the fbyte when the resource tag changes.
331 void changeByteOfPid(int32_t beforePid, int32_t afterPid,
332 size_t bytes, bool beforeRealAlloc, bool afterRealAlloc);
333
334 // OH ISSUE: init gpu memory limit.
335 void initGpuMemoryLimit(MemoryOverflowCalllback callback, uint64_t size);
336
337 // It'd be nice if this could be private but SkMessageBus relies on macros to define types that
338 // require this to be public.
339 class UnrefResourceMessage {
340 public:
recipient()341 GrDirectContext::DirectContextID recipient() const { return fRecipient; }
342
343 UnrefResourceMessage(UnrefResourceMessage&&) = default;
344 UnrefResourceMessage& operator=(UnrefResourceMessage&&) = default;
345
346 private:
347 friend class GrResourceCache;
348
349 using Bus = SkMessageBus<UnrefResourceMessage,
350 GrDirectContext::DirectContextID,
351 /*AllowCopyableMessage=*/false>;
352
UnrefResourceMessage(sk_sp<GrGpuResource> && resource,GrDirectContext::DirectContextID recipient)353 UnrefResourceMessage(sk_sp<GrGpuResource>&& resource,
354 GrDirectContext::DirectContextID recipient)
355 : fResource(std::move(resource)), fRecipient(recipient) {}
356
357 UnrefResourceMessage(const UnrefResourceMessage&) = delete;
358 UnrefResourceMessage& operator=(const UnrefResourceMessage&) = delete;
359
360 sk_sp<GrGpuResource> fResource;
361 GrDirectContext::DirectContextID fRecipient;
362 };
363
364 #ifdef SKIA_DFX_FOR_OHOS
365 void dumpInfo(SkString* out);
366 std::string cacheInfo();
367
368 #ifdef SKIA_OHOS
369 static bool purgeUnlocakedResTraceEnabled_;
370 struct SimpleCacheInfo {
371 int fPurgeableQueueCount;
372 int fNonpurgeableResourcesCount;
373 size_t fPurgeableBytes;
374 int fBudgetedCount;
375 size_t fBudgetedBytes;
376 size_t fAllocImageBytes;
377 size_t fAllocBufferBytes;
378 };
379 #endif
380 #endif
381 private:
382 ///////////////////////////////////////////////////////////////////////////
383 /// @name Methods accessible via ResourceAccess
384 ////
385 void insertResource(GrGpuResource*);
386 void removeResource(GrGpuResource*);
387 void notifyARefCntReachedZero(GrGpuResource*, GrGpuResource::LastRemovedRef);
388 void changeUniqueKey(GrGpuResource*, const skgpu::UniqueKey&);
389 void removeUniqueKey(GrGpuResource*);
390 void willRemoveScratchKey(const GrGpuResource*);
391 void didChangeBudgetStatus(GrGpuResource*);
392 void refResource(GrGpuResource* resource);
393 /// @}
394
395 void refAndMakeResourceMRU(GrGpuResource*);
396 void processFreedGpuResources();
397 void addToNonpurgeableArray(GrGpuResource*);
398 void removeFromNonpurgeableArray(GrGpuResource*);
399
wouldFit(size_t bytes)400 bool wouldFit(size_t bytes) const { return fBudgetedBytes+bytes <= fMaxBytes; }
401
402 uint32_t getNextTimestamp();
403
404 void purgeUnlockedResources(const skgpu::StdSteadyClock::time_point* purgeTime,
405 GrPurgeResourceOptions opts);
406
407 #ifdef SK_DEBUG
408 bool isInCache(const GrGpuResource* r) const;
409 void validate() const;
410 #else
validate()411 void validate() const {}
412 #endif
413
414 #ifdef SKIA_DFX_FOR_OHOS
415 #ifdef SKIA_OHOS
416 void traceBeforePurgeUnlockRes(const std::string& method, SimpleCacheInfo& simpleCacheInfo);
417 void traceAfterPurgeUnlockRes(const std::string& method, const SimpleCacheInfo& simpleCacheInfo);
418 std::string cacheInfoComparison(const SimpleCacheInfo& simpleCacheInfo);
419 #endif
420 std::string cacheInfoPurgeableQueue();
421 std::string cacheInfoNoPurgeableQueue();
422 void updatePurgeableWidMap(GrGpuResource* resource,
423 std::map<uint64_t, std::string>& nameInfoWid,
424 std::map<uint64_t, size_t>& sizeInfoWid,
425 std::map<uint64_t, int>& pidInfoWid,
426 std::map<uint64_t, int>& countInfoWid);
427 void updatePurgeablePidMap(GrGpuResource* resource,
428 std::map<uint32_t, std::string>& nameInfoPid,
429 std::map<uint32_t, size_t>& sizeInfoPid,
430 std::map<uint32_t, int>& countInfoPid);
431 void updatePurgeableFidMap(GrGpuResource* resource,
432 std::map<uint32_t, std::string>& nameInfoFid,
433 std::map<uint32_t, size_t>& sizeInfoFid,
434 std::map<uint32_t, int>& countInfoFid);
435 void updatePurgeableWidInfo(std::string& infoStr,
436 std::map<uint64_t, std::string>& nameInfoWid,
437 std::map<uint64_t, size_t>& sizeInfoWid,
438 std::map<uint64_t, int>& pidInfoWid,
439 std::map<uint64_t, int>& countInfoWid);
440 void updatePurgeablePidInfo(std::string& infoStr,
441 std::map<uint32_t, std::string>& nameInfoPid,
442 std::map<uint32_t, size_t>& sizeInfoPid,
443 std::map<uint32_t, int>& countInfoPid);
444 void updatePurgeableFidInfo(std::string& infoStr,
445 std::map<uint32_t, std::string>& nameInfoFid,
446 std::map<uint32_t, size_t>& sizeInfoFid,
447 std::map<uint32_t, int>& countInfoFid);
448 void updatePurgeableUnknownInfo(std::string& infoStr, const std::string& unknownPrefix,
449 const int countUnknown, const size_t sizeUnknown);
450 #endif
451
452 class AutoValidate;
453
454 struct ScratchMapTraits {
GetKeyScratchMapTraits455 static const skgpu::ScratchKey& GetKey(const GrGpuResource& r) {
456 return r.resourcePriv().getScratchKey();
457 }
458
HashScratchMapTraits459 static uint32_t Hash(const skgpu::ScratchKey& key) { return key.hash(); }
OnFreeScratchMapTraits460 static void OnFree(GrGpuResource*) { }
461 };
462 typedef SkTMultiMap<GrGpuResource, skgpu::ScratchKey, ScratchMapTraits> ScratchMap;
463
464 struct UniqueHashTraits {
GetKeyUniqueHashTraits465 static const skgpu::UniqueKey& GetKey(const GrGpuResource& r) { return r.getUniqueKey(); }
466
HashUniqueHashTraits467 static uint32_t Hash(const skgpu::UniqueKey& key) { return key.hash(); }
468 };
469 typedef SkTDynamicHash<GrGpuResource, skgpu::UniqueKey, UniqueHashTraits> UniqueHash;
470
CompareTimestamp(GrGpuResource * const & a,GrGpuResource * const & b)471 static bool CompareTimestamp(GrGpuResource* const& a, GrGpuResource* const& b) {
472 return a->cacheAccess().timestamp() < b->cacheAccess().timestamp();
473 }
474
AccessResourceIndex(GrGpuResource * const & res)475 static int* AccessResourceIndex(GrGpuResource* const& res) {
476 return res->cacheAccess().accessCacheIndex();
477 }
478
479 typedef SkMessageBus<skgpu::UniqueKeyInvalidatedMessage, uint32_t>::Inbox InvalidUniqueKeyInbox;
480 typedef SkTDPQueue<GrGpuResource*, CompareTimestamp, AccessResourceIndex> PurgeableQueue;
481 typedef SkTDArray<GrGpuResource*> ResourceArray;
482
483 GrProxyProvider* fProxyProvider = nullptr;
484 GrThreadSafeCache* fThreadSafeCache = nullptr;
485
486 // Whenever a resource is added to the cache or the result of a cache lookup, fTimestamp is
487 // assigned as the resource's timestamp and then incremented. fPurgeableQueue orders the
488 // purgeable resources by this value, and thus is used to purge resources in LRU order.
489 uint32_t fTimestamp = 0;
490 PurgeableQueue fPurgeableQueue;
491 ResourceArray fNonpurgeableResources;
492
493 // This map holds all resources that can be used as scratch resources.
494 ScratchMap fScratchMap;
495 // This holds all resources that have unique keys.
496 UniqueHash fUniqueHash;
497
498 // our budget, used in purgeAsNeeded()
499 size_t fMaxBytes = kDefaultMaxSize;
500
501 #if GR_CACHE_STATS
502 int fHighWaterCount = 0;
503 size_t fHighWaterBytes = 0;
504 int fBudgetedHighWaterCount = 0;
505 size_t fBudgetedHighWaterBytes = 0;
506 #endif
507
508 // our current stats for all resources
509 SkDEBUGCODE(int fCount = 0;)
510 size_t fBytes = 0;
511 #ifdef SKIA_DFX_FOR_OHOS
512 size_t fAllocImageBytes = 0;
513 size_t fAllocBufferBytes = 0;
514 #endif
515
516 // our current stats for resources that count against the budget
517 int fBudgetedCount = 0;
518 size_t fBudgetedBytes = 0;
519 size_t fPurgeableBytes = 0;
520 int fNumBudgetedResourcesFlushWillMakePurgeable = 0;
521
522 InvalidUniqueKeyInbox fInvalidUniqueKeyInbox;
523 UnrefResourceMessage::Bus::Inbox fUnrefResourceInbox;
524
525 GrDirectContext::DirectContextID fOwningContextID;
526 uint32_t fContextUniqueID = SK_InvalidUniqueID;
527 skgpu::SingleOwner* fSingleOwner = nullptr;
528
529 // This resource is allowed to be in the nonpurgeable array for the sake of validate() because
530 // we're in the midst of converting it to purgeable status.
531 SkDEBUGCODE(GrGpuResource* fNewlyPurgeableResourceForValidation = nullptr;)
532 std::stack<GrGpuResourceTag> grResourceTagCacheStack;
533
534 // OH ISSUE: gpu memory limit.
535 uint64_t fMemoryControl_ = UINT64_MAX;
536 // OH ISSUE: memory overflow callback.
537 MemoryOverflowCalllback fMemoryOverflowCallback_ = nullptr;
538 // OH ISSUE: record pid had exited.
539 std::unordered_set<int32_t> fExitedPid_;
540
541 //Indicates the cached resource tags.
542 std::stack<GrGpuResourceTag> GrResourceCacheStack;
543
544 // OH ISSUE: stores fBytes of each pid.
545 std::unordered_map<int32_t, size_t> fBytesOfPid;
546 // OH ISSUE: stores the memory information of the updated pid.
547 std::unordered_map<int32_t, size_t> fUpdatedBytesOfPid;
548 };
549
550 class GrResourceCache::ResourceAccess {
551 private:
ResourceAccess(GrResourceCache * cache)552 ResourceAccess(GrResourceCache* cache) : fCache(cache) { }
ResourceAccess(const ResourceAccess & that)553 ResourceAccess(const ResourceAccess& that) : fCache(that.fCache) { }
554 ResourceAccess& operator=(const ResourceAccess&) = delete;
555
556 /**
557 * Insert a resource into the cache.
558 */
insertResource(GrGpuResource * resource)559 void insertResource(GrGpuResource* resource) { fCache->insertResource(resource); }
560
561 /**
562 * Removes a resource from the cache.
563 */
removeResource(GrGpuResource * resource)564 void removeResource(GrGpuResource* resource) { fCache->removeResource(resource); }
565
566 /**
567 * Adds a ref to a resource with proper tracking if the resource has 0 refs prior to
568 * adding the ref.
569 */
refResource(GrGpuResource * resource)570 void refResource(GrGpuResource* resource) { fCache->refResource(resource); }
571
572 /**
573 * Get current resource tag for gpu cache recycle.
574 */
getCurrentGrResourceTag()575 GrGpuResourceTag getCurrentGrResourceTag() const { return fCache->getCurrentGrResourceTag(); }
576
577 /**
578 * Notifications that should be sent to the cache when the ref/io cnt status of resources
579 * changes.
580 */
581 enum RefNotificationFlags {
582 /** All types of refs on the resource have reached zero. */
583 kAllCntsReachedZero_RefNotificationFlag = 0x1,
584 /** The normal (not pending IO type) ref cnt has reached zero. */
585 kRefCntReachedZero_RefNotificationFlag = 0x2,
586 };
587 /**
588 * Called by GrGpuResources when they detect one of their ref cnts have reached zero. This may
589 * either be the main ref or the command buffer usage ref.
590 */
notifyARefCntReachedZero(GrGpuResource * resource,GrGpuResource::LastRemovedRef removedRef)591 void notifyARefCntReachedZero(GrGpuResource* resource,
592 GrGpuResource::LastRemovedRef removedRef) {
593 fCache->notifyARefCntReachedZero(resource, removedRef);
594 }
595
596 /**
597 * Called by GrGpuResources to change their unique keys.
598 */
changeUniqueKey(GrGpuResource * resource,const skgpu::UniqueKey & newKey)599 void changeUniqueKey(GrGpuResource* resource, const skgpu::UniqueKey& newKey) {
600 fCache->changeUniqueKey(resource, newKey);
601 }
602
603 /**
604 * Called by a GrGpuResource to remove its unique key.
605 */
removeUniqueKey(GrGpuResource * resource)606 void removeUniqueKey(GrGpuResource* resource) { fCache->removeUniqueKey(resource); }
607
608 /**
609 * Called by a GrGpuResource when it removes its scratch key.
610 */
willRemoveScratchKey(const GrGpuResource * resource)611 void willRemoveScratchKey(const GrGpuResource* resource) {
612 fCache->willRemoveScratchKey(resource);
613 }
614
615 /**
616 * Called by GrGpuResources when they change from budgeted to unbudgeted or vice versa.
617 */
didChangeBudgetStatus(GrGpuResource * resource)618 void didChangeBudgetStatus(GrGpuResource* resource) { fCache->didChangeBudgetStatus(resource); }
619
changeByteOfPid(int32_t beforePid,int32_t afterPid,size_t bytes,bool beforeRealAlloc,bool afterRealAlloc)620 void changeByteOfPid(int32_t beforePid, int32_t afterPid,
621 size_t bytes, bool beforeRealAlloc, bool afterRealAlloc)
622 {
623 fCache->changeByteOfPid(beforePid, afterPid, bytes, beforeRealAlloc, afterRealAlloc);
624 }
625
626 // No taking addresses of this type.
627 const ResourceAccess* operator&() const;
628 ResourceAccess* operator&();
629
630 GrResourceCache* fCache;
631
632 friend class GrGpuResource; // To access all the proxy inline methods.
633 friend class GrResourceCache; // To create this type.
634 };
635
SkShouldPostMessageToBus(const GrResourceCache::UnrefResourceMessage & msg,GrDirectContext::DirectContextID potentialRecipient)636 static inline bool SkShouldPostMessageToBus(const GrResourceCache::UnrefResourceMessage& msg,
637 GrDirectContext::DirectContextID potentialRecipient) {
638 return potentialRecipient == msg.recipient();
639 }
640
resourceAccess()641 inline GrResourceCache::ResourceAccess GrResourceCache::resourceAccess() {
642 return ResourceAccess(this);
643 }
644
645 #endif
646