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