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