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