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