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