• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <cassert>
17 #include <cstdint>
18 #include <cstdio>
19 #include <limits>
20 #include <thread>
21 #include <unordered_map>
22 #include <vector>
23 #include <iostream>
24 #include <malloc.h>
25 #include <algorithm>
26 #include <new>
27 #include <securec.h>
28 #include <cstring>
29 #include <cinttypes>
30 #include <refbase.h>
31 
32 #include <vulkan/vulkan_core.h>
33 #include <window.h>
34 #include <graphic_common.h>
35 #include <native_window.h>
36 #include <vulkan/vulkan.h>
37 #include "vk_dispatch_table_helper.h"
38 #include "vk_layer_dispatch_table.h"
39 #include "swapchain_layer_log.h"
40 #include "sync_fence.h"
41 
42 #define SWAPCHAIN_SURFACE_NAME "VK_LAYER_OHOS_surface"
43 
44 using namespace OHOS;
45 
46 enum Extension {
47     OHOS_SURFACE,
48     OHOS_NATIVE_BUFFER,
49     KHR_SURFACE,
50     KHR_SWAPCHAIN,
51     EXTENSION_COUNT,
52     EXTENSION_UNKNOWN,
53 };
54 
55 struct LayerData {
56     VkInstance instance = VK_NULL_HANDLE;
57     VkDevice device = VK_NULL_HANDLE;
58     uint32_t instanceVersion = VK_API_VERSION_1_0;
59     std::unique_ptr<VkLayerDispatchTable> deviceDispatchTable;
60     std::unique_ptr<VkLayerInstanceDispatchTable> instanceDispatchTable;
61     std::unordered_map<VkDebugUtilsMessengerEXT, VkDebugUtilsMessengerCreateInfoEXT> debugCallbacks;
62     PFN_vkSetDeviceLoaderData fpSetDeviceLoaderData = nullptr;
63     std::bitset<Extension::EXTENSION_COUNT> enabledExtensions;
64 };
65 
66 namespace {
67 constexpr uint32_t MIN_BUFFER_SIZE = 3;
68 constexpr uint32_t MAX_BUFFER_SIZE = 32;
69 struct LoaderVkLayerDispatchTable;
70 typedef uintptr_t DispatchKey;
71 
72 template <typename T>
GetDispatchKey(const T object)73 inline DispatchKey GetDispatchKey(const T object)
74 {
75     return reinterpret_cast<DispatchKey>(*reinterpret_cast<LoaderVkLayerDispatchTable* const*>(object));
76 }
77 
GetChainInfo(const VkInstanceCreateInfo * pCreateInfo,VkLayerFunction func)78 VkLayerInstanceCreateInfo* GetChainInfo(const VkInstanceCreateInfo* pCreateInfo, VkLayerFunction func)
79 {
80     auto chainInfo = static_cast<const VkLayerInstanceCreateInfo*>(pCreateInfo->pNext);
81     while (chainInfo != nullptr) {
82         if (chainInfo->sType == VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO && chainInfo->function == func) {
83             return const_cast<VkLayerInstanceCreateInfo*>(chainInfo);
84         }
85         chainInfo = static_cast<const VkLayerInstanceCreateInfo*>(chainInfo->pNext);
86     }
87     SWLOGE("Failed to find VkLayerInstanceCreateInfo");
88     return nullptr;
89 }
90 
GetChainInfo(const VkDeviceCreateInfo * pCreateInfo,VkLayerFunction func)91 VkLayerDeviceCreateInfo* GetChainInfo(const VkDeviceCreateInfo* pCreateInfo, VkLayerFunction func)
92 {
93     auto chainInfo = static_cast<const VkLayerDeviceCreateInfo*>(pCreateInfo->pNext);
94     while (chainInfo != nullptr) {
95         if (chainInfo->sType == VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO && chainInfo->function == func) {
96             return const_cast<VkLayerDeviceCreateInfo*>(chainInfo);
97         }
98         chainInfo = static_cast<const VkLayerDeviceCreateInfo*>(chainInfo->pNext);
99     }
100     SWLOGE("Failed to find VkLayerDeviceCreateInfo");
101     return nullptr;
102 }
103 }  // namespace
104 
105 #define VK_LAYER_API_VERSION VK_MAKE_VERSION(1, 1, VK_HEADER_VERSION)
106 
ToUint32(uint64_t val)107 static inline uint32_t ToUint32(uint64_t val)
108 {
109     if (val > UINT32_MAX) {
110         SWLOGE("%{public}" PRIu64 " is too large to convert to uint32", val);
111     }
112     return static_cast<uint32_t>(val);
113 }
114 
115 namespace SWAPCHAIN {
116 std::unordered_map<DispatchKey, LayerData*> g_layerDataMap;
117 
GetLayerDataPtr(DispatchKey dataKey)118 LayerData* GetLayerDataPtr(DispatchKey dataKey)
119 {
120     LayerData* layerData = nullptr;
121     auto it = g_layerDataMap.find(dataKey);
122     if (it == g_layerDataMap.end()) {
123         layerData = new LayerData;
124         g_layerDataMap[dataKey] = layerData;
125     } else {
126         layerData = it->second;
127     }
128     return layerData;
129 }
130 
FreeLayerDataPtr(DispatchKey dataKey)131 void FreeLayerDataPtr(DispatchKey dataKey)
132 {
133     auto it = g_layerDataMap.find(dataKey);
134     if (it == g_layerDataMap.end()) {
135         return;
136     }
137     delete it->second;
138     g_layerDataMap.erase(it);
139 }
140 
DebugMessageToUserCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity,const char * message)141 void DebugMessageToUserCallback(VkDebugUtilsMessageSeverityFlagBitsEXT severity, const char* message)
142 {
143     VkDebugUtilsMessengerCallbackDataEXT callbackData = {};
144     callbackData.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
145     callbackData.pMessageIdName = "SwapchainLayer";
146     callbackData.pMessage = message;
147 
148     for (auto [key, layerData] : g_layerDataMap) {
149         if (layerData->debugCallbacks.empty()) {
150             continue;
151         }
152         for (auto& callback : layerData->debugCallbacks) {
153             if (!(severity & callback.second.messageSeverity)) {
154                 continue;
155             }
156             if (!(VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT & callback.second.messageType)) {
157                 continue;
158             }
159             callback.second.pfnUserCallback(severity, VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT,
160                                             &callbackData, callback.second.pUserData);
161         }
162     }
163 }
164 
GetExtensionProperties(const uint32_t count,const VkExtensionProperties * layerExtensions,uint32_t * pCount,VkExtensionProperties * pProperties)165 VkResult GetExtensionProperties(const uint32_t count, const VkExtensionProperties* layerExtensions,
166                                 uint32_t* pCount, VkExtensionProperties* pProperties)
167 {
168     if (pProperties == nullptr || layerExtensions == nullptr) {
169         *pCount = count;
170         return VK_SUCCESS;
171     }
172 
173     uint32_t copySize = *pCount < count ? *pCount : count;
174     errno_t ret = memcpy_s(pProperties, copySize * sizeof(VkExtensionProperties),
175                            layerExtensions, copySize * sizeof(VkExtensionProperties));
176     if (ret != EOK) {
177         return VK_INCOMPLETE;
178     }
179     *pCount = copySize;
180     if (copySize < count) {
181         return VK_INCOMPLETE;
182     }
183 
184     return VK_SUCCESS;
185 }
186 
GetLayerProperties(const uint32_t count,const VkLayerProperties * layerProperties,uint32_t * pCount,VkLayerProperties * pProperties)187 VkResult GetLayerProperties(const uint32_t count, const VkLayerProperties* layerProperties,
188                             uint32_t* pCount, VkLayerProperties* pProperties)
189 {
190     if (pProperties == nullptr || layerProperties == nullptr) {
191         *pCount = count;
192         return VK_SUCCESS;
193     }
194 
195     uint32_t copySize = *pCount < count ? *pCount : count;
196     errno_t ret = memcpy_s(pProperties, copySize * sizeof(VkLayerProperties),
197                            layerProperties, copySize * sizeof(VkLayerProperties));
198     if (ret != EOK) {
199         return VK_INCOMPLETE;
200     }
201     *pCount = copySize;
202     if (copySize < count) {
203         return VK_INCOMPLETE;
204     }
205 
206     return VK_SUCCESS;
207 }
208 
209 static const VkExtensionProperties instanceExtensions[] = {
210     {
211         .extensionName = VK_KHR_SURFACE_EXTENSION_NAME,
212         .specVersion = 25,
213     },
214     {
215         .extensionName = VK_OHOS_SURFACE_EXTENSION_NAME,
216         .specVersion = 1,
217     }
218 };
219 
220 static const VkExtensionProperties deviceExtensions[] = {{
221     .extensionName = VK_KHR_SWAPCHAIN_EXTENSION_NAME,
222     .specVersion = 70,
223 }};
224 
225 constexpr VkLayerProperties swapchainLayer = {
226     SWAPCHAIN_SURFACE_NAME,
227     VK_LAYER_API_VERSION,
228     1,
229     "Vulkan Swapchain",
230 };
231 
232 struct Surface {
233     NativeWindow* window;
234     VkSwapchainKHR swapchainHandle;
235     int32_t consumerUsage;
236 };
237 
238 struct Swapchain {
SwapchainSWAPCHAIN::Swapchain239     Swapchain(Surface &surface, uint32_t numImages, VkPresentModeKHR presentMode, int preTransform)
240         : surface(surface), numImages(numImages), mailboxMode(presentMode == VK_PRESENT_MODE_MAILBOX_KHR),
241           preTransform(preTransform), frameTimestampsEnabled(false),
242           shared(presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
243                  presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) {}
244 
245     Surface &surface;
246     uint32_t numImages;
247     bool mailboxMode;
248     int preTransform;
249     bool frameTimestampsEnabled;
250     bool shared;
251 
252     struct Image {
ImageSWAPCHAIN::Swapchain::Image253         Image() : image(VK_NULL_HANDLE), buffer(nullptr), requestFence(-1), releaseFence(-1), requested(false) {}
254         VkImage image;
255         NativeWindowBuffer* buffer;
256         int requestFence;
257         int releaseFence;
258         bool requested;
259     } images[MAX_BUFFER_SIZE];
260 };
261 
262 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName);
263 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance,
264                                                              const char* funcName);
265 
HandleFromSurface(Surface * surface)266 VkSurfaceKHR HandleFromSurface(Surface* surface)
267 {
268     return VkSurfaceKHR(reinterpret_cast<uint64_t>(surface));
269 }
270 
SurfaceFromHandle(VkSurfaceKHR handle)271 Surface* SurfaceFromHandle(VkSurfaceKHR handle)
272 {
273     return reinterpret_cast<Surface*>(handle);
274 }
275 
SwapchainFromHandle(VkSwapchainKHR handle)276 Swapchain* SwapchainFromHandle(VkSwapchainKHR handle)
277 {
278     return reinterpret_cast<Swapchain*>(handle);
279 }
280 
HandleFromSwapchain(Swapchain * swapchain)281 VkSwapchainKHR HandleFromSwapchain(Swapchain* swapchain)
282 {
283     return VkSwapchainKHR(reinterpret_cast<uint64_t>(swapchain));
284 }
285 
DefaultAllocate(void *,size_t size,size_t alignment,VkSystemAllocationScope)286 VKAPI_ATTR void* DefaultAllocate(void*, size_t size, size_t alignment, VkSystemAllocationScope)
287 {
288     void* ptr = nullptr;
289     int ret = posix_memalign(&ptr, std::max(alignment, sizeof(void*)), size);
290     return ret == 0 ? ptr : nullptr;
291 }
292 
DefaultReallocate(void *,void * ptr,size_t size,size_t alignment,VkSystemAllocationScope)293 VKAPI_ATTR void* DefaultReallocate(void*, void* ptr, size_t size, size_t alignment, VkSystemAllocationScope)
294 {
295     if (size == 0) {
296         free(ptr);
297         return nullptr;
298     }
299 
300     size_t oldSize = ptr ? malloc_usable_size(ptr) : 0;
301     if (size <= oldSize) {
302         return ptr;
303     }
304 
305     void* newPtr = nullptr;
306     if (posix_memalign(&newPtr, std::max(alignment, sizeof(void*)), size) != 0) {
307         return nullptr;
308     }
309 
310     if (ptr != nullptr) {
311         auto ret = memcpy_s(newPtr, size, ptr, oldSize);
312         if (ret != EOK) {
313             free(newPtr);
314             return nullptr;
315         }
316         free(ptr);
317     }
318     return newPtr;
319 }
320 
DefaultFree(void *,void * ptr)321 VKAPI_ATTR void DefaultFree(void*, void* ptr)
322 {
323     free(ptr);
324 }
325 
GetDefaultAllocator()326 const VkAllocationCallbacks &GetDefaultAllocator()
327 {
328     static const VkAllocationCallbacks defaultAllocCallbacks = {
329         .pUserData = nullptr,
330         .pfnAllocation = DefaultAllocate,
331         .pfnReallocation = DefaultReallocate,
332         .pfnFree = DefaultFree,
333     };
334 
335     return defaultAllocCallbacks;
336 }
337 
GetColorDataspace(VkColorSpaceKHR colorspace)338 GraphicColorDataSpace GetColorDataspace(VkColorSpaceKHR colorspace)
339 {
340     switch (colorspace) {
341         case VK_COLOR_SPACE_SRGB_NONLINEAR_KHR:
342             return GRAPHIC_BT709_SRGB_FULL;
343         case VK_COLOR_SPACE_DISPLAY_P3_NONLINEAR_EXT:
344             return GRAPHIC_DCI_P3_GAMMA26_FULL;
345         case VK_COLOR_SPACE_EXTENDED_SRGB_LINEAR_EXT:
346             return GRAPHIC_BT709_LINEAR_EXTENDED;
347         case VK_COLOR_SPACE_EXTENDED_SRGB_NONLINEAR_EXT:
348             return GRAPHIC_BT709_SRGB_EXTENDED;
349         case VK_COLOR_SPACE_DCI_P3_LINEAR_EXT:
350             return GRAPHIC_DCI_P3_LINEAR_FULL;
351         case VK_COLOR_SPACE_DCI_P3_NONLINEAR_EXT:
352             return GRAPHIC_DCI_P3_GAMMA26_FULL;
353         case VK_COLOR_SPACE_BT709_LINEAR_EXT:
354             return GRAPHIC_BT709_LINEAR_FULL;
355         case VK_COLOR_SPACE_BT709_NONLINEAR_EXT:
356             return GRAPHIC_BT709_SRGB_FULL;
357         case VK_COLOR_SPACE_BT2020_LINEAR_EXT:
358             return GRAPHIC_BT2020_LINEAR_FULL;
359         case VK_COLOR_SPACE_HDR10_ST2084_EXT:
360             return GRAPHIC_BT2020_ST2084_FULL;
361         case VK_COLOR_SPACE_DOLBYVISION_EXT:
362             return GRAPHIC_BT2020_ST2084_FULL;
363         case VK_COLOR_SPACE_HDR10_HLG_EXT:
364             return GRAPHIC_BT2020_HLG_FULL;
365         case VK_COLOR_SPACE_ADOBERGB_LINEAR_EXT:
366             return static_cast<GraphicColorDataSpace>(GRAPHIC_GAMUT_ADOBE_RGB |
367                                                       GRAPHIC_TRANSFORM_FUNC_LINEAR | GRAPHIC_PRECISION_FULL);
368         case VK_COLOR_SPACE_ADOBERGB_NONLINEAR_EXT:
369             return GRAPHIC_ADOBE_RGB_GAMMA22_FULL;
370         default:
371             return GRAPHIC_COLOR_DATA_SPACE_UNKNOWN;
372     }
373 }
374 
IsFencePending(int fd)375 static bool IsFencePending(int fd)
376 {
377     if (fd < 0) {
378         return false;
379     }
380     errno = 0;
381     sptr<OHOS::SyncFence> syncFence = new OHOS::SyncFence(fd);
382     return syncFence->Wait(0) == -1 && errno == ETIME;
383 }
384 
ReleaseSwapchainImage(VkDevice device,NativeWindow * window,int releaseFence,Swapchain::Image & image,bool deferIfPending)385 void ReleaseSwapchainImage(VkDevice device, NativeWindow* window, int releaseFence, Swapchain::Image &image,
386                            bool deferIfPending)
387 {
388     if (releaseFence != -1 && !image.requested) {
389         SWLOGE("%{public}s, can't provide a release fence for non-requested images", __func__);
390         DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
391             "can't provide a release fence for non-requested images");
392         return;
393     }
394 
395     VkLayerDispatchTable* pDisp =
396         GetLayerDataPtr(GetDispatchKey(device))->deviceDispatchTable.get();
397     pDisp->DeviceWaitIdle(device);
398     if (image.requested) {
399         if (releaseFence >= 0) {
400             if (image.requestFence >= 0) {
401                 sptr<OHOS::SyncFence> requestFence = new OHOS::SyncFence(image.requestFence);
402                 requestFence->Wait(-1);
403                 close(image.requestFence);
404             }
405         } else {
406             releaseFence = image.requestFence;
407         }
408         image.requestFence = -1;
409 
410         if (window != nullptr) {
411             NativeWindowCancelBuffer(window, image.buffer);
412         } else {
413             if (releaseFence >= 0) {
414                 close(releaseFence);
415             }
416         }
417         image.requested = false;
418     }
419 
420     if (deferIfPending && IsFencePending(image.releaseFence)) {
421         return;
422     }
423 
424     if (image.releaseFence >= 0) {
425         close(image.releaseFence);
426         image.releaseFence = -1;
427     }
428 
429     if (image.image != VK_NULL_HANDLE) {
430         pDisp->DestroyImage(device, image.image, nullptr);
431         image.image = VK_NULL_HANDLE;
432     }
433 }
434 
ReleaseSwapchain(VkDevice device,Swapchain * swapchain)435 void ReleaseSwapchain(VkDevice device, Swapchain* swapchain)
436 {
437     if (swapchain->surface.swapchainHandle != HandleFromSwapchain(swapchain)) {
438         return;
439     }
440 
441     for (uint32_t i = 0; i < swapchain->numImages; i++) {
442         if (!swapchain->images[i].requested) {
443             ReleaseSwapchainImage(device, nullptr, -1, swapchain->images[i], true);
444         }
445     }
446     swapchain->surface.swapchainHandle = VK_NULL_HANDLE;
447 }
448 
GetPixelFormat(VkFormat format)449 GraphicPixelFormat GetPixelFormat(VkFormat format)
450 {
451     GraphicPixelFormat nativeFormat = GRAPHIC_PIXEL_FMT_RGBA_8888;
452     switch (format) {
453         case VK_FORMAT_R8G8B8A8_UNORM:
454         case VK_FORMAT_R8G8B8A8_SRGB:
455             nativeFormat = GRAPHIC_PIXEL_FMT_RGBA_8888;
456             break;
457         case VK_FORMAT_R5G6B5_UNORM_PACK16:
458             nativeFormat = GRAPHIC_PIXEL_FMT_RGB_565;
459             break;
460         default:
461             SWLOGE("unsupported swapchain format %{public}d", format);
462             DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
463                 ("unsupported swapchain format " + std::to_string(format)).c_str());
464             break;
465     }
466     return nativeFormat;
467 }
468 
SetWindowInfo(VkDevice device,const VkSwapchainCreateInfoKHR * createInfo,uint32_t * numImages)469 VKAPI_ATTR VkResult SetWindowInfo(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo, uint32_t* numImages)
470 {
471     GraphicPixelFormat pixelFormat = GetPixelFormat(createInfo->imageFormat);
472     Surface &surface = *SurfaceFromHandle(createInfo->surface);
473 
474     NativeWindow* window = surface.window;
475     int err = NativeWindowHandleOpt(window, SET_FORMAT, pixelFormat);
476     if (err != OHOS::GSERROR_OK) {
477         SWLOGE("native_window_set_buffers_format(%{public}d) failed: (%{public}d)", pixelFormat, err);
478         return VK_ERROR_SURFACE_LOST_KHR;
479     }
480 
481     err = NativeWindowHandleOpt(window, SET_BUFFER_GEOMETRY,
482                                 static_cast<int>(createInfo->imageExtent.width),
483                                 static_cast<int>(createInfo->imageExtent.height));
484     if (err != OHOS::GSERROR_OK) {
485         SWLOGE("NativeWindow SET_BUFFER_GEOMETRY width:%{public}d,height:%{public}d failed: %{public}d",
486             createInfo->imageExtent.width, createInfo->imageExtent.height, err);
487         return VK_ERROR_SURFACE_LOST_KHR;
488     }
489 
490     if (createInfo->presentMode == VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR ||
491         createInfo->presentMode == VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR) {
492         *numImages = 1;
493     }
494 
495     return VK_SUCCESS;
496 }
497 
SetSwapchainCreateInfo(VkDevice device,const VkSwapchainCreateInfoKHR * createInfo,uint32_t * numImages)498 VkResult SetSwapchainCreateInfo(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo,
499     uint32_t* numImages)
500 {
501     GraphicColorDataSpace colorDataSpace = GetColorDataspace(createInfo->imageColorSpace);
502     if (colorDataSpace == GRAPHIC_COLOR_DATA_SPACE_UNKNOWN) {
503         return VK_ERROR_INITIALIZATION_FAILED;
504     }
505     if (createInfo->oldSwapchain != VK_NULL_HANDLE) {
506         ReleaseSwapchain(device, SwapchainFromHandle(createInfo->oldSwapchain));
507     }
508 
509     return SetWindowInfo(device, createInfo, numImages);
510 }
511 
TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform)512 int TranslateVulkanToNativeTransform(VkSurfaceTransformFlagBitsKHR transform)
513 {
514     switch (transform) {
515         case VK_SURFACE_TRANSFORM_ROTATE_90_BIT_KHR:
516             return GRAPHIC_ROTATE_90;
517         case VK_SURFACE_TRANSFORM_ROTATE_180_BIT_KHR:
518             return GRAPHIC_ROTATE_180;
519         case VK_SURFACE_TRANSFORM_ROTATE_270_BIT_KHR:
520             return GRAPHIC_ROTATE_270;
521         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_BIT_KHR:
522             return GRAPHIC_FLIP_H;
523         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_90_BIT_KHR:
524             return GRAPHIC_FLIP_H_ROT90;
525         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_180_BIT_KHR:
526             return GRAPHIC_FLIP_H_ROT180;
527         case VK_SURFACE_TRANSFORM_HORIZONTAL_MIRROR_ROTATE_270_BIT_KHR:
528             return GRAPHIC_FLIP_H_ROT270;
529         case VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR:
530         case VK_SURFACE_TRANSFORM_INHERIT_BIT_KHR:
531         default:
532             return GRAPHIC_ROTATE_NONE;
533     }
534 }
535 
InitImageCreateInfo(const VkSwapchainCreateInfoKHR * createInfo,VkImageCreateInfo * imageCreate)536 void InitImageCreateInfo(const VkSwapchainCreateInfoKHR* createInfo, VkImageCreateInfo* imageCreate)
537 {
538     imageCreate->sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
539     bool swapchainCreateProtected = createInfo->flags & VK_SWAPCHAIN_CREATE_PROTECTED_BIT_KHR;
540     imageCreate->flags = swapchainCreateProtected ? VK_IMAGE_CREATE_PROTECTED_BIT : 0u;
541     imageCreate->imageType = VK_IMAGE_TYPE_2D;
542     imageCreate->format = createInfo->imageFormat;
543     imageCreate->extent = {0, 0, 1};
544     imageCreate->mipLevels = 1;
545     imageCreate->arrayLayers = 1;
546     imageCreate->samples = VK_SAMPLE_COUNT_1_BIT;
547     imageCreate->tiling = VK_IMAGE_TILING_OPTIMAL;
548     imageCreate->usage = createInfo->imageUsage;
549     imageCreate->sharingMode = createInfo->imageSharingMode;
550     imageCreate->queueFamilyIndexCount = createInfo->queueFamilyIndexCount;
551     imageCreate->pQueueFamilyIndices = createInfo->pQueueFamilyIndices;
552 }
553 
CreateImages(uint32_t & numImages,Swapchain * swapchain,const VkSwapchainCreateInfoKHR * createInfo,VkImageCreateInfo & imageCreate,VkDevice device)554 VKAPI_ATTR VkResult CreateImages(uint32_t &numImages, Swapchain* swapchain, const VkSwapchainCreateInfoKHR* createInfo,
555     VkImageCreateInfo &imageCreate, VkDevice device)
556 {
557     VkLayerDispatchTable* pDisp =
558         GetLayerDataPtr(GetDispatchKey(device))->deviceDispatchTable.get();
559     Surface &surface = *SurfaceFromHandle(createInfo->surface);
560     NativeWindow* window = surface.window;
561     if (createInfo->oldSwapchain != VK_NULL_HANDLE) {
562         SWLOGI("recreate swapchain ,clean buffer queue");
563         window->surface->CleanCache();
564     }
565     VkResult result = VK_SUCCESS;
566     for (uint32_t i = 0; i < numImages; i++) {
567         Swapchain::Image &img = swapchain->images[i];
568         NativeWindowBuffer* buffer = nullptr;
569         int err = NativeWindowRequestBuffer(window, &buffer, &img.requestFence);
570         if (err != OHOS::GSERROR_OK) {
571             SWLOGE("RequestBuffer[%{public}u] failed: (%{public}d)", i, err);
572             result = VK_ERROR_SURFACE_LOST_KHR;
573             break;
574         }
575         img.buffer = buffer;
576         img.requested = true;
577         imageCreate.extent = VkExtent3D {static_cast<uint32_t>(img.buffer->sfbuffer->GetWidth()),
578                                           static_cast<uint32_t>(img.buffer->sfbuffer->GetHeight()), 1};
579         ((VkNativeBufferOHOS*)(imageCreate.pNext))->handle =
580             reinterpret_cast<struct OHBufferHandle *>(img.buffer->sfbuffer->GetBufferHandle());
581         result = pDisp->CreateImage(device, &imageCreate, nullptr, &img.image);
582         if (result != VK_SUCCESS) {
583             SWLOGD("vkCreateImage native buffer failed: %{public}u", result);
584             break;
585         }
586     }
587 
588     SWLOGD("swapchain init shared %{public}d", swapchain->shared);
589     for (uint32_t i = 0; i < numImages; i++) {
590         Swapchain::Image &img = swapchain->images[i];
591         if (img.requested) {
592             if (!swapchain->shared) {
593                 NativeWindowCancelBuffer(window, img.buffer);
594                 img.requestFence = -1;
595                 img.requested = false;
596             }
597         }
598     }
599     return result;
600 }
601 
DestroySwapchainInternal(VkDevice device,VkSwapchainKHR swapchainHandle,const VkAllocationCallbacks * allocator)602 static void DestroySwapchainInternal(VkDevice device, VkSwapchainKHR swapchainHandle,
603                                      const VkAllocationCallbacks* allocator)
604 {
605     Swapchain* swapchain = SwapchainFromHandle(swapchainHandle);
606     if (swapchain == nullptr) {
607         return;
608     }
609 
610     bool active = swapchain->surface.swapchainHandle == swapchainHandle;
611     NativeWindow* window = active ? swapchain->surface.window : nullptr;
612 
613     for (uint32_t i = 0; i < swapchain->numImages; i++) {
614         ReleaseSwapchainImage(device, window, -1, swapchain->images[i], false);
615     }
616 
617     if (active) {
618         swapchain->surface.swapchainHandle = VK_NULL_HANDLE;
619     }
620     if (allocator == nullptr) {
621         allocator = &GetDefaultAllocator();
622     }
623     swapchain->~Swapchain();
624     allocator->pfnFree(allocator->pUserData, swapchain);
625 }
626 
CreateSwapchainKHR(VkDevice device,const VkSwapchainCreateInfoKHR * createInfo,const VkAllocationCallbacks * allocator,VkSwapchainKHR * swapchainHandle)627 VKAPI_ATTR VkResult VKAPI_CALL CreateSwapchainKHR(VkDevice device, const VkSwapchainCreateInfoKHR* createInfo,
628     const VkAllocationCallbacks* allocator, VkSwapchainKHR* swapchainHandle)
629 {
630     Surface &surface = *SurfaceFromHandle(createInfo->surface);
631     if (surface.swapchainHandle != createInfo->oldSwapchain) {
632         return VK_ERROR_NATIVE_WINDOW_IN_USE_KHR;
633     }
634 
635     uint32_t numImages = surface.window->surface->GetQueueSize();
636     VkResult result = SetSwapchainCreateInfo(device, createInfo, &numImages);
637     if (result != VK_SUCCESS) {
638         return result;
639     }
640 
641     if (numImages < createInfo->minImageCount) {
642         SWLOGE("swapchain init minImageCount[%{public}u] can not be more than maxBufferCount[%{public}u]",
643             createInfo->minImageCount, numImages);
644         return VK_ERROR_INITIALIZATION_FAILED;
645     }
646 
647     if (allocator == nullptr) {
648         allocator = &GetDefaultAllocator();
649     }
650     void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Swapchain), alignof(Swapchain),
651         VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
652     if (mem == nullptr) {
653         return VK_ERROR_OUT_OF_HOST_MEMORY;
654     }
655 
656     Swapchain* swapchain = new (mem) Swapchain(surface, numImages, createInfo->presentMode,
657         TranslateVulkanToNativeTransform(createInfo->preTransform));
658     VkSwapchainImageCreateInfoOHOS swapchainImageCreate = {
659         .sType = VK_STRUCTURE_TYPE_SWAPCHAIN_IMAGE_CREATE_INFO_OHOS,
660         .pNext = nullptr,
661     };
662     VkNativeBufferOHOS imageNativeBuffer = {
663         .sType = VK_STRUCTURE_TYPE_NATIVE_BUFFER_OHOS,
664         .pNext = &swapchainImageCreate,
665     };
666 
667     VkImageCreateInfo imageCreate = {
668         .pNext = &imageNativeBuffer,
669     };
670 
671     InitImageCreateInfo(createInfo, &imageCreate);
672     result = CreateImages(numImages, swapchain, createInfo, imageCreate, device);
673     if (result != VK_SUCCESS) {
674         DestroySwapchainInternal(device, HandleFromSwapchain(swapchain), allocator);
675         return result;
676     }
677     surface.swapchainHandle = HandleFromSwapchain(swapchain);
678     *swapchainHandle = surface.swapchainHandle;
679     return VK_SUCCESS;
680 }
681 
DestroySwapchainKHR(VkDevice device,VkSwapchainKHR vkSwapchain,const VkAllocationCallbacks * pAllocator)682 VKAPI_ATTR void VKAPI_CALL DestroySwapchainKHR(
683     VkDevice device, VkSwapchainKHR vkSwapchain, const VkAllocationCallbacks* pAllocator)
684 {
685     DestroySwapchainInternal(device, vkSwapchain, pAllocator);
686 }
687 
GetSwapchainImagesKHR(VkDevice device,VkSwapchainKHR vkSwapchain,uint32_t * count,VkImage * images)688 VKAPI_ATTR VkResult VKAPI_CALL GetSwapchainImagesKHR(
689     VkDevice device, VkSwapchainKHR vkSwapchain, uint32_t* count, VkImage* images)
690 {
691     const Swapchain &swapchain = *SwapchainFromHandle(vkSwapchain);
692     if (images == nullptr) {
693         *count = swapchain.numImages;
694         return VK_SUCCESS;
695     }
696 
697     VkResult result = VK_SUCCESS;
698     uint32_t numImages = swapchain.numImages;
699     if (*count < swapchain.numImages) {
700         numImages = *count;
701         result = VK_INCOMPLETE;
702     }
703     for (uint32_t i = 0; i < numImages; i++) {
704         images[i] = swapchain.images[i].image;
705     }
706     *count = numImages;
707     return result;
708 }
709 
AcquireNextImageKHR(VkDevice device,VkSwapchainKHR swapchainHandle,uint64_t timeout,VkSemaphore semaphore,VkFence vkFence,uint32_t * imageIndex)710 VKAPI_ATTR VkResult VKAPI_CALL AcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchainHandle,
711     uint64_t timeout, VkSemaphore semaphore, VkFence vkFence, uint32_t* imageIndex)
712 {
713     Swapchain &swapchain = *SwapchainFromHandle(swapchainHandle);
714     NativeWindow* nativeWindow = swapchain.surface.window;
715     VkResult result = VK_SUCCESS;
716 
717     if (swapchain.surface.swapchainHandle != swapchainHandle) {
718         return VK_ERROR_OUT_OF_DATE_KHR;
719     }
720 
721     LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(device));
722     if (swapchain.shared) {
723         *imageIndex = 0;
724         return deviceLayerData->deviceDispatchTable->AcquireImageOHOS(device, swapchain.images[*imageIndex].image, -1,
725                                                                       semaphore, vkFence);
726     }
727 
728     NativeWindowBuffer* nativeWindowBuffer = nullptr;
729     int fence = -1;
730     int32_t ret = NativeWindowRequestBuffer(nativeWindow, &nativeWindowBuffer, &fence);
731     if (ret != OHOS::GSERROR_OK) {
732         SWLOGE("RequestBuffer failed: (%{public}d)", ret);
733         DebugMessageToUserCallback(VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT,
734             ("RequestBuffer failed: " + std::to_string(ret)).c_str());
735         return VK_ERROR_SURFACE_LOST_KHR;
736     }
737 
738     uint32_t index = 0;
739     for (; index < swapchain.numImages; index++) {
740         if (swapchain.images[index].buffer->sfbuffer == nativeWindowBuffer->sfbuffer) {
741             swapchain.images[index].requested = true;
742             swapchain.images[index].requestFence = fence;
743             break;
744         }
745     }
746 
747     if (index == swapchain.numImages) {
748         SWLOGD("RequestBuffer returned unrecognized buffer");
749         if (NativeWindowCancelBuffer(nativeWindow, nativeWindowBuffer) != OHOS::GSERROR_OK) {
750             SWLOGE("NativeWindowCancelBuffer failed: (%{public}d)", ret);
751         }
752         return VK_ERROR_OUT_OF_DATE_KHR;
753     }
754     result = deviceLayerData->deviceDispatchTable->AcquireImageOHOS(device, swapchain.images[index].image, -1,
755                                                                     semaphore, vkFence);
756     if (result != VK_SUCCESS) {
757         if (NativeWindowCancelBuffer(nativeWindow, nativeWindowBuffer) != OHOS::GSERROR_OK) {
758             SWLOGE("NativeWindowCancelBuffer failed: (%{public}d)", ret);
759         }
760         swapchain.images[index].requested = false;
761         swapchain.images[index].requestFence = -1;
762         return result;
763     }
764 
765     *imageIndex = index;
766     return VK_SUCCESS;
767 }
768 
769 VKAPI_ATTR
GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,uint32_t * pRectCount,VkRect2D * pRects)770 VkResult GetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
771     VkSurfaceKHR surface, uint32_t* pRectCount, VkRect2D* pRects)
772 {
773     if (pRects == nullptr) {
774         *pRectCount = 1;
775         return VK_SUCCESS;
776     }
777     bool incomplete = *pRectCount < 1;
778     *pRectCount = std::min(*pRectCount, 1u);
779     if (incomplete) {
780         return VK_INCOMPLETE;
781     }
782 
783     NativeWindow* window = SurfaceFromHandle(surface)->window;
784 
785     int width = 0;
786     int height = 0;
787     int err = NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &height, &width);
788     if (err != OHOS::GSERROR_OK) {
789         SWLOGE("NATIVE_WINDOW_DEFAULT_WIDTH GET BUFFER GEOMETRY failed: (%{public}d)", err);
790     }
791     pRects[0].offset.x = 0;
792     pRects[0].offset.y = 0;
793     pRects[0].extent = VkExtent2D{static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
794     return VK_SUCCESS;
795 }
796 
797 VKAPI_ATTR
AcquireNextImage2KHR(VkDevice device,const VkAcquireNextImageInfoKHR * pAcquireInfo,uint32_t * pImageIndex)798 VkResult AcquireNextImage2KHR(VkDevice device, const VkAcquireNextImageInfoKHR* pAcquireInfo, uint32_t* pImageIndex)
799 {
800     return AcquireNextImageKHR(device, pAcquireInfo->swapchain, pAcquireInfo->timeout,
801                                pAcquireInfo->semaphore, pAcquireInfo->fence, pImageIndex);
802 }
803 
GetPresentRegion(const VkPresentRegionKHR * regions,const Swapchain & swapchain,uint32_t index)804 const VkPresentRegionKHR* GetPresentRegion(
805     const VkPresentRegionKHR* regions, const Swapchain &swapchain, uint32_t index)
806 {
807     return (regions && !swapchain.mailboxMode) ? &regions[index] : nullptr;
808 }
809 
GetPresentRegions(const VkPresentInfoKHR * presentInfo)810 const VkPresentRegionKHR* GetPresentRegions(const VkPresentInfoKHR* presentInfo)
811 {
812     const VkPresentRegionsKHR* presentRegions = nullptr;
813     const VkPresentRegionsKHR* nextRegions = reinterpret_cast<const VkPresentRegionsKHR*>(presentInfo->pNext);
814     while (nextRegions != nullptr) {
815         if (nextRegions->sType == VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR) {
816             presentRegions = nextRegions;
817         }
818         nextRegions = reinterpret_cast<const VkPresentRegionsKHR*>(nextRegions->pNext);
819     }
820 
821     if (presentRegions == nullptr) {
822         return nullptr;
823     } else {
824         return presentRegions->pRegions;
825     }
826 }
827 
ReleaseImage(VkQueue queue,const VkPresentInfoKHR * presentInfo,Swapchain::Image & img,int32_t & fence)828 VkResult ReleaseImage(VkQueue queue, const VkPresentInfoKHR* presentInfo,
829     Swapchain::Image &img, int32_t &fence)
830 {
831     LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(queue));
832     VkResult result = deviceLayerData->deviceDispatchTable->QueueSignalReleaseImageOHOS(
833         queue, presentInfo->waitSemaphoreCount, presentInfo->pWaitSemaphores, img.image, &fence);
834     if (img.releaseFence >= 0) {
835         close(img.releaseFence);
836         img.releaseFence = -1;
837     }
838     if (fence >= 0) {
839         img.releaseFence = dup(fence);
840     }
841     return result;
842 }
843 
GetRegionRect(const VkAllocationCallbacks * defaultAllocator,struct Region::Rect ** rects,int32_t rectangleCount)844 struct Region::Rect* GetRegionRect(
845     const VkAllocationCallbacks* defaultAllocator, struct Region::Rect** rects, int32_t rectangleCount)
846 {
847     return static_cast<struct Region::Rect*>(
848                 defaultAllocator->pfnReallocation(
849                     defaultAllocator->pUserData, *rects,
850                     sizeof(Region::Rect) *rectangleCount,
851                     alignof(Region::Rect), VK_SYSTEM_ALLOCATION_SCOPE_COMMAND));
852 }
853 
InitRegionRect(const VkRectLayerKHR * layer,struct Region::Rect * rect)854 void InitRegionRect(const VkRectLayerKHR* layer, struct Region::Rect* rect)
855 {
856     rect->x = layer->offset.x;
857     rect->y = layer->offset.y;
858     rect->w = layer->extent.width;
859     rect->h = layer->extent.height;
860 }
861 
FlushBuffer(const VkPresentRegionKHR * region,struct Region::Rect * rects,Swapchain & swapchain,Swapchain::Image & img,int32_t fence)862 VkResult FlushBuffer(const VkPresentRegionKHR* region, struct Region::Rect* rects,
863     Swapchain &swapchain, Swapchain::Image &img, int32_t fence)
864 {
865     const VkAllocationCallbacks* defaultAllocator = &GetDefaultAllocator();
866     Region localRegion = {};
867     if (memset_s(&localRegion, sizeof(localRegion), 0, sizeof(Region)) != EOK) {
868         return VK_ERROR_SURFACE_LOST_KHR;
869     }
870     if (region != nullptr) {
871         int32_t rectangleCount = region->rectangleCount;
872         if (rectangleCount > 0) {
873             struct Region::Rect* tmpRects = GetRegionRect(defaultAllocator, &rects, rectangleCount);
874             if (tmpRects != nullptr) {
875                 rects = tmpRects;
876             } else {
877                 rectangleCount = 0;
878             }
879         }
880         for (int32_t r = 0; r < rectangleCount; ++r) {
881             InitRegionRect(&region->pRectangles[r], &rects[r]);
882         }
883 
884         localRegion.rects = rects;
885         localRegion.rectNumber = rectangleCount;
886     }
887     NativeWindow* window = swapchain.surface.window;
888     // the acquire fence will be close by BufferQueue module
889     int err = NativeWindowFlushBuffer(window, img.buffer, fence, localRegion);
890     VkResult scResult = VK_SUCCESS;
891     if (err != OHOS::GSERROR_OK) {
892         SWLOGE("FlushBuffer failed: (%{public}d)", err);
893         scResult = VK_ERROR_SURFACE_LOST_KHR;
894     } else {
895         if (img.requestFence >= 0) {
896             close(img.requestFence);
897             img.requestFence = -1;
898         }
899         img.requested = false;
900     }
901 
902     if (swapchain.shared && scResult == VK_SUCCESS) {
903         NativeWindowBuffer* buffer = nullptr;
904         int releaseFence = -1;
905         err = NativeWindowRequestBuffer(window, &buffer, &releaseFence);
906         if (err != OHOS::GSERROR_OK) {
907             scResult = VK_ERROR_SURFACE_LOST_KHR;
908         } else if (img.buffer != buffer) {
909             scResult = VK_ERROR_SURFACE_LOST_KHR;
910         } else {
911             img.requestFence = releaseFence;
912             img.requested = true;
913         }
914     }
915 
916     return scResult;
917 }
918 
QueuePresentKHR(VkQueue queue,const VkPresentInfoKHR * presentInfo)919 VKAPI_ATTR VkResult VKAPI_CALL QueuePresentKHR(
920     VkQueue queue, const VkPresentInfoKHR* presentInfo)
921 {
922     VkResult ret = VK_SUCCESS;
923 
924     const VkPresentRegionKHR* regions = GetPresentRegions(presentInfo);
925     const VkAllocationCallbacks* defaultAllocator = &GetDefaultAllocator();
926     struct Region::Rect* rects = nullptr;
927     LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(queue));
928     VkDevice device = deviceLayerData->device;
929 
930     for (uint32_t i = 0; i < presentInfo->swapchainCount; i++) {
931         Swapchain &swapchain = *(reinterpret_cast<Swapchain*>(presentInfo->pSwapchains[i]));
932         Swapchain::Image &img = swapchain.images[presentInfo->pImageIndices[i]];
933         const VkPresentRegionKHR* region = GetPresentRegion(regions, swapchain, i);
934         int32_t fence = -1;
935         ret = ReleaseImage(queue, presentInfo, img, fence);
936         if (swapchain.surface.swapchainHandle == presentInfo->pSwapchains[i]) {
937             if (ret == VK_SUCCESS) {
938                 ret = FlushBuffer(region, rects, swapchain, img, fence);
939             } else {
940                 ReleaseSwapchain(device, &swapchain);
941             }
942         } else {
943             SWLOGE("QueuePresentKHR swapchainHandle != pSwapchains[%{public}d]", i);
944             ReleaseSwapchainImage(device, nullptr, fence, img, true);
945             ret = VK_ERROR_OUT_OF_DATE_KHR;
946         }
947 
948         if (presentInfo->pResults) {
949             presentInfo->pResults[i] = ret;
950         }
951     }
952     if (rects != nullptr) {
953         defaultAllocator->pfnFree(defaultAllocator->pUserData, rects);
954     }
955     return ret;
956 }
957 
GetDeviceGroupPresentCapabilitiesKHR(VkDevice,VkDeviceGroupPresentCapabilitiesKHR * pDeviceGroupPresentCapabilities)958 VKAPI_ATTR VkResult GetDeviceGroupPresentCapabilitiesKHR(
959     VkDevice, VkDeviceGroupPresentCapabilitiesKHR* pDeviceGroupPresentCapabilities)
960 {
961     if (pDeviceGroupPresentCapabilities == nullptr) {
962         return VK_ERROR_OUT_OF_HOST_MEMORY;
963     }
964 
965     memset_s(pDeviceGroupPresentCapabilities->presentMask,
966         sizeof(pDeviceGroupPresentCapabilities->presentMask), 0, sizeof(pDeviceGroupPresentCapabilities->presentMask));
967     pDeviceGroupPresentCapabilities->presentMask[0] = 1u;
968     pDeviceGroupPresentCapabilities->modes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
969 
970     return VK_SUCCESS;
971 }
972 
GetDeviceGroupSurfacePresentModesKHR(VkDevice,VkSurfaceKHR,VkDeviceGroupPresentModeFlagsKHR * pModes)973 VKAPI_ATTR VkResult GetDeviceGroupSurfacePresentModesKHR(
974     VkDevice, VkSurfaceKHR, VkDeviceGroupPresentModeFlagsKHR* pModes)
975 {
976     *pModes = VK_DEVICE_GROUP_PRESENT_MODE_LOCAL_BIT_KHR;
977     return VK_SUCCESS;
978 }
979 
GetPhysicalDeviceSurfaceSupportKHR(VkPhysicalDevice physicalDevice,uint32_t queueFamilyIndex,const VkSurfaceKHR surface,VkBool32 * pSupported)980 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceSupportKHR(
981     VkPhysicalDevice physicalDevice, uint32_t queueFamilyIndex, const VkSurfaceKHR surface, VkBool32* pSupported)
982 {
983     *pSupported = VK_TRUE;
984     return VK_SUCCESS;
985 }
986 
CreateSurfaceOHOS(VkInstance instance,const VkSurfaceCreateInfoOHOS * pCreateInfo,const VkAllocationCallbacks * allocator,VkSurfaceKHR * outSurface)987 VKAPI_ATTR VkResult VKAPI_CALL CreateSurfaceOHOS(VkInstance instance,
988     const VkSurfaceCreateInfoOHOS* pCreateInfo,
989     const VkAllocationCallbacks* allocator, VkSurfaceKHR* outSurface)
990 {
991     if (allocator == nullptr) {
992         allocator = &GetDefaultAllocator();
993     }
994     void* mem = allocator->pfnAllocation(allocator->pUserData, sizeof(Surface), alignof(Surface),
995                                          VK_SYSTEM_ALLOCATION_SCOPE_OBJECT);
996     if (mem == nullptr) {
997         return VK_ERROR_OUT_OF_HOST_MEMORY;
998     }
999 
1000     Surface* surface = new (mem) Surface;
1001     surface->window = pCreateInfo->window;
1002     surface->swapchainHandle = VK_NULL_HANDLE;
1003     NativeWindowHandleOpt(pCreateInfo->window, GET_USAGE, &(surface->consumerUsage));
1004 
1005     if (surface->consumerUsage == 0) {
1006         SWLOGE("native window get usage failed, error num : %{public}d", VK_ERROR_SURFACE_LOST_KHR);
1007         surface->~Surface();
1008         allocator->pfnFree(allocator->pUserData, surface);
1009         return VK_ERROR_SURFACE_LOST_KHR;
1010     }
1011 
1012     *outSurface = HandleFromSurface(surface);
1013     return VK_SUCCESS;
1014 }
1015 
DestroySurfaceKHR(VkInstance instance,VkSurfaceKHR vkSurface,const VkAllocationCallbacks * pAllocator)1016 VKAPI_ATTR void VKAPI_CALL DestroySurfaceKHR(
1017     VkInstance instance, VkSurfaceKHR vkSurface, const VkAllocationCallbacks* pAllocator)
1018 {
1019     Surface* surface = SurfaceFromHandle(vkSurface);
1020     if (surface == nullptr) {
1021         return;
1022     }
1023     if (pAllocator == nullptr) {
1024         pAllocator = &GetDefaultAllocator();
1025     }
1026     surface->~Surface();
1027     pAllocator->pfnFree(pAllocator->pUserData, surface);
1028 }
1029 
GetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice,VkSurfaceKHR surface,VkSurfaceCapabilitiesKHR * capabilities)1030 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceCapabilitiesKHR(
1031     VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR* capabilities)
1032 {
1033     int width = 0;
1034     int height = 0;
1035     uint32_t maxBufferCount = MAX_BUFFER_SIZE;
1036     if (surface != VK_NULL_HANDLE) {
1037         NativeWindow* window = SurfaceFromHandle(surface)->window;
1038         int err = NativeWindowHandleOpt(window, GET_BUFFER_GEOMETRY, &height, &width);
1039         if (err != OHOS::GSERROR_OK) {
1040             SWLOGE("NATIVE_WINDOW GET_BUFFER_GEOMETRY failed: (%{public}d)", err);
1041             return VK_ERROR_SURFACE_LOST_KHR;
1042         }
1043         maxBufferCount = window->surface->GetQueueSize();
1044         SWLOGD("queue size : (%{public}d)", maxBufferCount);
1045     }
1046 
1047     capabilities->minImageCount = std::min(maxBufferCount, MIN_BUFFER_SIZE);
1048     capabilities->maxImageCount = maxBufferCount;
1049     capabilities->currentExtent = VkExtent2D {static_cast<uint32_t>(width), static_cast<uint32_t>(height)};
1050     capabilities->minImageExtent = VkExtent2D {1, 1};
1051     capabilities->maxImageExtent = VkExtent2D {4096, 4096};
1052     capabilities->maxImageArrayLayers = 1;
1053     capabilities->supportedCompositeAlpha = VK_COMPOSITE_ALPHA_INHERIT_BIT_KHR;
1054     capabilities->supportedUsageFlags = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT |
1055                                         VK_IMAGE_USAGE_SAMPLED_BIT | VK_IMAGE_USAGE_STORAGE_BIT |
1056                                         VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
1057     return VK_SUCCESS;
1058 }
1059 
GetPhysicalDeviceSurfaceFormatsKHR(VkPhysicalDevice physicalDevice,const VkSurfaceKHR surface,uint32_t * count,VkSurfaceFormatKHR * formats)1060 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfaceFormatsKHR(
1061     VkPhysicalDevice physicalDevice, const VkSurfaceKHR surface, uint32_t* count, VkSurfaceFormatKHR* formats)
1062 {
1063     std::vector<VkSurfaceFormatKHR> allFormats = {
1064         {VK_FORMAT_R8G8B8A8_UNORM, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR},
1065         {VK_FORMAT_R8G8B8A8_SRGB, VK_COLOR_SPACE_SRGB_NONLINEAR_KHR}
1066     };
1067     VkResult result = VK_SUCCESS;
1068     if (formats != nullptr) {
1069         uint32_t transferCount = allFormats.size();
1070         if (transferCount > *count) {
1071             transferCount = *count;
1072             result = VK_INCOMPLETE;
1073         }
1074         std::copy(allFormats.begin(), allFormats.begin() + transferCount, formats);
1075         *count = transferCount;
1076     } else {
1077         *count = allFormats.size();
1078     }
1079 
1080     return result;
1081 }
1082 
QueryPresentationProperties(VkPhysicalDevice physicalDevice,VkPhysicalDevicePresentationPropertiesOHOS * presentationProperties)1083 void QueryPresentationProperties(
1084     VkPhysicalDevice physicalDevice,
1085     VkPhysicalDevicePresentationPropertiesOHOS* presentationProperties)
1086 {
1087     VkPhysicalDeviceProperties2 properties = {
1088         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2,
1089         presentationProperties,
1090         {},
1091     };
1092 
1093     presentationProperties->sType =
1094         VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PRESENTATION_PROPERTIES_OHOS;
1095     presentationProperties->pNext = nullptr;
1096     presentationProperties->sharedImage = VK_FALSE;
1097 
1098     DispatchKey key = GetDispatchKey(physicalDevice);
1099     LayerData* curLayerData = GetLayerDataPtr(key);
1100     if (curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2) {
1101         curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2(physicalDevice, &properties);
1102     } else if (curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2KHR) {
1103         curLayerData->instanceDispatchTable->GetPhysicalDeviceProperties2KHR(physicalDevice, &properties);
1104     } else {
1105         SWLOGE("Func vkGetPhysicalDeviceProperties2 and vkGetPhysicalDeviceProperties2KHR are both null.");
1106     }
1107 }
1108 
GetPhysicalDeviceSurfacePresentModesKHR(VkPhysicalDevice physicalDevice,const VkSurfaceKHR surface,uint32_t * count,VkPresentModeKHR * pPresentModes)1109 VKAPI_ATTR VkResult VKAPI_CALL GetPhysicalDeviceSurfacePresentModesKHR(
1110     VkPhysicalDevice physicalDevice, const VkSurfaceKHR surface, uint32_t* count, VkPresentModeKHR* pPresentModes)
1111 {
1112     std::vector<VkPresentModeKHR> presentModes = {
1113         VK_PRESENT_MODE_MAILBOX_KHR,
1114         VK_PRESENT_MODE_FIFO_KHR
1115     };
1116 
1117     VkPhysicalDevicePresentationPropertiesOHOS presentProperties = {};
1118     QueryPresentationProperties(physicalDevice, &presentProperties);
1119     if (presentProperties.sharedImage) {
1120         presentModes.push_back(VK_PRESENT_MODE_SHARED_DEMAND_REFRESH_KHR);
1121         presentModes.push_back(VK_PRESENT_MODE_SHARED_CONTINUOUS_REFRESH_KHR);
1122     }
1123 
1124     uint32_t numModes = static_cast<uint32_t>(presentModes.size());
1125     VkResult result = VK_SUCCESS;
1126     if (pPresentModes != nullptr) {
1127         if (*count < numModes) {
1128             result = VK_INCOMPLETE;
1129         }
1130         *count = std::min(*count, numModes);
1131         std::copy_n(presentModes.data(), *count, pPresentModes);
1132     } else {
1133         *count = numModes;
1134     }
1135     return result;
1136 }
1137 
GetExtensionBitFromName(const char * name)1138 Extension GetExtensionBitFromName(const char* name)
1139 {
1140     if (name == nullptr) {
1141         return Extension::EXTENSION_UNKNOWN;
1142     }
1143     if (strcmp(name, VK_OHOS_SURFACE_EXTENSION_NAME) == 0) {
1144         return Extension::OHOS_SURFACE;
1145     }
1146     if (strcmp(name, VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME) == 0) {
1147         return Extension::OHOS_NATIVE_BUFFER;
1148     }
1149     if (strcmp(name, VK_KHR_SURFACE_EXTENSION_NAME) == 0) {
1150         return Extension::KHR_SURFACE;
1151     }
1152     if (strcmp(name, VK_KHR_SWAPCHAIN_EXTENSION_NAME) == 0) {
1153         return Extension::KHR_SWAPCHAIN;
1154     }
1155     return Extension::EXTENSION_UNKNOWN;
1156 }
1157 
CreateInstance(const VkInstanceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkInstance * pInstance)1158 VKAPI_ATTR VkResult VKAPI_CALL CreateInstance(
1159     const VkInstanceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkInstance* pInstance)
1160 {
1161     VkLayerInstanceCreateInfo* chainInfo = GetChainInfo(pCreateInfo, VK_LAYER_LINK_INFO);
1162 
1163     if (chainInfo == nullptr || chainInfo->u.pLayerInfo == nullptr) {
1164         return VK_ERROR_INITIALIZATION_FAILED;
1165     }
1166     PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr =
1167         chainInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1168     PFN_vkCreateInstance fpCreateInstance =
1169         (PFN_vkCreateInstance)fpGetInstanceProcAddr(nullptr, "vkCreateInstance");
1170     if (fpCreateInstance == nullptr) {
1171         return VK_ERROR_INITIALIZATION_FAILED;
1172     }
1173 
1174     chainInfo->u.pLayerInfo = chainInfo->u.pLayerInfo->pNext;
1175 
1176     VkResult result = fpCreateInstance(pCreateInfo, pAllocator, pInstance);
1177     if (result != VK_SUCCESS) {
1178         return result;
1179     }
1180 
1181     LayerData* instanceLayerData = GetLayerDataPtr(GetDispatchKey(*pInstance));
1182     instanceLayerData->instance = *pInstance;
1183     instanceLayerData->instanceDispatchTable = std::make_unique<VkLayerInstanceDispatchTable>();
1184     layer_init_instance_dispatch_table(*pInstance, instanceLayerData->instanceDispatchTable.get(),
1185                                        fpGetInstanceProcAddr);
1186     for (uint32_t index = 0; index < pCreateInfo->enabledExtensionCount; index++) {
1187         auto extBit = GetExtensionBitFromName(pCreateInfo->ppEnabledExtensionNames[index]);
1188         if (extBit != Extension::EXTENSION_UNKNOWN) {
1189             instanceLayerData->enabledExtensions.set(extBit);
1190         }
1191     }
1192     return result;
1193 }
1194 
DestroyInstance(VkInstance instance,const VkAllocationCallbacks * pAllocator)1195 VKAPI_ATTR void VKAPI_CALL DestroyInstance(
1196     VkInstance instance, const VkAllocationCallbacks* pAllocator)
1197 {
1198     DispatchKey instanceKey = GetDispatchKey(instance);
1199     LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1200     curLayerData->instanceDispatchTable->DestroyInstance(instance, pAllocator);
1201     FreeLayerDataPtr(instanceKey);
1202 }
1203 
CheckExtensionAvailable(const std::string & extensionName,const std::vector<VkExtensionProperties> & deviceExtensions)1204 bool CheckExtensionAvailable(const std::string &extensionName,
1205                              const std::vector<VkExtensionProperties> &deviceExtensions)
1206 {
1207     bool extensionAvailable = false;
1208     for (uint32_t i = 0; i < deviceExtensions.size(); i++) {
1209         if (strcmp(extensionName.data(), deviceExtensions[i].extensionName) == 0) {
1210             extensionAvailable = true;
1211             break;
1212         }
1213     }
1214     return extensionAvailable;
1215 }
1216 
AddDeviceExtensions(VkPhysicalDevice gpu,const LayerData * gpuLayerData,std::vector<const char * > & enabledExtensions)1217 VkResult AddDeviceExtensions(VkPhysicalDevice gpu, const LayerData* gpuLayerData,
1218                              std::vector<const char*> &enabledExtensions)
1219 {
1220     VkResult result = VK_SUCCESS;
1221     uint32_t deviceExtensionCount = 0;
1222     result = gpuLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(
1223         gpu, nullptr, &deviceExtensionCount, nullptr);
1224     if (result == VK_SUCCESS && deviceExtensionCount > 0) {
1225         std::vector<VkExtensionProperties> deviceExtensions(deviceExtensionCount);
1226         result = gpuLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(
1227             gpu, nullptr, &deviceExtensionCount, deviceExtensions.data());
1228         if (result == VK_SUCCESS) {
1229             if (!CheckExtensionAvailable(VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME, deviceExtensions)) {
1230                 return VK_ERROR_INITIALIZATION_FAILED;
1231             }
1232             enabledExtensions.push_back(VK_OHOS_NATIVE_BUFFER_EXTENSION_NAME);
1233             if (CheckExtensionAvailable(VK_OHOS_EXTERNAL_MEMORY_EXTENSION_NAME,
1234                                         deviceExtensions)) {
1235                 enabledExtensions.push_back(VK_OHOS_EXTERNAL_MEMORY_EXTENSION_NAME);
1236             }
1237         }
1238     }
1239     return VK_SUCCESS;
1240 }
1241 
CreateDevice(VkPhysicalDevice gpu,const VkDeviceCreateInfo * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDevice * pDevice)1242 VKAPI_ATTR VkResult VKAPI_CALL CreateDevice(VkPhysicalDevice gpu,
1243     const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice)
1244 {
1245     DispatchKey gpuKey = GetDispatchKey(gpu);
1246     LayerData* gpuLayerData = GetLayerDataPtr(gpuKey);
1247 
1248     VkDeviceCreateInfo createInfo = *pCreateInfo;
1249     std::vector<const char*> enabledExtensions = {};
1250     for (uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) {
1251         enabledExtensions.push_back(createInfo.ppEnabledExtensionNames[i]);
1252     }
1253 
1254     VkResult result = AddDeviceExtensions(gpu, gpuLayerData, enabledExtensions);
1255     if (result != VK_SUCCESS) {
1256         return result;
1257     }
1258 
1259     createInfo.enabledExtensionCount = ToUint32(enabledExtensions.size());
1260     createInfo.ppEnabledExtensionNames = enabledExtensions.data();
1261 
1262     VkLayerDeviceCreateInfo* linkInfo = GetChainInfo(pCreateInfo, VK_LAYER_LINK_INFO);
1263 
1264     if (linkInfo == nullptr || linkInfo->u.pLayerInfo == nullptr) {
1265         return VK_ERROR_INITIALIZATION_FAILED;
1266     }
1267     PFN_vkGetInstanceProcAddr fpGetInstanceProcAddr = linkInfo->u.pLayerInfo->pfnNextGetInstanceProcAddr;
1268     PFN_vkGetDeviceProcAddr fpGetDeviceProcAddr = linkInfo->u.pLayerInfo->pfnNextGetDeviceProcAddr;
1269     PFN_vkCreateDevice fpCreateDevice =
1270         (PFN_vkCreateDevice)fpGetInstanceProcAddr(gpuLayerData->instance, "vkCreateDevice");
1271     if (fpCreateDevice == nullptr) {
1272         return VK_ERROR_INITIALIZATION_FAILED;
1273     }
1274 
1275     linkInfo->u.pLayerInfo = linkInfo->u.pLayerInfo->pNext;
1276 
1277     result = fpCreateDevice(gpu, &createInfo, pAllocator, pDevice);
1278     if (result != VK_SUCCESS) {
1279         return result;
1280     }
1281 
1282     LayerData* deviceLayerData = GetLayerDataPtr(GetDispatchKey(*pDevice));
1283     for (uint32_t i = 0; i < createInfo.enabledExtensionCount; i++) {
1284         auto extBit = GetExtensionBitFromName(createInfo.ppEnabledExtensionNames[i]);
1285         if (extBit != Extension::EXTENSION_UNKNOWN) {
1286             deviceLayerData->enabledExtensions.set(extBit);
1287         }
1288     }
1289 
1290     deviceLayerData->deviceDispatchTable = std::make_unique<VkLayerDispatchTable>();
1291     deviceLayerData->instance = gpuLayerData->instance;
1292     deviceLayerData->device = *pDevice;
1293     layer_init_device_dispatch_table(*pDevice, deviceLayerData->deviceDispatchTable.get(), fpGetDeviceProcAddr);
1294 
1295     VkLayerDeviceCreateInfo* callbackInfo = GetChainInfo(pCreateInfo, VK_LOADER_DATA_CALLBACK);
1296     if (callbackInfo == nullptr || callbackInfo->u.pfnSetDeviceLoaderData == nullptr) {
1297         return VK_ERROR_INITIALIZATION_FAILED;
1298     }
1299     deviceLayerData->fpSetDeviceLoaderData = callbackInfo->u.pfnSetDeviceLoaderData;
1300 
1301     return VK_SUCCESS;
1302 }
1303 
DestroyDevice(VkDevice device,const VkAllocationCallbacks * pAllocator)1304 VKAPI_ATTR void VKAPI_CALL DestroyDevice(VkDevice device, const VkAllocationCallbacks* pAllocator)
1305 {
1306     DispatchKey deviceKey = GetDispatchKey(device);
1307     LayerData* deviceData = GetLayerDataPtr(deviceKey);
1308     deviceData->deviceDispatchTable->DestroyDevice(device, pAllocator);
1309     FreeLayerDataPtr(deviceKey);
1310 }
1311 
CreateDebugUtilsMessengerEXT(VkInstance instance,const VkDebugUtilsMessengerCreateInfoEXT * pCreateInfo,const VkAllocationCallbacks * pAllocator,VkDebugUtilsMessengerEXT * pMessenger)1312 VKAPI_ATTR VkResult VKAPI_CALL CreateDebugUtilsMessengerEXT(
1313     VkInstance instance,
1314     const VkDebugUtilsMessengerCreateInfoEXT* pCreateInfo,
1315     const VkAllocationCallbacks* pAllocator, VkDebugUtilsMessengerEXT* pMessenger)
1316 {
1317     DispatchKey instanceKey = GetDispatchKey(instance);
1318     LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1319     VkResult res = curLayerData->instanceDispatchTable->CreateDebugUtilsMessengerEXT(
1320         instance, pCreateInfo, pAllocator, pMessenger);
1321     if (res == VK_SUCCESS) {
1322         curLayerData->debugCallbacks[*pMessenger] = *pCreateInfo;
1323     }
1324     return res;
1325 }
1326 
DestroyDebugUtilsMessengerEXT(VkInstance instance,VkDebugUtilsMessengerEXT messenger,const VkAllocationCallbacks * pAllocator)1327 VKAPI_ATTR void VKAPI_CALL DestroyDebugUtilsMessengerEXT(
1328     VkInstance instance, VkDebugUtilsMessengerEXT messenger, const VkAllocationCallbacks* pAllocator)
1329 {
1330     DispatchKey instanceKey = GetDispatchKey(instance);
1331     LayerData* curLayerData = GetLayerDataPtr(instanceKey);
1332     curLayerData->debugCallbacks.erase(messenger);
1333     curLayerData->instanceDispatchTable->DestroyDebugUtilsMessengerEXT(instance, messenger, pAllocator);
1334 }
1335 
EnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)1336 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceExtensionProperties(
1337     const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1338 {
1339     if ((pLayerName != nullptr) && (strcmp(pLayerName, swapchainLayer.layerName) == 0)) {
1340         return GetExtensionProperties(std::size(instanceExtensions), instanceExtensions, pCount, pProperties);
1341     }
1342     return VK_ERROR_LAYER_NOT_PRESENT;
1343 }
1344 
EnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)1345 VKAPI_ATTR VkResult VKAPI_CALL EnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties)
1346 {
1347     return GetLayerProperties(1, &swapchainLayer, pCount, pProperties);
1348 }
1349 
EnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)1350 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceLayerProperties(
1351     VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties)
1352 {
1353     return GetLayerProperties(1, &swapchainLayer, pCount, pProperties);
1354 }
1355 
EnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)1356 VKAPI_ATTR VkResult VKAPI_CALL EnumerateDeviceExtensionProperties(
1357     VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1358 {
1359     if ((pLayerName != nullptr) && (strcmp(pLayerName, swapchainLayer.layerName) == 0)) {
1360         return GetExtensionProperties(
1361             std::size(deviceExtensions), deviceExtensions, pCount, pProperties);
1362     }
1363 
1364     if (physicalDevice == nullptr) {
1365         SWLOGE("physicalDevice is null.");
1366         return VK_ERROR_LAYER_NOT_PRESENT;
1367     }
1368 
1369     DispatchKey key = GetDispatchKey(physicalDevice);
1370     LayerData* curLayerData = GetLayerDataPtr(key);
1371     return curLayerData->instanceDispatchTable->EnumerateDeviceExtensionProperties(physicalDevice, nullptr,
1372                                                                                    pCount, pProperties);
1373 }
1374 
GetPhysicalDeviceProcAddr(VkInstance instance,const char * funcName)1375 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetPhysicalDeviceProcAddr(VkInstance instance, const char* funcName)
1376 {
1377     if (instance == VK_NULL_HANDLE) {
1378         SWLOGE("instance is null.");
1379         return nullptr;
1380     }
1381 
1382     LayerData* layerData = GetLayerDataPtr(GetDispatchKey(instance));
1383     VkLayerInstanceDispatchTable* pTable = layerData->instanceDispatchTable.get();
1384 
1385     if (pTable->GetPhysicalDeviceProcAddr == nullptr) {
1386         return nullptr;
1387     }
1388     return pTable->GetPhysicalDeviceProcAddr(instance, funcName);
1389 }
1390 
GetDebugUtilsProc(const char * name)1391 static inline PFN_vkVoidFunction GetDebugUtilsProc(const char* name)
1392 {
1393     if (name == nullptr) {
1394         return nullptr;
1395     }
1396     if (strcmp(name, "vkCreateDebugUtilsMessengerEXT") == 0) {
1397         return reinterpret_cast<PFN_vkVoidFunction>(CreateDebugUtilsMessengerEXT);
1398     }
1399     if (strcmp(name, "vkDestroyDebugUtilsMessengerEXT") == 0) {
1400         return reinterpret_cast<PFN_vkVoidFunction>(DestroyDebugUtilsMessengerEXT);
1401     }
1402     return nullptr;
1403 }
1404 
GetGlobalProc(const char * name)1405 static inline PFN_vkVoidFunction GetGlobalProc(const char* name)
1406 {
1407     if (name == nullptr) {
1408         return nullptr;
1409     }
1410     if (strcmp("vkEnumerateDeviceLayerProperties", name) == 0) {
1411         return reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceLayerProperties);
1412     }
1413     return nullptr;
1414 }
1415 
GetSwapchainProc(const char * name)1416 static inline PFN_vkVoidFunction GetSwapchainProc(const char* name)
1417 {
1418     if (name == nullptr) {
1419         return nullptr;
1420     }
1421     if (strcmp("vkCreateSwapchainKHR", name) == 0) {
1422         return reinterpret_cast<PFN_vkVoidFunction>(CreateSwapchainKHR);
1423     }
1424     if (strcmp("vkDestroySwapchainKHR", name) == 0) {
1425         return reinterpret_cast<PFN_vkVoidFunction>(DestroySwapchainKHR);
1426     }
1427     if (strcmp("vkAcquireNextImageKHR", name) == 0) {
1428         return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImageKHR);
1429     }
1430     if (strcmp("vkAcquireNextImage2KHR", name) == 0) {
1431         return reinterpret_cast<PFN_vkVoidFunction>(AcquireNextImage2KHR);
1432     }
1433     if (strcmp("vkQueuePresentKHR", name) == 0) {
1434         return reinterpret_cast<PFN_vkVoidFunction>(QueuePresentKHR);
1435     }
1436     if (strcmp("vkGetSwapchainImagesKHR", name) == 0) {
1437         return reinterpret_cast<PFN_vkVoidFunction>(GetSwapchainImagesKHR);
1438     }
1439     if (strcmp("vkGetDeviceGroupPresentCapabilitiesKHR", name) == 0) {
1440         return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceGroupPresentCapabilitiesKHR);
1441     }
1442     if (strcmp("vkGetDeviceGroupSurfacePresentModesKHR", name) == 0) {
1443         return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceGroupSurfacePresentModesKHR);
1444     }
1445     if (strcmp("vkGetPhysicalDevicePresentRectanglesKHR", name) == 0) {
1446         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDevicePresentRectanglesKHR);
1447     }
1448     return nullptr;
1449 }
1450 
LayerInterceptDeviceProc(std::bitset<Extension::EXTENSION_COUNT> & enabledExtensions,const char * name)1451 static inline PFN_vkVoidFunction LayerInterceptDeviceProc(
1452     std::bitset<Extension::EXTENSION_COUNT>& enabledExtensions, const char* name)
1453 {
1454     if (name == nullptr) {
1455         return nullptr;
1456     }
1457     if (strcmp("vkGetDeviceProcAddr", name) == 0) {
1458         return reinterpret_cast<PFN_vkVoidFunction>(GetDeviceProcAddr);
1459     }
1460     if (strcmp("vkDestroyDevice", name) == 0) {
1461         return reinterpret_cast<PFN_vkVoidFunction>(DestroyDevice);
1462     }
1463     if (enabledExtensions.test(Extension::KHR_SWAPCHAIN)) {
1464         PFN_vkVoidFunction addr = GetSwapchainProc(name);
1465         if (addr != nullptr) {
1466             return addr;
1467         }
1468     }
1469     return nullptr;
1470 }
1471 
GetSurfaceKHRProc(const char * name)1472 static inline PFN_vkVoidFunction GetSurfaceKHRProc(const char* name)
1473 {
1474     if (name == nullptr) {
1475         return nullptr;
1476     }
1477     if (strcmp("vkDestroySurfaceKHR", name) == 0) {
1478         return reinterpret_cast<PFN_vkVoidFunction>(DestroySurfaceKHR);
1479     }
1480     if (strcmp("vkGetPhysicalDeviceSurfacePresentModesKHR", name) == 0) {
1481         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfacePresentModesKHR);
1482     }
1483     if (strcmp("vkGetPhysicalDeviceSurfaceSupportKHR", name) == 0) {
1484         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceSupportKHR);
1485     }
1486     if (strcmp("vkGetPhysicalDeviceSurfaceCapabilitiesKHR", name) == 0) {
1487         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceCapabilitiesKHR);
1488     }
1489     if (strcmp("vkGetPhysicalDeviceSurfaceFormatsKHR", name) == 0) {
1490         return reinterpret_cast<PFN_vkVoidFunction>(GetPhysicalDeviceSurfaceFormatsKHR);
1491     }
1492     return nullptr;
1493 }
1494 
LayerInterceptInstanceProc(std::bitset<Extension::EXTENSION_COUNT> & enabledExtensions,const char * name)1495 static inline PFN_vkVoidFunction LayerInterceptInstanceProc(
1496     std::bitset<Extension::EXTENSION_COUNT>& enabledExtensions, const char* name)
1497 {
1498     if (name == nullptr) {
1499         return nullptr;
1500     }
1501     if (enabledExtensions.test(Extension::OHOS_SURFACE)) {
1502         if (strcmp("vkCreateSurfaceOHOS", name) == 0) {
1503             return reinterpret_cast<PFN_vkVoidFunction>(CreateSurfaceOHOS);
1504         }
1505     }
1506     if (enabledExtensions.test(Extension::KHR_SURFACE)) {
1507         PFN_vkVoidFunction addr = GetSurfaceKHRProc(name);
1508         if (addr != nullptr) {
1509             return addr;
1510         }
1511     }
1512 
1513     if (enabledExtensions.test(Extension::KHR_SWAPCHAIN)) {
1514         PFN_vkVoidFunction addr = GetSwapchainProc(name);
1515         if (addr != nullptr) {
1516             return addr;
1517         }
1518     }
1519 
1520     PFN_vkVoidFunction addr = GetDebugUtilsProc(name);
1521     if (addr != nullptr) {
1522         return addr;
1523     }
1524     return GetGlobalProc(name);
1525 }
1526 
GetDeviceProcAddr(VkDevice device,const char * funcName)1527 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetDeviceProcAddr(VkDevice device, const char* funcName)
1528 {
1529     if (funcName == nullptr) {
1530         return nullptr;
1531     }
1532     if (device == VK_NULL_HANDLE) {
1533         SWLOGE("device is null.");
1534         return nullptr;
1535     }
1536     LayerData* layerData = GetLayerDataPtr(GetDispatchKey(device));
1537     if (layerData == nullptr) {
1538         SWLOGE("libvulkan_swapchain GetInstanceProcAddr layerData is null");
1539         return nullptr;
1540     }
1541 
1542     PFN_vkVoidFunction addr = LayerInterceptDeviceProc(layerData->enabledExtensions, funcName);
1543     if (addr != nullptr) {
1544         return addr;
1545     }
1546     LayerData* devData = GetLayerDataPtr(GetDispatchKey(device));
1547     VkLayerDispatchTable* pTable = devData->deviceDispatchTable.get();
1548     if (pTable->GetDeviceProcAddr == nullptr) {
1549         return nullptr;
1550     }
1551     return pTable->GetDeviceProcAddr(device, funcName);
1552 }
1553 
GetInstanceProcAddr(VkInstance instance,const char * funcName)1554 VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL GetInstanceProcAddr(VkInstance instance, const char* funcName)
1555 {
1556     if (funcName == nullptr) {
1557         return nullptr;
1558     }
1559 
1560     if (strcmp("vkGetInstanceProcAddr", funcName) == 0) {
1561         return reinterpret_cast<PFN_vkVoidFunction>(GetInstanceProcAddr);
1562     }
1563     if (strcmp("vkCreateInstance", funcName) == 0) {
1564         return reinterpret_cast<PFN_vkVoidFunction>(CreateInstance);
1565     }
1566     if (strcmp("vkEnumerateInstanceExtensionProperties", funcName) == 0) {
1567         return reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceExtensionProperties);
1568     }
1569     if (strcmp("vkEnumerateInstanceLayerProperties", funcName) == 0) {
1570         return reinterpret_cast<PFN_vkVoidFunction>(EnumerateInstanceLayerProperties);
1571     }
1572     if (strcmp("vkDestroyInstance", funcName) == 0) {
1573         return reinterpret_cast<PFN_vkVoidFunction>(DestroyInstance);
1574     }
1575     if (strcmp("vkCreateDevice", funcName) == 0) {
1576         return reinterpret_cast<PFN_vkVoidFunction>(CreateDevice);
1577     }
1578     if (strcmp("vkEnumerateDeviceExtensionProperties", funcName) == 0) {
1579         return reinterpret_cast<PFN_vkVoidFunction>(EnumerateDeviceExtensionProperties);
1580     }
1581 
1582     if (instance == VK_NULL_HANDLE) {
1583         SWLOGE("libvulkan_swapchain GetInstanceProcAddr(func name %{public}s) instance is null", funcName);
1584         return nullptr;
1585     }
1586 
1587     LayerData* layerData = GetLayerDataPtr(GetDispatchKey(instance));
1588     if (layerData == nullptr) {
1589         SWLOGE("libvulkan_swapchain GetInstanceProcAddr layerData is null");
1590         return nullptr;
1591     }
1592 
1593     PFN_vkVoidFunction addr = LayerInterceptInstanceProc(layerData->enabledExtensions, funcName);
1594     if (addr != nullptr) {
1595         return addr;
1596     }
1597 
1598     VkLayerInstanceDispatchTable* pTable = layerData->instanceDispatchTable.get();
1599     if (pTable == nullptr) {
1600         SWLOGE("libvulkan_swapchain GetInstanceProcAddr pTable = null");
1601         return nullptr;
1602     }
1603     if (pTable->GetInstanceProcAddr == nullptr) {
1604         SWLOGE("libvulkan_swapchain GetInstanceProcAddr pTable->GetInstanceProcAddr = null");
1605         return nullptr;
1606     }
1607     addr = pTable->GetInstanceProcAddr(instance, funcName);
1608 
1609     return addr;
1610 }
1611 }  // namespace SWAPCHAIN
1612 
1613 #if defined(__GNUC__) && __GNUC__ >= 4
1614 #define SWAPCHAIN_EXPORT __attribute__((visibility("default")))
1615 #else
1616 #define SWAPCHAIN_EXPORT
1617 #endif
1618 
1619 extern "C" {
vkEnumerateInstanceExtensionProperties(const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)1620 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateInstanceExtensionProperties(
1621     const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1622 {
1623     return SWAPCHAIN::EnumerateInstanceExtensionProperties(pLayerName, pCount, pProperties);
1624 }
1625 
1626 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL
vkEnumerateInstanceLayerProperties(uint32_t * pCount,VkLayerProperties * pProperties)1627 vkEnumerateInstanceLayerProperties(uint32_t* pCount, VkLayerProperties* pProperties)
1628 {
1629     return SWAPCHAIN::EnumerateInstanceLayerProperties(pCount, pProperties);
1630 }
1631 
vkEnumerateDeviceLayerProperties(VkPhysicalDevice physicalDevice,uint32_t * pCount,VkLayerProperties * pProperties)1632 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceLayerProperties(
1633     VkPhysicalDevice physicalDevice, uint32_t* pCount, VkLayerProperties* pProperties)
1634 {
1635     return SWAPCHAIN::EnumerateDeviceLayerProperties(VK_NULL_HANDLE, pCount, pProperties);
1636 }
1637 
vkEnumerateDeviceExtensionProperties(VkPhysicalDevice physicalDevice,const char * pLayerName,uint32_t * pCount,VkExtensionProperties * pProperties)1638 SWAPCHAIN_EXPORT VKAPI_ATTR VkResult VKAPI_CALL vkEnumerateDeviceExtensionProperties(
1639     VkPhysicalDevice physicalDevice, const char* pLayerName, uint32_t* pCount, VkExtensionProperties* pProperties)
1640 {
1641     return SWAPCHAIN::EnumerateDeviceExtensionProperties(VK_NULL_HANDLE, pLayerName, pCount, pProperties);
1642 }
1643 
vkGetDeviceProcAddr(VkDevice dev,const char * funcName)1644 SWAPCHAIN_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice dev, const char* funcName)
1645 {
1646     return SWAPCHAIN::GetDeviceProcAddr(dev, funcName);
1647 }
1648 
1649 SWAPCHAIN_EXPORT VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL
vkGetInstanceProcAddr(VkInstance instance,const char * funcName)1650 vkGetInstanceProcAddr(VkInstance instance, const char* funcName)
1651 {
1652     return SWAPCHAIN::GetInstanceProcAddr(instance, funcName);
1653 }
1654 }