| /* |
| * Copyright 2023 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| #ifndef GraphiteVulkanWindowContext_DEFINED |
| #define GraphiteVulkanWindowContext_DEFINED |
| |
| #include "include/core/SkTypes.h" |
| |
| #ifdef SK_VULKAN |
| |
| #include "include/core/SkSurface.h" |
| #include "include/private/base/SkTemplates.h" |
| #include "tools/gpu/vk/VkTestUtils.h" |
| #include "tools/window/WindowContext.h" |
| |
| namespace skgpu { |
| struct VulkanInterface; |
| } |
| namespace skwindow::internal { |
| class GraphiteVulkanWindowContext : public WindowContext { |
| public: |
| ~GraphiteVulkanWindowContext() override; |
| |
| sk_sp<SkSurface> getBackbufferSurface() override; |
| |
| bool isValid() override { return fDevice != VK_NULL_HANDLE; } |
| |
| void resize(int w, int h) override { this->createSwapchain(w, h); } |
| |
| void setDisplayParams(std::unique_ptr<const DisplayParams> params) override { |
| this->destroyContext(); |
| fDisplayParams = std::move(params); |
| this->initializeContext(); |
| } |
| |
| /* Platform specific function that creates a VkSurfaceKHR for a window */ |
| using CreateVkSurfaceFn = std::function<VkSurfaceKHR(VkInstance)>; |
| /* Platform specific function that determines whether presentation will succeed. */ |
| using CanPresentFn = sk_gpu_test::CanPresentFn; |
| |
| GraphiteVulkanWindowContext(std::unique_ptr<const DisplayParams>, |
| CreateVkSurfaceFn, |
| CanPresentFn, |
| PFN_vkGetInstanceProcAddr); |
| |
| private: |
| void initializeContext(); |
| void destroyContext(); |
| |
| bool createSwapchain(int width, int height); |
| bool populateSwapchainImages(VkFormat, VkImageUsageFlags, SkColorType, VkSharingMode); |
| |
| /** |
| * Swap backbuffers/frames, presenting the next available image. |
| */ |
| void onSwapBuffers() override; |
| |
| /** |
| * Define private method to submit work to the GPU (rather than using Window::submitToGpu) in |
| * order to properly configure semaphores. Submits work to render the image at |
| * fCurrentImageIndex. Return false upon failure. |
| */ |
| bool submitToGpu(); |
| |
| /** |
| * Reset the container of images (and destroy each image's associated rendering semaphore). |
| */ |
| void resetSwapchainImages(); |
| |
| /** |
| * Define a struct which represents a swapchain image to be presented. Each SwapchainImage |
| * contains the native VkImage, its image layout while not being used as a color attachment |
| * (which we initialize as VK_IMAGE_LAYOUT_UNDEFINED), a semaphore for signaling render |
| * completion, and an SkSurface the client renders to. |
| */ |
| struct SwapchainImage { |
| VkImage fVkImage = VK_NULL_HANDLE; |
| VkImageLayout fImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; |
| VkSemaphore fRenderCompletionSemaphore = VK_NULL_HANDLE; |
| sk_sp<SkSurface> fSurface = nullptr; /* May not be based on rts */ |
| }; |
| |
| skia_private::AutoTArray<SwapchainImage> fImages; |
| uint32_t fCurrentImageIndex; /* Index of image currently being presented */ |
| VkSemaphore fAcquireSemaphore = VK_NULL_HANDLE; /* Semaphore to signal image acquisition */ |
| sk_sp<const skgpu::VulkanInterface> fInterface; |
| |
| /* Vulkan driver structs + info */ |
| VkInstance fInstance = VK_NULL_HANDLE; |
| VkPhysicalDevice fPhysicalDevice = VK_NULL_HANDLE; |
| VkDevice fDevice = VK_NULL_HANDLE; |
| VkDebugUtilsMessengerEXT fDebugMessenger = VK_NULL_HANDLE; |
| VkSurfaceKHR fDeviceSurface; |
| VkSwapchainKHR fSwapchain; |
| uint32_t fGraphicsQueueIndex; |
| VkQueue fGraphicsQueue; |
| uint32_t fPresentQueueIndex; |
| VkQueue fPresentQueue; |
| |
| /* Create functions */ |
| CreateVkSurfaceFn fCreateVkSurfaceFn; |
| CanPresentFn fCanPresentFn; |
| PFN_vkGetInstanceProcAddr fGetInstanceProcAddr = nullptr; |
| |
| /* WSI interface functions */ |
| PFN_vkDestroySurfaceKHR fDestroySurfaceKHR = nullptr; |
| PFN_vkGetPhysicalDeviceSurfaceSupportKHR fGetPhysicalDeviceSurfaceSupportKHR = nullptr; |
| PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR fGetPhysicalDeviceSurfaceCapabilitiesKHR = |
| nullptr; |
| PFN_vkGetPhysicalDeviceSurfaceFormatsKHR fGetPhysicalDeviceSurfaceFormatsKHR = nullptr; |
| PFN_vkGetPhysicalDeviceSurfacePresentModesKHR fGetPhysicalDeviceSurfacePresentModesKHR = |
| nullptr; |
| PFN_vkCreateSwapchainKHR fCreateSwapchainKHR = nullptr; |
| PFN_vkDestroySwapchainKHR fDestroySwapchainKHR = nullptr; |
| PFN_vkGetSwapchainImagesKHR fGetSwapchainImagesKHR = nullptr; |
| PFN_vkAcquireNextImageKHR fAcquireNextImageKHR = nullptr; |
| PFN_vkQueuePresentKHR fQueuePresentKHR = nullptr; |
| |
| PFN_vkDestroyInstance fDestroyInstance = nullptr; |
| PFN_vkDeviceWaitIdle fDeviceWaitIdle = nullptr; |
| PFN_vkDestroyDebugUtilsMessengerEXT fDestroyDebugUtilsMessengerEXT = nullptr; |
| PFN_vkQueueWaitIdle fQueueWaitIdle = nullptr; |
| PFN_vkDestroyDevice fDestroyDevice = nullptr; |
| PFN_vkGetDeviceQueue fGetDeviceQueue = nullptr; |
| }; |
| |
| } // namespace skwindow::internal |
| |
| #endif // SK_VULKAN |
| |
| #endif // GraphiteVulkanWindowContext_DEFINED |