• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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