Commit 122a1cc5 by Peng Huang Committed by Commit Bot

Fix several vulkan backend problem on Android.

* Load AHardwarebuffer API dynamically, so vulkan backend can be built with old NDK, but can work with newer android releases. * Do not link with libvulkan on android. * Expose EGL_ANDROID_get_native_client_buffer extension with vulkan backend. Bug: chromium:1170339 Change-Id: Idf7f6867a86ae40ba6d57a86e419c610ba404ba8 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2653506Reviewed-by: 's avatarGeoff Lang <geofflang@chromium.org> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Commit-Queue: Peng Huang <penghuang@chromium.org>
parent 4ec7021c
...@@ -204,6 +204,7 @@ IGNORED_INCLUDES = { ...@@ -204,6 +204,7 @@ IGNORED_INCLUDES = {
b'libANGLE/renderer/gl/wgl/DisplayWGL.h', b'libANGLE/renderer/gl/wgl/DisplayWGL.h',
b'libANGLE/renderer/metal/DisplayMtl_api.h', b'libANGLE/renderer/metal/DisplayMtl_api.h',
b'libANGLE/renderer/null/DisplayNULL.h', b'libANGLE/renderer/null/DisplayNULL.h',
b'libANGLE/renderer/vulkan/android/AHBFunctions.h',
b'libANGLE/renderer/vulkan/android/DisplayVkAndroid.h', b'libANGLE/renderer/vulkan/android/DisplayVkAndroid.h',
b'libANGLE/renderer/vulkan/fuchsia/DisplayVkFuchsia.h', b'libANGLE/renderer/vulkan/fuchsia/DisplayVkFuchsia.h',
b'libANGLE/renderer/vulkan/ggp/DisplayVkGGP.h', b'libANGLE/renderer/vulkan/ggp/DisplayVkGGP.h',
......
...@@ -7,12 +7,6 @@ import("../../../gni/angle.gni") ...@@ -7,12 +7,6 @@ import("../../../gni/angle.gni")
assert(angle_enable_vulkan) assert(angle_enable_vulkan)
config("angle_vulkan_lib_android") {
if (is_android) {
libs = [ "vulkan" ]
}
}
config("angle_vulkan_headers_config") { config("angle_vulkan_headers_config") {
if (angle_shared_libvulkan) { if (angle_shared_libvulkan) {
defines = [ "ANGLE_SHARED_LIBVULKAN=1" ] defines = [ "ANGLE_SHARED_LIBVULKAN=1" ]
...@@ -34,7 +28,6 @@ angle_source_set("angle_vulkan_headers") { ...@@ -34,7 +28,6 @@ angle_source_set("angle_vulkan_headers") {
} }
group("angle_vulkan_entry_points") { group("angle_vulkan_entry_points") {
public_configs = [ ":angle_vulkan_lib_android" ]
public_deps = [ ":angle_vulkan_headers" ] public_deps = [ ":angle_vulkan_headers" ]
if (is_fuchsia) { if (is_fuchsia) {
public_deps += [ public_deps += [
......
...@@ -118,6 +118,8 @@ if (is_linux) { ...@@ -118,6 +118,8 @@ if (is_linux) {
if (is_android) { if (is_android) {
_vulkan_backend_sources += [ _vulkan_backend_sources += [
"android/AHBFunctions.cpp",
"android/AHBFunctions.h",
"android/DisplayVkAndroid.cpp", "android/DisplayVkAndroid.cpp",
"android/DisplayVkAndroid.h", "android/DisplayVkAndroid.h",
"android/HardwareBufferImageSiblingVkAndroid.cpp", "android/HardwareBufferImageSiblingVkAndroid.cpp",
...@@ -244,10 +246,6 @@ angle_source_set("angle_vulkan_backend") { ...@@ -244,10 +246,6 @@ angle_source_set("angle_vulkan_backend") {
data_deps += [ "$angle_root/src/common/vulkan:vulkan_validation_layers" ] data_deps += [ "$angle_root/src/common/vulkan:vulkan_validation_layers" ]
} }
if (is_android) {
libs += [ "vulkan" ]
}
if (is_fuchsia) { if (is_fuchsia) {
public_deps += [ "$angle_root/src/common/fuchsia_egl:backend" ] public_deps += [ "$angle_root/src/common/fuchsia_egl:backend" ]
} }
......
...@@ -212,7 +212,8 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -212,7 +212,8 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
outExtensions->glColorspace && getRenderer()->getFeatures().supportsImageFormatList.enabled; outExtensions->glColorspace && getRenderer()->getFeatures().supportsImageFormatList.enabled;
#if defined(ANGLE_PLATFORM_ANDROID) #if defined(ANGLE_PLATFORM_ANDROID)
outExtensions->framebufferTargetANDROID = true; outExtensions->getNativeClientBufferANDROID = true;
outExtensions->framebufferTargetANDROID = true;
#endif // defined(ANGLE_PLATFORM_ANDROID) #endif // defined(ANGLE_PLATFORM_ANDROID)
// Disable context priority when non-zero memory init is enabled. This enforces a queue order. // Disable context priority when non-zero memory init is enabled. This enforces a queue order.
......
...@@ -292,6 +292,8 @@ class RendererVk : angle::NonCopyable ...@@ -292,6 +292,8 @@ class RendererVk : angle::NonCopyable
} }
} }
egl::Display *getDisplay() const { return mDisplay; }
VkResult getLastPresentResult(VkSwapchainKHR swapchain) VkResult getLastPresentResult(VkSwapchainKHR swapchain)
{ {
return mCommandProcessor.getLastPresentResult(swapchain); return mCommandProcessor.getLastPresentResult(swapchain);
......
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "libANGLE/renderer/vulkan/android/AHBFunctions.h"
#include <dlfcn.h>
namespace rx
{
namespace
{
template <class T>
void AssignFn(void *handle, const char *name, T &fn)
{
fn = reinterpret_cast<T>(dlsym(handle, name));
}
} // namespace
AHBFunctions::AHBFunctions()
{
void *handle = dlopen(nullptr, RTLD_NOW);
AssignFn(handle, "AHardwareBuffer_acquire", mAcquireFn);
AssignFn(handle, "AHardwareBuffer_describe", mDescribeFn);
AssignFn(handle, "AHardwareBuffer_release", mReleaseFn);
}
AHBFunctions::~AHBFunctions() = default;
} // namespace rx
//
// Copyright 2021 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef LIBANGLE_RENDERER_VULKAN_ANDROID_AHBFUNCTIONS_H_
#define LIBANGLE_RENDERER_VULKAN_ANDROID_AHBFUNCTIONS_H_
#include <android/hardware_buffer.h>
namespace rx
{
class AHBFunctions
{
public:
AHBFunctions();
~AHBFunctions();
void acquire(AHardwareBuffer *buffer) const { mAcquireFn(buffer); }
void describe(const AHardwareBuffer *buffer, AHardwareBuffer_Desc *outDesc) const
{
mDescribeFn(buffer, outDesc);
}
void release(AHardwareBuffer *buffer) const { mReleaseFn(buffer); }
bool valid() const { return mAcquireFn && mDescribeFn && mReleaseFn; }
private:
using PFN_AHARDWAREBUFFER_acquire = void (*)(AHardwareBuffer *buffer);
using PFN_AHARDWAREBUFFER_describe = void (*)(const AHardwareBuffer *buffer,
AHardwareBuffer_Desc *outDesc);
using PFN_AHARDWAREBUFFER_release = void (*)(AHardwareBuffer *buffer);
PFN_AHARDWAREBUFFER_acquire mAcquireFn = nullptr;
PFN_AHARDWAREBUFFER_describe mDescribeFn = nullptr;
PFN_AHARDWAREBUFFER_release mReleaseFn = nullptr;
};
} // namespace rx
#endif // LIBANGLE_RENDERER_VULKAN_ANDROID_AHBFUNCTIONS_H_
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#define LIBANGLE_RENDERER_VULKAN_ANDROID_DISPLAYVKANDROID_H_ #define LIBANGLE_RENDERER_VULKAN_ANDROID_DISPLAYVKANDROID_H_
#include "libANGLE/renderer/vulkan/DisplayVk.h" #include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/android/AHBFunctions.h"
namespace rx namespace rx
{ {
...@@ -40,6 +41,11 @@ class DisplayVkAndroid : public DisplayVk ...@@ -40,6 +41,11 @@ class DisplayVkAndroid : public DisplayVk
const egl::AttributeMap &attribs) override; const egl::AttributeMap &attribs) override;
const char *getWSIExtension() const override; const char *getWSIExtension() const override;
const AHBFunctions &getAHBFunctions() const { return mAHBFunctions; }
private:
AHBFunctions mAHBFunctions;
}; };
} // namespace rx } // namespace rx
......
...@@ -13,14 +13,15 @@ ...@@ -13,14 +13,15 @@
#include "libANGLE/Display.h" #include "libANGLE/Display.h"
#include "libANGLE/renderer/vulkan/DisplayVk.h" #include "libANGLE/renderer/vulkan/DisplayVk.h"
#include "libANGLE/renderer/vulkan/RendererVk.h" #include "libANGLE/renderer/vulkan/RendererVk.h"
#include "libANGLE/renderer/vulkan/android/AHBFunctions.h"
#include <android/hardware_buffer.h> #include "libANGLE/renderer/vulkan/android/DisplayVkAndroid.h"
namespace rx namespace rx
{ {
namespace namespace
{ {
VkImageTiling AhbDescUsageToVkImageTiling(const AHardwareBuffer_Desc &ahbDescription) VkImageTiling AhbDescUsageToVkImageTiling(const AHardwareBuffer_Desc &ahbDescription)
{ {
if ((ahbDescription.usage & AHARDWAREBUFFER_USAGE_CPU_READ_MASK) != 0 || if ((ahbDescription.usage & AHARDWAREBUFFER_USAGE_CPU_READ_MASK) != 0 ||
...@@ -140,6 +141,9 @@ VkImageUsageFlags AhbDescUsageToVkImageUsage(const AHardwareBuffer_Desc &ahbDesc ...@@ -140,6 +141,9 @@ VkImageUsageFlags AhbDescUsageToVkImageUsage(const AHardwareBuffer_Desc &ahbDesc
angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk) angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk)
{ {
const AHBFunctions &functions = static_cast<DisplayVkAndroid *>(displayVk)->getAHBFunctions();
ANGLE_VK_CHECK(displayVk, functions.valid(), VK_ERROR_INITIALIZATION_FAILED);
RendererVk *renderer = displayVk->getRenderer(); RendererVk *renderer = displayVk->getRenderer();
struct ANativeWindowBuffer *windowBuffer = struct ANativeWindowBuffer *windowBuffer =
...@@ -154,7 +158,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk ...@@ -154,7 +158,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
struct AHardwareBuffer *hardwareBuffer = struct AHardwareBuffer *hardwareBuffer =
angle::android::ANativeWindowBufferToAHardwareBuffer(windowBuffer); angle::android::ANativeWindowBufferToAHardwareBuffer(windowBuffer);
AHardwareBuffer_acquire(hardwareBuffer); functions.acquire(hardwareBuffer);
VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties; VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties;
bufferFormatProperties.sType = bufferFormatProperties.sType =
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID; VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
...@@ -181,7 +185,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk ...@@ -181,7 +185,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
// 1. Derive VkImageTiling mode based on AHB usage flags // 1. Derive VkImageTiling mode based on AHB usage flags
// 2. Map AHB usage flags to VkImageUsageFlags // 2. Map AHB usage flags to VkImageUsageFlags
AHardwareBuffer_Desc ahbDescription; AHardwareBuffer_Desc ahbDescription;
AHardwareBuffer_describe(hardwareBuffer, &ahbDescription); functions.describe(hardwareBuffer, &ahbDescription);
VkImageTiling imageTilingMode = AhbDescUsageToVkImageTiling(ahbDescription); VkImageTiling imageTilingMode = AhbDescUsageToVkImageTiling(ahbDescription);
VkImageUsageFlags usage = AhbDescUsageToVkImageUsage(ahbDescription, isDepthOrStencilFormat); VkImageUsageFlags usage = AhbDescUsageToVkImageUsage(ahbDescription, isDepthOrStencilFormat);
...@@ -310,7 +314,10 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk ...@@ -310,7 +314,10 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
void HardwareBufferImageSiblingVkAndroid::onDestroy(const egl::Display *display) void HardwareBufferImageSiblingVkAndroid::onDestroy(const egl::Display *display)
{ {
AHardwareBuffer_release(angle::android::ANativeWindowBufferToAHardwareBuffer( const AHBFunctions &functions = GetImplAs<DisplayVkAndroid>(display)->getAHBFunctions();
ASSERT(functions.valid());
functions.release(angle::android::ANativeWindowBufferToAHardwareBuffer(
angle::android::ClientBufferToANativeWindowBuffer(mBuffer))); angle::android::ClientBufferToANativeWindowBuffer(mBuffer)));
ASSERT(mImage == nullptr); ASSERT(mImage == nullptr);
......
...@@ -12,10 +12,10 @@ ...@@ -12,10 +12,10 @@
#include "libANGLE/renderer/vulkan/ContextVk.h" #include "libANGLE/renderer/vulkan/ContextVk.h"
#include "libANGLE/renderer/vulkan/vk_utils.h" #include "libANGLE/renderer/vulkan/vk_utils.h"
#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26 #if defined(ANGLE_PLATFORM_ANDROID)
# define ANGLE_AHARDWARE_BUFFER_SUPPORT # include "libANGLE/Display.h"
// NDK header file for access to Android Hardware Buffers # include "libANGLE/renderer/vulkan/android/AHBFunctions.h"
# include <android/hardware_buffer.h> # include "libANGLE/renderer/vulkan/android/DisplayVkAndroid.h"
#endif #endif
namespace rx namespace rx
...@@ -26,7 +26,10 @@ angle::Result GetClientBufferMemoryRequirements(ContextVk *contextVk, ...@@ -26,7 +26,10 @@ angle::Result GetClientBufferMemoryRequirements(ContextVk *contextVk,
const AHardwareBuffer *hardwareBuffer, const AHardwareBuffer *hardwareBuffer,
VkMemoryRequirements &memRequirements) VkMemoryRequirements &memRequirements)
{ {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT) #if defined(ANGLE_PLATFORM_ANDROID)
ASSERT(GetImplAs<DisplayVkAndroid>(contextVk->getRenderer()->getDisplay())
->getAHBFunctions()
.valid());
// Get Android Buffer Properties // Get Android Buffer Properties
VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties = {}; VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties = {};
...@@ -49,7 +52,8 @@ angle::Result GetClientBufferMemoryRequirements(ContextVk *contextVk, ...@@ -49,7 +52,8 @@ angle::Result GetClientBufferMemoryRequirements(ContextVk *contextVk,
#else #else
ANGLE_VK_UNREACHABLE(contextVk); ANGLE_VK_UNREACHABLE(contextVk);
return angle::Result::Stop; return angle::Result::Stop;
#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT
#endif
} }
angle::Result InitAndroidExternalMemory(ContextVk *contextVk, angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
...@@ -59,7 +63,11 @@ angle::Result InitAndroidExternalMemory(ContextVk *contextVk, ...@@ -59,7 +63,11 @@ angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
VkMemoryPropertyFlags *memoryPropertyFlagsOut, VkMemoryPropertyFlags *memoryPropertyFlagsOut,
DeviceMemory *deviceMemoryOut) DeviceMemory *deviceMemoryOut)
{ {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT) #if defined(ANGLE_PLATFORM_ANDROID)
const AHBFunctions &functions =
GetImplAs<DisplayVkAndroid>(contextVk->getRenderer()->getDisplay())->getAHBFunctions();
ASSERT(functions.valid());
struct AHardwareBuffer *hardwareBuffer = struct AHardwareBuffer *hardwareBuffer =
angle::android::ClientBufferToAHardwareBuffer(clientBuffer); angle::android::ClientBufferToAHardwareBuffer(clientBuffer);
...@@ -76,22 +84,25 @@ angle::Result InitAndroidExternalMemory(ContextVk *contextVk, ...@@ -76,22 +84,25 @@ angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
contextVk, memoryProperties, externalMemoryRequirements, &importHardwareBufferInfo, buffer, contextVk, memoryProperties, externalMemoryRequirements, &importHardwareBufferInfo, buffer,
memoryPropertyFlagsOut, deviceMemoryOut)); memoryPropertyFlagsOut, deviceMemoryOut));
AHardwareBuffer_acquire(hardwareBuffer); functions.acquire(hardwareBuffer);
return angle::Result::Continue; return angle::Result::Continue;
#else #else
ANGLE_VK_UNREACHABLE(contextVk); ANGLE_VK_UNREACHABLE(contextVk);
return angle::Result::Stop; return angle::Result::Stop;
#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT #endif
} }
void ReleaseAndroidExternalMemory(EGLClientBuffer clientBuffer) void ReleaseAndroidExternalMemory(RendererVk *rendererVk, EGLClientBuffer clientBuffer)
{ {
#if defined(ANGLE_AHARDWARE_BUFFER_SUPPORT) #if defined(ANGLE_PLATFORM_ANDROID)
const AHBFunctions &functions =
GetImplAs<DisplayVkAndroid>(rendererVk->getDisplay())->getAHBFunctions();
ASSERT(functions.valid());
struct AHardwareBuffer *hardwareBuffer = struct AHardwareBuffer *hardwareBuffer =
angle::android::ClientBufferToAHardwareBuffer(clientBuffer); angle::android::ClientBufferToAHardwareBuffer(clientBuffer);
AHardwareBuffer_release(hardwareBuffer); functions.release(hardwareBuffer);
#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT #endif
} }
} // namespace vk } // namespace vk
} // namespace rx } // namespace rx
...@@ -20,6 +20,9 @@ class DeviceMemory; ...@@ -20,6 +20,9 @@ class DeviceMemory;
namespace rx namespace rx
{ {
class RendererVk;
namespace vk namespace vk
{ {
angle::Result InitAndroidExternalMemory(ContextVk *contextVk, angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
...@@ -29,7 +32,7 @@ angle::Result InitAndroidExternalMemory(ContextVk *contextVk, ...@@ -29,7 +32,7 @@ angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
VkMemoryPropertyFlags *memoryPropertyFlagsOut, VkMemoryPropertyFlags *memoryPropertyFlagsOut,
DeviceMemory *deviceMemoryOut); DeviceMemory *deviceMemoryOut);
void ReleaseAndroidExternalMemory(EGLClientBuffer clientBuffer); void ReleaseAndroidExternalMemory(RendererVk *rendererVk, EGLClientBuffer clientBuffer);
} // namespace vk } // namespace vk
} // namespace rx } // namespace rx
......
...@@ -3044,7 +3044,7 @@ void BufferMemory::destroy(RendererVk *renderer) ...@@ -3044,7 +3044,7 @@ void BufferMemory::destroy(RendererVk *renderer)
if (isExternalBuffer()) if (isExternalBuffer())
{ {
mExternalMemory.destroy(renderer->getDevice()); mExternalMemory.destroy(renderer->getDevice());
ReleaseAndroidExternalMemory(mClientBuffer); ReleaseAndroidExternalMemory(renderer, mClientBuffer);
} }
else else
{ {
......
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