Home | History | Annotate | Download | only in renderthread
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef VULKANMANAGER_H
     18 #define VULKANMANAGER_H
     19 
     20 #include <SkSurface.h>
     21 #include <vk/GrVkBackendContext.h>
     22 
     23 #include <vulkan/vulkan.h>
     24 
     25 namespace android {
     26 namespace uirenderer {
     27 namespace renderthread {
     28 
     29 class RenderThread;
     30 
     31 class VulkanSurface {
     32 public:
     33     VulkanSurface() {}
     34 
     35     sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; }
     36 
     37 private:
     38     friend class VulkanManager;
     39     struct BackbufferInfo {
     40         uint32_t mImageIndex;           // image this is associated with
     41         VkSemaphore mAcquireSemaphore;  // we signal on this for acquisition of image
     42         VkSemaphore mRenderSemaphore;   // we wait on this for rendering to be done
     43         VkCommandBuffer
     44                 mTransitionCmdBuffers[2];  // to transition layout between present and render
     45         // We use these fences to make sure the above Command buffers have finished their work
     46         // before attempting to reuse them or destroy them.
     47         VkFence mUsageFences[2];
     48     };
     49 
     50     struct ImageInfo {
     51         VkImageLayout mImageLayout = VK_IMAGE_LAYOUT_UNDEFINED;
     52         sk_sp<SkSurface> mSurface;
     53         uint16_t mLastUsed = 0;
     54         bool mInvalid = true;
     55     };
     56 
     57     sk_sp<SkSurface> mBackbuffer;
     58 
     59     VkSurfaceKHR mVkSurface = VK_NULL_HANDLE;
     60     VkSwapchainKHR mSwapchain = VK_NULL_HANDLE;
     61 
     62     BackbufferInfo* mBackbuffers = nullptr;
     63     uint32_t mCurrentBackbufferIndex;
     64 
     65     uint32_t mImageCount;
     66     VkImage* mImages = nullptr;
     67     ImageInfo* mImageInfos;
     68     uint16_t mCurrentTime = 0;
     69 };
     70 
     71 // This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue,
     72 // which are re-used by CanvasContext. This class is created once and should be used by all vulkan
     73 // windowing contexts. The VulkanManager must be initialized before use.
     74 class VulkanManager {
     75 public:
     76     // Sets up the vulkan context that is shared amonst all clients of the VulkanManager. This must
     77     // be call once before use of the VulkanManager. Multiple calls after the first will simiply
     78     // return.
     79     void initialize();
     80 
     81     // Quick check to see if the VulkanManager has been initialized.
     82     bool hasVkContext() { return mBackendContext.get() != nullptr; }
     83 
     84     // Given a window this creates a new VkSurfaceKHR and VkSwapchain and stores them inside a new
     85     // VulkanSurface object which is returned.
     86     VulkanSurface* createSurface(ANativeWindow* window);
     87 
     88     // Destroy the VulkanSurface and all associated vulkan objects.
     89     void destroySurface(VulkanSurface* surface);
     90 
     91     // Cleans up all the global state in the VulkanManger.
     92     void destroy();
     93 
     94     // No work is needed to make a VulkanSurface current, and all functions require that a
     95     // VulkanSurface is passed into them so we just return true here.
     96     bool isCurrent(VulkanSurface* surface) { return true; }
     97 
     98     int getAge(VulkanSurface* surface);
     99 
    100     // Returns an SkSurface which wraps the next image returned from vkAcquireNextImageKHR. It also
    101     // will transition the VkImage from a present layout to color attachment so that it can be used
    102     // by the client for drawing.
    103     SkSurface* getBackbufferSurface(VulkanSurface* surface);
    104 
    105     // Presents the current VkImage.
    106     void swapBuffers(VulkanSurface* surface);
    107 
    108 private:
    109     friend class RenderThread;
    110 
    111     explicit VulkanManager(RenderThread& thread);
    112     ~VulkanManager() { destroy(); }
    113 
    114     void destroyBuffers(VulkanSurface* surface);
    115 
    116     bool createSwapchain(VulkanSurface* surface);
    117     void createBuffers(VulkanSurface* surface, VkFormat format, VkExtent2D extent);
    118 
    119     VulkanSurface::BackbufferInfo* getAvailableBackbuffer(VulkanSurface* surface);
    120 
    121     // simple wrapper class that exists only to initialize a pointer to NULL
    122     template <typename FNPTR_TYPE>
    123     class VkPtr {
    124     public:
    125         VkPtr() : fPtr(NULL) {}
    126         VkPtr operator=(FNPTR_TYPE ptr) {
    127             fPtr = ptr;
    128             return *this;
    129         }
    130         operator FNPTR_TYPE() const { return fPtr; }
    131 
    132     private:
    133         FNPTR_TYPE fPtr;
    134     };
    135 
    136     // WSI interface functions
    137     VkPtr<PFN_vkCreateAndroidSurfaceKHR> mCreateAndroidSurfaceKHR;
    138     VkPtr<PFN_vkDestroySurfaceKHR> mDestroySurfaceKHR;
    139     VkPtr<PFN_vkGetPhysicalDeviceSurfaceSupportKHR> mGetPhysicalDeviceSurfaceSupportKHR;
    140     VkPtr<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR> mGetPhysicalDeviceSurfaceCapabilitiesKHR;
    141     VkPtr<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR> mGetPhysicalDeviceSurfaceFormatsKHR;
    142     VkPtr<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR> mGetPhysicalDeviceSurfacePresentModesKHR;
    143 
    144     VkPtr<PFN_vkCreateSwapchainKHR> mCreateSwapchainKHR;
    145     VkPtr<PFN_vkDestroySwapchainKHR> mDestroySwapchainKHR;
    146     VkPtr<PFN_vkGetSwapchainImagesKHR> mGetSwapchainImagesKHR;
    147     VkPtr<PFN_vkAcquireNextImageKHR> mAcquireNextImageKHR;
    148     VkPtr<PFN_vkQueuePresentKHR> mQueuePresentKHR;
    149     VkPtr<PFN_vkCreateSharedSwapchainsKHR> mCreateSharedSwapchainsKHR;
    150 
    151     // Additional vulkan functions
    152     VkPtr<PFN_vkCreateCommandPool> mCreateCommandPool;
    153     VkPtr<PFN_vkDestroyCommandPool> mDestroyCommandPool;
    154     VkPtr<PFN_vkAllocateCommandBuffers> mAllocateCommandBuffers;
    155     VkPtr<PFN_vkFreeCommandBuffers> mFreeCommandBuffers;
    156     VkPtr<PFN_vkResetCommandBuffer> mResetCommandBuffer;
    157     VkPtr<PFN_vkBeginCommandBuffer> mBeginCommandBuffer;
    158     VkPtr<PFN_vkEndCommandBuffer> mEndCommandBuffer;
    159     VkPtr<PFN_vkCmdPipelineBarrier> mCmdPipelineBarrier;
    160 
    161     VkPtr<PFN_vkGetDeviceQueue> mGetDeviceQueue;
    162     VkPtr<PFN_vkQueueSubmit> mQueueSubmit;
    163     VkPtr<PFN_vkQueueWaitIdle> mQueueWaitIdle;
    164     VkPtr<PFN_vkDeviceWaitIdle> mDeviceWaitIdle;
    165 
    166     VkPtr<PFN_vkCreateSemaphore> mCreateSemaphore;
    167     VkPtr<PFN_vkDestroySemaphore> mDestroySemaphore;
    168     VkPtr<PFN_vkCreateFence> mCreateFence;
    169     VkPtr<PFN_vkDestroyFence> mDestroyFence;
    170     VkPtr<PFN_vkWaitForFences> mWaitForFences;
    171     VkPtr<PFN_vkResetFences> mResetFences;
    172 
    173     RenderThread& mRenderThread;
    174 
    175     sk_sp<const GrVkBackendContext> mBackendContext;
    176     uint32_t mPresentQueueIndex;
    177     VkQueue mPresentQueue = VK_NULL_HANDLE;
    178     VkCommandPool mCommandPool = VK_NULL_HANDLE;
    179 
    180     enum class SwapBehavior {
    181         Discard,
    182         BufferAge,
    183     };
    184     SwapBehavior mSwapBehavior = SwapBehavior::Discard;
    185 };
    186 
    187 } /* namespace renderthread */
    188 } /* namespace uirenderer */
    189 } /* namespace android */
    190 
    191 #endif /* VULKANMANAGER_H */
    192