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