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 <SkSurface.h> 24 #include <android-base/unique_fd.h> 25 #include <include/gpu/ganesh/GrContextOptions.h> 26 #include <utils/StrongPointer.h> 27 #include <vk/VulkanExtensions.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 mInitialized; } 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 86 struct VkDrawResult { 87 // The estimated start time for intiating GPU work, -1 if unknown. 88 nsecs_t submissionTime; 89 android::base::unique_fd presentFence; 90 }; 91 92 // Finishes the frame and submits work to the GPU 93 VkDrawResult finishFrame(SkSurface* surface); 94 void swapBuffers(VulkanSurface* surface, const SkRect& dirtyRect, 95 android::base::unique_fd&& presentFence); 96 97 // Inserts a wait on fence command into the Vulkan command buffer. 98 status_t fenceWait(int fence, GrDirectContext* grContext); 99 100 // Creates a fence that is signaled when all the pending Vulkan commands are finished on the 101 // GPU. 102 status_t createReleaseFence(int* nativeFence, GrDirectContext* grContext); 103 104 // Returned pointers are owned by VulkanManager. 105 // An instance of VkFunctorInitParams returned from getVkFunctorInitParams refers to 106 // the internal state of VulkanManager: VulkanManager must be alive to use the returned value. 107 VkFunctorInitParams getVkFunctorInitParams() const; 108 109 110 enum class ContextType { 111 kRenderThread, 112 kUploadThread 113 }; 114 115 // returns a Skia graphic context used to draw content on the specified thread 116 sk_sp<GrDirectContext> createContext(GrContextOptions& options, 117 ContextType contextType = ContextType::kRenderThread); 118 getDriverVersion()119 uint32_t getDriverVersion() const { return mDriverVersion; } 120 121 private: 122 friend class VulkanSurface; 123 VulkanManager()124 explicit VulkanManager() {} 125 ~VulkanManager(); 126 127 // Sets up the VkInstance and VkDevice objects. Also fills out the passed in 128 // VkPhysicalDeviceFeatures struct. 129 void setupDevice(skgpu::VulkanExtensions&, VkPhysicalDeviceFeatures2&); 130 131 // simple wrapper class that exists only to initialize a pointer to NULL 132 template <typename FNPTR_TYPE> 133 class VkPtr { 134 public: VkPtr()135 VkPtr() : fPtr(NULL) {} 136 VkPtr operator=(FNPTR_TYPE ptr) { 137 fPtr = ptr; 138 return *this; 139 } 140 // NOLINTNEXTLINE(google-explicit-constructor) FNPTR_TYPE()141 operator FNPTR_TYPE() const { return fPtr; } 142 143 private: 144 FNPTR_TYPE fPtr; 145 }; 146 147 // Instance Functions 148 VkPtr<PFN_vkEnumerateInstanceVersion> mEnumerateInstanceVersion; 149 VkPtr<PFN_vkEnumerateInstanceExtensionProperties> mEnumerateInstanceExtensionProperties; 150 VkPtr<PFN_vkCreateInstance> mCreateInstance; 151 152 VkPtr<PFN_vkDestroyInstance> mDestroyInstance; 153 VkPtr<PFN_vkEnumeratePhysicalDevices> mEnumeratePhysicalDevices; 154 VkPtr<PFN_vkGetPhysicalDeviceProperties> mGetPhysicalDeviceProperties; 155 VkPtr<PFN_vkGetPhysicalDeviceQueueFamilyProperties2> mGetPhysicalDeviceQueueFamilyProperties2; 156 VkPtr<PFN_vkGetPhysicalDeviceFeatures2> mGetPhysicalDeviceFeatures2; 157 VkPtr<PFN_vkGetPhysicalDeviceImageFormatProperties2> mGetPhysicalDeviceImageFormatProperties2; 158 VkPtr<PFN_vkCreateDevice> mCreateDevice; 159 VkPtr<PFN_vkEnumerateDeviceExtensionProperties> mEnumerateDeviceExtensionProperties; 160 161 // Device Functions 162 VkPtr<PFN_vkGetDeviceQueue> mGetDeviceQueue; 163 VkPtr<PFN_vkDeviceWaitIdle> mDeviceWaitIdle; 164 VkPtr<PFN_vkDestroyDevice> mDestroyDevice; 165 VkPtr<PFN_vkCreateCommandPool> mCreateCommandPool; 166 VkPtr<PFN_vkDestroyCommandPool> mDestroyCommandPool; 167 VkPtr<PFN_vkAllocateCommandBuffers> mAllocateCommandBuffers; 168 VkPtr<PFN_vkFreeCommandBuffers> mFreeCommandBuffers; 169 VkPtr<PFN_vkResetCommandBuffer> mResetCommandBuffer; 170 VkPtr<PFN_vkBeginCommandBuffer> mBeginCommandBuffer; 171 VkPtr<PFN_vkEndCommandBuffer> mEndCommandBuffer; 172 VkPtr<PFN_vkCmdPipelineBarrier> mCmdPipelineBarrier; 173 174 VkPtr<PFN_vkQueueSubmit> mQueueSubmit; 175 VkPtr<PFN_vkQueueWaitIdle> mQueueWaitIdle; 176 177 VkPtr<PFN_vkCreateSemaphore> mCreateSemaphore; 178 VkPtr<PFN_vkDestroySemaphore> mDestroySemaphore; 179 VkPtr<PFN_vkImportSemaphoreFdKHR> mImportSemaphoreFdKHR; 180 VkPtr<PFN_vkGetSemaphoreFdKHR> mGetSemaphoreFdKHR; 181 VkPtr<PFN_vkCreateFence> mCreateFence; 182 VkPtr<PFN_vkDestroyFence> mDestroyFence; 183 VkPtr<PFN_vkWaitForFences> mWaitForFences; 184 VkPtr<PFN_vkResetFences> mResetFences; 185 VkPtr<PFN_vkFrameBoundaryANDROID> mFrameBoundaryANDROID; 186 187 VkInstance mInstance = VK_NULL_HANDLE; 188 VkPhysicalDevice mPhysicalDevice = VK_NULL_HANDLE; 189 VkDevice mDevice = VK_NULL_HANDLE; 190 191 uint32_t mGraphicsQueueIndex; 192 VkQueue mGraphicsQueue = VK_NULL_HANDLE; 193 VkQueue mAHBUploadQueue = VK_NULL_HANDLE; 194 195 // Variables saved to populate VkFunctorInitParams. 196 static const uint32_t mAPIVersion = VK_MAKE_VERSION(1, 1, 0); 197 std::vector<VkExtensionProperties> mInstanceExtensionsOwner; 198 std::vector<const char*> mInstanceExtensions; 199 std::vector<VkExtensionProperties> mDeviceExtensionsOwner; 200 std::vector<const char*> mDeviceExtensions; 201 VkPhysicalDeviceFeatures2 mPhysicalDeviceFeatures2{}; 202 203 enum class SwapBehavior { 204 Discard, 205 BufferAge, 206 }; 207 SwapBehavior mSwapBehavior = SwapBehavior::Discard; 208 skgpu::VulkanExtensions mExtensions; 209 uint32_t mDriverVersion = 0; 210 211 std::once_flag mInitFlag; 212 std::atomic_bool mInitialized = false; 213 }; 214 215 } /* namespace renderthread */ 216 } /* namespace uirenderer */ 217 } /* namespace android */ 218 219 #endif /* VULKANMANAGER_H */ 220