mirror of
https://github.com/godotengine/godot-angle-static.git
synced 2026-01-14 14:10:04 +03:00
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/+/2653506 Reviewed-by: Geoff Lang <geofflang@chromium.org> Reviewed-by: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Peng Huang <penghuang@chromium.org>
This commit is contained in:
@@ -204,6 +204,7 @@ IGNORED_INCLUDES = {
|
||||
b'libANGLE/renderer/gl/wgl/DisplayWGL.h',
|
||||
b'libANGLE/renderer/metal/DisplayMtl_api.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/fuchsia/DisplayVkFuchsia.h',
|
||||
b'libANGLE/renderer/vulkan/ggp/DisplayVkGGP.h',
|
||||
|
||||
@@ -7,12 +7,6 @@ import("../../../gni/angle.gni")
|
||||
|
||||
assert(angle_enable_vulkan)
|
||||
|
||||
config("angle_vulkan_lib_android") {
|
||||
if (is_android) {
|
||||
libs = [ "vulkan" ]
|
||||
}
|
||||
}
|
||||
|
||||
config("angle_vulkan_headers_config") {
|
||||
if (angle_shared_libvulkan) {
|
||||
defines = [ "ANGLE_SHARED_LIBVULKAN=1" ]
|
||||
@@ -34,7 +28,6 @@ angle_source_set("angle_vulkan_headers") {
|
||||
}
|
||||
|
||||
group("angle_vulkan_entry_points") {
|
||||
public_configs = [ ":angle_vulkan_lib_android" ]
|
||||
public_deps = [ ":angle_vulkan_headers" ]
|
||||
if (is_fuchsia) {
|
||||
public_deps += [
|
||||
|
||||
@@ -118,6 +118,8 @@ if (is_linux) {
|
||||
|
||||
if (is_android) {
|
||||
_vulkan_backend_sources += [
|
||||
"android/AHBFunctions.cpp",
|
||||
"android/AHBFunctions.h",
|
||||
"android/DisplayVkAndroid.cpp",
|
||||
"android/DisplayVkAndroid.h",
|
||||
"android/HardwareBufferImageSiblingVkAndroid.cpp",
|
||||
@@ -244,10 +246,6 @@ angle_source_set("angle_vulkan_backend") {
|
||||
data_deps += [ "$angle_root/src/common/vulkan:vulkan_validation_layers" ]
|
||||
}
|
||||
|
||||
if (is_android) {
|
||||
libs += [ "vulkan" ]
|
||||
}
|
||||
|
||||
if (is_fuchsia) {
|
||||
public_deps += [ "$angle_root/src/common/fuchsia_egl:backend" ]
|
||||
}
|
||||
|
||||
@@ -212,7 +212,8 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
|
||||
outExtensions->glColorspace && getRenderer()->getFeatures().supportsImageFormatList.enabled;
|
||||
|
||||
#if defined(ANGLE_PLATFORM_ANDROID)
|
||||
outExtensions->framebufferTargetANDROID = true;
|
||||
outExtensions->getNativeClientBufferANDROID = true;
|
||||
outExtensions->framebufferTargetANDROID = true;
|
||||
#endif // defined(ANGLE_PLATFORM_ANDROID)
|
||||
|
||||
// Disable context priority when non-zero memory init is enabled. This enforces a queue order.
|
||||
|
||||
@@ -292,6 +292,8 @@ class RendererVk : angle::NonCopyable
|
||||
}
|
||||
}
|
||||
|
||||
egl::Display *getDisplay() const { return mDisplay; }
|
||||
|
||||
VkResult getLastPresentResult(VkSwapchainKHR swapchain)
|
||||
{
|
||||
return mCommandProcessor.getLastPresentResult(swapchain);
|
||||
|
||||
35
src/libANGLE/renderer/vulkan/android/AHBFunctions.cpp
Normal file
35
src/libANGLE/renderer/vulkan/android/AHBFunctions.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
//
|
||||
// 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
|
||||
43
src/libANGLE/renderer/vulkan/android/AHBFunctions.h
Normal file
43
src/libANGLE/renderer/vulkan/android/AHBFunctions.h
Normal file
@@ -0,0 +1,43 @@
|
||||
//
|
||||
// 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 @@
|
||||
#define LIBANGLE_RENDERER_VULKAN_ANDROID_DISPLAYVKANDROID_H_
|
||||
|
||||
#include "libANGLE/renderer/vulkan/DisplayVk.h"
|
||||
#include "libANGLE/renderer/vulkan/android/AHBFunctions.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
@@ -40,6 +41,11 @@ class DisplayVkAndroid : public DisplayVk
|
||||
const egl::AttributeMap &attribs) override;
|
||||
|
||||
const char *getWSIExtension() const override;
|
||||
|
||||
const AHBFunctions &getAHBFunctions() const { return mAHBFunctions; }
|
||||
|
||||
private:
|
||||
AHBFunctions mAHBFunctions;
|
||||
};
|
||||
|
||||
} // namespace rx
|
||||
|
||||
@@ -13,14 +13,15 @@
|
||||
#include "libANGLE/Display.h"
|
||||
#include "libANGLE/renderer/vulkan/DisplayVk.h"
|
||||
#include "libANGLE/renderer/vulkan/RendererVk.h"
|
||||
|
||||
#include <android/hardware_buffer.h>
|
||||
#include "libANGLE/renderer/vulkan/android/AHBFunctions.h"
|
||||
#include "libANGLE/renderer/vulkan/android/DisplayVkAndroid.h"
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
VkImageTiling AhbDescUsageToVkImageTiling(const AHardwareBuffer_Desc &ahbDescription)
|
||||
{
|
||||
if ((ahbDescription.usage & AHARDWAREBUFFER_USAGE_CPU_READ_MASK) != 0 ||
|
||||
@@ -140,6 +141,9 @@ VkImageUsageFlags AhbDescUsageToVkImageUsage(const AHardwareBuffer_Desc &ahbDesc
|
||||
|
||||
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();
|
||||
|
||||
struct ANativeWindowBuffer *windowBuffer =
|
||||
@@ -154,7 +158,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
|
||||
struct AHardwareBuffer *hardwareBuffer =
|
||||
angle::android::ANativeWindowBufferToAHardwareBuffer(windowBuffer);
|
||||
|
||||
AHardwareBuffer_acquire(hardwareBuffer);
|
||||
functions.acquire(hardwareBuffer);
|
||||
VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties;
|
||||
bufferFormatProperties.sType =
|
||||
VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_FORMAT_PROPERTIES_ANDROID;
|
||||
@@ -181,7 +185,7 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
|
||||
// 1. Derive VkImageTiling mode based on AHB usage flags
|
||||
// 2. Map AHB usage flags to VkImageUsageFlags
|
||||
AHardwareBuffer_Desc ahbDescription;
|
||||
AHardwareBuffer_describe(hardwareBuffer, &ahbDescription);
|
||||
functions.describe(hardwareBuffer, &ahbDescription);
|
||||
VkImageTiling imageTilingMode = AhbDescUsageToVkImageTiling(ahbDescription);
|
||||
VkImageUsageFlags usage = AhbDescUsageToVkImageUsage(ahbDescription, isDepthOrStencilFormat);
|
||||
|
||||
@@ -310,7 +314,10 @@ angle::Result HardwareBufferImageSiblingVkAndroid::initImpl(DisplayVk *displayVk
|
||||
|
||||
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)));
|
||||
|
||||
ASSERT(mImage == nullptr);
|
||||
|
||||
@@ -12,10 +12,10 @@
|
||||
#include "libANGLE/renderer/vulkan/ContextVk.h"
|
||||
#include "libANGLE/renderer/vulkan/vk_utils.h"
|
||||
|
||||
#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 26
|
||||
# define ANGLE_AHARDWARE_BUFFER_SUPPORT
|
||||
// NDK header file for access to Android Hardware Buffers
|
||||
# include <android/hardware_buffer.h>
|
||||
#if defined(ANGLE_PLATFORM_ANDROID)
|
||||
# include "libANGLE/Display.h"
|
||||
# include "libANGLE/renderer/vulkan/android/AHBFunctions.h"
|
||||
# include "libANGLE/renderer/vulkan/android/DisplayVkAndroid.h"
|
||||
#endif
|
||||
|
||||
namespace rx
|
||||
@@ -26,7 +26,10 @@ angle::Result GetClientBufferMemoryRequirements(ContextVk *contextVk,
|
||||
const AHardwareBuffer *hardwareBuffer,
|
||||
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
|
||||
VkAndroidHardwareBufferFormatPropertiesANDROID bufferFormatProperties = {};
|
||||
@@ -49,7 +52,8 @@ angle::Result GetClientBufferMemoryRequirements(ContextVk *contextVk,
|
||||
#else
|
||||
ANGLE_VK_UNREACHABLE(contextVk);
|
||||
return angle::Result::Stop;
|
||||
#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
|
||||
@@ -59,7 +63,11 @@ angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
|
||||
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
|
||||
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 =
|
||||
angle::android::ClientBufferToAHardwareBuffer(clientBuffer);
|
||||
|
||||
@@ -76,22 +84,25 @@ angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
|
||||
contextVk, memoryProperties, externalMemoryRequirements, &importHardwareBufferInfo, buffer,
|
||||
memoryPropertyFlagsOut, deviceMemoryOut));
|
||||
|
||||
AHardwareBuffer_acquire(hardwareBuffer);
|
||||
functions.acquire(hardwareBuffer);
|
||||
|
||||
return angle::Result::Continue;
|
||||
#else
|
||||
ANGLE_VK_UNREACHABLE(contextVk);
|
||||
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 =
|
||||
angle::android::ClientBufferToAHardwareBuffer(clientBuffer);
|
||||
AHardwareBuffer_release(hardwareBuffer);
|
||||
#endif // ANGLE_AHARDWARE_BUFFER_SUPPORT
|
||||
functions.release(hardwareBuffer);
|
||||
#endif
|
||||
}
|
||||
} // namespace vk
|
||||
} // namespace rx
|
||||
|
||||
@@ -20,6 +20,9 @@ class DeviceMemory;
|
||||
|
||||
namespace rx
|
||||
{
|
||||
|
||||
class RendererVk;
|
||||
|
||||
namespace vk
|
||||
{
|
||||
angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
|
||||
@@ -29,7 +32,7 @@ angle::Result InitAndroidExternalMemory(ContextVk *contextVk,
|
||||
VkMemoryPropertyFlags *memoryPropertyFlagsOut,
|
||||
DeviceMemory *deviceMemoryOut);
|
||||
|
||||
void ReleaseAndroidExternalMemory(EGLClientBuffer clientBuffer);
|
||||
void ReleaseAndroidExternalMemory(RendererVk *rendererVk, EGLClientBuffer clientBuffer);
|
||||
} // namespace vk
|
||||
} // namespace rx
|
||||
|
||||
|
||||
@@ -3044,7 +3044,7 @@ void BufferMemory::destroy(RendererVk *renderer)
|
||||
if (isExternalBuffer())
|
||||
{
|
||||
mExternalMemory.destroy(renderer->getDevice());
|
||||
ReleaseAndroidExternalMemory(mClientBuffer);
|
||||
ReleaseAndroidExternalMemory(renderer, mClientBuffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user