• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <cassert>
17 #include <cstdint>
18 #include <cstdio>
19 #include <limits>
20 #include <thread>
21 #include <unordered_map>
22 #include <vector>
23 #include <iostream>
24 #include <malloc.h>
25 #include <algorithm>
26 #include <new>
27 #include <securec.h>
28 #include <cstring>
29 #include <cinttypes>
30 #include <refbase.h>
31 
32 #include <vulkan/vulkan_core.h>
33 #include <window.h>
34 #include <graphic_common.h>
35 #include <native_window.h>
36 #include <vulkan/vulkan.h>
37 #include <scoped_bytrace.h>
38 #include "vk_dispatch_table_helper.h"
39 #include "vk_layer_dispatch_table.h"
40 #include "swapchain_layer_log.h"
41 #include "sync_fence.h"
42 #if USE_APS_IGAMESERVICE_FUNC
43 #include "vulkan_slice_report.h"
44 #endif
45 
46 #define SWAPCHAIN_SURFACE_NAME "VK_LAYER_OHOS_surface"
47 using namespace OHOS;
48 
49 enum Extension {
50     OHOS_SURFACE,
51     OHOS_NATIVE_BUFFER,
52     KHR_SURFACE,
53     KHR_SWAPCHAIN,
54     EXT_SWAPCHAIN_COLOR_SPACE,
55     KHR_GET_SURFACE_CAPABILITIES_2,
56     EXT_HDR_METADATA,
57     EXTENSION_COUNT,
58     EXTENSION_UNKNOWN,
59 };
60 
61 struct LayerData {
62     VkInstance instance = VK_NULL_HANDLE;
63     VkDevice device = VK_NULL_HANDLE;
64     uint32_t instanceVersion = VK_API_VERSION_1_0;
65     std::unique_ptr<VkLayerDispatchTable> deviceDispatchTable;
66     std::unique_ptr<VkLayerInstanceDispatchTable> instanceDispatchTable;
67     std::unordered_map<VkDebugUtilsMessengerEXT, VkDebugUtilsMessengerCreateInfoEXT> debugCallbacks;
68     PFN_vkSetDeviceLoaderData fpSetDeviceLoaderData = nullptr;
69     std::bitset<Extension::EXTENSION_COUNT> enabledExtensions;
70 };
71 
72 namespace {
73 constexpr uint32_t MIN_BUFFER_SIZE = SURFACE_DEFAULT_QUEUE_SIZE;
74 constexpr uint32_t MAX_BUFFER_SIZE = SURFACE_MAX_QUEUE_SIZE;
75 struct LoaderVkLayerDispatchTable;
76 typedef uintptr_t DispatchKey;
77 
78 template <typename T>
GetDispatchKey(const T object)79 inline DispatchKey GetDispatchKey(const T object)
80 {
81     return reinterpret_cast<DispatchKey>(*reinterpret_cast<LoaderVkLayerDispatchTable* const*>(object));
82 }
83 
GetChainInfo(const VkInstanceCreateInfo * pCreateInfo,VkLayerFunction func)84 VkLayerInstanceCreateInfo* GetChainInfo(const VkInstanceCreateInfo* pCreateInfo, VkLayerFunction func)
85 {
86     auto chainInfo = static_cast<const VkLayerInstanceCreateInfo*>(pCreateInfo->pNext);
87     while (chainInfo != nullptr) {
88         if (chainInfo->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chainInfo->function == func) {
89             return const_cast<VkLayerInstanceCreateInfo*>(chainInfo);
90         }
91         chainInfo = static_cast<const VkLayerInstanceCreateInfo*>(chainInfo->pNext);
92     }
93     SWLOGE("SwapchainLayer Find VkLayerInstanceCreateInfo Failed");
94     return nullptr;
95 }
96 
GetChainInfo(const VkDeviceCreateInfo * pCreateInfo,VkLayerFunction func)97 VkLayerDeviceCreateInfo* GetChainInfo(const VkDeviceCreateInfo* pCreateInfo, VkLayerFunction func)
98 {
99     auto chainInfo = static_cast<const VkLayerDeviceCreateInfo*>(pCreateInfo->pNext);
100     while (chainInfo != nullptr) {
101         if (chainInfo->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chainInfo->function == func) {
102             return const_cast<VkLayerDeviceCreateInfo*>(chainInfo);
103         }
104         chainInfo = static_cast<const VkLayerDeviceCreateInfo*>(chainInfo->pNext);
105     }
106     SWLOGE("SwapchainLayer Find VkLayerDeviceCreateInfo Failed");
107     return nullptr;
108 }
109 }  // namespace
110 
111 #define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)
112 
ToUint32(uint64_t val)113 static inline uint32_t ToUint32(uint64_t val)
114 {
115     if (val > UINT32_MAX) {
116         SWLOGE("%{public}" PRIu64 " is too large to convert to uint32", val);
117     }
118     return static_cast<uint32_t>(val);
119 }
120 
121 namespace SWAPCHAIN {
122 std::unordered_map<DispatchKey, LayerData*> g_layerDataMap;
123 const VkSurfaceTransformFlagsKHR g_supportedTransforms =
124     VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR |
125     VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR |
126     VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR |
127     VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR |
128     VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR |
129     VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR |
130     VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR |
131     VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR |
132     VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR;
133 
GetLayerDataPtr(DispatchKey dataKey)134 LayerData* GetLayerDataPtr(DispatchKey dataKey)
135 {
136     LayerData* layerData = nullptr;
137     auto it = g_layerDataMap.find(dataKey);
138     if (it == g_layerDataMap.end()) {
139         layerData = new LayerData;
140         g_layerDataMap[dataKey] = layerData;
141     } else {
142         layerData = it->second;
143     }
144     return layerData;
145 }
146 
FreeLayerDataPtr(DispatchKey dataKey)147 void FreeLayerDataPtr(DispatchKey dataKey)
148 {
149     auto it = g_layerDataMap.find(dataKey);
150     if (it == g_layerDataMap.end()) {
151         return;
152     }
153     delete it->second;
154     g_layerDataMap.erase(it);
155 }
156 
DebugMessageToUserCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,const char * message)157 void DebugMessageToUserCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, const char* message)
158 {
159     VkDebugUtilsMessengerCallbackDataEXT callbackData = {};
160     callbackData.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
161     callbackData.pMessageIdName = "SwapchainLayer";
162     callbackData.pMessage = message;
163 
164     for (auto [key, layerData] : g_layerDataMap) {
165         if (layerData->debugCallbacks.empty()) {
166             continue;
167         }
168         for (auto& callback : layerData->debugCallbacks) {
169             if (!(severity & callback.second.messageSeverity)) {
170                 continue;
171             }
172             if (!(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT & callback.second.messageType)) {
173                 continue;
174             }
175             callback.second.pfnUserCallback(severity, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
176                                             &callbackData, callback.second.pUserData);
177         }
178     }
179 }
180 
GetExtensionProperties(const uint32_t count,const VkExtensionProperties * layerExtensions,uint32_t * pCount,VkExtensionProperties * pProperties)181 VkResult GetExtensionProperties(const uint32_t count, const VkExtensionProperties* layerExtensions,
182                                 uint32_t* pCount, VkExtensionProperties* pProperties)
183 {
184     if (pProperties == nullptr || layerExtensions == nullptr) {
185         *pCount = count;
186         return VK_SUCCESS;
187     }
188 
189     uint32_t copySize = *pCount < count ? *pCount : count;
190     errno_t ret = memcpy_s(pProperties, copySize * sizeof(VkExtensionProperties),
191                            layerExtensions, copySize * sizeof(VkExtensionProperties));
192     if (ret != EOK) {
193         return VK_INCOMPLETE;
194     }
195     *pCount = copySize;
196     if (copySize < count) {
197         return VK_INCOMPLETE;
198     }
199 
200     return VK_SUCCESS;
201 }
202 
GetLayerProperties(const uint32_t count,const VkLayerProperties * layerProperties,uint32_t * pCount,VkLayerProperties * pProperties)203 VkResult GetLayerProperties(const uint32_t count, const VkLayerProperties* layerProperties,
204                             uint32_t* pCount, VkLayerProperties* pProperties)
205 {
206     if (pProperties == nullptr || layerProperties == nullptr) {
207         *pCount = count;
208         return VK_SUCCESS;
209     }
210 
211     uint32_t copySize = *pCount < count ? *pCount : count;
212     errno_t ret = memcpy_s(pProperties, copySize * sizeof(VkLayerProperties),
213                            layerProperties, copySize * sizeof(VkLayerProperties));
214     if (ret != EOK) {
215         return VK_INCOMPLETE;
216     }
217     *pCount = copySize;
218     if (copySize < count) {
219         return VK_INCOMPLETE;
220     }
221 
222     return VK_SUCCESS;
223 }
224 
225 static const VkExtensionProperties g_instanceExtensions[] = {
226     {
227         .extensionName = VK_KHR_SURFACE_EXTENSION_NAME,
228         .specVersion = 25,
229     },
230     {
231         .extensionName = VK_OHOS_SURFACE_EXTENSION_NAME,
232         .specVersion = 1,
233     },
234     {
235         .extensionName = VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME,
236         .specVersion = 4,
237     },
238     {
239         .extensionName = VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME,
240         .specVersion = 1,
241     }
242 };
243 
244 static const VkExtensionProperties g_deviceExtensions[] = {
245     {
246         .extensionName = VK_KHR_SWAPCHAIN_EXTENSION_NAME,
247         .specVersion = 70,
248     },
249     {
250         .extensionName = VK_EXT_HDR_METADATA_EXTENSION_NAME,
251         .specVersion = 2,
252     }
253 };
254 
255 constexpr VkLayerProperties swapchainLayer = {
256     SWAPCHAIN_SURFACE_NAME,
257     VK_LAYER_API_VERSION,
258     1,
259     "Vulkan Swapchain",
260 };
261 
262 struct Surface {
263     NativeWindow* window;
264     VkSwapchainKHR swapchainHandle;
265     uint64_t usage;
266 };
267 
268 struct Swapchain {
SwapchainSWAPCHAIN::Swapchain269     Swapchain(Surface &surface, uint32_t numImages, VkPresentModeKHR presentMode,
270         OH_NativeBuffer_TransformType preTransform)
271         : surface(surface), numImages(numImages), mailboxMode(presentMode == VK_PRESENT_MODE_MAILBOX_KHR),
272           preTransform(preTransform),
273           shared(presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
274                  presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) {}
275 
276     Surface &surface;
277     uint32_t numImages;
278     bool mailboxMode;
279     OH_NativeBuffer_TransformType preTransform;
280     bool shared;
281 
282     struct Image {
ImageSWAPCHAIN::Swapchain::Image283         Image() : image(VK_NULL_HANDLE), buffer(nullptr), requestFence(-1), releaseFence(-1), requested(false) {}
284         VkImage image;
285         NativeWindowBuffer* buffer;
286         int requestFence;
287         int releaseFence;
288         bool requested;
289     } images[MAX_BUFFER_SIZE];
290 };
291 
292 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName);
293 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance,
294                                                              const char* funcName);
295 
HandleFromSurface(Surface * surface)296 VkSurfaceKHR HandleFromSurface(Surface* surface)
297 {
298     return VkSurfaceKHR(reinterpret_cast<uint64_t>(surface));
299 }
300 
SurfaceFromHandle(VkSurfaceKHR handle)301 Surface* SurfaceFromHandle(VkSurfaceKHR handle)
302 {
303     return reinterpret_cast<Surface*>(handle);
304 }
305 
SwapchainFromHandle(VkSwapchainKHR handle)306 Swapchain* SwapchainFromHandle(VkSwapchainKHR handle)
307 {
308     return reinterpret_cast<Swapchain*>(handle);
309 }
310 
HandleFromSwapchain(Swapchain * swapchain)311 VkSwapchainKHR HandleFromSwapchain(Swapchain* swapchain)
312 {
313     return VkSwapchainKHR(reinterpret_cast<uint64_t>(swapchain));
314 }
315 
DefaultAllocate(void *,size_t size,size_t alignment,VkSystemAllocationScope)316 VKAPI_ATTR void* DefaultAllocate(void*, size_t size, size_t alignment, VkSystemAllocationScope)
317 {
318     void* ptr = nullptr;
319     int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
320     return ret == 0 ? ptr : nullptr;
321 }
322 
DefaultReallocate(void *,void * ptr,size_t size,size_t alignment,VkSystemAllocationScope)323 VKAPI_ATTR void* DefaultReallocate(void*, void* ptr, size_t size, size_t alignment, VkSystemAllocationScope)
324 {
325     if (size == 0) {
326         free(ptr);
327         return nullptr;
328     }
329 
330     size_t oldSize = ptr ? malloc_usable_size(ptr) : 0;
331     if (size <= oldSize) {
332         return ptr;
333     }
334 
335     void* newPtr = nullptr;
336     if (posix_memalign(&newPtr, std::max(alignment, sizeof(void*)), size) != 0) {
337         return nullptr;
338     }
339 
340     if (ptr != nullptr) {
341         auto ret = memcpy_s(newPtr, size, ptr, oldSize);
342         if (ret != EOK) {
343             free(newPtr);
344             return nullptr;
345         }
346         free(ptr);
347     }
348     return newPtr;
349 }
350 
DefaultFree(void *,void * ptr)351 VKAPI_ATTR void DefaultFree(void*, void* ptr)
352 {
353     free(ptr);
354 }
355 
GetDefaultAllocator()356 const VkAllocationCallbacks &GetDefaultAllocator()
357 {
358     static const VkAllocationCallbacks defaultAllocCallbacks = {
359         .pUserData = nullptr,
360         .pfnAllocation = DefaultAllocate,
361         .pfnReallocation = DefaultReallocate,
362         .pfnFree = DefaultFree,
363     };
364 
365     return defaultAllocCallbacks;
366 }
367 
TranslateVkColorSpaceToNative(VkColorSpaceKHR colorspace)368 OH_NativeBuffer_ColorSpace TranslateVkColorSpaceToNative(VkColorSpaceKHR colorspace)
369 {
370     switch (colorspace) {
371         case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
372             return OH_COLORSPACE_SRGB_FULL;
373         case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT:
374             return OH_COLORSPACE_P3_FULL;
375         case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
376             return OH_COLORSPACE_LINEAR_SRGB;
377         case VK_COLOR_SPACE_DCI_P3_LINEAR_EXT:
378             return OH_COLORSPACE_LINEAR_P3;
379         case VK_COLOR_SPACE_BT709_LINEAR_EXT:
380             return OH_COLORSPACE_LINEAR_BT709;
381         case VK_COLOR_SPACE_BT709_NONLINEAR_EXT:
382             return OH_COLORSPACE_BT709_FULL;
383         case VK_COLOR_SPACE_BT2020_LINEAR_EXT:
384             return OH_COLORSPACE_LINEAR_BT2020;
385         case VK_COLOR_SPACE_HDR10_ST2084_EXT:
386             return OH_COLORSPACE_BT2020_PQ_FULL;
387         case VK_COLOR_SPACE_DOLBYVISION_EXT:
388             return OH_COLORSPACE_BT2020_PQ_FULL;
389         case VK_COLOR_SPACE_HDR10_HLG_EXT:
390             return OH_COLORSPACE_BT2020_HLG_FULL;
391         case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT:
392             return OH_COLORSPACE_ADOBERGB_FULL;
393         case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT:
394             return OH_COLORSPACE_SRGB_FULL;
395         default:
396             return OH_COLORSPACE_NONE;
397     }
398 }
399 
SwapchainCloseFd(int & fd)400 void SwapchainCloseFd(int &fd)
401 {
402     if (fd < 0) {
403         return;
404     }
405     close(fd);
406     fd = -1;
407 }
408 
IsFencePending(int fd)409 static bool IsFencePending(int fd)
410 {
411     if (fd < 0) {
412         return false;
413     }
414     errno = 0;
415     sptr<OHOS::SyncFence> syncFence = new OHOS::SyncFence(fd);
416     return syncFence->Wait(0) == -1 && errno == ETIME;
417 }
418 
ReleaseSwapchainImage(VkDevice device,NativeWindow * window,int releaseFence,Swapchain::Image & image,bool deferIfPending)419 void ReleaseSwapchainImage(VkDevice device, NativeWindow* window, int releaseFence, Swapchain::Image &image,
420                            bool deferIfPending)
421 {
422     ScopedBytrace trace(__func__);
423     if (releaseFence != -1 && !image.requested) {
424         SWLOGE("%{public}s, can't provide a release fence for non-requested images", __func__);
425         DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
426             "can't provide a release fence for non-requested images");
427         return;
428     }
429 
430     VkLayerDispatchTable* pDisp =
431         GetLayerDataPtr(GetDispatchKey(device))->deviceDispatchTable.get();
432     if (image.requested) {
433         if (releaseFence >= 0) {
434             SwapchainCloseFd(image.requestFence);
435         } else {
436             releaseFence = image.requestFence;
437         }
438         image.requestFence = -1;
439 
440         if (window != nullptr) {
441             NativeWindowCancelBuffer(window, image.buffer);
442             SwapchainCloseFd(releaseFence);
443         } else {
444             if (releaseFence >= 0) {
445                 sptr<OHOS::SyncFence> releaseSyncFence = new OHOS::SyncFence(releaseFence);
446                 releaseSyncFence->Wait(-1);
447             }
448         }
449         releaseFence = -1;
450         image.requested = false;
451     }
452 
453     if (deferIfPending && IsFencePending(image.releaseFence)) {
454         return;
455     }
456 
457     SwapchainCloseFd(image.releaseFence);
458 
459     if (image.image != VK_NULL_HANDLE) {
460         NativeObjectUnreference(image.buffer);
461         image.buffer = nullptr;
462         pDisp->DestroyImage(device, image.image, nullptr);
463         image.image = VK_NULL_HANDLE;
464     }
465 }
466 
ReleaseSwapchain(VkDevice device,Swapchain * swapchain)467 void ReleaseSwapchain(VkDevice device, Swapchain* swapchain)
468 {
469     ScopedBytrace trace(__func__);
470     if (swapchain->surface.swapchainHandle != HandleFromSwapchain(swapchain)) {
471         return;
472     }
473 
474     for (uint32_t i = 0; i < swapchain->numImages; i++) {
475         if (!swapchain->images[i].requested) {
476             ReleaseSwapchainImage(device, nullptr, -1, swapchain->images[i], true);
477         }
478     }
479     swapchain->surface.swapchainHandle = VK_NULL_HANDLE;
480 }
481 
GetPixelFormat(VkFormat format)482 GraphicPixelFormat GetPixelFormat(VkFormat format)
483 {
484     switch (format) {
485         case VK_FORMAT_R8G8B8A8_UNORM:
486         case VK_FORMAT_R8G8B8A8_SRGB:
487             return GRAPHIC_PIXEL_FMT_RGBA_8888;
488         case VK_FORMAT_R5G6B5_UNORM_PACK16:
489             return GRAPHIC_PIXEL_FMT_RGB_565;
490         case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
491             return GRAPHIC_PIXEL_FMT_RGBA_1010102;
492         default:
493             SWLOGE("Swapchain format %{public}d unsupported return GRAPHIC_PIXEL_FMT_RGBA_8888;", format);
494             DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
495                 ("unsupported swapchain format " + std::to_string(format)).c_str());
496             return GRAPHIC_PIXEL_FMT_RGBA_8888;
497     }
498 }
499 
500 /*
501     On OpenHarmony, the direction of rotation is counterclockwise
502 */
503 
TranslateNativeToVulkanTransformHint(OH_NativeBuffer_TransformType nativeTransformType)504 VkSurfaceTransformFlagBitsKHR TranslateNativeToVulkanTransformHint(OH_NativeBuffer_TransformType nativeTransformType)
505 {
506     switch (nativeTransformType) {
507         case NATIVEBUFFER_ROTATE_NONE:
508             return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
509         case NATIVEBUFFER_ROTATE_90:
510             return VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR;
511         case NATIVEBUFFER_ROTATE_180:
512             return VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR;
513         case NATIVEBUFFER_ROTATE_270:
514             return VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR;
515         case NATIVEBUFFER_FLIP_H:
516         case NATIVEBUFFER_FLIP_V_ROT180:
517             return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR;
518         case NATIVEBUFFER_FLIP_V:
519         case NATIVEBUFFER_FLIP_H_ROT180:
520             return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR;
521         case NATIVEBUFFER_FLIP_H_ROT90:
522         case NATIVEBUFFER_FLIP_V_ROT270:
523             return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR;
524         case NATIVEBUFFER_FLIP_V_ROT90:
525         case NATIVEBUFFER_FLIP_H_ROT270:
526             return VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR;
527         default:
528             return VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
529     }
530 }
531 
532 //Use to compare preTransform to transformHint
TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform)533 OH_NativeBuffer_TransformType TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform)
534 {
535     switch (transform) {
536         case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
537             return NATIVEBUFFER_ROTATE_NONE;
538         case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
539             return NATIVEBUFFER_ROTATE_270;
540         case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
541             return NATIVEBUFFER_ROTATE_180;
542         case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
543             return NATIVEBUFFER_ROTATE_90;
544         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
545             return NATIVEBUFFER_FLIP_H;
546         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
547             return NATIVEBUFFER_FLIP_V_ROT90;
548         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
549             return NATIVEBUFFER_FLIP_V;
550         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
551             return NATIVEBUFFER_FLIP_H_ROT90;
552         default:
553             return NATIVEBUFFER_ROTATE_NONE;
554     }
555 }
556 
557 //After pre-rotation, the window needs to be rotated counterclockwise to the corresponding angle
InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform)558 OH_NativeBuffer_TransformType InvertTransformToNative(VkSurfaceTransformFlagBitsKHR transform)
559 {
560     switch (transform) {
561         case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
562             return NATIVEBUFFER_ROTATE_NONE;
563         case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
564             return NATIVEBUFFER_ROTATE_90;
565         case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
566             return NATIVEBUFFER_ROTATE_180;
567         case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
568             return NATIVEBUFFER_ROTATE_270;
569         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
570             return NATIVEBUFFER_FLIP_H;
571         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
572             return NATIVEBUFFER_FLIP_H_ROT270;
573         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
574             return NATIVEBUFFER_FLIP_V;
575         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
576             return NATIVEBUFFER_FLIP_H_ROT90;
577         default:
578             return NATIVEBUFFER_ROTATE_NONE;
579     }
580 }
581 
SetWindowPixelFormat(NativeWindow * window,GraphicPixelFormat pixelFormat)582 VKAPI_ATTR VkResult SetWindowPixelFormat(NativeWindow* window, GraphicPixelFormat pixelFormat)
583 {
584     if (window == nullptr) {
585         return VK_ERROR_SURFACE_LOST_KHR;
586     }
587     int err = NativeWindowHandleOpt(window, SET_FORMAT, pixelFormat);
588     if (err != OHOS::GSERROR_OK) {
589         SWLOGE("NativeWindow Set Buffers Format(%{public}d) failed: (%{public}d)", pixelFormat, err);
590         return VK_ERROR_SURFACE_LOST_KHR;
591     }
592     return VK_SUCCESS;
593 }
594 
SetWindowColorSpace(NativeWindow * window,OH_NativeBuffer_ColorSpace colorSpace)595 VKAPI_ATTR VkResult SetWindowColorSpace(NativeWindow* window, OH_NativeBuffer_ColorSpace colorSpace)
596 {
597     if (window == nullptr) {
598         return VK_ERROR_SURFACE_LOST_KHR;
599     }
600     int err = OH_NativeWindow_SetColorSpace(window, colorSpace);
601     if (err != OHOS::GSERROR_OK) {
602         SWLOGE("NativeWindow Set ColorSpace [%{public}d] Failed : %{public}d",
603             static_cast<int>(colorSpace), err);
604         return VK_ERROR_SURFACE_LOST_KHR;
605     }
606     return VK_SUCCESS;
607 }
608 
SetWindowBufferGeometry(NativeWindow * window,int width,int height)609 VKAPI_ATTR VkResult SetWindowBufferGeometry(NativeWindow* window, int width, int height)
610 {
611     if (window == nullptr) {
612         return VK_ERROR_SURFACE_LOST_KHR;
613     }
614     int err = NativeWindowHandleOpt(window, SET_BUFFER_GEOMETRY, width, height);
615     if (err != OHOS::GSERROR_OK) {
616         SWLOGE("NativeWindow Set Buffer Geometry width:%{public}d,height:%{public}d failed: %{public}d",
617             width, height, err);
618         return VK_ERROR_SURFACE_LOST_KHR;
619     }
620 
621     return VK_SUCCESS;
622 }
623 
SetWindowTransform(NativeWindow * window,const VkSwapchainCreateInfoKHR * createInfo)624 VKAPI_ATTR VkResult SetWindowTransform(NativeWindow* window, const VkSwapchainCreateInfoKHR* createInfo)
625 {
626     OH_NativeBuffer_TransformType transformType = InvertTransformToNative(createInfo->preTransform);
627     SWLOGD("Swapchain translate VkSurfaceTransformFlagBitsKHR:%{public}d to OH_NativeBuffer_TransformType:%{public}d",
628         static_cast<int>(createInfo->preTransform), static_cast<int>(transformType));
629     if (window == nullptr) {
630         return VK_ERROR_SURFACE_LOST_KHR;
631     }
632     int err = NativeWindowHandleOpt(window, SET_TRANSFORM, transformType);
633     if (err != OHOS::GSERROR_OK) {
634         SWLOGE("NativeWindow Set Transform failed: %{public}d", err);
635         return VK_ERROR_SURFACE_LOST_KHR;
636     }
637 
638     OH_NativeBuffer_TransformType transformHint = NATIVEBUFFER_ROTATE_NONE;
639     err = NativeWindowGetTransformHint(window, &transformHint);
640     if (err != OHOS::GSERROR_OK) {
641         SWLOGE("NativeWindow get TransformHint failed, error num : %{public}d", err);
642         return VK_ERROR_SURFACE_LOST_KHR;
643     }
644     if (transformHint != TranslateVulkanToNativeTransform(createInfo->preTransform)) {
645         SWLOGE("The App Is Not Doing Pre-rotation, transformHint: %{public}d, preTransform(to native): %{public}d",
646                transformHint, TranslateVulkanToNativeTransform(createInfo->preTransform));
647     }
648 
649     return VK_SUCCESS;
650 }
651 
SetWindowBufferUsage(VkDevice device,NativeWindow * window,const VkSwapchainCreateInfoKHR * createInfo)652 VKAPI_ATTR VkResult SetWindowBufferUsage(VkDevice device, NativeWindow* window,
653     const VkSwapchainCreateInfoKHR* createInfo)
654 {
655     uint64_t grallocUsage = 0;
656     VkLayerDispatchTable* pDisp =
657         GetLayerDataPtr(GetDispatchKey(device))->deviceDispatchTable.get();
658     if (pDisp->GetSwapchainGrallocUsageOHOS != nullptr) {
659         VkResult res =
660             pDisp->GetSwapchainGrallocUsageOHOS(device, createInfo->imageFormat, createInfo->imageUsage, &grallocUsage);
661         if (res != VK_SUCCESS) {
662             SWLOGE("GetSwapchainGrallocUsageOHOS failed: %{public}d", res);
663             return VK_ERROR_SURFACE_LOST_KHR;
664         }
665         SWLOGD("GetSwapchainGrallocUsageOHOS Get grallocUsage %{public}" PRIu64"", grallocUsage);
666     }
667 
668     bool userSetVkTransform = createInfo->preTransform != VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR;
669     SWLOGD("User %{public}d Set VkTransform, preTransform is %{public}d",
670         userSetVkTransform, static_cast<int32_t>(createInfo->preTransform));
671     bool needSetFlgForDSS = false;
672     if (!userSetVkTransform) {
673         OH_NativeBuffer_TransformType curWindowTransformType = NATIVEBUFFER_ROTATE_NONE;
674         int err = NativeWindowGetTransformHint(window, &curWindowTransformType);
675         if (err != OHOS::GSERROR_OK) {
676             SWLOGE("NativeWindow Get TransformHint failed: %{public}d", err);
677             return VK_ERROR_SURFACE_LOST_KHR;
678         }
679         SWLOGD("NativeWindow Get NativeTransformHint %{public}d", static_cast<int>(curWindowTransformType));
680         if (curWindowTransformType == NATIVEBUFFER_ROTATE_270 || curWindowTransformType == NATIVEBUFFER_ROTATE_90) {
681             needSetFlgForDSS = true;
682         }
683     }
684 
685     if (needSetFlgForDSS) {
686         grallocUsage |= BUFFER_USAGE_VENDOR_PRI19;
687     } else {
688         grallocUsage &= ~BUFFER_USAGE_VENDOR_PRI19;
689     }
690     SWLOGD("[%{public}d] Set Rotated Flag in Usage: %{public}" PRIu64"", needSetFlgForDSS, grallocUsage);
691 
692     if (createInfo->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR) {
693         grallocUsage |= BUFFER_USAGE_PROTECTED;
694     }
695     int err = NativeWindowHandleOpt(window, SET_USAGE, grallocUsage);
696     if (err != OHOS::GSERROR_OK) {
697         SWLOGE("NativeWindow Set Usage %{public}" PRIu64" failed: %{public}d", grallocUsage, err);
698         return VK_ERROR_SURFACE_LOST_KHR;
699     }
700     return VK_SUCCESS;
701 }
702 
SetWindowScalingMode(NativeWindow * window,OHScalingModeV2 scalingMode)703 VKAPI_ATTR VkResult SetWindowScalingMode(NativeWindow* window, OHScalingModeV2 scalingMode)
704 {
705     if (window == nullptr) {
706         return VK_ERROR_SURFACE_LOST_KHR;
707     }
708     SWLOGD("NativeWindow Set OHScalingMode is [%{public}d]", static_cast<int>(scalingMode));
709     int err = OH_NativeWindow_NativeWindowSetScalingModeV2(window, scalingMode);
710     if (err != OHOS::GSERROR_OK) {
711         SWLOGE("NativeWindow Set ScalingMode[%{public}d] failed, error: %{public}d",
712             static_cast<int>(scalingMode), err);
713         return VK_ERROR_SURFACE_LOST_KHR;
714     }
715 
716     return VK_SUCCESS;
717 }
718 
SetWindowQueueSize(NativeWindow * window,const VkSwapchainCreateInfoKHR * createInfo)719 VKAPI_ATTR VkResult SetWindowQueueSize(NativeWindow* window, const VkSwapchainCreateInfoKHR* createInfo)
720 {
721     if (window == nullptr) {
722         return VK_ERROR_SURFACE_LOST_KHR;
723     }
724     uint32_t numImages = createInfo->minImageCount;
725     if (numImages > MAX_BUFFER_SIZE) {
726         SWLOGE("Swapchain init minImageCount[%{public}u] can not be more than maxBufferCount[%{public}u]",
727             numImages, MAX_BUFFER_SIZE);
728         return VK_ERROR_INITIALIZATION_FAILED;
729     }
730     if (createInfo->presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
731         createInfo->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) {
732         numImages = 1;
733     }
734     SWLOGD("NativeWindow Set Queue Size [%{public}u], Swapchain has the same number of iamge", numImages);
735     window->surface->SetQueueSize(numImages);
736 
737     return VK_SUCCESS;
738 }
739 
SetWindowInfo(VkDevice device,const VkSwapchainCreateInfoKHR * createInfo)740 VKAPI_ATTR VkResult SetWindowInfo(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo)
741 {
742     OH_NativeBuffer_ColorSpace OHColorSpace = TranslateVkColorSpaceToNative(createInfo->imageColorSpace);
743     SWLOGD("Swapchain translate VkColorSpaceKHR:%{public}d to OHColorSpace:%{public}d",
744         static_cast<int>(createInfo->imageColorSpace), static_cast<int>(OHColorSpace));
745     GraphicPixelFormat pixelFormat = GetPixelFormat(createInfo->imageFormat);
746     SWLOGD("Swapchain translate VkFormat:%{public}d to GraphicPixelFormat:%{public}d",
747         static_cast<int>(createInfo->imageFormat), static_cast<int>(pixelFormat));
748     Surface &surface = *SurfaceFromHandle(createInfo->surface);
749 
750     NativeWindow* window = surface.window;
751     // Set PixelFormat
752     if (SetWindowPixelFormat(window, pixelFormat) != VK_SUCCESS) {
753         return VK_ERROR_SURFACE_LOST_KHR;
754     }
755     // Set ColorSpace
756     if (OHColorSpace == OH_COLORSPACE_NONE) {
757         SWLOGE("Color Space [%{public}d] Not Support, Not Set Native Window!",
758             static_cast<int>(createInfo->imageColorSpace));
759     } else if (SetWindowColorSpace(window, OHColorSpace) != VK_SUCCESS) {
760         return VK_ERROR_SURFACE_LOST_KHR;
761     }
762     // Set BufferGeometry
763     if (SetWindowBufferGeometry(window, static_cast<int>(createInfo->imageExtent.width),
764         static_cast<int>(createInfo->imageExtent.height)) != VK_SUCCESS) {
765         return VK_ERROR_SURFACE_LOST_KHR;
766     }
767 
768     // Set Buffer Usage
769     if (SetWindowBufferUsage(device, window, createInfo) != VK_SUCCESS) {
770         return VK_ERROR_SURFACE_LOST_KHR;
771     }
772 
773     // Set Transform
774     if (SetWindowTransform(window, createInfo) != VK_SUCCESS) {
775         return VK_ERROR_SURFACE_LOST_KHR;
776     }
777 
778     // Set Scaling mode
779     if (SetWindowScalingMode(window, OHScalingModeV2::OH_SCALING_MODE_SCALE_TO_WINDOW_V2) != VK_SUCCESS) {
780         return VK_ERROR_SURFACE_LOST_KHR;
781     }
782 
783     // Set Bufferqueue Size
784     if (SetWindowQueueSize(window, createInfo) != VK_SUCCESS) {
785         return VK_ERROR_SURFACE_LOST_KHR;
786     }
787 
788     return VK_SUCCESS;
789 }
790 
SetSwapchainCreateInfo(VkDevice device,const VkSwapchainCreateInfoKHR * createInfo)791 VkResult SetSwapchainCreateInfo(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo)
792 {
793     if (createInfo->oldSwapchain != VK_NULL_HANDLE) {
794         ReleaseSwapchain(device, SwapchainFromHandle(createInfo->oldSwapchain));
795     }
796 
797     return SetWindowInfo(device, createInfo);
798 }
799 
InitImageCreateInfo(const VkSwapchainCreateInfoKHR * createInfo,VkImageCreateInfo * imageCreate)800 void InitImageCreateInfo(const VkSwapchainCreateInfoKHR* createInfo, VkImageCreateInfo* imageCreate)
801 {
802     imageCreate->sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
803     bool swapchainCreateProtected = createInfo->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR;
804     imageCreate->flags = swapchainCreateProtected ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u;
805     imageCreate->imageType = VK_IMAGE_TYPE_2D;
806     imageCreate->format = createInfo->imageFormat;
807     imageCreate->extent = {0, 0, 1};
808     imageCreate->mipLevels = 1;
809     imageCreate->arrayLayers = 1;
810     imageCreate->samples = VK_SAMPLE_COUNT_1_BIT;
811     imageCreate->tiling = VK_IMAGE_TILING_OPTIMAL;
812     imageCreate->usage = createInfo->imageUsage;
813     imageCreate->sharingMode = createInfo->imageSharingMode;
814     imageCreate->queueFamilyIndexCount = createInfo->queueFamilyIndexCount;
815     imageCreate->pQueueFamilyIndices = createInfo->pQueueFamilyIndices;
816 }
817 
CreateImages(uint32_t & numImages,Swapchain * swapchain,const VkSwapchainCreateInfoKHR * createInfo,VkImageCreateInfo & imageCreate,VkDevice device)818 VKAPI_ATTR VkResult CreateImages(uint32_t &numImages, Swapchain* swapchain, const VkSwapchainCreateInfoKHR* createInfo,
819     VkImageCreateInfo &imageCreate, VkDevice device)
820 {
821     ScopedBytrace trace(__func__);
822     VkLayerDispatchTable* pDisp =
823         GetLayerDataPtr(GetDispatchKey(device))->deviceDispatchTable.get();
824     Surface &surface = *SurfaceFromHandle(createInfo->surface);
825     NativeWindow* window = surface.window;
826     if (createInfo->oldSwapchain != VK_NULL_HANDLE) {
827         SWLOGD("Swapchain Recreate ,clean buffer queue");
828         window->surface->CleanCache();
829     }
830     VkResult result = VK_SUCCESS;
831     for (uint32_t i = 0; i < numImages; i++) {
832         Swapchain::Image &img = swapchain->images[i];
833         NativeWindowBuffer* buffer = nullptr;
834         int fencefd = -1;
835         // if NativeWindowRequestBuffer success, should close fencefd
836         int err = NativeWindowRequestBuffer(window, &buffer, &fencefd);
837         if (err != OHOS::GSERROR_OK) {
838             SWLOGE("NativeWindow RequestBuffer[%{public}u] failed: (%{public}d)", i, err);
839             result = VK_ERROR_SURFACE_LOST_KHR;
840             break;
841         }
842         img.buffer = buffer;
843         img.requested = true;
844         img.requestFence = fencefd;
845         imageCreate.extent = VkExtent3D {static_cast<uint32_t>(img.buffer->sfbuffer->GetWidth()),
846                                           static_cast<uint32_t>(img.buffer->sfbuffer->GetHeight()), 1};
847         ((VkNativeBufferOHOS*)(imageCreate.pNext))->handle =
848             reinterpret_cast<struct OHBufferHandle *>(img.buffer->sfbuffer->GetBufferHandle());
849         result = pDisp->CreateImage(device, &imageCreate, nullptr, &img.image);
850         if (result != VK_SUCCESS) {
851             SWLOGD("vkCreateImage failed error: %{public}u", result);
852             break;
853         }
854         NativeObjectReference(buffer);
855     }
856 
857     SWLOGD("swapchain init shared %{public}d", swapchain->shared);
858     for (uint32_t i = 0; i < numImages; i++) {
859         Swapchain::Image &img = swapchain->images[i];
860         if (img.requested) {
861             if (!swapchain->shared) {
862                 NativeWindowCancelBuffer(window, img.buffer);
863                 SwapchainCloseFd(img.requestFence);
864                 img.requested = false;
865             }
866         }
867     }
868     return result;
869 }
870 
DestroySwapchainInternal(VkDevice device,VkSwapchainKHR swapchainHandle,const VkAllocationCallbacks * allocator)871 static void DestroySwapchainInternal(VkDevice device, VkSwapchainKHR swapchainHandle,
872                                      const VkAllocationCallbacks* allocator)
873 {
874     ScopedBytrace trace(__func__);
875     Swapchain* swapchain = SwapchainFromHandle(swapchainHandle);
876     if (swapchain == nullptr) {
877         return;
878     }
879 
880     bool active = swapchain->surface.swapchainHandle == swapchainHandle;
881     NativeWindow* window = active ? swapchain->surface.window : nullptr;
882 
883     for (uint32_t i = 0; i < swapchain->numImages; i++) {
884         ReleaseSwapchainImage(device, window, -1, swapchain->images[i], false);
885     }
886 
887     if (active) {
888         swapchain->surface.swapchainHandle = VK_NULL_HANDLE;
889         window->surface->CleanCache();
890     }
891     if (allocator == nullptr) {
892         allocator = &GetDefaultAllocator();
893     }
894     swapchain->~Swapchain();
895     allocator->pfnFree(allocator->pUserData, swapchain);
896 }
897 
CreateSwapchainKHR(VkDevice device,const VkSwapchainCreateInfoKHR * createInfo,const VkAllocationCallbacks * allocator,VkSwapchainKHR * swapchainHandle)898 VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo,
899     const VkAllocationCallbacks* allocator, VkSwapchainKHR* swapchainHandle)
900 {
901     ScopedBytrace trace(__func__);
902     Surface &surface = *SurfaceFromHandle(createInfo->surface);
903     if (surface.swapchainHandle != createInfo->oldSwapchain) {
904         return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
905     }
906 
907     VkResult result = SetSwapchainCreateInfo(device, createInfo);
908     if (result != VK_SUCCESS) {
909         return result;
910     }
911     uint32_t numImages = surface.window->surface->GetQueueSize();
912 
913     if (allocator == nullptr) {
914         allocator = &GetDefaultAllocator();
915     }
916     void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Swapchain), alignof(Swapchain),
917         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
918     if (mem == nullptr) {
919         return VK_ERROR_OUT_OF_HOST_MEMORY;
920     }
921 
922     OH_NativeBuffer_TransformType transformType = TranslateVulkanToNativeTransform(createInfo->preTransform);
923     SWLOGD("Swapchain translate VkSurfaceTransformFlagBitsKHR:%{public}d to OH_NativeBuffer_TransformType:%{public}d",
924         static_cast<int>(createInfo->preTransform), static_cast<int>(transformType));
925     Swapchain* swapchain = new (mem) Swapchain(surface, numImages, createInfo->presentMode, transformType);
926 
927     VkSwapchainImageCreateInfoOHOS swapchainImageCreate = {
928         .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_OHOS,
929         .pNext = nullptr,
930     };
931     VkNativeBufferOHOS imageNativeBuffer = {
932         .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_OHOS,
933         .pNext = &swapchainImageCreate,
934     };
935 
936     VkImageCreateInfo imageCreate = {
937         .pNext = &imageNativeBuffer,
938     };
939 
940     InitImageCreateInfo(createInfo, &imageCreate);
941     result = CreateImages(numImages, swapchain, createInfo, imageCreate, device);
942     if (result != VK_SUCCESS) {
943         DestroySwapchainInternal(device, HandleFromSwapchain(swapchain), allocator);
944         return result;
945     }
946 
947     surface.swapchainHandle = HandleFromSwapchain(swapchain);
948     *swapchainHandle = surface.swapchainHandle;
949     return VK_SUCCESS;
950 }
951 
DestroySwapchainKHR(VkDevice device,VkSwapchainKHR vkSwapchain,const VkAllocationCallbacks * pAllocator)952 VKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(
953     VkDevice device, VkSwapchainKHR vkSwapchain, const VkAllocationCallbacks* pAllocator)
954 {
955     ScopedBytrace trace(__func__);
956     DestroySwapchainInternal(device, vkSwapchain, pAllocator);
957 }
958 
GetSwapchainImagesKHR(VkDevice device,VkSwapchainKHR vkSwapchain,uint32_t * count,VkImage * images)959 VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(
960     VkDevice device, VkSwapchainKHR vkSwapchain, uint32_t* count, VkImage* images)
961 {
962     const Swapchain &swapchain = *SwapchainFromHandle(vkSwapchain);
963     if (images == nullptr) {
964         *count = swapchain.numImages;
965         return VK_SUCCESS;
966     }
967 
968     VkResult result = VK_SUCCESS;
969     uint32_t numImages = swapchain.numImages;
970     if (*count < swapchain.numImages) {
971         numImages = *count;
972         result = VK_INCOMPLETE;
973     }
974     for (uint32_t i = 0; i < numImages; i++) {
975         images[i] = swapchain.images[i].image;
976     }
977     *count = numImages;
978     return result;
979 }
980 
AcquireNextImageKHR(VkDevice device,VkSwapchainKHR swapchainHandle,uint64_t timeout,VkSemaphore semaphore,VkFence vkFence,uint32_t * imageIndex)981 VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchainHandle,
982     uint64_t timeout, VkSemaphore semaphore, VkFence vkFence, uint32_t* imageIndex)
983 {
984     ScopedBytrace trace(__func__);
985     Swapchain &swapchain = *SwapchainFromHandle(swapchainHandle);
986     NativeWindow* nativeWindow = swapchain.surface.window;
987     VkResult result = VK_SUCCESS;
988 
989     if (swapchain.surface.swapchainHandle != swapchainHandle) {
990         return VK_ERROR_OUT_OF_DATE_KHR;
991     }
992 
993     LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(device));
994     if (swapchain.shared) {
995         *imageIndex = 0;
996         return deviceLayerData->deviceDispatchTable->AcquireImageOHOS(device, swapchain.images[*imageIndex].image, -1,
997                                                                       semaphore, vkFence);
998     }
999 
1000     NativeWindowBuffer* nativeWindowBuffer = nullptr;
1001     int fence = -1;
1002     int32_t ret = NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fence);
1003     if (ret != OHOS::GSERROR_OK) {
1004         SWLOGE("NativeWindow RequestBuffer failed: (%{public}d)", ret);
1005         DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
1006             ("RequestBuffer failed: " + std::to_string(ret)).c_str());
1007         return VK_ERROR_SURFACE_LOST_KHR;
1008     }
1009 
1010     uint32_t index = 0;
1011     for (; index < swapchain.numImages; index++) {
1012         if (swapchain.images[index].buffer->sfbuffer == nativeWindowBuffer->sfbuffer) {
1013             swapchain.images[index].requested = true;
1014             swapchain.images[index].requestFence = fence;
1015             break;
1016         }
1017     }
1018 
1019     if (index == swapchain.numImages) {
1020         SWLOGD("NativeWindow RequestBuffer returned unrecognized buffer");
1021         if (NativeWindowCancelBuffer(nativeWindow, nativeWindowBuffer) != OHOS::GSERROR_OK) {
1022             SWLOGE("NativeWindowCancelBuffer failed: (%{public}d)", ret);
1023         }
1024         SwapchainCloseFd(fence);
1025         return VK_ERROR_OUT_OF_DATE_KHR;
1026     }
1027     int fenceDup = -1;
1028     if (fence != -1) {
1029         fenceDup = ::dup(fence);
1030         if (fenceDup == -1) {
1031             SWLOGE("dup NativeWindow requested fencefd failed, wait for signalled");
1032             sptr<OHOS::SyncFence> syncFence = new OHOS::SyncFence(fence);
1033             syncFence->Wait(-1);
1034         }
1035     }
1036     // in vkAcquireImageOHOS should close fenceDup fd
1037     result = deviceLayerData->deviceDispatchTable->AcquireImageOHOS(device, swapchain.images[index].image, fenceDup,
1038                                                                     semaphore, vkFence);
1039     if (result != VK_SUCCESS) {
1040         if (NativeWindowCancelBuffer(nativeWindow, nativeWindowBuffer) != OHOS::GSERROR_OK) {
1041             SWLOGE("NativeWindowCancelBuffer failed: (%{public}d)", ret);
1042         }
1043         swapchain.images[index].requested = false;
1044         swapchain.images[index].requestFence = -1;
1045         SwapchainCloseFd(fence);
1046         return result;
1047     }
1048 
1049     *imageIndex = index;
1050     return VK_SUCCESS;
1051 }
1052 
1053 VKAPI_ATTR
GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pRectCount,VkRect2D * pRects)1054 VkResult GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
1055     VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects)
1056 {
1057     if (pRects == nullptr) {
1058         *pRectCount = 1;
1059         return VK_SUCCESS;
1060     }
1061     bool incomplete = *pRectCount < 1;
1062     *pRectCount = std::min(*pRectCount, 1u);
1063     if (incomplete) {
1064         return VK_INCOMPLETE;
1065     }
1066 
1067     NativeWindow* window = SurfaceFromHandle(surface)->window;
1068 
1069     int32_t width = 0;
1070     int32_t height = 0;
1071     int err = NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &height, &width);
1072     if (err != OHOS::GSERROR_OK) {
1073         SWLOGE("NativeWindow get buffer geometry failed: (%{public}d)", err);
1074     }
1075     pRects[0].offset.x = 0;
1076     pRects[0].offset.y = 0;
1077     pRects[0].extent = VkExtent2D{static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
1078     return VK_SUCCESS;
1079 }
1080 
1081 VKAPI_ATTR
AcquireNextImage2KHR(VkDevice device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)1082 VkResult AcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex)
1083 {
1084     return AcquireNextImageKHR(device, pAcquireInfo->swapchain, pAcquireInfo->timeout,
1085                                pAcquireInfo->semaphore, pAcquireInfo->fence, pImageIndex);
1086 }
1087 
GetPresentRegions(const VkPresentInfoKHR * presentInfo)1088 const VkPresentRegionKHR* GetPresentRegions(const VkPresentInfoKHR* presentInfo)
1089 {
1090     const VkPresentRegionsKHR* presentRegions = nullptr;
1091     const VkPresentRegionsKHR* nextRegions = reinterpret_cast<const VkPresentRegionsKHR*>(presentInfo->pNext);
1092     while (nextRegions != nullptr) {
1093         if (nextRegions->sType == VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR) {
1094             presentRegions = nextRegions;
1095         }
1096         nextRegions = reinterpret_cast<const VkPresentRegionsKHR*>(nextRegions->pNext);
1097     }
1098 
1099     if (presentRegions == nullptr) {
1100         return nullptr;
1101     } else {
1102         if (presentRegions->swapchainCount != presentInfo->swapchainCount) {
1103             SWLOGE("vkQueuePresentKHR VkPresentRegions::swapchainCount != VkPresentInfo::swapchainCount");
1104         }
1105         return presentRegions->pRegions;
1106     }
1107 }
1108 
ReleaseImage(VkQueue queue,const VkPresentInfoKHR * presentInfo,Swapchain::Image & img,int32_t & fence)1109 VkResult ReleaseImage(VkQueue queue, const VkPresentInfoKHR* presentInfo,
1110     Swapchain::Image &img, int32_t &fence)
1111 {
1112     ScopedBytrace trace(__func__);
1113     LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(queue));
1114     VkResult result = deviceLayerData->deviceDispatchTable->QueueSignalReleaseImageOHOS(
1115         queue, presentInfo->waitSemaphoreCount, presentInfo->pWaitSemaphores, img.image, &fence);
1116     SwapchainCloseFd(img.releaseFence);
1117     if (fence >= 0) {
1118         img.releaseFence = dup(fence);
1119     }
1120     return result;
1121 }
1122 
GetRegionRect(const VkAllocationCallbacks * defaultAllocator,struct Region::Rect ** rects,int32_t rectangleCount)1123 struct Region::Rect* GetRegionRect(
1124     const VkAllocationCallbacks* defaultAllocator, struct Region::Rect** rects, int32_t rectangleCount)
1125 {
1126     return static_cast<struct Region::Rect*>(
1127                 defaultAllocator->pfnReallocation(
1128                     defaultAllocator->pUserData, *rects,
1129                     sizeof(Region::Rect) *rectangleCount,
1130                     alignof(Region::Rect), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
1131 }
1132 
InitRegionRect(const VkRectLayerKHR * layer,struct Region::Rect * rect,int32_t bufferHeight)1133 void InitRegionRect(const VkRectLayerKHR* layer, struct Region::Rect* rect, int32_t bufferHeight)
1134 {
1135     rect->x = layer->offset.x;
1136     // flip rect to adapt to bottom-left coordinate
1137     rect->y = bufferHeight - layer->extent.height - layer->offset.y;
1138     rect->w = layer->extent.width;
1139     rect->h = layer->extent.height;
1140 }
1141 
FlushBuffer(const VkPresentRegionKHR * region,struct Region::Rect * rects,Swapchain & swapchain,Swapchain::Image & img,int32_t fence)1142 VkResult FlushBuffer(const VkPresentRegionKHR* region, struct Region::Rect* rects,
1143     Swapchain &swapchain, Swapchain::Image &img, int32_t fence)
1144 {
1145     ScopedBytrace trace(__func__);
1146     const VkAllocationCallbacks* defaultAllocator = &GetDefaultAllocator();
1147     Region localRegion = {};
1148     if (memset_s(&localRegion, sizeof(localRegion), 0, sizeof(Region)) != EOK) {
1149         return VK_ERROR_SURFACE_LOST_KHR;
1150     }
1151     NativeWindow* window = swapchain.surface.window;
1152     // Get buffer width and height for flip damage rect
1153     int32_t bufferWidth = 0;
1154     int32_t bufferHeight = 0;
1155     int err = NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &bufferHeight, &bufferWidth);
1156     if (err != OHOS::GSERROR_OK) {
1157         SWLOGE("NativeWindow get buffer geometry failed, error num: %{public}d", err);
1158         return VK_ERROR_SURFACE_LOST_KHR;
1159     }
1160     if (region != nullptr) {
1161         int32_t rectangleCount = region->rectangleCount;
1162         if (rectangleCount > 0) {
1163             struct Region::Rect* tmpRects = GetRegionRect(defaultAllocator, &rects, rectangleCount);
1164             if (tmpRects != nullptr) {
1165                 rects = tmpRects;
1166             } else {
1167                 rectangleCount = 0;
1168             }
1169         }
1170         for (int32_t r = 0; r < rectangleCount; ++r) {
1171             InitRegionRect(&region->pRectangles[r], &rects[r], bufferHeight);
1172         }
1173 
1174         localRegion.rects = rects;
1175         localRegion.rectNumber = rectangleCount;
1176     }
1177     // the acquire fence will be close by BufferQueue module
1178     err = NativeWindowFlushBuffer(window, img.buffer, fence, localRegion);
1179     VkResult scResult = VK_SUCCESS;
1180     if (err != OHOS::GSERROR_OK) {
1181         SWLOGE("NativeWindow FlushBuffer failed: (%{public}d)", err);
1182         scResult = VK_ERROR_SURFACE_LOST_KHR;
1183     } else {
1184         SwapchainCloseFd(img.requestFence);
1185         img.requested = false;
1186     }
1187 
1188     if (swapchain.shared && scResult == VK_SUCCESS) {
1189         NativeWindowBuffer* buffer = nullptr;
1190         int fenceFd = -1;
1191         err = NativeWindowRequestBuffer(window, &buffer, &fenceFd);
1192         if (err != OHOS::GSERROR_OK) {
1193             scResult = VK_ERROR_SURFACE_LOST_KHR;
1194         } else if (img.buffer != buffer) {
1195             scResult = VK_ERROR_SURFACE_LOST_KHR;
1196             SwapchainCloseFd(fenceFd);
1197         } else {
1198             img.requestFence = fenceFd;
1199             img.requested = true;
1200         }
1201     }
1202 
1203     return scResult;
1204 }
1205 
QueuePresentKHR(VkQueue queue,const VkPresentInfoKHR * presentInfo)1206 VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(
1207     VkQueue queue, const VkPresentInfoKHR* presentInfo)
1208 {
1209     ScopedBytrace trace(__func__);
1210     VkResult ret = VK_SUCCESS;
1211 
1212     const VkPresentRegionKHR* regions = GetPresentRegions(presentInfo);
1213     const VkAllocationCallbacks* defaultAllocator = &GetDefaultAllocator();
1214     struct Region::Rect* rects = nullptr;
1215     LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(queue));
1216     VkDevice device = deviceLayerData->device;
1217 
1218     for (uint32_t i = 0; i < presentInfo->swapchainCount; i++) {
1219         Swapchain &swapchain = *(reinterpret_cast<Swapchain*>(presentInfo->pSwapchains[i]));
1220         Swapchain::Image &img = swapchain.images[presentInfo->pImageIndices[i]];
1221         const VkPresentRegionKHR* region = (regions != nullptr) ? &regions[i] : nullptr;
1222         int32_t fence = -1;
1223         ret = ReleaseImage(queue, presentInfo, img, fence);
1224         if (swapchain.surface.swapchainHandle == presentInfo->pSwapchains[i]) {
1225             if (ret == VK_SUCCESS) {
1226                 ret = FlushBuffer(region, rects, swapchain, img, fence);
1227             } else {
1228                 ReleaseSwapchain(device, &swapchain);
1229             }
1230         } else {
1231             SWLOGE("vkQueuePresentKHR swapchainHandle != pSwapchains[%{public}d]", i);
1232             ReleaseSwapchainImage(device, nullptr, fence, img, true);
1233             ret = VK_ERROR_OUT_OF_DATE_KHR;
1234         }
1235 
1236         if (presentInfo->pResults) {
1237             presentInfo->pResults[i] = ret;
1238         }
1239     }
1240     if (rects != nullptr) {
1241         defaultAllocator->pfnFree(defaultAllocator->pUserData, rects);
1242     }
1243 #if USE_APS_IGAMESERVICE_FUNC
1244     OHOS::GameService::VulkanSliceReport::GetInstance().ReportVulkanRender();
1245 #endif
1246     return ret;
1247 }
1248 
GetDeviceGroupPresentCapabilitiesKHR(VkDevice,VkDeviceGroupPresentCapabilitiesKHR * pDeviceGroupPresentCapabilities)1249 VKAPI_ATTR VkResult GetDeviceGroupPresentCapabilitiesKHR(
1250     VkDevice, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities)
1251 {
1252     if (pDeviceGroupPresentCapabilities == nullptr) {
1253         return VK_ERROR_OUT_OF_HOST_MEMORY;
1254     }
1255 
1256     memset_s(pDeviceGroupPresentCapabilities->presentMask,
1257         sizeof(pDeviceGroupPresentCapabilities->presentMask), 0, sizeof(pDeviceGroupPresentCapabilities->presentMask));
1258     pDeviceGroupPresentCapabilities->presentMask[0] = 1u;
1259     pDeviceGroupPresentCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
1260 
1261     return VK_SUCCESS;
1262 }
1263 
GetDeviceGroupSurfacePresentModesKHR(VkDevice,VkSurfaceKHR,VkDeviceGroupPresentModeFlagsKHR * pModes)1264 VKAPI_ATTR VkResult GetDeviceGroupSurfacePresentModesKHR(
1265     VkDevice, VkSurfaceKHR, VkDeviceGroupPresentModeFlagsKHR* pModes)
1266 {
1267     *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
1268     return VK_SUCCESS;
1269 }
1270 
GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,const VkSurfaceKHR surface,VkBool32 * pSupported)1271 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(
1272     VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, const VkSurfaceKHR surface, VkBool32* pSupported)
1273 {
1274     *pSupported = VK_TRUE;
1275     return VK_SUCCESS;
1276 }
1277 
CreateSurfaceOHOS(VkInstance instance,const VkSurfaceCreateInfoOHOS * pCreateInfo,const VkAllocationCallbacks * allocator,VkSurfaceKHR * outSurface)1278 VKAPI_ATTR VkResult VKAPI_CALL CreateSurfaceOHOS(VkInstance instance,
1279     const VkSurfaceCreateInfoOHOS* pCreateInfo,
1280     const VkAllocationCallbacks* allocator, VkSurfaceKHR* outSurface)
1281 {
1282     ScopedBytrace trace(__func__);
1283     if (allocator == nullptr) {
1284         allocator = &GetDefaultAllocator();
1285     }
1286     void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface), alignof(Surface),
1287                                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
1288     if (mem == nullptr) {
1289         return VK_ERROR_OUT_OF_HOST_MEMORY;
1290     }
1291 
1292     Surface* surface = new (mem) Surface;
1293     surface->window = pCreateInfo->window;
1294     NativeObjectReference(surface->window);
1295     surface->swapchainHandle = VK_NULL_HANDLE;
1296     int err = NativeWindowHandleOpt(pCreateInfo->window, GET_USAGE, &(surface->usage));
1297     if (err != OHOS::GSERROR_OK) {
1298         NativeObjectUnreference(surface->window);
1299         surface->~Surface();
1300         allocator->pfnFree(allocator->pUserData, surface);
1301         SWLOGE("NativeWindow get usage failed, error num : %{public}d", err);
1302         return VK_ERROR_SURFACE_LOST_KHR;
1303     }
1304 
1305     *outSurface = HandleFromSurface(surface);
1306     return VK_SUCCESS;
1307 }
1308 
DestroySurfaceKHR(VkInstance instance,VkSurfaceKHR vkSurface,const VkAllocationCallbacks * pAllocator)1309 VKAPI_ATTR void VKAPI_CALL DestroySurfaceKHR(
1310     VkInstance instance, VkSurfaceKHR vkSurface, const VkAllocationCallbacks* pAllocator)
1311 {
1312     ScopedBytrace trace(__func__);
1313     Surface* surface = SurfaceFromHandle(vkSurface);
1314     if (surface == nullptr) {
1315         return;
1316     }
1317     if (pAllocator == nullptr) {
1318         pAllocator = &GetDefaultAllocator();
1319     }
1320     NativeObjectUnreference(surface->window);
1321     surface->~Surface();
1322     pAllocator->pfnFree(pAllocator->pUserData, surface);
1323 }
1324 
GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilitiesKHR * capabilities)1325 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilitiesKHR(
1326     VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* capabilities)
1327 {
1328     int32_t width = 0;
1329     int32_t height = 0;
1330     OH_NativeBuffer_TransformType transformHint = NATIVEBUFFER_ROTATE_NONE;
1331     uint32_t defaultQueueSize = MAX_BUFFER_SIZE;
1332     if (surface != VK_NULL_HANDLE) {
1333         NativeWindow* window = SurfaceFromHandle(surface)->window;
1334         int err = NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &height, &width);
1335         if (err != OHOS::GSERROR_OK) {
1336             SWLOGE("NativeWindow get buffer geometry failed, error num : %{public}d", err);
1337             return VK_ERROR_SURFACE_LOST_KHR;
1338         }
1339         err = NativeWindowGetTransformHint(window, &transformHint);
1340         if (err != OHOS::GSERROR_OK) {
1341             SWLOGE("NativeWindow get TransformHint failed, error num : %{public}d", err);
1342             return VK_ERROR_SURFACE_LOST_KHR;
1343         }
1344         defaultQueueSize = window->surface->GetQueueSize();
1345         SWLOGD("NativeWindow default Queue Size : (%{public}d)", defaultQueueSize);
1346     }
1347 
1348     capabilities->minImageCount = std::min(defaultQueueSize, MIN_BUFFER_SIZE);
1349     capabilities->maxImageCount = std::max(defaultQueueSize, MAX_BUFFER_SIZE);
1350     capabilities->currentExtent = VkExtent2D {static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
1351     capabilities->minImageExtent = VkExtent2D {1, 1};
1352     capabilities->maxImageExtent = VkExtent2D {4096, 4096};
1353     capabilities->maxImageArrayLayers = 1;
1354     capabilities->supportedTransforms = g_supportedTransforms;
1355     capabilities->currentTransform = TranslateNativeToVulkanTransformHint(transformHint);
1356     capabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
1357     capabilities->supportedUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1358                                         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
1359                                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1360     return VK_SUCCESS;
1361 }
1362 
1363 
1364 /*
1365     VK_EXT_hdr_metadata
1366 */
SetHdrMetadataEXT(VkDevice device,uint32_t swapchainCount,const VkSwapchainKHR * pSwapchains,const VkHdrMetadataEXT * pMetadata)1367 VKAPI_ATTR void VKAPI_CALL SetHdrMetadataEXT(
1368     VkDevice device, uint32_t swapchainCount, const VkSwapchainKHR* pSwapchains, const VkHdrMetadataEXT* pMetadata)
1369 {
1370     SWLOGE("NativeWindow Not Support Set HdrMetaData[TODO]");
1371 }
1372 
GetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,VkSurfaceCapabilities2KHR * pSurfaceCapabilities)1373 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilities2KHR(
1374     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
1375     VkSurfaceCapabilities2KHR* pSurfaceCapabilities)
1376 {
1377     VkResult result = GetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice, pSurfaceInfo->surface,
1378                                                               &pSurfaceCapabilities->surfaceCapabilities);
1379 
1380     VkSurfaceCapabilities2KHR* caps = pSurfaceCapabilities;
1381     while(caps->pNext != nullptr) {
1382         caps = reinterpret_cast<VkSurfaceCapabilities2KHR*>(caps->pNext);
1383         if (caps->sType == VK_STRUCTURE_TYPE_SHARED_PRESENT_SURFACE_CAPABILITIES_KHR) {
1384             reinterpret_cast<VkSharedPresentSurfaceCapabilitiesKHR*>(caps)->sharedPresentSupportedUsageFlags =
1385                 pSurfaceCapabilities->surfaceCapabilities.supportedUsageFlags;
1386         } else if (caps->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR) {
1387             reinterpret_cast<VkSurfaceProtectedCapabilitiesKHR*>(caps)->supportsProtected= VK_TRUE;
1388         }
1389     }
1390     return result;
1391 }
1392 
1393 
GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,const VkSurfaceKHR surface,uint32_t * count,VkSurfaceFormatKHR * formats)1394 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormatsKHR(
1395     VkPhysicalDevice physicalDevice, const VkSurfaceKHR surface, uint32_t* count, VkSurfaceFormatKHR* formats)
1396 {
1397     if (surface == VK_NULL_HANDLE) {
1398         return VK_ERROR_SURFACE_LOST_KHR;
1399     }
1400 
1401     LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(physicalDevice));
1402     bool enableSwapchainColorSpace = deviceLayerData->enabledExtensions.test(Extension::EXT_SWAPCHAIN_COLOR_SPACE);
1403 
1404     std::vector<VkSurfaceFormatKHR> allFormats = {
1405         // RGBA_8888
1406         {VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
1407         {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
1408         // RGB_565
1409         {VK_FORMAT_R5G6B5_UNORM_PACK16, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
1410         // RGBA_1010102
1411         {VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
1412         {VK_FORMAT_A2B10G10R10_UNORM_PACK32, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT}
1413     };
1414 
1415     if (enableSwapchainColorSpace) {
1416         allFormats.emplace_back(VkSurfaceFormatKHR{
1417             VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_BT709_LINEAR_EXT});
1418         allFormats.emplace_back(VkSurfaceFormatKHR{
1419             VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT});
1420         allFormats.emplace_back(VkSurfaceFormatKHR{
1421             VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT});
1422     }
1423     VkResult result = VK_SUCCESS;
1424     if (formats != nullptr) {
1425         uint32_t transferCount = allFormats.size();
1426         if (transferCount > *count) {
1427             transferCount = *count;
1428             result = VK_INCOMPLETE;
1429         }
1430         std::copy(allFormats.begin(), allFormats.begin() + transferCount, formats);
1431         *count = transferCount;
1432     } else {
1433         *count = allFormats.size();
1434     }
1435 
1436     return result;
1437 }
1438 
GetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,const VkPhysicalDeviceSurfaceInfo2KHR * pSurfaceInfo,uint32_t * pSurfaceFormatCount,VkSurfaceFormat2KHR * pSurfaceFormats)1439 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormats2KHR(
1440     VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
1441     uint32_t* pSurfaceFormatCount, VkSurfaceFormat2KHR* pSurfaceFormats)
1442 {
1443     // Get pSurfaceFormatCount
1444     if (pSurfaceFormats == nullptr) {
1445         return GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount, nullptr);
1446     }
1447     // Get pSurfaceFormats
1448     uint32_t formatCount = *pSurfaceFormatCount;
1449 
1450     std::vector<VkSurfaceFormatKHR> surfaceFormats(formatCount);
1451     VkResult res = GetPhysicalDeviceSurfaceFormatsKHR(physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount,
1452         surfaceFormats.data());
1453 
1454     if (res == VK_SUCCESS || res == VK_INCOMPLETE) {
1455         for (uint32_t i = 0; i < formatCount; i++) {
1456             pSurfaceFormats[i].surfaceFormat = surfaceFormats[i];
1457         }
1458     }
1459 
1460     return res;
1461 }
1462 
QueryPresentationProperties(VkPhysicalDevice physicalDevice,VkPhysicalDevicePresentationPropertiesOHOS * presentationProperties)1463 void QueryPresentationProperties(
1464     VkPhysicalDevice physicalDevice,
1465     VkPhysicalDevicePresentationPropertiesOHOS* presentationProperties)
1466 {
1467     VkPhysicalDeviceProperties2 properties = {
1468         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
1469         presentationProperties,
1470         {},
1471     };
1472 
1473     presentationProperties->sType =
1474         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_OHOS;
1475     presentationProperties->pNext = nullptr;
1476     presentationProperties->sharedImage = VK_FALSE;
1477 
1478     DispatchKey key = GetDispatchKey(physicalDevice);
1479     LayerData* curLayerData = GetLayerDataPtr(key);
1480     if (curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2) {
1481         curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2(physicalDevice, &properties);
1482     } else if (curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2KHR) {
1483         curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2KHR(physicalDevice, &properties);
1484     } else {
1485         SWLOGE("Func vkGetPhysicalDeviceProperties2 and vkGetPhysicalDeviceProperties2KHR are both null.");
1486     }
1487 }
1488 
GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,const VkSurfaceKHR surface,uint32_t * count,VkPresentModeKHR * pPresentModes)1489 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(
1490     VkPhysicalDevice physicalDevice, const VkSurfaceKHR surface, uint32_t* count, VkPresentModeKHR* pPresentModes)
1491 {
1492     std::vector<VkPresentModeKHR> presentModes = {
1493         VK_PRESENT_MODE_MAILBOX_KHR,
1494         VK_PRESENT_MODE_FIFO_KHR
1495     };
1496 
1497     VkPhysicalDevicePresentationPropertiesOHOS presentProperties = {};
1498     QueryPresentationProperties(physicalDevice, &presentProperties);
1499     if (presentProperties.sharedImage) {
1500         SWLOGE("NativeWindow Not Support Shared Mode, now. Not Report Shared Mode.");
1501     }
1502 
1503     uint32_t numModes = static_cast<uint32_t>(presentModes.size());
1504     VkResult result = VK_SUCCESS;
1505     if (pPresentModes != nullptr) {
1506         if (*count < numModes) {
1507             result = VK_INCOMPLETE;
1508         }
1509         *count = std::min(*count, numModes);
1510         std::copy_n(presentModes.data(), *count, pPresentModes);
1511     } else {
1512         *count = numModes;
1513     }
1514     return result;
1515 }
1516 
GetExtensionBitFromName(const char * name)1517 Extension GetExtensionBitFromName(const char* name)
1518 {
1519     if (name == nullptr) {
1520         return Extension::EXTENSION_UNKNOWN;
1521     }
1522     if (strcmp(name, VK_OHOS_SURFACE_EXTENSION_NAME) == 0) {
1523         return Extension::OHOS_SURFACE;
1524     }
1525     if (strcmp(name, VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME) == 0) {
1526         return Extension::OHOS_NATIVE_BUFFER;
1527     }
1528     if (strcmp(name, VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
1529         return Extension::KHR_SURFACE;
1530     }
1531     if (strcmp(name, VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
1532         return Extension::KHR_SWAPCHAIN;
1533     }
1534     if (strcmp(name, VK_EXT_SWAPCHAIN_COLOR_SPACE_EXTENSION_NAME) == 0) {
1535         return Extension::EXT_SWAPCHAIN_COLOR_SPACE;
1536     }
1537     if (strcmp(name, VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME) == 0) {
1538         return Extension::KHR_GET_SURFACE_CAPABILITIES_2;
1539     }
1540     if (strcmp(name, VK_EXT_HDR_METADATA_EXTENSION_NAME) == 0) {
1541         return Extension::EXT_HDR_METADATA;
1542     }
1543     return Extension::EXTENSION_UNKNOWN;
1544 }
1545 
CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)1546 VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(
1547     const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
1548 {
1549     ScopedBytrace trace(__func__);
1550     VkLayerInstanceCreateInfo* chainInfo = GetChainInfo(pCreateInfo, VK_LAYER_LINK_INFO);
1551 
1552     if (chainInfo == nullptr || chainInfo->u.pLayerInfo == nullptr) {
1553         return VK_ERROR_INITIALIZATION_FAILED;
1554     }
1555     PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
1556         chainInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1557     PFN_vkCreateInstance fpCreateInstance =
1558         (PFN_vkCreateInstance)fpGetInstanceProcAddr(nullptr, "vkCreateInstance");
1559     if (fpCreateInstance == nullptr) {
1560         return VK_ERROR_INITIALIZATION_FAILED;
1561     }
1562 
1563     chainInfo->u.pLayerInfo = chainInfo->u.pLayerInfo->pNext;
1564 
1565     VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
1566     if (result != VK_SUCCESS) {
1567         return result;
1568     }
1569 #if USE_APS_IGAMESERVICE_FUNC
1570     OHOS::GameService::VulkanSliceReport::GetInstance().InitVulkanReport();
1571 #endif
1572 
1573     LayerData* instanceLayerData = GetLayerDataPtr(GetDispatchKey(*pInstance));
1574     instanceLayerData->instance = *pInstance;
1575     instanceLayerData->instanceDispatchTable = std::make_unique<VkLayerInstanceDispatchTable>();
1576     layer_init_instance_dispatch_table(*pInstance, instanceLayerData->instanceDispatchTable.get(),
1577                                        fpGetInstanceProcAddr);
1578     for (uint32_t index = 0; index < pCreateInfo->enabledExtensionCount; index++) {
1579         auto extBit = GetExtensionBitFromName(pCreateInfo->ppEnabledExtensionNames[index]);
1580         if (extBit != Extension::EXTENSION_UNKNOWN) {
1581             instanceLayerData->enabledExtensions.set(extBit);
1582         }
1583     }
1584     return result;
1585 }
1586 
DestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)1587 VKAPI_ATTR void VKAPI_CALL DestroyInstance(
1588     VkInstance instance, const VkAllocationCallbacks* pAllocator)
1589 {
1590     ScopedBytrace trace(__func__);
1591     DispatchKey instanceKey = GetDispatchKey(instance);
1592     LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1593     curLayerData->instanceDispatchTable->DestroyInstance(instance, pAllocator);
1594     FreeLayerDataPtr(instanceKey);
1595 }
1596 
CheckExtensionAvailable(const std::string & extensionName,const std::vector<VkExtensionProperties> & deviceExtensions)1597 bool CheckExtensionAvailable(const std::string &extensionName,
1598                              const std::vector<VkExtensionProperties> &deviceExtensions)
1599 {
1600     bool extensionAvailable = false;
1601     for (uint32_t i = 0; i < deviceExtensions.size(); i++) {
1602         if (strcmp(extensionName.data(), deviceExtensions[i].extensionName) == 0) {
1603             extensionAvailable = true;
1604             break;
1605         }
1606     }
1607     return extensionAvailable;
1608 }
1609 
AddDeviceExtensions(VkPhysicalDevice gpu,const LayerData * gpuLayerData,std::vector<const char * > & enabledExtensions)1610 VkResult AddDeviceExtensions(VkPhysicalDevice gpu, const LayerData* gpuLayerData,
1611                              std::vector<const char*> &enabledExtensions)
1612 {
1613     VkResult result = VK_SUCCESS;
1614     uint32_t deviceExtensionCount = 0;
1615     result = gpuLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(
1616         gpu, nullptr, &deviceExtensionCount, nullptr);
1617     if (result == VK_SUCCESS && deviceExtensionCount > 0) {
1618         std::vector<VkExtensionProperties> deviceExtensions(deviceExtensionCount);
1619         result = gpuLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(
1620             gpu, nullptr, &deviceExtensionCount, deviceExtensions.data());
1621         if (result == VK_SUCCESS) {
1622             if (!CheckExtensionAvailable(VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME, deviceExtensions)) {
1623                 return VK_ERROR_INITIALIZATION_FAILED;
1624             }
1625             enabledExtensions.push_back(VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME);
1626             if (CheckExtensionAvailable(VK_OHOS_EXTERNAL_MEMORY_EXTENSION_NAME,
1627                                         deviceExtensions)) {
1628                 enabledExtensions.push_back(VK_OHOS_EXTERNAL_MEMORY_EXTENSION_NAME);
1629             }
1630         }
1631     }
1632     return VK_SUCCESS;
1633 }
1634 
CreateDevice(VkPhysicalDevice gpu,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1635 VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu,
1636     const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
1637 {
1638     ScopedBytrace trace(__func__);
1639     DispatchKey gpuKey = GetDispatchKey(gpu);
1640     LayerData* gpuLayerData = GetLayerDataPtr(gpuKey);
1641 
1642     VkDeviceCreateInfo createInfo = *pCreateInfo;
1643     std::vector<const char*> enabledExtensions = {};
1644     for (uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) {
1645         enabledExtensions.push_back(createInfo.ppEnabledExtensionNames[i]);
1646     }
1647 
1648     VkResult result = AddDeviceExtensions(gpu, gpuLayerData, enabledExtensions);
1649     if (result != VK_SUCCESS) {
1650         return result;
1651     }
1652 
1653     createInfo.enabledExtensionCount = ToUint32(enabledExtensions.size());
1654     createInfo.ppEnabledExtensionNames = enabledExtensions.data();
1655 
1656     VkLayerDeviceCreateInfo* linkInfo = GetChainInfo(pCreateInfo, VK_LAYER_LINK_INFO);
1657 
1658     if (linkInfo == nullptr || linkInfo->u.pLayerInfo == nullptr) {
1659         return VK_ERROR_INITIALIZATION_FAILED;
1660     }
1661     PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = linkInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1662     PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = linkInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
1663     PFN_vkCreateDevice fpCreateDevice =
1664         (PFN_vkCreateDevice)fpGetInstanceProcAddr(gpuLayerData->instance, "vkCreateDevice");
1665     if (fpCreateDevice == nullptr) {
1666         return VK_ERROR_INITIALIZATION_FAILED;
1667     }
1668 
1669     linkInfo->u.pLayerInfo = linkInfo->u.pLayerInfo->pNext;
1670 
1671     result = fpCreateDevice(gpu, &createInfo, pAllocator, pDevice);
1672     if (result != VK_SUCCESS) {
1673         return result;
1674     }
1675 
1676     LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(*pDevice));
1677     for (uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) {
1678         auto extBit = GetExtensionBitFromName(createInfo.ppEnabledExtensionNames[i]);
1679         if (extBit != Extension::EXTENSION_UNKNOWN) {
1680             deviceLayerData->enabledExtensions.set(extBit);
1681         }
1682     }
1683 
1684     deviceLayerData->deviceDispatchTable = std::make_unique<VkLayerDispatchTable>();
1685     deviceLayerData->instance = gpuLayerData->instance;
1686     deviceLayerData->device = *pDevice;
1687     layer_init_device_dispatch_table(*pDevice, deviceLayerData->deviceDispatchTable.get(), fpGetDeviceProcAddr);
1688 
1689     VkLayerDeviceCreateInfo* callbackInfo = GetChainInfo(pCreateInfo, VK_LOADER_DATA_CALLBACK);
1690     if (callbackInfo == nullptr || callbackInfo->u.pfnSetDeviceLoaderData == nullptr) {
1691         return VK_ERROR_INITIALIZATION_FAILED;
1692     }
1693     deviceLayerData->fpSetDeviceLoaderData = callbackInfo->u.pfnSetDeviceLoaderData;
1694 
1695     return VK_SUCCESS;
1696 }
1697 
DestroyDevice(VkDevice device,const VkAllocationCallbacks * pAllocator)1698 VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
1699 {
1700     ScopedBytrace trace(__func__);
1701     DispatchKey deviceKey = GetDispatchKey(device);
1702     LayerData* deviceData = GetLayerDataPtr(deviceKey);
1703     deviceData->deviceDispatchTable->DestroyDevice(device, pAllocator);
1704     FreeLayerDataPtr(deviceKey);
1705 }
1706 
CreateDebugUtilsMessengerEXT(VkInstance instance,const VkDebugUtilsMessengerCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDebugUtilsMessengerEXT * pMessenger)1707 VKAPI_ATTR VkResult VKAPI_CALL CreateDebugUtilsMessengerEXT(
1708     VkInstance instance,
1709     const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
1710     const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger)
1711 {
1712     DispatchKey instanceKey = GetDispatchKey(instance);
1713     LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1714     VkResult res = curLayerData->instanceDispatchTable->CreateDebugUtilsMessengerEXT(
1715         instance, pCreateInfo, pAllocator, pMessenger);
1716     if (res == VK_SUCCESS) {
1717         curLayerData->debugCallbacks[*pMessenger] = *pCreateInfo;
1718     }
1719     return res;
1720 }
1721 
DestroyDebugUtilsMessengerEXT(VkInstance instance,VkDebugUtilsMessengerEXT messenger,const VkAllocationCallbacks * pAllocator)1722 VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(
1723     VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator)
1724 {
1725     DispatchKey instanceKey = GetDispatchKey(instance);
1726     LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1727     curLayerData->debugCallbacks.erase(messenger);
1728     curLayerData->instanceDispatchTable->DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
1729 }
1730 
EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)1731 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(
1732     const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1733 {
1734     if ((pLayerName != nullptr) && (strcmp(pLayerName, swapchainLayer.layerName) == 0)) {
1735         return GetExtensionProperties(std::size(g_instanceExtensions), g_instanceExtensions, pCount, pProperties);
1736     }
1737     return VK_ERROR_LAYER_NOT_PRESENT;
1738 }
1739 
1740 // Vulkan Loader will read json and call this func
EnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)1741 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties)
1742 {
1743     return GetLayerProperties(1, &swapchainLayer, pCount, pProperties);
1744 }
1745 
EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)1746 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(
1747     VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties)
1748 {
1749     return GetLayerProperties(1, &swapchainLayer, pCount, pProperties);
1750 }
1751 
EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)1752 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(
1753     VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1754 {
1755     if ((pLayerName != nullptr) && (strcmp(pLayerName, swapchainLayer.layerName) == 0)) {
1756         return GetExtensionProperties(
1757             std::size(g_deviceExtensions), g_deviceExtensions, pCount, pProperties);
1758     }
1759 
1760     if (physicalDevice == nullptr) {
1761         SWLOGE("vkEnumerateDeviceExtensionProperties physicalDevice is null.");
1762         return VK_ERROR_LAYER_NOT_PRESENT;
1763     }
1764 
1765     DispatchKey key = GetDispatchKey(physicalDevice);
1766     LayerData* curLayerData = GetLayerDataPtr(key);
1767     return curLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(physicalDevice, nullptr,
1768                                                                                    pCount, pProperties);
1769 }
1770 
GetPhysicalDeviceProcAddr(VkInstance instance,const char * funcName)1771 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char* funcName)
1772 {
1773     if (instance == VK_NULL_HANDLE) {
1774         SWLOGE("vkGetPhysicalDeviceProcAddr instance is null.");
1775         return nullptr;
1776     }
1777 
1778     LayerData* layerData = GetLayerDataPtr(GetDispatchKey(instance));
1779     VkLayerInstanceDispatchTable* pTable = layerData->instanceDispatchTable.get();
1780 
1781     if (pTable->GetPhysicalDeviceProcAddr == nullptr) {
1782         return nullptr;
1783     }
1784     return pTable->GetPhysicalDeviceProcAddr(instance, funcName);
1785 }
1786 
GetDebugUtilsProc(const char * name)1787 static inline PFN_vkVoidFunction GetDebugUtilsProc(const char* name)
1788 {
1789     if (name == nullptr) {
1790         return nullptr;
1791     }
1792     if (strcmp(name, "vkCreateDebugUtilsMessengerEXT") == 0) {
1793         return reinterpret_cast<PFN_vkVoidFunction>(CreateDebugUtilsMessengerEXT);
1794     }
1795     if (strcmp(name, "vkDestroyDebugUtilsMessengerEXT") == 0) {
1796         return reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugUtilsMessengerEXT);
1797     }
1798     return nullptr;
1799 }
1800 
GetGlobalProc(const char * name)1801 static inline PFN_vkVoidFunction GetGlobalProc(const char* name)
1802 {
1803     if (name == nullptr) {
1804         return nullptr;
1805     }
1806     if (strcmp("vkEnumerateDeviceLayerProperties", name) == 0) {
1807         return reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties);
1808     }
1809     return nullptr;
1810 }
1811 
GetSwapchainProc(const char * name)1812 static inline PFN_vkVoidFunction GetSwapchainProc(const char* name)
1813 {
1814     if (name == nullptr) {
1815         return nullptr;
1816     }
1817     if (strcmp("vkCreateSwapchainKHR", name) == 0) {
1818         return reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR);
1819     }
1820     if (strcmp("vkDestroySwapchainKHR", name) == 0) {
1821         return reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR);
1822     }
1823     if (strcmp("vkAcquireNextImageKHR", name) == 0) {
1824         return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR);
1825     }
1826     if (strcmp("vkAcquireNextImage2KHR", name) == 0) {
1827         return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImage2KHR);
1828     }
1829     if (strcmp("vkQueuePresentKHR", name) == 0) {
1830         return reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR);
1831     }
1832     if (strcmp("vkGetSwapchainImagesKHR", name) == 0) {
1833         return reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR);
1834     }
1835     if (strcmp("vkGetDeviceGroupPresentCapabilitiesKHR", name) == 0) {
1836         return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceGroupPresentCapabilitiesKHR);
1837     }
1838     if (strcmp("vkGetDeviceGroupSurfacePresentModesKHR", name) == 0) {
1839         return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceGroupSurfacePresentModesKHR);
1840     }
1841     if (strcmp("vkGetPhysicalDevicePresentRectanglesKHR", name) == 0) {
1842         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDevicePresentRectanglesKHR);
1843     }
1844     return nullptr;
1845 }
1846 
LayerInterceptDeviceProc(std::bitset<Extension::EXTENSION_COUNT> & enabledExtensions,const char * name)1847 static inline PFN_vkVoidFunction LayerInterceptDeviceProc(
1848     std::bitset<Extension::EXTENSION_COUNT>& enabledExtensions, const char* name)
1849 {
1850     if (name == nullptr) {
1851         return nullptr;
1852     }
1853     if (strcmp("vkGetDeviceProcAddr", name) == 0) {
1854         return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr);
1855     }
1856     if (strcmp("vkDestroyDevice", name) == 0) {
1857         return reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice);
1858     }
1859     if (enabledExtensions.test(Extension::KHR_SWAPCHAIN)) {
1860         PFN_vkVoidFunction addr = GetSwapchainProc(name);
1861         if (addr != nullptr) {
1862             return addr;
1863         }
1864     }
1865     if (enabledExtensions.test(Extension::EXT_HDR_METADATA)) {
1866         if (strcmp("vkSetHdrMetadataEXT", name) == 0) {
1867             return reinterpret_cast<PFN_vkVoidFunction>(SetHdrMetadataEXT);
1868         }
1869     }
1870     return nullptr;
1871 }
1872 
GetSurfaceKHRProc(const char * name)1873 static inline PFN_vkVoidFunction GetSurfaceKHRProc(const char* name)
1874 {
1875     if (name == nullptr) {
1876         return nullptr;
1877     }
1878     if (strcmp("vkDestroySurfaceKHR", name) == 0) {
1879         return reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR);
1880     }
1881     if (strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name) == 0) {
1882         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR);
1883     }
1884     if (strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name) == 0) {
1885         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR);
1886     }
1887     if (strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name) == 0) {
1888         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR);
1889     }
1890     if (strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name) == 0) {
1891         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR);
1892     }
1893     return nullptr;
1894 }
1895 
GetSurfaceCapabilities2Proc(const char * name)1896 static inline PFN_vkVoidFunction GetSurfaceCapabilities2Proc(const char* name)
1897 {
1898     if (name == nullptr) {
1899         return nullptr;
1900     }
1901     if (strcmp("vkGetPhysicalDeviceSurfaceCapabilities2KHR", name) == 0) {
1902         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilities2KHR);
1903     }
1904     if (strcmp("vkGetPhysicalDeviceSurfaceFormats2KHR", name) == 0) {
1905         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormats2KHR);
1906     }
1907     return nullptr;
1908 }
1909 
LayerInterceptInstanceProc(std::bitset<Extension::EXTENSION_COUNT> & enabledExtensions,const char * name)1910 static inline PFN_vkVoidFunction LayerInterceptInstanceProc(
1911     std::bitset<Extension::EXTENSION_COUNT>& enabledExtensions, const char* name)
1912 {
1913     if (name == nullptr) {
1914         return nullptr;
1915     }
1916     if (enabledExtensions.test(Extension::OHOS_SURFACE)) {
1917         if (strcmp("vkCreateSurfaceOHOS", name) == 0) {
1918             return reinterpret_cast<PFN_vkVoidFunction>(CreateSurfaceOHOS);
1919         }
1920     }
1921     if (enabledExtensions.test(Extension::KHR_SURFACE)) {
1922         PFN_vkVoidFunction addr = GetSurfaceKHRProc(name);
1923         if (addr != nullptr) {
1924             return addr;
1925         }
1926         if (enabledExtensions.test(Extension::KHR_GET_SURFACE_CAPABILITIES_2)) {
1927             PFN_vkVoidFunction addr = GetSurfaceCapabilities2Proc(name);
1928             if (addr != nullptr) {
1929                 return addr;
1930             }
1931         }
1932     }
1933 
1934     if (enabledExtensions.test(Extension::KHR_SWAPCHAIN)) {
1935         PFN_vkVoidFunction addr = GetSwapchainProc(name);
1936         if (addr != nullptr) {
1937             return addr;
1938         }
1939     }
1940 
1941     PFN_vkVoidFunction addr = GetDebugUtilsProc(name);
1942     if (addr != nullptr) {
1943         return addr;
1944     }
1945     return GetGlobalProc(name);
1946 }
1947 
GetDeviceProcAddr(VkDevice device,const char * funcName)1948 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName)
1949 {
1950     if (funcName == nullptr) {
1951         return nullptr;
1952     }
1953     if (device == VK_NULL_HANDLE) {
1954         SWLOGE("vkGetDeviceProcAddr device is null.");
1955         return nullptr;
1956     }
1957     LayerData* layerData = GetLayerDataPtr(GetDispatchKey(device));
1958     if (layerData == nullptr) {
1959         SWLOGE("libvulkan_swapchain GetInstanceProcAddr layerData is null");
1960         return nullptr;
1961     }
1962 
1963     PFN_vkVoidFunction addr = LayerInterceptDeviceProc(layerData->enabledExtensions, funcName);
1964     if (addr != nullptr) {
1965         return addr;
1966     }
1967     LayerData* devData = GetLayerDataPtr(GetDispatchKey(device));
1968     VkLayerDispatchTable* pTable = devData->deviceDispatchTable.get();
1969     if (pTable->GetDeviceProcAddr == nullptr) {
1970         return nullptr;
1971     }
1972     return pTable->GetDeviceProcAddr(device, funcName);
1973 }
1974 
GetInstanceProcAddr(VkInstance instance,const char * funcName)1975 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName)
1976 {
1977     if (funcName == nullptr) {
1978         return nullptr;
1979     }
1980 
1981     if (strcmp("vkGetInstanceProcAddr", funcName) == 0) {
1982         return reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr);
1983     }
1984     if (strcmp("vkCreateInstance", funcName) == 0) {
1985         return reinterpret_cast<PFN_vkVoidFunction>(CreateInstance);
1986     }
1987     if (strcmp("vkEnumerateInstanceExtensionProperties", funcName) == 0) {
1988         return reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties);
1989     }
1990     if (strcmp("vkEnumerateInstanceLayerProperties", funcName) == 0) {
1991         return reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties);
1992     }
1993     if (strcmp("vkDestroyInstance", funcName) == 0) {
1994         return reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance);
1995     }
1996     if (strcmp("vkCreateDevice", funcName) == 0) {
1997         return reinterpret_cast<PFN_vkVoidFunction>(CreateDevice);
1998     }
1999     if (strcmp("vkEnumerateDeviceExtensionProperties", funcName) == 0) {
2000         return reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties);
2001     }
2002 
2003     if (instance == VK_NULL_HANDLE) {
2004         SWLOGE("SwapchainLayer GetInstanceProcAddr(func name %{public}s) instance is null", funcName);
2005         return nullptr;
2006     }
2007 
2008     LayerData* layerData = GetLayerDataPtr(GetDispatchKey(instance));
2009     if (layerData == nullptr) {
2010         SWLOGE("SwapchainLayer GetInstanceProcAddr layerData is null");
2011         return nullptr;
2012     }
2013 
2014     PFN_vkVoidFunction addr = LayerInterceptInstanceProc(layerData->enabledExtensions, funcName);
2015     if (addr != nullptr) {
2016         return addr;
2017     }
2018 
2019     VkLayerInstanceDispatchTable* pTable = layerData->instanceDispatchTable.get();
2020     if (pTable == nullptr) {
2021         SWLOGE("SwapchainLayer GetInstanceProcAddr pTable = null");
2022         return nullptr;
2023     }
2024     if (pTable->GetInstanceProcAddr == nullptr) {
2025         SWLOGE("SwapchainLayer GetInstanceProcAddr pTable->GetInstanceProcAddr = null");
2026         return nullptr;
2027     }
2028     addr = pTable->GetInstanceProcAddr(instance, funcName);
2029 
2030     return addr;
2031 }
2032 }  // namespace SWAPCHAIN
2033 
2034 #if defined(__GNUC__) && __GNUC__ >= 4
2035 #define SWAPCHAIN_EXPORT __attribute__((visibility("default")))
2036 #else
2037 #define SWAPCHAIN_EXPORT
2038 #endif
2039 
2040 extern "C" {
vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)2041 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
2042     const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
2043 {
2044     return SWAPCHAIN::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
2045 }
2046 
2047 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkEnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)2048 vkEnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties)
2049 {
2050     return SWAPCHAIN::EnumerateInstanceLayerProperties(pCount, pProperties);
2051 }
2052 
vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)2053 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
2054     VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties)
2055 {
2056     return SWAPCHAIN::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
2057 }
2058 
vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)2059 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(
2060     VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
2061 {
2062     return SWAPCHAIN::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
2063 }
2064 
vkGetDeviceProcAddr(VkDevice dev,const char * funcName)2065 SWAPCHAIN_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
2066 {
2067     return SWAPCHAIN::GetDeviceProcAddr(dev, funcName);
2068 }
2069 
2070 SWAPCHAIN_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vkGetInstanceProcAddr(VkInstance instance,const char * funcName)2071 vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
2072 {
2073     return SWAPCHAIN::GetInstanceProcAddr(instance, funcName);
2074 }
2075 }