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