1aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski/* 2aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * Copyright (C) 2016 The Android Open Source Project 3aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * 4aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * you may not use this file except in compliance with the License. 6aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * You may obtain a copy of the License at 7aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * 8aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * 10aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * Unless required by applicable law or agreed to in writing, software 11aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * See the License for the specific language governing permissions and 14aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski * limitations under the License. 15aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski */ 16aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 17aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski#ifndef VULKANMANAGER_H 18aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski#define VULKANMANAGER_H 19aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 20aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski#include <SkSurface.h> 21aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski#include <vk/GrVkBackendContext.h> 22aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 23aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski#include <vulkan/vulkan.h> 24aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 25aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinskinamespace android { 26aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinskinamespace uirenderer { 27aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinskinamespace renderthread { 28aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 29aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinskiclass RenderThread; 30aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 31aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinskiclass VulkanSurface { 32aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinskipublic: 33aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski VulkanSurface() {} 34aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 35aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski sk_sp<SkSurface> getBackBufferSurface() { return mBackbuffer; } 36aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 37aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinskiprivate: 38aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski friend class VulkanManager; 39aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski struct BackbufferInfo { 40aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski uint32_t mImageIndex; // image this is associated with 41aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski VkSemaphore mAcquireSemaphore; // we signal on this for acquisition of image 42aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski VkSemaphore mRenderSemaphore; // we wait on this for rendering to be done 43aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski VkCommandBuffer mTransitionCmdBuffers[2]; // to transition layout between present and render 44aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski // We use these fences to make sure the above Command buffers have finished their work 45aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski // before attempting to reuse them or destroy them. 46aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski VkFence mUsageFences[2]; 47aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski }; 48aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 49aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski struct ImageInfo { 50aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski VkImageLayout mImageLayout = VK_IMAGE_LAYOUT_UNDEFINED; 51aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski sk_sp<SkSurface> mSurface; 52aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski uint16_t mLastUsed = 0; 53aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski bool mInvalid = true; 54aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski }; 55aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 56aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski sk_sp<SkSurface> mBackbuffer; 57aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 58aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski VkSurfaceKHR mVkSurface = VK_NULL_HANDLE; 59aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski VkSwapchainKHR mSwapchain = VK_NULL_HANDLE; 60aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 61aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski BackbufferInfo* mBackbuffers; 62aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski uint32_t mCurrentBackbufferIndex; 63aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 64aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski uint32_t mImageCount; 65aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski VkImage* mImages; 66aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski ImageInfo* mImageInfos; 67aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski uint16_t mCurrentTime = 0; 68aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski}; 69aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski 70aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski// This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue, 71aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski// which are re-used by CanvasContext. This class is created once and should be used by all vulkan 72aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski// windowing contexts. The VulkanManager must be initialized before use. 73aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinskiclass VulkanManager { 74aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinskipublic: 75aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski // Sets up the vulkan context that is shared amonst all clients of the VulkanManager. This must 76aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski // be call once before use of the VulkanManager. Multiple calls after the first will simiply 77aa0255da28675431c93593a8dd2d225538cbb3acAdam Lesinski // return. 78 void initialize(); 79 80 // Quick check to see if the VulkanManager has been initialized. 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. 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 107private: 108 friend class RenderThread; 109 110 explicit VulkanManager(RenderThread& thread); 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: 123 VkPtr() : fPtr(NULL) {} 124 VkPtr operator=(FNPTR_TYPE ptr) { fPtr = ptr; return *this; } 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