19f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
29f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth/*
39f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth * Copyright 2016 Google Inc.
49f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth *
59f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth * Use of this source code is governed by a BSD-style license that can be
69f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth * found in the LICENSE file.
79f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth */
8a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth#ifndef VulkanWindowContext_DEFINED
9a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth#define VulkanWindowContext_DEFINED
109f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
119207caebbb34a8f239191a2f9f639abf183bf568djsollen#include "SkTypes.h" // required to pull in any SkUserConfig defines
129207caebbb34a8f239191a2f9f639abf183bf568djsollen
139f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth#ifdef SK_VULKAN
149f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
159f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth#include "vk/GrVkBackendContext.h"
16a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth#include "WindowContext.h"
179f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
18af236b5aa9e7d71d59bee6533d16deb76e9d098bjvanverthclass GrRenderTarget;
199f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
20a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverthnamespace sk_app {
21a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth
22a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverthclass VulkanWindowContext : public WindowContext {
239f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverthpublic:
24a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth    ~VulkanWindowContext() override;
259f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
26af236b5aa9e7d71d59bee6533d16deb76e9d098bjvanverth    sk_sp<SkSurface> getBackbufferSurface() override;
27a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth    void swapBuffers() override;
289f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
29a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth    bool isValid() override { return SkToBool(fBackendContext.get()); }
309f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
31ccde4ab8e6f5d9f0634d7f156dc1617fd0e48581bsalomon    void resize(int w, int h) override {
3205de216ffb864cb1f3a4fa37a2c3a772be38a0c9brianosman        this->createSwapchain(w, h, fDisplayParams);
3305de216ffb864cb1f3a4fa37a2c3a772be38a0c9brianosman    }
3405de216ffb864cb1f3a4fa37a2c3a772be38a0c9brianosman
35796c5bb4655a511553970e111c96d90963fb9ae4liyuqian    void setDisplayParams(const DisplayParams& params) override {
3605de216ffb864cb1f3a4fa37a2c3a772be38a0c9brianosman        this->createSwapchain(fWidth, fHeight, params);
379f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth    }
389f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
391f05f44e8fc0d54afdda04c8e2b846ebad5d9d2fGreg Daniel    GrBackendContext getBackendContext() override {
401f05f44e8fc0d54afdda04c8e2b846ebad5d9d2fGreg Daniel        return (GrBackendContext) fBackendContext.get();
41a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth    }
429f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
43d1bdd1fcbd308afb9903f39d231742f5c951cf07bsalomon    /** Platform specific function that creates a VkSurfaceKHR for a window */
44d1bdd1fcbd308afb9903f39d231742f5c951cf07bsalomon    using CreateVkSurfaceFn = std::function<VkSurfaceKHR(VkInstance)>;
45d1bdd1fcbd308afb9903f39d231742f5c951cf07bsalomon    /** Platform specific function that determines whether presentation will succeed. */
46d1bdd1fcbd308afb9903f39d231742f5c951cf07bsalomon    using CanPresentFn = GrVkBackendContext::CanPresentFn;
47d1bdd1fcbd308afb9903f39d231742f5c951cf07bsalomon
48d1bdd1fcbd308afb9903f39d231742f5c951cf07bsalomon    VulkanWindowContext(const DisplayParams&, CreateVkSurfaceFn, CanPresentFn);
49d1bdd1fcbd308afb9903f39d231742f5c951cf07bsalomon
509f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverthprivate:
519f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth    void destroyContext();
529f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
539f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth    struct BackbufferInfo {
549f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth        uint32_t        fImageIndex;          // image this is associated with
559f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth        VkSemaphore     fAcquireSemaphore;    // we signal on this for acquisition of image
569f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth        VkSemaphore     fRenderSemaphore;     // we wait on this for rendering to be done
579f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth        VkCommandBuffer fTransitionCmdBuffers[2]; // to transition layout between present and render
589f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth        VkFence         fUsageFences[2];      // used to ensure this data is no longer used on GPU
599f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth    };
609f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
619f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth    BackbufferInfo* getAvailableBackbuffer();
62ccde4ab8e6f5d9f0634d7f156dc1617fd0e48581bsalomon    bool createSwapchain(int width, int height, const DisplayParams& params);
6358a8d9214a70e0f6c81c88a8b0b563c06bf0f70eegdaniel    void createBuffers(VkFormat format);
649f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth    void destroyBuffers();
659f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
661b612a89fba2275e3effe12bdc9b6cdc2f4d9eeeHal Canary    sk_sp<const GrVkBackendContext> fBackendContext;
679f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
68b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    // simple wrapper class that exists only to initialize a pointer to NULL
69b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    template <typename FNPTR_TYPE> class VkPtr {
70b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    public:
71b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth        VkPtr() : fPtr(NULL) {}
72b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth        VkPtr operator=(FNPTR_TYPE ptr) { fPtr = ptr; return *this; }
73b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth        operator FNPTR_TYPE() const { return fPtr; }
74b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    private:
75b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth        FNPTR_TYPE fPtr;
76b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    };
77a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth
78b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    // WSI interface functions
79b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkDestroySurfaceKHR> fDestroySurfaceKHR;
80b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkGetPhysicalDeviceSurfaceSupportKHR> fGetPhysicalDeviceSurfaceSupportKHR;
81b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR> fGetPhysicalDeviceSurfaceCapabilitiesKHR;
82b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR> fGetPhysicalDeviceSurfaceFormatsKHR;
83b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR> fGetPhysicalDeviceSurfacePresentModesKHR;
84b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth
85b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkCreateSwapchainKHR> fCreateSwapchainKHR;
86b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkDestroySwapchainKHR> fDestroySwapchainKHR;
87b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkGetSwapchainImagesKHR> fGetSwapchainImagesKHR;
88b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkAcquireNextImageKHR> fAcquireNextImageKHR;
89b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkQueuePresentKHR> fQueuePresentKHR;
90b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth    VkPtr<PFN_vkCreateSharedSwapchainsKHR> fCreateSharedSwapchainsKHR;
91b0d4352ca610654f98c3c4ebc67ed9ad9c8c8493jvanverth
929f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth    VkSurfaceKHR      fSurface;
939f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth    VkSwapchainKHR    fSwapchain;
949f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth    uint32_t          fPresentQueueIndex;
959f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth    VkQueue           fPresentQueue;
96af236b5aa9e7d71d59bee6533d16deb76e9d098bjvanverth
97af236b5aa9e7d71d59bee6533d16deb76e9d098bjvanverth    uint32_t               fImageCount;
98af236b5aa9e7d71d59bee6533d16deb76e9d098bjvanverth    VkImage*               fImages;         // images in the swapchain
99af236b5aa9e7d71d59bee6533d16deb76e9d098bjvanverth    VkImageLayout*         fImageLayouts;   // layouts of these images when not color attachment
100af236b5aa9e7d71d59bee6533d16deb76e9d098bjvanverth    sk_sp<SkSurface>*      fSurfaces;       // surfaces client renders to (may not be based on rts)
101af236b5aa9e7d71d59bee6533d16deb76e9d098bjvanverth    VkCommandPool          fCommandPool;
102af236b5aa9e7d71d59bee6533d16deb76e9d098bjvanverth    BackbufferInfo*        fBackbuffers;
103af236b5aa9e7d71d59bee6533d16deb76e9d098bjvanverth    uint32_t               fCurrentBackbufferIndex;
1049f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth};
1059f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
106a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth}   // namespace sk_app
107a8d0d6c8bad00e713bc33e5f0d47ca4fec104433jvanverth
1089f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth#endif // SK_VULKAN
1099f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth
1109f37246d6856d40f916e8f1fff5b43cfdc42e567jvanverth#endif
111