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: VulkanSurface()33 VulkanSurface() {} 34 getBackBufferSurface()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 mTransitionCmdBuffers[2]; // to transition layout between present and render 44 // We use these fences to make sure the above Command buffers have finished their work 45 // before attempting to reuse them or destroy them. 46 VkFence mUsageFences[2]; 47 }; 48 49 struct ImageInfo { 50 VkImageLayout mImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; 51 sk_sp<SkSurface> mSurface; 52 uint16_t mLastUsed = 0; 53 bool mInvalid = true; 54 }; 55 56 sk_sp<SkSurface> mBackbuffer; 57 58 VkSurfaceKHR mVkSurface = VK_NULL_HANDLE; 59 VkSwapchainKHR mSwapchain = VK_NULL_HANDLE; 60 61 BackbufferInfo* mBackbuffers; 62 uint32_t mCurrentBackbufferIndex; 63 64 uint32_t mImageCount; 65 VkImage* mImages; 66 ImageInfo* mImageInfos; 67 uint16_t mCurrentTime = 0; 68 }; 69 70 // This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue, 71 // which are re-used by CanvasContext. This class is created once and should be used by all vulkan 72 // windowing contexts. The VulkanManager must be initialized before use. 73 class VulkanManager { 74 public: 75 // Sets up the vulkan context that is shared amonst all clients of the VulkanManager. This must 76 // be call once before use of the VulkanManager. Multiple calls after the first will simiply 77 // return. 78 void initialize(); 79 80 // Quick check to see if the VulkanManager has been initialized. hasVkContext()81 bool hasVkContext() { return mBackendContext.get() != nullptr; } 82 83 // Given a window this creates a new VkSurfaceKHR and VkSwapchain and stores them inside a new 84 // VulkanSurface object which is returned. 85 VulkanSurface* createSurface(ANativeWindow* window); 86 87 // Destroy the VulkanSurface and all associated vulkan objects. 88 void destroySurface(VulkanSurface* surface); 89 90 // Cleans up all the global state in the VulkanManger. 91 void destroy(); 92 93 // No work is needed to make a VulkanSurface current, and all functions require that a 94 // VulkanSurface is passed into them so we just return true here. isCurrent(VulkanSurface * surface)95 bool isCurrent(VulkanSurface* surface) { return true; } 96 97 int getAge(VulkanSurface* surface); 98 99 // Returns an SkSurface which wraps the next image returned from vkAcquireNextImageKHR. It also 100 // will transition the VkImage from a present layout to color attachment so that it can be used 101 // by the client for drawing. 102 SkSurface* getBackbufferSurface(VulkanSurface* surface); 103 104 // Presents the current VkImage. 105 void swapBuffers(VulkanSurface* surface); 106 107 private: 108 friend class RenderThread; 109 110 explicit VulkanManager(RenderThread& thread); ~VulkanManager()111 ~VulkanManager() { destroy(); } 112 113 void destroyBuffers(VulkanSurface* surface); 114 115 bool createSwapchain(VulkanSurface* surface); 116 void createBuffers(VulkanSurface* surface, VkFormat format, VkExtent2D extent); 117 118 VulkanSurface::BackbufferInfo* getAvailableBackbuffer(VulkanSurface* surface); 119 120 // simple wrapper class that exists only to initialize a pointer to NULL 121 template <typename FNPTR_TYPE> class VkPtr { 122 public: VkPtr()123 VkPtr() : fPtr(NULL) {} 124 VkPtr operator=(FNPTR_TYPE ptr) { fPtr = ptr; return *this; } FNPTR_TYPE()125 operator FNPTR_TYPE() const { return fPtr; } 126 private: 127 FNPTR_TYPE fPtr; 128 }; 129 130 // WSI interface functions 131 VkPtr<PFN_vkCreateAndroidSurfaceKHR> mCreateAndroidSurfaceKHR; 132 VkPtr<PFN_vkDestroySurfaceKHR> mDestroySurfaceKHR; 133 VkPtr<PFN_vkGetPhysicalDeviceSurfaceSupportKHR> mGetPhysicalDeviceSurfaceSupportKHR; 134 VkPtr<PFN_vkGetPhysicalDeviceSurfaceCapabilitiesKHR> mGetPhysicalDeviceSurfaceCapabilitiesKHR; 135 VkPtr<PFN_vkGetPhysicalDeviceSurfaceFormatsKHR> mGetPhysicalDeviceSurfaceFormatsKHR; 136 VkPtr<PFN_vkGetPhysicalDeviceSurfacePresentModesKHR> mGetPhysicalDeviceSurfacePresentModesKHR; 137 138 VkPtr<PFN_vkCreateSwapchainKHR> mCreateSwapchainKHR; 139 VkPtr<PFN_vkDestroySwapchainKHR> mDestroySwapchainKHR; 140 VkPtr<PFN_vkGetSwapchainImagesKHR> mGetSwapchainImagesKHR; 141 VkPtr<PFN_vkAcquireNextImageKHR> mAcquireNextImageKHR; 142 VkPtr<PFN_vkQueuePresentKHR> mQueuePresentKHR; 143 VkPtr<PFN_vkCreateSharedSwapchainsKHR> mCreateSharedSwapchainsKHR; 144 145 // Additional vulkan functions 146 VkPtr<PFN_vkCreateCommandPool> mCreateCommandPool; 147 VkPtr<PFN_vkDestroyCommandPool> mDestroyCommandPool; 148 VkPtr<PFN_vkAllocateCommandBuffers> mAllocateCommandBuffers; 149 VkPtr<PFN_vkFreeCommandBuffers> mFreeCommandBuffers; 150 VkPtr<PFN_vkResetCommandBuffer> mResetCommandBuffer; 151 VkPtr<PFN_vkBeginCommandBuffer> mBeginCommandBuffer; 152 VkPtr<PFN_vkEndCommandBuffer> mEndCommandBuffer; 153 VkPtr<PFN_vkCmdPipelineBarrier> mCmdPipelineBarrier; 154 155 VkPtr<PFN_vkGetDeviceQueue> mGetDeviceQueue; 156 VkPtr<PFN_vkQueueSubmit> mQueueSubmit; 157 VkPtr<PFN_vkQueueWaitIdle> mQueueWaitIdle; 158 VkPtr<PFN_vkDeviceWaitIdle> mDeviceWaitIdle; 159 160 VkPtr<PFN_vkCreateSemaphore> mCreateSemaphore; 161 VkPtr<PFN_vkDestroySemaphore> mDestroySemaphore; 162 VkPtr<PFN_vkCreateFence> mCreateFence; 163 VkPtr<PFN_vkDestroyFence> mDestroyFence; 164 VkPtr<PFN_vkWaitForFences> mWaitForFences; 165 VkPtr<PFN_vkResetFences> mResetFences; 166 167 RenderThread& mRenderThread; 168 169 sk_sp<const GrVkBackendContext> mBackendContext; 170 uint32_t mPresentQueueIndex; 171 VkQueue mPresentQueue = VK_NULL_HANDLE; 172 VkCommandPool mCommandPool = VK_NULL_HANDLE; 173 174 enum class SwapBehavior { 175 Discard, 176 BufferAge, 177 }; 178 SwapBehavior mSwapBehavior = SwapBehavior::Discard; 179 }; 180 181 } /* namespace renderthread */ 182 } /* namespace uirenderer */ 183 } /* namespace android */ 184 185 #endif /* VULKANMANAGER_H */ 186 187