1 
2 /*
3  * Copyright 2016 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #ifndef VulkanWindowContext_DEFINED
9 #define VulkanWindowContext_DEFINED
10 
11 #include "SkTypes.h" // required to pull in any SkUserConfig defines
12 
13 #ifdef SK_VULKAN
14 
15 #include "vk/GrVkBackendContext.h"
16 #include "WindowContext.h"
17 
18 class GrRenderTarget;
19 
20 namespace sk_app {
21 
22 class VulkanWindowContext : public WindowContext {
23 public:
24     ~VulkanWindowContext() override;
25 
26     sk_sp<SkSurface> getBackbufferSurface() override;
27     void swapBuffers() override;
28 
isValid()29     bool isValid() override { return SkToBool(fBackendContext.get()); }
30 
resize(int w,int h)31     void resize(int w, int h) override {
32         this->createSwapchain(w, h, fDisplayParams);
33     }
34 
setDisplayParams(const DisplayParams & params)35     void setDisplayParams(const DisplayParams& params) override {
36         this->createSwapchain(fWidth, fHeight, params);
37     }
38 
getBackendContext()39     GrBackendContext getBackendContext() override {
40         return (GrBackendContext) fBackendContext.get();
41     }
42 
43     /** Platform specific function that creates a VkSurfaceKHR for a window */
44     using CreateVkSurfaceFn = std::function<VkSurfaceKHR(VkInstance)>;
45     /** Platform specific function that determines whether presentation will succeed. */
46     using CanPresentFn = GrVkBackendContext::CanPresentFn;
47 
48     VulkanWindowContext(const DisplayParams&, CreateVkSurfaceFn, CanPresentFn);
49 
50 private:
51     void destroyContext();
52 
53     struct BackbufferInfo {
54         uint32_t        fImageIndex;          // image this is associated with
55         VkSemaphore     fAcquireSemaphore;    // we signal on this for acquisition of image
56         VkSemaphore     fRenderSemaphore;     // we wait on this for rendering to be done
57         VkCommandBuffer fTransitionCmdBuffers[2]; // to transition layout between present and render
58         VkFence         fUsageFences[2];      // used to ensure this data is no longer used on GPU
59     };
60 
61     BackbufferInfo* getAvailableBackbuffer();
62     bool createSwapchain(int width, int height, const DisplayParams& params);
63     void createBuffers(VkFormat format);
64     void destroyBuffers();
65 
66     sk_sp<const GrVkBackendContext> fBackendContext;
67 
68     // simple wrapper class that exists only to initialize a pointer to NULL
69     template <typename FNPTR_TYPE> class VkPtr {
70     public:
VkPtr()71         VkPtr() : fPtr(NULL) {}
72         VkPtr operator=(FNPTR_TYPE ptr) { fPtr = ptr; return *this; }
FNPTR_TYPE()73         operator FNPTR_TYPE() const { return fPtr; }
74     private:
75         FNPTR_TYPE fPtr;
76     };
77 
78     // WSI interface functions
79     VkPtr<PFN_vkDestroySurfaceKHR> fDestroySurfaceKHR;
80     VkPtr<PFN_vkGetPhysicalDeviceSurfaceSupportKHR> fGetPhysicalDeviceSurfaceSupportKHR;
81     VkPtr<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR> fGetPhysicalDeviceSurfaceCapabilitiesKHR;
82     VkPtr<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR> fGetPhysicalDeviceSurfaceFormatsKHR;
83     VkPtr<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR> fGetPhysicalDeviceSurfacePresentModesKHR;
84 
85     VkPtr<PFN_vkCreateSwapchainKHR> fCreateSwapchainKHR;
86     VkPtr<PFN_vkDestroySwapchainKHR> fDestroySwapchainKHR;
87     VkPtr<PFN_vkGetSwapchainImagesKHR> fGetSwapchainImagesKHR;
88     VkPtr<PFN_vkAcquireNextImageKHR> fAcquireNextImageKHR;
89     VkPtr<PFN_vkQueuePresentKHR> fQueuePresentKHR;
90     VkPtr<PFN_vkCreateSharedSwapchainsKHR> fCreateSharedSwapchainsKHR;
91 
92     VkSurfaceKHR      fSurface;
93     VkSwapchainKHR    fSwapchain;
94     uint32_t          fPresentQueueIndex;
95     VkQueue           fPresentQueue;
96 
97     uint32_t               fImageCount;
98     VkImage*               fImages;         // images in the swapchain
99     VkImageLayout*         fImageLayouts;   // layouts of these images when not color attachment
100     sk_sp<SkSurface>*      fSurfaces;       // surfaces client renders to (may not be based on rts)
101     VkCommandPool          fCommandPool;
102     BackbufferInfo*        fBackbuffers;
103     uint32_t               fCurrentBackbufferIndex;
104 };
105 
106 }   // namespace sk_app
107 
108 #endif // SK_VULKAN
109 
110 #endif
111