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