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