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 #if !defined(VK_USE_PLATFORM_ANDROID_KHR) 21 #define VK_USE_PLATFORM_ANDROID_KHR 22 #endif 23 #include <GrContextOptions.h> 24 #include <SkSurface.h> 25 #include <utils/StrongPointer.h> 26 #include <vk/GrVkBackendContext.h> 27 #include <vk/GrVkExtensions.h> 28 #include <vulkan/vulkan.h> 29 30 // VK_ANDROID_frame_boundary is a bespoke extension defined by AGI 31 // (https://github.com/google/agi) to enable profiling of apps rendering via 32 // HWUI. This extension is not defined in Khronos, hence the need to declare it 33 // manually here. There's a superseding extension (VK_EXT_frame_boundary) being 34 // discussed in Khronos, but in the meantime we use the bespoke 35 // VK_ANDROID_frame_boundary. This is a device extension that is implemented by 36 // AGI's Vulkan capture layer, such that it is only supported by devices when 37 // AGI is doing a capture of the app. 38 // 39 // TODO(b/182165045): use the Khronos blessed VK_EXT_frame_boudary once it has 40 // landed in the spec. 41 typedef void(VKAPI_PTR* PFN_vkFrameBoundaryANDROID)(VkDevice device, VkSemaphore semaphore, 42 VkImage image); 43 #define VK_ANDROID_FRAME_BOUNDARY_EXTENSION_NAME "VK_ANDROID_frame_boundary" 44 45 #include "Frame.h" 46 #include "IRenderPipeline.h" 47 #include "VulkanSurface.h" 48 #include "private/hwui/DrawVkInfo.h" 49 50 #include <SkColorSpace.h> 51 #include <SkRefCnt.h> 52 53 namespace android { 54 namespace uirenderer { 55 namespace renderthread { 56 57 class RenderThread; 58 59 // This class contains the shared global Vulkan objects, such as VkInstance, VkDevice and VkQueue, 60 // which are re-used by CanvasContext. This class is created once and should be used by all vulkan 61 // windowing contexts. The VulkanManager must be initialized before use. 62 class VulkanManager final : public RefBase { 63 public: 64 static sp<VulkanManager> getInstance(); 65 static sp<VulkanManager> peekInstance(); 66 67 // Sets up the vulkan context that is shared amonst all clients of the VulkanManager. This must 68 // be call once before use of the VulkanManager. Multiple calls after the first will simiply 69 // return. 70 void initialize(); 71 72 // Quick check to see if the VulkanManager has been initialized. hasVkContext()73 bool hasVkContext() { return mDevice != VK_NULL_HANDLE; } 74 75 // Create and destroy functions for wrapping an ANativeWindow in a VulkanSurface 76 VulkanSurface* createSurface(ANativeWindow* window, 77 ColorMode colorMode, 78 sk_sp<SkColorSpace> surfaceColorSpace, 79 SkColorType surfaceColorType, 80 GrDirectContext* grContext, 81 uint32_t extraBuffers); 82 void destroySurface(VulkanSurface* surface); 83 84 Frame dequeueNextBuffer(VulkanSurface* surface); 85 // Finishes the frame and submits work to the GPU 86 // Returns the estimated start time for intiating GPU work, -1 otherwise. 87 nsecs_t finishFrame(SkSurface* surface); 88 void swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect); 89 90 // Inserts a wait on fence command into the Vulkan command buffer. 91 status_t fenceWait(int fence, GrDirectContext* grContext); 92 93 // Creates a fence that is signaled when all the pending Vulkan commands are finished on the 94 // GPU. 95 status_t createReleaseFence(int* nativeFence, GrDirectContext* grContext); 96 97 // Returned pointers are owned by VulkanManager. 98 // An instance of VkFunctorInitParams returned from getVkFunctorInitParams refers to 99 // the internal state of VulkanManager: VulkanManager must be alive to use the returned value. 100 VkFunctorInitParams getVkFunctorInitParams() const; 101 102 103 enum class ContextType { 104 kRenderThread, 105 kUploadThread 106 }; 107 108 // returns a Skia graphic context used to draw content on the specified thread 109 sk_sp<GrDirectContext> createContext(GrContextOptions& options, 110 ContextType contextType = ContextType::kRenderThread); 111 getDriverVersion()112 uint32_t getDriverVersion() const { return mDriverVersion; } 113 114 private: 115 friend class VulkanSurface; 116 VulkanManager()117 explicit VulkanManager() {} 118 ~VulkanManager(); 119 120 // Sets up the VkInstance and VkDevice objects. Also fills out the passed in 121 // VkPhysicalDeviceFeatures struct. 122 void setupDevice(GrVkExtensions&, VkPhysicalDeviceFeatures2&); 123 124 // simple wrapper class that exists only to initialize a pointer to NULL 125 template <typename FNPTR_TYPE> 126 class VkPtr { 127 public: VkPtr()128 VkPtr() : fPtr(NULL) {} 129 VkPtr operator=(FNPTR_TYPE ptr) { 130 fPtr = ptr; 131 return *this; 132 } 133 // NOLINTNEXTLINE(google-explicit-constructor) FNPTR_TYPE()134 operator FNPTR_TYPE() const { return fPtr; } 135 136 private: 137 FNPTR_TYPE fPtr; 138 }; 139 140 // Instance Functions 141 VkPtr<PFN_vkEnumerateInstanceVersion> mEnumerateInstanceVersion; 142 VkPtr<PFN_vkEnumerateInstanceExtensionProperties> mEnumerateInstanceExtensionProperties; 143 VkPtr<PFN_vkCreateInstance> mCreateInstance; 144 145 VkPtr<PFN_vkDestroyInstance> mDestroyInstance; 146 VkPtr<PFN_vkEnumeratePhysicalDevices> mEnumeratePhysicalDevices; 147 VkPtr<PFN_vkGetPhysicalDeviceProperties> mGetPhysicalDeviceProperties; 148 VkPtr<PFN_vkGetPhysicalDeviceQueueFamilyProperties> mGetPhysicalDeviceQueueFamilyProperties; 149 VkPtr<PFN_vkGetPhysicalDeviceFeatures2> mGetPhysicalDeviceFeatures2; 150 VkPtr<PFN_vkGetPhysicalDeviceImageFormatProperties2> mGetPhysicalDeviceImageFormatProperties2; 151 VkPtr<PFN_vkCreateDevice> mCreateDevice; 152 VkPtr<PFN_vkEnumerateDeviceExtensionProperties> mEnumerateDeviceExtensionProperties; 153 154 // Device Functions 155 VkPtr<PFN_vkGetDeviceQueue> mGetDeviceQueue; 156 VkPtr<PFN_vkDeviceWaitIdle> mDeviceWaitIdle; 157 VkPtr<PFN_vkDestroyDevice> mDestroyDevice; 158 VkPtr<PFN_vkCreateCommandPool> mCreateCommandPool; 159 VkPtr<PFN_vkDestroyCommandPool> mDestroyCommandPool; 160 VkPtr<PFN_vkAllocateCommandBuffers> mAllocateCommandBuffers; 161 VkPtr<PFN_vkFreeCommandBuffers> mFreeCommandBuffers; 162 VkPtr<PFN_vkResetCommandBuffer> mResetCommandBuffer; 163 VkPtr<PFN_vkBeginCommandBuffer> mBeginCommandBuffer; 164 VkPtr<PFN_vkEndCommandBuffer> mEndCommandBuffer; 165 VkPtr<PFN_vkCmdPipelineBarrier> mCmdPipelineBarrier; 166 167 VkPtr<PFN_vkQueueSubmit> mQueueSubmit; 168 VkPtr<PFN_vkQueueWaitIdle> mQueueWaitIdle; 169 170 VkPtr<PFN_vkCreateSemaphore> mCreateSemaphore; 171 VkPtr<PFN_vkDestroySemaphore> mDestroySemaphore; 172 VkPtr<PFN_vkImportSemaphoreFdKHR> mImportSemaphoreFdKHR; 173 VkPtr<PFN_vkGetSemaphoreFdKHR> mGetSemaphoreFdKHR; 174 VkPtr<PFN_vkCreateFence> mCreateFence; 175 VkPtr<PFN_vkDestroyFence> mDestroyFence; 176 VkPtr<PFN_vkWaitForFences> mWaitForFences; 177 VkPtr<PFN_vkResetFences> mResetFences; 178 VkPtr<PFN_vkFrameBoundaryANDROID> mFrameBoundaryANDROID; 179 180 VkInstance mInstance = VK_NULL_HANDLE; 181 VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE; 182 VkDevice mDevice = VK_NULL_HANDLE; 183 184 uint32_t mGraphicsQueueIndex; 185 VkQueue mGraphicsQueue = VK_NULL_HANDLE; 186 VkQueue mAHBUploadQueue = VK_NULL_HANDLE; 187 188 // Variables saved to populate VkFunctorInitParams. 189 static const uint32_t mAPIVersion = VK_MAKE_VERSION(1, 1, 0); 190 std::vector<VkExtensionProperties> mInstanceExtensionsOwner; 191 std::vector<const char*> mInstanceExtensions; 192 std::vector<VkExtensionProperties> mDeviceExtensionsOwner; 193 std::vector<const char*> mDeviceExtensions; 194 VkPhysicalDeviceFeatures2 mPhysicalDeviceFeatures2{}; 195 196 enum class SwapBehavior { 197 Discard, 198 BufferAge, 199 }; 200 SwapBehavior mSwapBehavior = SwapBehavior::Discard; 201 GrVkExtensions mExtensions; 202 uint32_t mDriverVersion = 0; 203 204 VkSemaphore mSwapSemaphore = VK_NULL_HANDLE; 205 void* mDestroySemaphoreContext = nullptr; 206 207 std::mutex mInitializeLock; 208 }; 209 210 } /* namespace renderthread */ 211 } /* namespace uirenderer */ 212 } /* namespace android */ 213 214 #endif /* VULKANMANAGER_H */ 215