1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef GPU_CONTEXT_H
17 #define GPU_CONTEXT_H
18 #include <functional>
19 #include <set>
20 #include "impl_interface/gpu_context_impl.h"
21 #include "utils/drawing_macros.h"
22 #include "utils/data.h"
23 #include "trace_memory_dump.h"
24 
25 typedef void* EGLContext;
26 namespace OHOS {
27 namespace Rosen {
28 namespace Drawing {
29 enum class PathRenderers : uint32_t {
30     NONE              = 0,
31     DASHLINE          = 1 << 0,
32     STENCILANDCOVER   = 1 << 1,
33     COVERAGECOUNTING  = 1 << 2,
34     AAHAIRLINE        = 1 << 3,
35     AACONVEX          = 1 << 4,
36     AALINEARIZING     = 1 << 5,
37     SMALL             = 1 << 6,
38     TESSELLATING      = 1 << 7,
39 
40     ALL               = (TESSELLATING | (TESSELLATING - 1)),
41     DEFAULT           = ALL & ~COVERAGECOUNTING
42 };
43 
44 struct GPUResourceTag {
GPUResourceTagGPUResourceTag45     GPUResourceTag()
46         : fPid(0), fTid(0), fWid(0), fFid(0) {}
GPUResourceTagGPUResourceTag47     GPUResourceTag(uint32_t pid, uint32_t tid, uint32_t wid, uint32_t fid, const std::string& name)
48         : fPid(pid), fTid(tid), fWid(wid), fFid(fid), fName(name) {}
49     uint32_t fPid;
50     uint32_t fTid;
51     uint32_t fWid;
52     uint32_t fFid;
53     std::string fName;
54 };
55 
56 /**
57  * @brief Option to create a GPUContext. Currently only supports setting persistent cache,
58  * other options may be expanded in the future
59  */
60 class DRAWING_API GPUContextOptions {
61 public:
62     /**
63      * @brief Cache compiled shaders for use between sessions.
64      */
65     class PersistentCache {
66     public:
67         PersistentCache() = default;
68         virtual ~PersistentCache() = default;
69 
70         /**
71          * @brief Returns the data for the key if it exists in the cache.
72          */
73         virtual std::shared_ptr<Data> Load(const Data& key) = 0;
74 
75         /**
76          * @brief Stores the data and key.
77          */
78         virtual void Store(const Data& key, const Data& data) = 0;
79     };
80 
81     /**
82      * @brief Gets persistent cache object.
83      */
84     PersistentCache* GetPersistentCache() const;
85 
86     /**
87      * @brief Sets persistent cache object.
88      * @param persistentCache A pointer to persistent cache object.
89      */
90     void SetPersistentCache(PersistentCache* persistentCache);
91 
92     void SetAllowPathMaskCaching(bool allowPathMaskCaching);
93     bool GetAllowPathMaskCaching() const;
94 
95 private:
96     PersistentCache* persistentCache_ = nullptr;
97     bool allowPathMaskCaching_ = true;
98 };
99 
100 class DRAWING_API GPUContext {
101 public:
102     GPUContext();
~GPUContext()103     ~GPUContext() {}
104 
105     /**
106      * @brief           Creates a GL GPUContext for a backend context.
107      * @param options   Option to create a GL GPUContext.
108      */
109     bool BuildFromGL(const GPUContextOptions& options);
110 
111 #ifdef RS_ENABLE_VK
112     bool BuildFromVK(const GrVkBackendContext& context);
113 
114     /**
115      * @brief           Creates a VK GPUContext for a backend context.
116      * @param context   An existed VK Context used to create a VK GPUContext.
117      * @param options   Option to create a VK GPUContext.
118      */
119     bool BuildFromVK(const GrVkBackendContext& context, const GPUContextOptions& options);
120 #endif
121 
122     /**
123      * @brief   Call to ensure all drawing to the context has been flushed to underlying 3D API specific objects.
124      */
125     void Flush();
126 
127     /**
128      * @brief   Call to ensure all drawing to the context has been submitted to underlying 3D API.
129      */
130     void Submit();
131 
132     /**
133      * @brief           Call to ensure all drawing to the context has been flushed and submitted to underlying 3D API.
134      * @param syncCpu   Whether to sync CPU or not.
135      */
136     void FlushAndSubmit(bool syncCpu = false);
137 
138     /**
139      * @brief             Purge GPU resources that haven't been used in the past 'msNotUsed' milliseconds
140                           or are otherwise marked for deletion.
141      * @param msNotUsed   Only unlocked resources not used in these last milliseconds will be cleaned up.
142      */
143     void PerformDeferredCleanup(std::chrono::milliseconds msNotUsed);
144 
145     /**
146      * @brief                   Gets the current GPU resource cache limits.
147      * @param maxResource       If non-null, returns maximum number of resources that can be held in the cache.
148      * @param maxResourceBytes  If non-null, returns maximum number of bytes of video memory
149                                 that can be held in the cache.
150      */
151     void GetResourceCacheLimits(int* maxResource, size_t* maxResourceBytes) const;
152 
153     /**
154      * @brief                   Specify the GPU resource cache limits.
155      * @param maxResource       The maximum number of resources that can be held in the cache.
156      * @param maxResourceBytes  The maximum number of bytes of video memory that can be held in the cache.
157      */
158     void SetResourceCacheLimits(int maxResource, size_t maxResourceBytes);
159 
160     /**
161      * @brief                   Gets the current GPU resource cache usage.
162      * @param resourceCount     If non-null, returns the number of resources that are held in the cache.
163      * @param resourceBytes     If non-null, returns the total number of bytes of video memory held in the cache.
164      */
165     void GetResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const;
166 
167     /**
168      * @brief                   Free GPU created by the contetx.
169      */
170     void FreeGpuResources();
171 
172     /**
173      * @brief                   Dump GPU stats.
174      * @param out               Dump GPU stat string.
175      */
176     void DumpGpuStats(std::string& out) const;
177 
178     /**
179      * @brief                   After returning it will assume that the underlying context may no longer be valid.
180      */
181     void ReleaseResourcesAndAbandonContext();
182 
183     /**
184      * @brief                         Purge unlocked resources from the cache until
185      *                                the provided byte count has been reached or we have purged all unlocked resources.
186      * @param scratchResourcesOnly    Whether to scratch the resources only or not.
187      */
188     void PurgeUnlockedResources(bool scratchResourcesOnly);
189 
190     /**
191      * @brief                         Purge unlocked resources by tag from the cache until
192      *                                the provided byte count has been reached or we have purged all unlocked resources.
193      * @param scratchResourcesOnly    Whether to scratch the resources only or not.
194      * @param tag                     GPU resource tag used to purge unlocked resources.
195      */
196     void PurgeUnlockedResourcesByTag(bool scratchResourcesOnly, const GPUResourceTag &tag);
197 
198     /**
199      * @brief                         Purge unlocked resources by pid from the cache until
200      *                                the provided byte count has been reached or we have purged all unlocked resources.
201      * @param scratchResourcesOnly    Whether to scratch the resources only or not.
202      * @param exitedPidSet            GPU resource exitedPidSet used to purge unlocked resources.
203      */
204     void PurgeUnlockedResourcesByPid(bool scratchResourcesOnly, const std::set<pid_t>& exitedPidSet);
205 
206     /**
207      * @brief                       Purge unlocked resources in every frame
208      * @param scratchResourcesOnly  Whether to scratch the resources only or not.
209      * @param exitedPidSet          GPU resource of exited PidSet used to purge unlocked resources.
210      * @param protectedPidSet       GPU resource of protectedPidSet will not be purged.
211      */
212     void PurgeCacheBetweenFrames(bool scratchResourcesOnly, const std::set<pid_t>& exitedPidSet,
213         const std::set<pid_t>& protectedPidSet);
214 
215     /**
216      * @brief                   Purge unlocked resources from the safe cache until
217      *                          the provided byte count has been reached or we have purged all unlocked resources.
218      */
219     void PurgeUnlockAndSafeCacheGpuResources();
220 
221     /**
222      * @brief                   Releases GPUResource objects and removes them from the cache by tag.
223      * @param tag               GPU resource tag used to release.
224      */
225     void ReleaseByTag(const GPUResourceTag &tag);
226 
227     /**
228      * @brief                   Enumerates all cached GPU resources and dumps their memory to traceMemoryDump.
229      * @param traceMemoryDump   A trace to memory dump.
230      * @param tag               GPU resource tag used to dump memory statistics.
231      */
232     void DumpMemoryStatisticsByTag(TraceMemoryDump* traceMemoryDump, GPUResourceTag &tag) const;
233 
234     /**
235      * @brief                   Enumerates all cached GPU resources and dumps their memory to traceMemoryDump.
236      * @param traceMemoryDump   A trace to memory dump.
237      */
238     void DumpMemoryStatistics(TraceMemoryDump* traceMemoryDump) const;
239 
240     /**
241      * @brief                   Reset GPU contect cache.
242      */
243     void ResetContext();
244 
245     /**
246      * @brief                   Set current resource tag for gpu cache recycle.
247      * @param tag               GPU resource tag used to set current GPU resource tag.
248      */
249     void SetCurrentGpuResourceTag(const GPUResourceTag &tag);
250 
251     /**
252      * @brief                   Get updated memory map.
253      * @param out               Updated memory map.
254      */
255     void GetUpdatedMemoryMap(std::unordered_map<pid_t, size_t> &out);
256 
257     /**
258      * @brief                   Init gpu memory limit.
259      * @param callback          Memory overflow calllback.
260      * @param size              Memory size limit.
261      */
262     void InitGpuMemoryLimit(MemoryOverflowCalllback callback, uint64_t size);
263 
264 #ifdef RS_ENABLE_VK
265     /**
266      * @brief                   Store vulkan pipeline cache
267      */
268     void StoreVkPipelineCacheData();
269 #endif
270 
271     void BeginFrame();
272 
273     void EndFrame();
274 
275     void SetGpuCacheSuppressWindowSwitch(bool enabled);
276 
277     void SetGpuMemoryAsyncReclaimerSwitch(bool enabled, const std::function<void()>& setThreadPriority);
278 
279     void FlushGpuMemoryInWaitQueue();
280 
281     void SuppressGpuCacheBelowCertainRatio(const std::function<bool(void)>& nextFrameHasArrived);
282 
283     /**
284      * @brief       Get the adaptation layer instance, called in the adaptation layer.
285      * @param T     The name of Impl class.
286      * @return      Adaptation Layer instance.
287      */
288     template<typename T>
GetImpl()289     T* GetImpl() const
290     {
291         return impl_->DowncastingTo<T>();
292     }
293 
294     void RegisterPostFunc(const std::function<void(const std::function<void()>& task)>& func);
295 
296     /**
297      * @brief                   Defragment or clear Vma Cache if needed
298      */
299     void VmaDefragment();
300 private:
301     std::shared_ptr<GPUContextImpl> impl_;
302 };
303 } // namespace Drawing
304 } // namespace Rosen
305 } // namespace OHOS
306 
307 #endif // !GPU_CONTEXT_H
308