From a3fced5da1e6734a6087d246094865997cd4b083 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Thu, 30 Jan 2025 11:41:04 -0800 Subject: [PATCH] [Impeller] Disable Vulkan on Emulators. (#162454) Forces known android emulators to use OpenGLES. This is a very conservative check that could be expanded over time if need be. For testing emulators can still use the debug flags. Fixes https://github.com/flutter/flutter/issues/160442 Fixes https://github.com/flutter/flutter/issues/160439 Fixes https://github.com/flutter/flutter/issues/155973 --- .../flutter/shell/platform/android/flutter_main.cc | 14 ++++++++++++++ .../flutter/shell/platform/android/flutter_main.h | 2 ++ .../android/platform_view_android_unittests.cc | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/engine/src/flutter/shell/platform/android/flutter_main.cc b/engine/src/flutter/shell/platform/android/flutter_main.cc index 4159d3713c..31aa094b07 100644 --- a/engine/src/flutter/shell/platform/android/flutter_main.cc +++ b/engine/src/flutter/shell/platform/android/flutter_main.cc @@ -5,7 +5,9 @@ #define FML_USED_ON_EMBEDDER #include +#include #include +#include #include #include "common/settings.h" @@ -230,6 +232,11 @@ bool FlutterMain::Register(JNIEnv* env) { return env->RegisterNatives(clazz, methods, std::size(methods)) == 0; } +// static +bool FlutterMain::IsDeviceEmulator(std::string_view product_model) { + return std::string(product_model).find("gphone") != std::string::npos; +} + // static AndroidRenderingAPI FlutterMain::SelectedRenderingAPI( const flutter::Settings& settings) { @@ -266,6 +273,13 @@ AndroidRenderingAPI FlutterMain::SelectedRenderingAPI( if (api_level < kMinimumAndroidApiLevelForVulkan) { return kVulkanUnsupportedFallback; } + char product_model[PROP_VALUE_MAX]; + __system_property_get("ro.product.model", product_model); + if (IsDeviceEmulator(product_model)) { + // Avoid using Vulkan on known emulators. + return kVulkanUnsupportedFallback; + } + // Determine if Vulkan is supported by creating a Vulkan context and // checking if it is valid. impeller::ScopedValidationDisable disable_validation; diff --git a/engine/src/flutter/shell/platform/android/flutter_main.h b/engine/src/flutter/shell/platform/android/flutter_main.h index c572b458fb..4db1230882 100644 --- a/engine/src/flutter/shell/platform/android/flutter_main.h +++ b/engine/src/flutter/shell/platform/android/flutter_main.h @@ -26,6 +26,8 @@ class FlutterMain { static AndroidRenderingAPI SelectedRenderingAPI( const flutter::Settings& settings); + static bool IsDeviceEmulator(std::string_view product_model); + private: const flutter::Settings settings_; DartServiceIsolate::CallbackHandle vm_service_uri_callback_ = 0; diff --git a/engine/src/flutter/shell/platform/android/platform_view_android_unittests.cc b/engine/src/flutter/shell/platform/android/platform_view_android_unittests.cc index fc1c2d9d1b..321e2e26b9 100644 --- a/engine/src/flutter/shell/platform/android/platform_view_android_unittests.cc +++ b/engine/src/flutter/shell/platform/android/platform_view_android_unittests.cc @@ -34,5 +34,13 @@ TEST(AndroidPlatformView, SoftwareRenderingNotSupportedWithImpeller) { ASSERT_DEATH(FlutterMain::SelectedRenderingAPI(settings), ""); } +TEST(AndroidPlatformView, FallsBackToGLESonEmulator) { + std::string emulator_product = "gphone_x64"; + std::string device_product = "smg1234"; + + EXPECT_TRUE(FlutterMain::IsDeviceEmulator(emulator_product)); + EXPECT_FALSE(FlutterMain::IsDeviceEmulator(device_product)); +} + } // namespace testing } // namespace flutter