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 RS_VULKAN_CONTEXT_H
17 #define RS_VULKAN_CONTEXT_H
18 
19 #include <list>
20 #include <memory>
21 #include <mutex>
22 #include <string>
23 #include "sync_fence.h"
24 #include "include/gpu/vk/GrVkExtensions.h"
25 #include "vulkan/vulkan_core.h"
26 #include "vulkan/vulkan_xeg.h"
27 
28 #define VK_NO_PROTOTYPES 1
29 
30 #include "vulkan/vulkan.h"
31 #include "include/gpu/vk/GrVkBackendContext.h"
32 #include "include/gpu/GrDirectContext.h"
33 #include "rs_vulkan_mem_statistic.h"
34 
35 #include "image/gpu_context.h"
36 
37 namespace OHOS {
38 namespace Rosen {
39 class MemoryHandler;
40 class RsVulkanInterface {
41 public:
42     struct CallbackSemaphoreInfo {
43         RsVulkanInterface& mVkContext;
44         VkSemaphore mSemaphore;
45         int mFenceFd;
46 
47         int mRefs = 2; // 2 : both skia and rs hold fence fd
CallbackSemaphoreInfoCallbackSemaphoreInfo48         CallbackSemaphoreInfo(RsVulkanInterface& vkContext, VkSemaphore semaphore, int fenceFd)
49             : mVkContext(vkContext),
50             mSemaphore(semaphore),
51             mFenceFd(fenceFd)
52         {
53         }
54 
DestroyCallbackRefsCallbackSemaphoreInfo55         static void DestroyCallbackRefs(void* context)
56         {
57             if (context == nullptr) {
58                 return;
59             }
60             CallbackSemaphoreInfo* info = reinterpret_cast<CallbackSemaphoreInfo*>(context);
61             --info->mRefs;
62             if (!info->mRefs) {
63                 info->mVkContext.SendSemaphoreWithFd(info->mSemaphore, info->mFenceFd);
64                 delete info;
65             }
66         }
67     };
68     template <class T>
69     class Func {
70     public:
71         using Proto = T;
72         explicit Func(T proc = nullptr) : func_(proc) {}
~Func()73         ~Func() { func_ = nullptr; }
74 
75         Func operator=(T proc)
76         {
77             func_ = proc;
78             return *this;
79         }
80 
81         Func operator=(PFN_vkVoidFunction proc)
82         {
83             func_ = reinterpret_cast<Proto>(proc);
84             return *this;
85         }
86 
87         operator bool() const { return func_ != nullptr; }
T()88         operator T() const { return func_; }
89     private:
90         T func_;
91     };
92 
93     RsVulkanInterface() = default;
94     ~RsVulkanInterface();
95     void Init(bool isProtected = false);
96     bool CreateInstance();
97     bool SelectPhysicalDevice(bool isProtected = false);
98     bool CreateDevice(bool isProtected = false);
99     bool CreateSkiaBackendContext(GrVkBackendContext* context, bool createNew = false, bool isProtected = false);
GetRsVkMemStat()100     RsVulkanMemStat& GetRsVkMemStat()
101     {
102         return mVkMemStat;
103     }
104 
105     bool IsValid() const;
106     GrVkGetProc CreateSkiaGetProc() const;
GetMemoryHandler()107     const std::shared_ptr<MemoryHandler> GetMemoryHandler() const
108     {
109         return memHandler_;
110     }
111 
112 #define DEFINE_FUNC(name) Func<PFN_vk##name> vk##name
113 
114     DEFINE_FUNC(AcquireNextImageKHR);
115     DEFINE_FUNC(AllocateCommandBuffers);
116     DEFINE_FUNC(AllocateMemory);
117     DEFINE_FUNC(BeginCommandBuffer);
118     DEFINE_FUNC(BindImageMemory);
119     DEFINE_FUNC(BindImageMemory2);
120     DEFINE_FUNC(CmdPipelineBarrier);
121     DEFINE_FUNC(CreateCommandPool);
122     DEFINE_FUNC(CreateDebugReportCallbackEXT);
123     DEFINE_FUNC(CreateDevice);
124     DEFINE_FUNC(CreateFence);
125     DEFINE_FUNC(CreateImage);
126     DEFINE_FUNC(CreateImageView);
127     DEFINE_FUNC(CreateInstance);
128     DEFINE_FUNC(CreateSemaphore);
129     DEFINE_FUNC(CreateSwapchainKHR);
130     DEFINE_FUNC(DestroyCommandPool);
131     DEFINE_FUNC(DestroyDebugReportCallbackEXT);
132     DEFINE_FUNC(DestroyDevice);
133     DEFINE_FUNC(DestroyFence);
134     DEFINE_FUNC(DestroyImage);
135     DEFINE_FUNC(DestroyImageView);
136     DEFINE_FUNC(DestroyInstance);
137     DEFINE_FUNC(DestroySemaphore);
138     DEFINE_FUNC(DestroySurfaceKHR);
139     DEFINE_FUNC(DestroySwapchainKHR);
140     DEFINE_FUNC(DeviceWaitIdle);
141     DEFINE_FUNC(EndCommandBuffer);
142     DEFINE_FUNC(EnumerateDeviceLayerProperties);
143     DEFINE_FUNC(EnumerateInstanceExtensionProperties);
144     DEFINE_FUNC(EnumerateInstanceLayerProperties);
145     DEFINE_FUNC(EnumeratePhysicalDevices);
146     DEFINE_FUNC(FreeCommandBuffers);
147     DEFINE_FUNC(FreeMemory);
148     DEFINE_FUNC(GetDeviceProcAddr);
149     DEFINE_FUNC(GetDeviceQueue);
150     DEFINE_FUNC(GetImageMemoryRequirements);
151     DEFINE_FUNC(GetInstanceProcAddr);
152     DEFINE_FUNC(GetPhysicalDeviceFeatures);
153     DEFINE_FUNC(GetPhysicalDeviceQueueFamilyProperties);
154     DEFINE_FUNC(QueueSubmit);
155     DEFINE_FUNC(QueueWaitIdle);
156     DEFINE_FUNC(ResetCommandBuffer);
157     DEFINE_FUNC(ResetFences);
158     DEFINE_FUNC(WaitForFences);
159     DEFINE_FUNC(GetPhysicalDeviceSurfaceCapabilitiesKHR);
160     DEFINE_FUNC(GetPhysicalDeviceSurfaceFormatsKHR);
161     DEFINE_FUNC(GetPhysicalDeviceSurfacePresentModesKHR);
162     DEFINE_FUNC(GetPhysicalDeviceSurfaceSupportKHR);
163     DEFINE_FUNC(GetSwapchainImagesKHR);
164     DEFINE_FUNC(QueuePresentKHR);
165     DEFINE_FUNC(CreateSurfaceOHOS);
166     DEFINE_FUNC(GetPhysicalDeviceMemoryProperties);
167     DEFINE_FUNC(GetPhysicalDeviceMemoryProperties2);
168     DEFINE_FUNC(GetNativeBufferPropertiesOHOS);
169     DEFINE_FUNC(QueueSignalReleaseImageOHOS);
170     DEFINE_FUNC(ImportSemaphoreFdKHR);
171     DEFINE_FUNC(GetPhysicalDeviceFeatures2);
172     DEFINE_FUNC(SetFreqAdjustEnable);
173 #undef DEFINE_FUNC
174 
GetPhysicalDevice()175     VkPhysicalDevice GetPhysicalDevice() const
176     {
177         return physicalDevice_;
178     }
179 
GetDevice()180     VkDevice GetDevice() const
181     {
182         return device_;
183     }
184 
GetQueue()185     VkQueue GetQueue() const
186     {
187         return backendContext_.fQueue;
188     }
189 
190     inline const GrVkBackendContext& GetGrVkBackendContext(
191         bool useHBackendContext = false) const noexcept
192     {
193         return useHBackendContext ? hbackendContext_ : backendContext_;
194     }
195 
GetVulkanVersion()196     inline const std::string GetVulkanVersion() const
197     {
198         return std::to_string(VK_API_VERSION_1_2);
199     }
200 
201     std::shared_ptr<Drawing::GPUContext> CreateDrawingContext(bool independentContext = false,
202         bool isProtected = false);
203     std::shared_ptr<Drawing::GPUContext> GetDrawingContext();
204 
GetHardWareGrContext()205     std::shared_ptr<Drawing::GPUContext> GetHardWareGrContext() const
206     {
207         return hcontext_;
208     }
209 
GetHardwareQueue()210     VkQueue GetHardwareQueue() const
211     {
212         return hbackendContext_.fQueue;
213     }
214 
215     VkSemaphore RequireSemaphore();
216     void SendSemaphoreWithFd(VkSemaphore semaphore, int fenceFd);
217     void DestroyAllSemaphoreFence();
218 
219 friend class RsVulkanContext;
220 private:
221     std::mutex vkMutex_;
222     std::mutex graphicsQueueMutex_;
223     std::mutex hGraphicsQueueMutex_;
224     void* handle_ = nullptr;
225     bool acquiredMandatoryProcAddresses_ = false;
226     VkInstance instance_ = VK_NULL_HANDLE;
227     VkPhysicalDevice physicalDevice_ = VK_NULL_HANDLE;
228     uint32_t graphicsQueueFamilyIndex_ = UINT32_MAX;
229     VkDevice device_ = VK_NULL_HANDLE;
230     VkQueue hardwareQueue_ = VK_NULL_HANDLE;
231     VkQueue queue_ = VK_NULL_HANDLE;
232     VkPhysicalDeviceFeatures2 physicalDeviceFeatures2_;
233     VkPhysicalDeviceProtectedMemoryFeatures* protectedMemoryFeatures_ = nullptr;
234     VkPhysicalDeviceSamplerYcbcrConversionFeatures ycbcrFeature_;
235     GrVkExtensions skVkExtensions_;
236     RsVulkanMemStat mVkMemStat;
237 
238     std::shared_ptr<Drawing::GPUContext> hcontext_ = nullptr;
239     // static thread_local GrVkBackendContext backendContext_;
240     GrVkBackendContext backendContext_;
241     GrVkBackendContext hbackendContext_;
242 
243     RsVulkanInterface(const RsVulkanInterface &) = delete;
244     RsVulkanInterface &operator=(const RsVulkanInterface &) = delete;
245 
246     RsVulkanInterface(RsVulkanInterface &&) = delete;
247     RsVulkanInterface &operator=(RsVulkanInterface &&) = delete;
248 
249     bool OpenLibraryHandle();
250     bool SetupLoaderProcAddresses();
251     bool CloseLibraryHandle();
252     bool SetupDeviceProcAddresses(VkDevice device);
253     PFN_vkVoidFunction AcquireProc(
254         const char* proc_name,
255         const VkInstance& instance) const;
256     PFN_vkVoidFunction AcquireProc(const char* proc_name, const VkDevice& device) const;
257     std::shared_ptr<Drawing::GPUContext> CreateNewDrawingContext(bool isProtected = false);
258     std::shared_ptr<MemoryHandler> memHandler_;
259 
260     struct semaphoreFence {
261         VkSemaphore semaphore;
262         std::unique_ptr<SyncFence> fence;
263     };
264     std::list<semaphoreFence> usedSemaphoreFenceList_;
265     std::mutex semaphoreLock_;
266 };
267 
268 class RsVulkanContext {
269 public:
270     static RsVulkanContext& GetSingleton();
271     RsVulkanContext();
~RsVulkanContext()272     ~RsVulkanContext() {};
273 
274     RsVulkanContext(const RsVulkanContext&) = delete;
275     RsVulkanContext &operator=(const RsVulkanContext&) = delete;
276 
277     RsVulkanContext(const RsVulkanContext&&) = delete;
278     RsVulkanContext &operator=(const RsVulkanContext&&) = delete;
279 
280     void SetIsProtected(bool isProtected);
281 
282     RsVulkanInterface& GetRsVulkanInterface();
283 
IsValid()284     bool IsValid()
285     {
286         return GetRsVulkanInterface().IsValid();
287     }
288 
CreateSkiaGetProc()289     GrVkGetProc CreateSkiaGetProc()
290     {
291         return GetRsVulkanInterface().CreateSkiaGetProc();
292     }
293 
GetRsVkMemStat()294     RsVulkanMemStat& GetRsVkMemStat()
295     {
296         return GetRsVulkanInterface().GetRsVkMemStat();
297     }
298 
GetPhysicalDevice()299     VkPhysicalDevice GetPhysicalDevice()
300     {
301         return GetRsVulkanInterface().GetPhysicalDevice();
302     }
303 
GetDevice()304     VkDevice GetDevice()
305     {
306         return GetRsVulkanInterface().GetDevice();
307     }
308 
GetQueue()309     VkQueue GetQueue()
310     {
311         return GetRsVulkanInterface().GetQueue();
312     }
313 
314     inline const GrVkBackendContext& GetGrVkBackendContext(
315         bool useHBackendContext = false) noexcept
316     {
317         return GetRsVulkanInterface().GetGrVkBackendContext(useHBackendContext);
318     }
319 
GetVulkanVersion()320     inline const std::string GetVulkanVersion()
321     {
322         return std::to_string(VK_API_VERSION_1_2);
323     }
324 
325     std::shared_ptr<Drawing::GPUContext> CreateDrawingContext(bool isProtected = false);
326     std::shared_ptr<Drawing::GPUContext> GetDrawingContext();
327 
328     void ClearGrContext(bool isProtected = false);
329 
330     static VKAPI_ATTR VkResult HookedVkQueueSubmit(VkQueue queue, uint32_t submitCount,
331         VkSubmitInfo* pSubmits, VkFence fence);
332 
333     static VKAPI_ATTR VkResult HookedVkQueueSignalReleaseImageOHOS(VkQueue queue, uint32_t waitSemaphoreCount,
334         const VkSemaphore* pWaitSemaphores, VkImage image, int32_t* pNativeFenceFd);
335 
GetHardWareGrContext()336     std::shared_ptr<Drawing::GPUContext> GetHardWareGrContext()
337     {
338         return GetRsVulkanInterface().GetHardWareGrContext();
339     }
340 
GetHardwareQueue()341     VkQueue GetHardwareQueue()
342     {
343         return GetRsVulkanInterface().GetHardwareQueue();
344     }
345 
GetMemoryHandler()346     const std::shared_ptr<MemoryHandler> GetMemoryHandler()
347     {
348         return GetRsVulkanInterface().GetMemoryHandler();
349     }
350 
GetIsProtected()351     bool GetIsProtected() const
352     {
353         return isProtected_;
354     }
355 
356 private:
357     static thread_local bool isProtected_;
358     static thread_local std::shared_ptr<Drawing::GPUContext> drawingContext_;
359     static thread_local std::shared_ptr<Drawing::GPUContext> protectedDrawingContext_;
360 };
361 
362 } // namespace Rosen
363 } // namespace OHOS
364 
365 #endif
366