1 // Copyright (c) 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "gpu/vulkan/android/vulkan_implementation_android.h"
6 
7 #include "base/android/android_hardware_buffer_compat.h"
8 #include "base/callback_helpers.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "gpu/ipc/common/vulkan_ycbcr_info.h"
12 #include "gpu/vulkan/vulkan_device_queue.h"
13 #include "gpu/vulkan/vulkan_function_pointers.h"
14 #include "gpu/vulkan/vulkan_image.h"
15 #include "gpu/vulkan/vulkan_instance.h"
16 #include "gpu/vulkan/vulkan_surface.h"
17 #include "gpu/vulkan/vulkan_util.h"
18 #include "ui/gfx/gpu_fence.h"
19 #include "ui/gfx/gpu_memory_buffer.h"
20 
21 namespace gpu {
22 
23 VulkanImplementationAndroid::VulkanImplementationAndroid() = default;
24 
25 VulkanImplementationAndroid::~VulkanImplementationAndroid() = default;
26 
InitializeVulkanInstance(bool using_surface)27 bool VulkanImplementationAndroid::InitializeVulkanInstance(bool using_surface) {
28   DCHECK(using_surface);
29   std::vector<const char*> required_extensions = {
30       VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_ANDROID_SURFACE_EXTENSION_NAME,
31       VK_KHR_EXTERNAL_MEMORY_CAPABILITIES_EXTENSION_NAME,
32       VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME};
33 
34   VulkanFunctionPointers* vulkan_function_pointers =
35       gpu::GetVulkanFunctionPointers();
36 
37   base::NativeLibraryLoadError native_library_load_error;
38   vulkan_function_pointers->vulkan_loader_library = base::LoadNativeLibrary(
39       base::FilePath("libvulkan.so"), &native_library_load_error);
40   if (!vulkan_function_pointers->vulkan_loader_library)
41     return false;
42 
43   return vulkan_instance_.Initialize(required_extensions, {});
44 }
45 
GetVulkanInstance()46 VulkanInstance* VulkanImplementationAndroid::GetVulkanInstance() {
47   return &vulkan_instance_;
48 }
49 
CreateViewSurface(gfx::AcceleratedWidget window)50 std::unique_ptr<VulkanSurface> VulkanImplementationAndroid::CreateViewSurface(
51     gfx::AcceleratedWidget window) {
52   VkSurfaceKHR surface;
53   VkAndroidSurfaceCreateInfoKHR surface_create_info = {};
54   surface_create_info.sType = VK_STRUCTURE_TYPE_ANDROID_SURFACE_CREATE_INFO_KHR;
55   surface_create_info.window = window;
56   VkResult result = vkCreateAndroidSurfaceKHR(
57       vulkan_instance_.vk_instance(), &surface_create_info, nullptr, &surface);
58   if (VK_SUCCESS != result) {
59     DLOG(ERROR) << "vkCreateAndroidSurfaceKHR() failed: " << result;
60     return nullptr;
61   }
62 
63   return std::make_unique<VulkanSurface>(vulkan_instance_.vk_instance(), window,
64                                          surface,
65                                          false /* use_protected_memory */);
66 }
67 
GetPhysicalDevicePresentationSupport(VkPhysicalDevice device,const std::vector<VkQueueFamilyProperties> & queue_family_properties,uint32_t queue_family_index)68 bool VulkanImplementationAndroid::GetPhysicalDevicePresentationSupport(
69     VkPhysicalDevice device,
70     const std::vector<VkQueueFamilyProperties>& queue_family_properties,
71     uint32_t queue_family_index) {
72   // On Android, all physical devices and queue families must be capable of
73   // presentation with any native window.
74   // As a result there is no Android-specific query for these capabilities.
75   return true;
76 }
77 
78 std::vector<const char*>
GetRequiredDeviceExtensions()79 VulkanImplementationAndroid::GetRequiredDeviceExtensions() {
80   return {};
81 }
82 
83 std::vector<const char*>
GetOptionalDeviceExtensions()84 VulkanImplementationAndroid::GetOptionalDeviceExtensions() {
85   // VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME also requires
86   // VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME as per spec.
87   return {
88       VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME,
89       VK_KHR_EXTERNAL_MEMORY_EXTENSION_NAME,
90       VK_KHR_EXTERNAL_MEMORY_FD_EXTENSION_NAME,
91       VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
92       VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME,
93       VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME,
94       VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME,
95       VK_KHR_SAMPLER_YCBCR_CONVERSION_EXTENSION_NAME,
96       VK_KHR_SWAPCHAIN_EXTENSION_NAME,
97       VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME,
98   };
99 }
100 
CreateVkFenceForGpuFence(VkDevice vk_device)101 VkFence VulkanImplementationAndroid::CreateVkFenceForGpuFence(
102     VkDevice vk_device) {
103   NOTREACHED();
104   return VK_NULL_HANDLE;
105 }
106 
107 std::unique_ptr<gfx::GpuFence>
ExportVkFenceToGpuFence(VkDevice vk_device,VkFence vk_fence)108 VulkanImplementationAndroid::ExportVkFenceToGpuFence(VkDevice vk_device,
109                                                      VkFence vk_fence) {
110   NOTREACHED();
111   return nullptr;
112 }
113 
CreateExternalSemaphore(VkDevice vk_device)114 VkSemaphore VulkanImplementationAndroid::CreateExternalSemaphore(
115     VkDevice vk_device) {
116   return CreateExternalVkSemaphore(
117       vk_device, VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);
118 }
119 
ImportSemaphoreHandle(VkDevice vk_device,SemaphoreHandle sync_handle)120 VkSemaphore VulkanImplementationAndroid::ImportSemaphoreHandle(
121     VkDevice vk_device,
122     SemaphoreHandle sync_handle) {
123   return ImportVkSemaphoreHandle(vk_device, std::move(sync_handle));
124 }
125 
GetSemaphoreHandle(VkDevice vk_device,VkSemaphore vk_semaphore)126 SemaphoreHandle VulkanImplementationAndroid::GetSemaphoreHandle(
127     VkDevice vk_device,
128     VkSemaphore vk_semaphore) {
129   // VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT specifies a POSIX file
130   // descriptor handle to a Linux Sync File or Android Fence object.
131   return GetVkSemaphoreHandle(vk_device, vk_semaphore,
132                               VK_EXTERNAL_SEMAPHORE_HANDLE_TYPE_SYNC_FD_BIT);
133 }
134 
135 VkExternalMemoryHandleTypeFlagBits
GetExternalImageHandleType()136 VulkanImplementationAndroid::GetExternalImageHandleType() {
137   return VK_EXTERNAL_MEMORY_HANDLE_TYPE_ANDROID_HARDWARE_BUFFER_BIT_ANDROID;
138 }
139 
CanImportGpuMemoryBuffer(gfx::GpuMemoryBufferType memory_buffer_type)140 bool VulkanImplementationAndroid::CanImportGpuMemoryBuffer(
141     gfx::GpuMemoryBufferType memory_buffer_type) {
142   return false;
143 }
144 
145 std::unique_ptr<VulkanImage>
CreateImageFromGpuMemoryHandle(VulkanDeviceQueue * device_queue,gfx::GpuMemoryBufferHandle gmb_handle,gfx::Size size,VkFormat vk_formae)146 VulkanImplementationAndroid::CreateImageFromGpuMemoryHandle(
147     VulkanDeviceQueue* device_queue,
148     gfx::GpuMemoryBufferHandle gmb_handle,
149     gfx::Size size,
150     VkFormat vk_formae) {
151   // TODO(sergeyu): Move code from CreateVkImageAndImportAHB() here and remove
152   // CreateVkImageAndImportAHB().
153   NOTIMPLEMENTED();
154   return nullptr;
155 }
156 
GetSamplerYcbcrConversionInfo(const VkDevice & vk_device,base::android::ScopedHardwareBufferHandle ahb_handle,VulkanYCbCrInfo * ycbcr_info)157 bool VulkanImplementationAndroid::GetSamplerYcbcrConversionInfo(
158     const VkDevice& vk_device,
159     base::android::ScopedHardwareBufferHandle ahb_handle,
160     VulkanYCbCrInfo* ycbcr_info) {
161   DCHECK(ycbcr_info);
162 
163   // To obtain format properties of an Android hardware buffer, include an
164   // instance of VkAndroidHardwareBufferFormatPropertiesANDROID in the pNext
165   // chain of the VkAndroidHardwareBufferPropertiesANDROID instance passed to
166   // vkGetAndroidHardwareBufferPropertiesANDROID.
167   VkAndroidHardwareBufferFormatPropertiesANDROID ahb_format_props = {
168       VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID};
169   VkAndroidHardwareBufferPropertiesANDROID ahb_props = {
170       .sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID,
171       .pNext = &ahb_format_props,
172   };
173 
174   VkResult result = vkGetAndroidHardwareBufferPropertiesANDROID(
175       vk_device, ahb_handle.get(), &ahb_props);
176   if (result != VK_SUCCESS) {
177     LOG(ERROR)
178         << "GetAhbProps: vkGetAndroidHardwareBufferPropertiesANDROID failed : "
179         << result;
180     return false;
181   }
182 
183   *ycbcr_info = VulkanYCbCrInfo(
184       VK_FORMAT_UNDEFINED, ahb_format_props.externalFormat,
185       ahb_format_props.suggestedYcbcrModel,
186       ahb_format_props.suggestedYcbcrRange,
187       ahb_format_props.suggestedXChromaOffset,
188       ahb_format_props.suggestedYChromaOffset, ahb_format_props.formatFeatures);
189   return true;
190 }
191 
192 }  // namespace gpu
193