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