From 62673ac3ece301e1653c41acbb4e6678930e31de Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 29 Aug 2024 14:16:14 -0700 Subject: [PATCH 1/3] [android] Disable AHB swapchain and import on huawei API 29 devices. --- .../renderer/backend/vulkan/driver_info_vk.cc | 4 +++ .../renderer/backend/vulkan/driver_info_vk.h | 1 + .../backend/vulkan/swapchain/swapchain_vk.cc | 4 ++- impeller/toolkit/android/BUILD.gn | 2 ++ impeller/toolkit/android/shadow_realm.cc | 33 +++++++++++++++++++ impeller/toolkit/android/shadow_realm.h | 26 +++++++++++++++ .../android/toolkit_android_unittests.cc | 8 +++++ .../flutter/embedding/engine/FlutterJNI.java | 10 ++++++ .../engine/renderer/FlutterRenderer.java | 4 ++- .../android/platform_view_android_jni_impl.cc | 8 ++++- 10 files changed, 97 insertions(+), 3 deletions(-) create mode 100644 impeller/toolkit/android/shadow_realm.cc create mode 100644 impeller/toolkit/android/shadow_realm.h diff --git a/impeller/renderer/backend/vulkan/driver_info_vk.cc b/impeller/renderer/backend/vulkan/driver_info_vk.cc index 3dbfaacab33a8..725acdad9052a 100644 --- a/impeller/renderer/backend/vulkan/driver_info_vk.cc +++ b/impeller/renderer/backend/vulkan/driver_info_vk.cc @@ -35,6 +35,8 @@ constexpr VendorVK IdentifyVendor(uint32_t vendor) { return VendorVK::kIntel; case 0x106B: return VendorVK::kApple; + case 0x19E5: + return VendorVK::kHuawei; } // Check if the ID is a known Khronos vendor. switch (vendor) { @@ -68,6 +70,8 @@ constexpr const char* VendorToString(VendorVK vendor) { return "Mesa"; case VendorVK::kApple: return "Apple"; + case VendorVK::kHuawei: + return "Huawei"; } FML_UNREACHABLE(); } diff --git a/impeller/renderer/backend/vulkan/driver_info_vk.h b/impeller/renderer/backend/vulkan/driver_info_vk.h index 152b1ba3b340d..e973985105739 100644 --- a/impeller/renderer/backend/vulkan/driver_info_vk.h +++ b/impeller/renderer/backend/vulkan/driver_info_vk.h @@ -23,6 +23,7 @@ enum class VendorVK { kAMD, kNvidia, kIntel, + kHuawei, //---------------------------------------------------------------------------- /// Includes the LLVM Pipe CPU implementation. /// diff --git a/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc b/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc index 534c1f8b22e83..f6c6d440e4534 100644 --- a/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc +++ b/impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc @@ -11,6 +11,7 @@ #if FML_OS_ANDROID #include "impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h" +#include "impeller/toolkit/android/shadow_realm.h" #endif // FML_OS_ANDROID namespace impeller { @@ -59,7 +60,8 @@ std::shared_ptr SwapchainVK::Create( const auto emulator = ContextVK::Cast(*context).GetDriverInfo()->IsEmulator(); // Try AHB swapchains first. - if (!emulator && AHBSwapchainVK::IsAvailableOnPlatform()) { + if (!emulator && AHBSwapchainVK::IsAvailableOnPlatform() && + !android::ShadowRealm::ShouldDisableAHB()) { auto ahb_swapchain = std::shared_ptr(new AHBSwapchainVK( context, // window.GetHandle(), // diff --git a/impeller/toolkit/android/BUILD.gn b/impeller/toolkit/android/BUILD.gn index 0e0b30337f64e..c4a95f768161a 100644 --- a/impeller/toolkit/android/BUILD.gn +++ b/impeller/toolkit/android/BUILD.gn @@ -19,6 +19,8 @@ impeller_component("android") { "native_window.h", "proc_table.cc", "proc_table.h", + "shadow_realm.cc", + "shadow_realm.h", "surface_control.cc", "surface_control.h", "surface_transaction.cc", diff --git a/impeller/toolkit/android/shadow_realm.cc b/impeller/toolkit/android/shadow_realm.cc new file mode 100644 index 0000000000000..6d19e6fe459f4 --- /dev/null +++ b/impeller/toolkit/android/shadow_realm.cc @@ -0,0 +1,33 @@ +// Copyright 2013 The Flutter 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 "impeller/toolkit/android/shadow_realm.h" + +#include + +namespace impeller::android { + +constexpr std::string_view kAndroidHuawei = "android-huawei"; + +bool ShadowRealm::ShouldDisableAHB() { + char clientidbase[PROP_VALUE_MAX]; + __system_property_get("ro.com.google.clientidbase", clientidbase); + + auto api_level = android_get_device_api_level(); + + return ShouldDisableAHBInternal(clientidbase, api_level); +} + +// static +bool ShadowRealm::ShouldDisableAHBInternal(std::string_view clientidbase, + uint32_t api_level) { + // From local testing, neither the swapchain nor AHB import works, see also: + // https://github.com/flutter/flutter/issues/154068 + if (clientidbase == kAndroidHuawei && api_level <= 29) { + return true; + } + return false; +} + +} // namespace impeller::android diff --git a/impeller/toolkit/android/shadow_realm.h b/impeller/toolkit/android/shadow_realm.h new file mode 100644 index 0000000000000..90f913b5af3bc --- /dev/null +++ b/impeller/toolkit/android/shadow_realm.h @@ -0,0 +1,26 @@ +// Copyright 2013 The Flutter 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 FLUTTER_IMPELLER_TOOLKIT_ANDROID_SHADOW_REALM_H_ +#define FLUTTER_IMPELLER_TOOLKIT_ANDROID_SHADOW_REALM_H_ + +#include + +namespace impeller::android { + +// Looks like you're going to the Shadow Realm, Jimbo. +class ShadowRealm { + public: + /// @brief Whether the device should disable any usage of Android Hardware + /// Buffers regardless of stated support. + static bool ShouldDisableAHB(); + + // For testing. + static bool ShouldDisableAHBInternal(std::string_view clientidbase, + uint32_t api_level); +}; + +} // namespace impeller::android + +#endif // FLUTTER_IMPELLER_TOOLKIT_ANDROID_SHADOW_REALM_H_ diff --git a/impeller/toolkit/android/toolkit_android_unittests.cc b/impeller/toolkit/android/toolkit_android_unittests.cc index 9c6218fa87962..37980409c14a3 100644 --- a/impeller/toolkit/android/toolkit_android_unittests.cc +++ b/impeller/toolkit/android/toolkit_android_unittests.cc @@ -134,4 +134,12 @@ TEST(ToolkitAndroidTest, CanPostAndWaitForFrameCallbacks) { event.Wait(); } +TEST(ToolkitAndroidTest, ShouldDisableAHB) { + EXPECT_FALSE(ShadowRealm::ShouldDisableAHB()); + + EXPECT_TRUE(ShadowRealm::ShouldDisableAHBInternal("android-huawei", 29)); + EXPECT_FALSE(ShadowRealm::ShouldDisableAHBInternal("android-huawei", 30)); + EXPECT_FALSE(ShadowRealm::ShouldDisableAHBInternal("something made up", 29)); +} + } // namespace impeller::android::testing diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index eaf2bd6058558..3c966d2f4fa98 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -1536,4 +1536,14 @@ void updateSemantics( public interface AsyncWaitForVsyncDelegate { void asyncWaitForVsync(final long cookie); } + + /** + * Whether Android Hardware Buffer import is known to not work on this particular vendor + API + * level and should be disabled. + */ + public boolean ShouldDisableAHB() { + return nativeShouldDisableAHB(); + } + + private native boolean nativeShouldDisableAHB(); } diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java index c4e3df02c1cd7..532e692358981 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java @@ -211,7 +211,9 @@ public SurfaceProducer createSurfaceProducer() { // version that is // running Vulkan, so we don't have to worry about it not being supported. final SurfaceProducer entry; - if (!debugForceSurfaceProducerGlTextures && Build.VERSION.SDK_INT >= API_LEVELS.API_29) { + if (!debugForceSurfaceProducerGlTextures + && Build.VERSION.SDK_INT >= API_LEVELS.API_29 + && !flutterJNI.ShouldDisableAHB()) { final long id = nextTextureId.getAndIncrement(); final ImageReaderSurfaceProducer producer = new ImageReaderSurfaceProducer(id); registerImageTexture(id, producer); diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index 17b9ecbebe233..2b884fdab669f 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -12,6 +12,7 @@ #include #include +#include "impeller/toolkit/android/shadow_realm.h" #include "include/android/SkImageAndroid.h" #include "unicode/uchar.h" @@ -853,7 +854,12 @@ bool RegisterApi(JNIEnv* env) { .signature = "(J)V", .fnPtr = reinterpret_cast(&UpdateDisplayMetrics), }, - }; + { + .name = "nativeShouldDisableAHB", + .signature = "()Z", + .fnPtr = reinterpret_cast( + &impeller::android::ShadowRealm::ShouldDisableAHB), + }}; if (env->RegisterNatives(g_flutter_jni_class->obj(), flutter_jni_methods, std::size(flutter_jni_methods)) != 0) { From 5086f633c8d0b528c5a54b1a4ecc820f2b7e96de Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 29 Aug 2024 14:58:22 -0700 Subject: [PATCH 2/3] ++ --- impeller/toolkit/android/toolkit_android_unittests.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/impeller/toolkit/android/toolkit_android_unittests.cc b/impeller/toolkit/android/toolkit_android_unittests.cc index 37980409c14a3..c96e04c2dfe9c 100644 --- a/impeller/toolkit/android/toolkit_android_unittests.cc +++ b/impeller/toolkit/android/toolkit_android_unittests.cc @@ -7,6 +7,7 @@ #include "impeller/toolkit/android/choreographer.h" #include "impeller/toolkit/android/hardware_buffer.h" #include "impeller/toolkit/android/proc_table.h" +#include "impeller/toolkit/android/shadow_realm.h" #include "impeller/toolkit/android/surface_control.h" #include "impeller/toolkit/android/surface_transaction.h" From 0ca3141d7097860bd10f42d6cdfe26231e001db5 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 29 Aug 2024 15:28:52 -0700 Subject: [PATCH 3/3] ++ --- ci/licenses_golden/licenses_flutter | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index e3bba96226be3..0a1c1595184d6 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -43298,6 +43298,8 @@ ORIGIN: ../../../flutter/impeller/toolkit/android/native_window.cc + ../../../fl ORIGIN: ../../../flutter/impeller/toolkit/android/native_window.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/android/proc_table.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/android/proc_table.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/android/shadow_realm.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/impeller/toolkit/android/shadow_realm.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/android/surface_control.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/android/surface_control.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/impeller/toolkit/android/surface_transaction.cc + ../../../flutter/LICENSE @@ -44436,6 +44438,8 @@ ORIGIN: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_impeller.h ORIGIN: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_impeller.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_skia.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_skia.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/darwin/ios/ios_context_noop.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/darwin/ios/ios_context_noop.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/ios_context_software.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/ios_context_software.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/ios/ios_external_texture_metal.h + ../../../flutter/LICENSE @@ -46185,6 +46189,8 @@ FILE: ../../../flutter/impeller/toolkit/android/native_window.cc FILE: ../../../flutter/impeller/toolkit/android/native_window.h FILE: ../../../flutter/impeller/toolkit/android/proc_table.cc FILE: ../../../flutter/impeller/toolkit/android/proc_table.h +FILE: ../../../flutter/impeller/toolkit/android/shadow_realm.cc +FILE: ../../../flutter/impeller/toolkit/android/shadow_realm.h FILE: ../../../flutter/impeller/toolkit/android/surface_control.cc FILE: ../../../flutter/impeller/toolkit/android/surface_control.h FILE: ../../../flutter/impeller/toolkit/android/surface_transaction.cc @@ -47342,6 +47348,8 @@ FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_impeller.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_impeller.mm FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_skia.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_metal_skia.mm +FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_noop.h +FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_noop.mm FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_software.h FILE: ../../../flutter/shell/platform/darwin/ios/ios_context_software.mm FILE: ../../../flutter/shell/platform/darwin/ios/ios_external_texture_metal.h