[android] Disable AHB swapchain and import on huawei API 29 devices. (flutter/engine#54879)

From local testing, it seems that AHB imports and swapchain usage of AHBs does not work on these Huawei devices. Vulkan does seem to work OK with these optional features disabled, but so far we've only tested on the P40 Pro.

Fixes https://github.com/flutter/flutter/issues/154068

* https://github.com/flutter/flutter/issues/153228
* https://github.com/flutter/flutter/issues/153762
* https://github.com/flutter/flutter/issues/154068
This commit is contained in:
Jonah Williams 2024-08-29 17:09:24 -07:00 committed by GitHub
parent fdc343efec
commit beb4e397b3
11 changed files with 102 additions and 3 deletions

View File

@ -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
@ -46187,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

View File

@ -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();
}

View File

@ -23,6 +23,7 @@ enum class VendorVK {
kAMD,
kNvidia,
kIntel,
kHuawei,
//----------------------------------------------------------------------------
/// Includes the LLVM Pipe CPU implementation.
///

View File

@ -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> 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<AHBSwapchainVK>(new AHBSwapchainVK(
context, //
window.GetHandle(), //

View File

@ -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",

View File

@ -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 <sys/system_properties.h>
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

View File

@ -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 <string_view>
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_

View File

@ -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"
@ -134,4 +135,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

View File

@ -1536,4 +1536,14 @@ public class FlutterJNI {
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();
}

View File

@ -211,7 +211,9 @@ public class FlutterRenderer implements TextureRegistry {
// 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);

View File

@ -12,6 +12,7 @@
#include <sstream>
#include <utility>
#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<void*>(&UpdateDisplayMetrics),
},
};
{
.name = "nativeShouldDisableAHB",
.signature = "()Z",
.fnPtr = reinterpret_cast<void*>(
&impeller::android::ShadowRealm::ShouldDisableAHB),
}};
if (env->RegisterNatives(g_flutter_jni_class->obj(), flutter_jni_methods,
std::size(flutter_jni_methods)) != 0) {