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