Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit da87db6

Browse files
[android] Disable AHB swapchain and import on huawei API 29 devices. (#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 flutter/flutter#154068 * flutter/flutter#153228 * flutter/flutter#153762 * flutter/flutter#154068
1 parent e3a15e1 commit da87db6

File tree

11 files changed

+102
-3
lines changed

11 files changed

+102
-3
lines changed

ci/licenses_golden/licenses_flutter

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43298,6 +43298,8 @@ ORIGIN: ../../../flutter/impeller/toolkit/android/native_window.cc + ../../../fl
4329843298
ORIGIN: ../../../flutter/impeller/toolkit/android/native_window.h + ../../../flutter/LICENSE
4329943299
ORIGIN: ../../../flutter/impeller/toolkit/android/proc_table.cc + ../../../flutter/LICENSE
4330043300
ORIGIN: ../../../flutter/impeller/toolkit/android/proc_table.h + ../../../flutter/LICENSE
43301+
ORIGIN: ../../../flutter/impeller/toolkit/android/shadow_realm.cc + ../../../flutter/LICENSE
43302+
ORIGIN: ../../../flutter/impeller/toolkit/android/shadow_realm.h + ../../../flutter/LICENSE
4330143303
ORIGIN: ../../../flutter/impeller/toolkit/android/surface_control.cc + ../../../flutter/LICENSE
4330243304
ORIGIN: ../../../flutter/impeller/toolkit/android/surface_control.h + ../../../flutter/LICENSE
4330343305
ORIGIN: ../../../flutter/impeller/toolkit/android/surface_transaction.cc + ../../../flutter/LICENSE
@@ -46187,6 +46189,8 @@ FILE: ../../../flutter/impeller/toolkit/android/native_window.cc
4618746189
FILE: ../../../flutter/impeller/toolkit/android/native_window.h
4618846190
FILE: ../../../flutter/impeller/toolkit/android/proc_table.cc
4618946191
FILE: ../../../flutter/impeller/toolkit/android/proc_table.h
46192+
FILE: ../../../flutter/impeller/toolkit/android/shadow_realm.cc
46193+
FILE: ../../../flutter/impeller/toolkit/android/shadow_realm.h
4619046194
FILE: ../../../flutter/impeller/toolkit/android/surface_control.cc
4619146195
FILE: ../../../flutter/impeller/toolkit/android/surface_control.h
4619246196
FILE: ../../../flutter/impeller/toolkit/android/surface_transaction.cc

impeller/renderer/backend/vulkan/driver_info_vk.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ constexpr VendorVK IdentifyVendor(uint32_t vendor) {
3535
return VendorVK::kIntel;
3636
case 0x106B:
3737
return VendorVK::kApple;
38+
case 0x19E5:
39+
return VendorVK::kHuawei;
3840
}
3941
// Check if the ID is a known Khronos vendor.
4042
switch (vendor) {
@@ -68,6 +70,8 @@ constexpr const char* VendorToString(VendorVK vendor) {
6870
return "Mesa";
6971
case VendorVK::kApple:
7072
return "Apple";
73+
case VendorVK::kHuawei:
74+
return "Huawei";
7175
}
7276
FML_UNREACHABLE();
7377
}

impeller/renderer/backend/vulkan/driver_info_vk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ enum class VendorVK {
2323
kAMD,
2424
kNvidia,
2525
kIntel,
26+
kHuawei,
2627
//----------------------------------------------------------------------------
2728
/// Includes the LLVM Pipe CPU implementation.
2829
///

impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#if FML_OS_ANDROID
1313
#include "impeller/renderer/backend/vulkan/swapchain/ahb/ahb_swapchain_vk.h"
14+
#include "impeller/toolkit/android/shadow_realm.h"
1415
#endif // FML_OS_ANDROID
1516

1617
namespace impeller {
@@ -59,7 +60,8 @@ std::shared_ptr<SwapchainVK> SwapchainVK::Create(
5960
const auto emulator = ContextVK::Cast(*context).GetDriverInfo()->IsEmulator();
6061

6162
// Try AHB swapchains first.
62-
if (!emulator && AHBSwapchainVK::IsAvailableOnPlatform()) {
63+
if (!emulator && AHBSwapchainVK::IsAvailableOnPlatform() &&
64+
!android::ShadowRealm::ShouldDisableAHB()) {
6365
auto ahb_swapchain = std::shared_ptr<AHBSwapchainVK>(new AHBSwapchainVK(
6466
context, //
6567
window.GetHandle(), //

impeller/toolkit/android/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ impeller_component("android") {
1919
"native_window.h",
2020
"proc_table.cc",
2121
"proc_table.h",
22+
"shadow_realm.cc",
23+
"shadow_realm.h",
2224
"surface_control.cc",
2325
"surface_control.h",
2426
"surface_transaction.cc",
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#include "impeller/toolkit/android/shadow_realm.h"
6+
7+
#include <sys/system_properties.h>
8+
9+
namespace impeller::android {
10+
11+
constexpr std::string_view kAndroidHuawei = "android-huawei";
12+
13+
bool ShadowRealm::ShouldDisableAHB() {
14+
char clientidbase[PROP_VALUE_MAX];
15+
__system_property_get("ro.com.google.clientidbase", clientidbase);
16+
17+
auto api_level = android_get_device_api_level();
18+
19+
return ShouldDisableAHBInternal(clientidbase, api_level);
20+
}
21+
22+
// static
23+
bool ShadowRealm::ShouldDisableAHBInternal(std::string_view clientidbase,
24+
uint32_t api_level) {
25+
// From local testing, neither the swapchain nor AHB import works, see also:
26+
// https://github.com/flutter/flutter/issues/154068
27+
if (clientidbase == kAndroidHuawei && api_level <= 29) {
28+
return true;
29+
}
30+
return false;
31+
}
32+
33+
} // namespace impeller::android
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
#ifndef FLUTTER_IMPELLER_TOOLKIT_ANDROID_SHADOW_REALM_H_
6+
#define FLUTTER_IMPELLER_TOOLKIT_ANDROID_SHADOW_REALM_H_
7+
8+
#include <string_view>
9+
10+
namespace impeller::android {
11+
12+
// Looks like you're going to the Shadow Realm, Jimbo.
13+
class ShadowRealm {
14+
public:
15+
/// @brief Whether the device should disable any usage of Android Hardware
16+
/// Buffers regardless of stated support.
17+
static bool ShouldDisableAHB();
18+
19+
// For testing.
20+
static bool ShouldDisableAHBInternal(std::string_view clientidbase,
21+
uint32_t api_level);
22+
};
23+
24+
} // namespace impeller::android
25+
26+
#endif // FLUTTER_IMPELLER_TOOLKIT_ANDROID_SHADOW_REALM_H_

impeller/toolkit/android/toolkit_android_unittests.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "impeller/toolkit/android/choreographer.h"
88
#include "impeller/toolkit/android/hardware_buffer.h"
99
#include "impeller/toolkit/android/proc_table.h"
10+
#include "impeller/toolkit/android/shadow_realm.h"
1011
#include "impeller/toolkit/android/surface_control.h"
1112
#include "impeller/toolkit/android/surface_transaction.h"
1213

@@ -134,4 +135,12 @@ TEST(ToolkitAndroidTest, CanPostAndWaitForFrameCallbacks) {
134135
event.Wait();
135136
}
136137

138+
TEST(ToolkitAndroidTest, ShouldDisableAHB) {
139+
EXPECT_FALSE(ShadowRealm::ShouldDisableAHB());
140+
141+
EXPECT_TRUE(ShadowRealm::ShouldDisableAHBInternal("android-huawei", 29));
142+
EXPECT_FALSE(ShadowRealm::ShouldDisableAHBInternal("android-huawei", 30));
143+
EXPECT_FALSE(ShadowRealm::ShouldDisableAHBInternal("something made up", 29));
144+
}
145+
137146
} // namespace impeller::android::testing

shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,4 +1536,14 @@ void updateSemantics(
15361536
public interface AsyncWaitForVsyncDelegate {
15371537
void asyncWaitForVsync(final long cookie);
15381538
}
1539+
1540+
/**
1541+
* Whether Android Hardware Buffer import is known to not work on this particular vendor + API
1542+
* level and should be disabled.
1543+
*/
1544+
public boolean ShouldDisableAHB() {
1545+
return nativeShouldDisableAHB();
1546+
}
1547+
1548+
private native boolean nativeShouldDisableAHB();
15391549
}

shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,9 @@ public SurfaceProducer createSurfaceProducer() {
211211
// version that is
212212
// running Vulkan, so we don't have to worry about it not being supported.
213213
final SurfaceProducer entry;
214-
if (!debugForceSurfaceProducerGlTextures && Build.VERSION.SDK_INT >= API_LEVELS.API_29) {
214+
if (!debugForceSurfaceProducerGlTextures
215+
&& Build.VERSION.SDK_INT >= API_LEVELS.API_29
216+
&& !flutterJNI.ShouldDisableAHB()) {
215217
final long id = nextTextureId.getAndIncrement();
216218
final ImageReaderSurfaceProducer producer = new ImageReaderSurfaceProducer(id);
217219
registerImageTexture(id, producer);

shell/platform/android/platform_view_android_jni_impl.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <sstream>
1313
#include <utility>
1414

15+
#include "impeller/toolkit/android/shadow_realm.h"
1516
#include "include/android/SkImageAndroid.h"
1617
#include "unicode/uchar.h"
1718

@@ -853,7 +854,12 @@ bool RegisterApi(JNIEnv* env) {
853854
.signature = "(J)V",
854855
.fnPtr = reinterpret_cast<void*>(&UpdateDisplayMetrics),
855856
},
856-
};
857+
{
858+
.name = "nativeShouldDisableAHB",
859+
.signature = "()Z",
860+
.fnPtr = reinterpret_cast<void*>(
861+
&impeller::android::ShadowRealm::ShouldDisableAHB),
862+
}};
857863

858864
if (env->RegisterNatives(g_flutter_jni_class->obj(), flutter_jni_methods,
859865
std::size(flutter_jni_methods)) != 0) {

0 commit comments

Comments
 (0)