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

[android] Disable AHB swapchain and import on huawei API 29 devices. #54879

Merged
merged 4 commits into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions impeller/renderer/backend/vulkan/driver_info_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -68,6 +70,8 @@ constexpr const char* VendorToString(VendorVK vendor) {
return "Mesa";
case VendorVK::kApple:
return "Apple";
case VendorVK::kHuawei:
return "Huawei";
}
FML_UNREACHABLE();
}
Expand Down
1 change: 1 addition & 0 deletions impeller/renderer/backend/vulkan/driver_info_vk.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum class VendorVK {
kAMD,
kNvidia,
kIntel,
kHuawei,
//----------------------------------------------------------------------------
/// Includes the LLVM Pipe CPU implementation.
///
Expand Down
4 changes: 3 additions & 1 deletion impeller/renderer/backend/vulkan/swapchain/swapchain_vk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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(), //
Expand Down
2 changes: 2 additions & 0 deletions impeller/toolkit/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
33 changes: 33 additions & 0 deletions impeller/toolkit/android/shadow_realm.cc
Original file line number Diff line number Diff line change
@@ -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
26 changes: 26 additions & 0 deletions impeller/toolkit/android/shadow_realm.h
Original file line number Diff line number Diff line change
@@ -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_
9 changes: 9 additions & 0 deletions impeller/toolkit/android/toolkit_android_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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
10 changes: 10 additions & 0 deletions shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 7 additions & 1 deletion shell/platform/android/platform_view_android_jni_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <sstream>
#include <utility>

#include "impeller/toolkit/android/shadow_realm.h"
#include "include/android/SkImageAndroid.h"
#include "unicode/uchar.h"

Expand Down Expand Up @@ -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) {
Expand Down