diff --git a/common/settings.h b/common/settings.h index 9e9fa7dea24d9..d9df7e707b172 100644 --- a/common/settings.h +++ b/common/settings.h @@ -217,6 +217,9 @@ struct Settings { bool enable_impeller = false; #endif + // Requests a particular backend to be used (ex "opengles" or "vulkan") + std::optional impeller_backend; + // Enable Vulkan validation on backends that support it. The validation layers // must be available to the application. bool enable_vulkan_validation = false; diff --git a/shell/common/switches.cc b/shell/common/switches.cc index 702cbd45ea38e..e0d4ae3d5826e 100644 --- a/shell/common/switches.cc +++ b/shell/common/switches.cc @@ -443,11 +443,23 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) { settings.use_asset_fonts = !command_line.HasOption(FlagForSwitch(Switch::DisableAssetFonts)); - std::string enable_impeller_value; - if (command_line.GetOptionValue(FlagForSwitch(Switch::EnableImpeller), - &enable_impeller_value)) { - settings.enable_impeller = - enable_impeller_value.empty() || "true" == enable_impeller_value; + { + std::string enable_impeller_value; + if (command_line.GetOptionValue(FlagForSwitch(Switch::EnableImpeller), + &enable_impeller_value)) { + settings.enable_impeller = + enable_impeller_value.empty() || "true" == enable_impeller_value; + } + } + + { + std::string impeller_backend_value; + if (command_line.GetOptionValue(FlagForSwitch(Switch::ImpellerBackend), + &impeller_backend_value)) { + if (!impeller_backend_value.empty()) { + settings.impeller_backend = impeller_backend_value; + } + } } settings.enable_vulkan_validation = diff --git a/shell/common/switches.h b/shell/common/switches.h index 30d1f0307d515..c8a75f778664c 100644 --- a/shell/common/switches.h +++ b/shell/common/switches.h @@ -261,6 +261,10 @@ DEF_SWITCH(EnableImpeller, "enable-impeller", "Enable the Impeller renderer on supported platforms. Ignored if " "Impeller is not supported on the platform.") +DEF_SWITCH(ImpellerBackend, + "impeller-backend", + "Requests a particular Impeller backend on platforms that support " + "multiple backends. (ex `opengles` or `vulkan`)") DEF_SWITCH(EnableVulkanValidation, "enable-vulkan-validation", "Enable loading Vulkan validation layers. The layers must be " diff --git a/shell/platform/android/android_context_gl_impeller.cc b/shell/platform/android/android_context_gl_impeller.cc index a4bcd9fbc7f5c..c630ab2fb8f6e 100644 --- a/shell/platform/android/android_context_gl_impeller.cc +++ b/shell/platform/android/android_context_gl_impeller.cc @@ -74,7 +74,7 @@ static std::shared_ptr CreateImpellerContext( FML_LOG(ERROR) << "Could not add reactor worker."; return nullptr; } - FML_LOG(ERROR) << "Using the Impeller rendering backend."; + FML_LOG(ERROR) << "Using the Impeller rendering backend (OpenGLES)."; return context; } diff --git a/shell/platform/android/android_context_vulkan_impeller.cc b/shell/platform/android/android_context_vulkan_impeller.cc index 9a7c979c31f48..9d8deaaa1217e 100644 --- a/shell/platform/android/android_context_vulkan_impeller.cc +++ b/shell/platform/android/android_context_vulkan_impeller.cc @@ -34,6 +34,9 @@ static std::shared_ptr CreateImpellerContext( settings.cache_directory = fml::paths::GetCachesDirectory(); settings.worker_task_runner = std::move(worker_task_runner); settings.enable_validation = enable_vulkan_validation; + + FML_LOG(ERROR) << "Using the Impeller rendering backend (Vulkan)."; + return impeller::ContextVK::Create(std::move(settings)); } diff --git a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java index 5461838e7ad85..de484f816d2f8 100644 --- a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java +++ b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java @@ -41,6 +41,8 @@ public class FlutterLoader { "io.flutter.embedding.android.OldGenHeapSize"; private static final String ENABLE_IMPELLER_META_DATA_KEY = "io.flutter.embedding.android.EnableImpeller"; + private static final String IMPELLER_BACKEND_META_DATA_KEY = + "io.flutter.embedding.android.ImpellerBackend"; /** * Set whether leave or clean up the VM after the last shell shuts down. It can be set from app's @@ -316,8 +318,12 @@ public void ensureInitializationComplete( shellArgs.add("--prefetched-default-font-manager"); - if (metaData != null && metaData.getBoolean(ENABLE_IMPELLER_META_DATA_KEY, false)) { - shellArgs.add("--enable-impeller"); + if (metaData != null) { + if (metaData.getBoolean(ENABLE_IMPELLER_META_DATA_KEY, false)) { + shellArgs.add("--enable-impeller"); + } + String backend = metaData.getString(IMPELLER_BACKEND_META_DATA_KEY, "opengles"); + shellArgs.add("--impeller-backend=" + backend); } final String leakVM = isLeakVM(metaData) ? "true" : "false"; diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index b89c23a368d27..7e8b10f778d03 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -51,16 +51,9 @@ std::unique_ptr AndroidSurfaceFactoryImpl::CreateSurface() { } case AndroidRenderingAPI::kVulkan: FML_DCHECK(enable_impeller_); - // TODO(kaushikiska@): Enable this after wiring a preference for Vulkan - // backend. -#if false - return std::make_unique( + return std::make_unique( std::static_pointer_cast( android_context_)); -#else - return std::make_unique( - std::static_pointer_cast(android_context_)); -#endif default: FML_DCHECK(false); return nullptr; @@ -73,19 +66,36 @@ static std::shared_ptr CreateAndroidContext( const std::shared_ptr& worker_task_runner, uint8_t msaa_samples, bool enable_impeller, + const std::optional& impeller_backend, bool enable_vulkan_validation) { if (use_software_rendering) { return std::make_shared(AndroidRenderingAPI::kSoftware); } if (enable_impeller) { - // TODO(kaushikiska@): Enable this after wiring a preference for Vulkan - // backend. -#if false - return std::make_unique(enable_vulkan_validation, std::move(worker_task_runner)); -#else - return std::make_unique( - std::make_unique()); -#endif + // TODO(gaaclarke): We need to devise a more complete heuristic about what + // backend to use by default. + // Default value is OpenGLES. + AndroidRenderingAPI backend = AndroidRenderingAPI::kOpenGLES; + if (impeller_backend.has_value()) { + if (impeller_backend.value() == "opengles") { + backend = AndroidRenderingAPI::kOpenGLES; + } else if (impeller_backend.value() == "vulkan") { + backend = AndroidRenderingAPI::kVulkan; + } else { + FML_CHECK(impeller_backend.value() == "vulkan" || + impeller_backend.value() == "opengles"); + } + } + switch (backend) { + case AndroidRenderingAPI::kOpenGLES: + return std::make_unique( + std::make_unique()); + case AndroidRenderingAPI::kVulkan: + return std::make_unique( + enable_vulkan_validation, worker_task_runner); + default: + FML_UNREACHABLE(); + } } return std::make_unique( AndroidRenderingAPI::kOpenGLES, // @@ -112,6 +122,7 @@ PlatformViewAndroid::PlatformViewAndroid( worker_task_runner, msaa_samples, delegate.OnPlatformViewGetSettings().enable_impeller, + delegate.OnPlatformViewGetSettings().impeller_backend, delegate.OnPlatformViewGetSettings().enable_vulkan_validation)) {} PlatformViewAndroid::PlatformViewAndroid(