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