Commit 334077c8 authored by Peng Huang's avatar Peng Huang Committed by Commit Bot

Vulkan: support Android devices without Android hardware buffer

Some Android P devices don't support vulkan extension
VK_ANDROID_external_memory_android_hardware_buffer. For those devices,
chrome will fallback to ExternalVkImageBacking which uses
VK_KHR_external_memory_fd extension or pixel copy for GL and Vulkan
inerop.

Bug: 1049864
Change-Id: I101a4c83a2dbfcfdbade29084a863e7563f631e6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2067290Reviewed-by: default avatarVasiliy Telezhnikov <vasilyt@chromium.org>
Reviewed-by: default avatarMichael Spang <spang@chromium.org>
Commit-Queue: Peng Huang <penghuang@chromium.org>
Cr-Commit-Position: refs/heads/master@{#743931}
parent fdc0bdda
......@@ -195,7 +195,7 @@ GpuServiceImpl::GpuServiceImpl(
gpu_feature_info_.status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
gpu::kGpuFeatureStatusEnabled;
} else {
DLOG(WARNING) << "Failed to create Vulkan context provider.";
DLOG(ERROR) << "Failed to create Vulkan context provider.";
}
}
#endif
......@@ -208,7 +208,7 @@ GpuServiceImpl::GpuServiceImpl(
gpu_feature_info_.status_values[gpu::GPU_FEATURE_TYPE_OOP_RASTERIZATION] =
gpu::kGpuFeatureStatusEnabled;
} else {
DLOG(WARNING) << "Failed to create Dawn context provider.";
DLOG(ERROR) << "Failed to create Dawn context provider.";
}
}
#endif
......
......@@ -9,6 +9,7 @@
#include "base/strings/stringprintf.h"
#include "base/trace_event/memory_dump_manager.h"
#include "build/build_config.h"
#include "components/viz/common/gpu/vulkan_context_provider.h"
#include "components/viz/common/resources/resource_format_utils.h"
#include "gpu/command_buffer/common/gpu_memory_buffer_support.h"
#include "gpu/command_buffer/common/shared_image_trace_utils.h"
......@@ -32,6 +33,7 @@
#elif defined(OS_ANDROID) && BUILDFLAG(ENABLE_VULKAN)
#include "gpu/command_buffer/service/external_vk_image_factory.h"
#include "gpu/command_buffer/service/shared_image_backing_factory_ahardwarebuffer.h"
#include "gpu/vulkan/vulkan_device_queue.h"
#elif defined(OS_MACOSX)
#include "gpu/command_buffer/service/shared_image_backing_factory_iosurface.h"
#elif defined(OS_CHROMEOS)
......@@ -103,9 +105,19 @@ SharedImageFactory::SharedImageFactory(
if (using_vulkan_) {
external_vk_image_factory_ =
std::make_unique<ExternalVkImageFactory>(context_state);
const auto& enabled_extensions = context_state->vk_context_provider()
->GetDeviceQueue()
->enabled_extensions();
if (gfx::HasExtension(
enabled_extensions,
VK_ANDROID_EXTERNAL_MEMORY_ANDROID_HARDWARE_BUFFER_EXTENSION_NAME)) {
interop_backing_factory_ = std::make_unique<SharedImageBackingFactoryAHB>(
workarounds, gpu_feature_info);
}
} else {
interop_backing_factory_ = std::make_unique<SharedImageBackingFactoryAHB>(
workarounds, gpu_feature_info);
}
interop_backing_factory_ = std::make_unique<SharedImageBackingFactoryAHB>(
workarounds, gpu_feature_info);
#elif defined(OS_MACOSX)
// OSX
DCHECK(!using_vulkan_);
......@@ -414,10 +426,6 @@ SharedImageBackingFactory* SharedImageFactory::GetFactoryByUsage(
return wrapped_sk_image_factory_.get();
if (using_interop_factory) {
LOG_IF(ERROR, !interop_backing_factory_)
<< "Unable to create SharedImage backing: GL / Vulkan interoperability "
"is not supported on this platform";
// TODO(crbug.com/969114): Not all shared image factory implementations
// support concurrent read/write usage.
if (usage & SHARED_IMAGE_USAGE_CONCURRENT_READ_WRITE) {
......@@ -431,17 +439,21 @@ SharedImageBackingFactory* SharedImageFactory::GetFactoryByUsage(
// interop if the format is not supported by the AHB backing factory.
auto* ahb_backing_factory = static_cast<SharedImageBackingFactoryAHB*>(
interop_backing_factory_.get());
if (!ahb_backing_factory->IsFormatSupported(format) &&
external_vk_image_factory_) {
if (share_between_threads) {
LOG(FATAL) << "ExternalVkImageFactory currently do not support "
"cross-thread usage.";
}
*allow_legacy_mailbox = false;
return external_vk_image_factory_.get();
if (ahb_backing_factory && ahb_backing_factory->IsFormatSupported(format))
return ahb_backing_factory;
if (share_between_threads) {
LOG(FATAL) << "ExternalVkImageFactory currently do not support "
"cross-thread usage.";
}
#endif
*allow_legacy_mailbox = false;
return external_vk_image_factory_.get();
#else // defined(OS_ANDROID)
LOG_IF(ERROR, !interop_backing_factory_)
<< "Unable to create SharedImage backing: GL / Vulkan interoperability "
"is not supported on this platform";
return interop_backing_factory_.get();
#endif // !defined(OS_ANDROID)
}
return gl_backing_factory_.get();
......
......@@ -121,6 +121,11 @@ bool VulkanImplementationAndroid::GetPhysicalDevicePresentationSupport(
std::vector<const char*>
VulkanImplementationAndroid::GetRequiredDeviceExtensions() {
return {};
}
std::vector<const char*>
VulkanImplementationAndroid::GetOptionalDeviceExtensions() {
// VK_KHR_DEDICATED_ALLOCATION_EXTENSION_NAME also requires
// VK_KHR_GET_MEMORY_REQUIREMENTS_2_EXTENSION_NAME as per spec.
return {VK_KHR_SWAPCHAIN_EXTENSION_NAME,
......
......@@ -31,6 +31,7 @@ class COMPONENT_EXPORT(VULKAN_ANDROID) VulkanImplementationAndroid
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) override;
std::vector<const char*> GetRequiredDeviceExtensions() override;
std::vector<const char*> GetOptionalDeviceExtensions() override;
VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
......
......@@ -30,6 +30,7 @@ bool VulkanDeviceQueue::Initialize(
uint32_t options,
const VulkanInfo& info,
const std::vector<const char*>& required_extensions,
const std::vector<const char*>& optional_extensions,
bool allow_protected_memory,
const GetPresentationSupportCallback& get_presentation_support) {
DCHECK_EQ(static_cast<VkPhysicalDevice>(VK_NULL_HANDLE), vk_physical_device_);
......@@ -102,9 +103,35 @@ bool VulkanDeviceQueue::Initialize(
#endif // DCHECK_IS_ON()
std::vector<const char*> enabled_extensions;
enabled_extensions.insert(std::end(enabled_extensions),
std::begin(required_extensions),
std::end(required_extensions));
for (const char* extension : required_extensions) {
const auto it =
std::find_if(physical_device_info.extensions.begin(),
physical_device_info.extensions.end(),
[extension](const VkExtensionProperties& p) {
return std::strcmp(extension, p.extensionName) == 0;
});
if (it == physical_device_info.extensions.end()) {
DLOG(ERROR) << "Required Vulkan extension " << extension
<< " is not supported.";
return false;
}
enabled_extensions.push_back(extension);
}
for (const char* extension : optional_extensions) {
const auto it =
std::find_if(physical_device_info.extensions.begin(),
physical_device_info.extensions.end(),
[extension](const VkExtensionProperties& p) {
return std::strcmp(extension, p.extensionName) == 0;
});
if (it == physical_device_info.extensions.end()) {
DLOG(ERROR) << "Optional Vulkan extension " << extension
<< " is not supported.";
} else {
enabled_extensions.push_back(extension);
}
}
uint32_t device_api_version = std::min(
info.used_api_version, vk_physical_device_properties_.apiVersion);
......@@ -185,7 +212,6 @@ bool VulkanDeviceQueue::Initialize(
cleanup_helper_ = std::make_unique<VulkanFenceHelper>(this);
allow_protected_memory_ = allow_protected_memory;
return true;
}
......
......@@ -41,6 +41,7 @@ class VULKAN_EXPORT VulkanDeviceQueue {
uint32_t options,
const VulkanInfo& info,
const std::vector<const char*>& required_extensions,
const std::vector<const char*>& optional_extensions,
bool allow_protected_memory,
const GetPresentationSupportCallback& get_presentation_support);
......
......@@ -31,9 +31,11 @@ std::unique_ptr<VulkanDeviceQueue> CreateVulkanDeviceQueue(
base::Unretained(vulkan_implementation));
std::vector<const char*> required_extensions =
vulkan_implementation->GetRequiredDeviceExtensions();
std::vector<const char*> optional_extensions =
vulkan_implementation->GetOptionalDeviceExtensions();
if (!device_queue->Initialize(
option, vulkan_implementation->GetVulkanInstance()->vulkan_info(),
std::move(required_extensions),
std::move(required_extensions), std::move(optional_extensions),
vulkan_implementation->allow_protected_memory(), callback)) {
device_queue->Destroy();
return nullptr;
......
......@@ -70,6 +70,7 @@ class VULKAN_EXPORT VulkanImplementation {
uint32_t queue_family_index) = 0;
virtual std::vector<const char*> GetRequiredDeviceExtensions() = 0;
virtual std::vector<const char*> GetOptionalDeviceExtensions() = 0;
// Creates a VkFence that is exportable to a gfx::GpuFence.
virtual VkFence CreateVkFenceForGpuFence(VkDevice vk_device) = 0;
......
......@@ -94,6 +94,11 @@ VulkanImplementationWin32::GetRequiredDeviceExtensions() {
return {VK_KHR_SWAPCHAIN_EXTENSION_NAME};
}
std::vector<const char*>
VulkanImplementationWin32::GetOptionalDeviceExtensions() {
return {};
}
VkFence VulkanImplementationWin32::CreateVkFenceForGpuFence(
VkDevice vk_device) {
NOTREACHED();
......
......@@ -29,6 +29,7 @@ class COMPONENT_EXPORT(VULKAN_WIN32) VulkanImplementationWin32
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) override;
std::vector<const char*> GetRequiredDeviceExtensions() override;
std::vector<const char*> GetOptionalDeviceExtensions() override;
VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
......
......@@ -129,6 +129,11 @@ VulkanImplementationX11::GetRequiredDeviceExtensions() {
return extensions;
}
std::vector<const char*>
VulkanImplementationX11::GetOptionalDeviceExtensions() {
return {};
}
VkFence VulkanImplementationX11::CreateVkFenceForGpuFence(VkDevice vk_device) {
NOTREACHED();
return VK_NULL_HANDLE;
......
......@@ -30,6 +30,7 @@ class COMPONENT_EXPORT(VULKAN_X11) VulkanImplementationX11
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) override;
std::vector<const char*> GetRequiredDeviceExtensions() override;
std::vector<const char*> GetOptionalDeviceExtensions() override;
VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
......
......@@ -92,6 +92,12 @@ VulkanImplementationGbm::GetRequiredDeviceExtensions() {
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
VK_KHR_EXTERNAL_SEMAPHORE_FD_EXTENSION_NAME};
}
std::vector<const char*>
VulkanImplementationGbm::GetOptionalDeviceExtensions() {
return {};
}
VkFence VulkanImplementationGbm::CreateVkFenceForGpuFence(VkDevice vk_device) {
VkFenceCreateInfo fence_create_info = {};
fence_create_info.sType = VK_STRUCTURE_TYPE_FENCE_CREATE_INFO;
......
......@@ -27,6 +27,7 @@ class VulkanImplementationGbm : public gpu::VulkanImplementation {
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) override;
std::vector<const char*> GetRequiredDeviceExtensions() override;
std::vector<const char*> GetOptionalDeviceExtensions() override;
VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
......
......@@ -137,6 +137,11 @@ VulkanImplementationScenic::GetRequiredDeviceExtensions() {
};
}
std::vector<const char*>
VulkanImplementationScenic::GetOptionalDeviceExtensions() {
return {};
}
VkFence VulkanImplementationScenic::CreateVkFenceForGpuFence(
VkDevice vk_device) {
NOTIMPLEMENTED();
......
......@@ -35,6 +35,7 @@ class VulkanImplementationScenic : public gpu::VulkanImplementation {
const std::vector<VkQueueFamilyProperties>& queue_family_properties,
uint32_t queue_family_index) override;
std::vector<const char*> GetRequiredDeviceExtensions() override;
std::vector<const char*> GetOptionalDeviceExtensions() override;
VkFence CreateVkFenceForGpuFence(VkDevice vk_device) override;
std::unique_ptr<gfx::GpuFence> ExportVkFenceToGpuFence(
VkDevice vk_device,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment