Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from 2 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 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