diff --git a/common/settings.h b/common/settings.h index eb07585a33fb0..af002c93006c4 100644 --- a/common/settings.h +++ b/common/settings.h @@ -218,6 +218,9 @@ struct Settings { bool enable_impeller = false; #endif + // Indicates if image reader backed platform views are disabled. + bool disable_image_reader_platform_views = false; + // Requests a particular backend to be used (ex "opengles" or "vulkan") std::optional impeller_backend; diff --git a/shell/common/switches.cc b/shell/common/switches.cc index f9cbb548cc0f5..655742109ae0b 100644 --- a/shell/common/switches.cc +++ b/shell/common/switches.cc @@ -455,6 +455,17 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) { } } + { + std::string disable_image_reader_platform_views_value; + if (command_line.GetOptionValue( + FlagForSwitch(Switch::DisableImageReaderPlatformViews), + &disable_image_reader_platform_views_value)) { + settings.disable_image_reader_platform_views = + disable_image_reader_platform_views_value.empty() || + "true" == disable_image_reader_platform_views_value; + } + } + { std::string impeller_backend_value; if (command_line.GetOptionValue(FlagForSwitch(Switch::ImpellerBackend), diff --git a/shell/common/switches.h b/shell/common/switches.h index 7dd04fc7e12e4..c6048705f3121 100644 --- a/shell/common/switches.h +++ b/shell/common/switches.h @@ -280,6 +280,9 @@ DEF_SWITCH(LeakVM, "When the last shell shuts down, the shared VM is leaked by default " "(the leak_vm in VM settings is true). To clean up the leak VM, set " "this value to false.") +DEF_SWITCH(DisableImageReaderPlatformViews, + "disable-image-reader-platform-views", + "Disables the use of ImageReader backed Platform Views on Android.") DEF_SWITCH( MsaaSamples, "msaa-samples", diff --git a/shell/common/switches_unittests.cc b/shell/common/switches_unittests.cc index 617c0a891cfa7..dc80e87a93b5d 100644 --- a/shell/common/switches_unittests.cc +++ b/shell/common/switches_unittests.cc @@ -123,6 +123,25 @@ TEST(SwitchesTest, NoEnableImpeller) { } } +TEST(SwitchesTest, DisableImageReaderPlatformViews) { + { + // enable + fml::CommandLine command_line = fml::CommandLineFromInitializerList( + {"command", "--disable-image-reader-platform-views"}); + EXPECT_TRUE(command_line.HasOption("disable-image-reader-platform-views")); + Settings settings = SettingsFromCommandLine(command_line); + EXPECT_EQ(settings.disable_image_reader_platform_views, true); + } + { + // disable + fml::CommandLine command_line = fml::CommandLineFromInitializerList( + {"command", "--disable-image-reader-platform-views=false"}); + EXPECT_TRUE(command_line.HasOption("disable-image-reader-platform-views")); + Settings settings = SettingsFromCommandLine(command_line); + EXPECT_EQ(settings.disable_image_reader_platform_views, false); + } +} + } // namespace testing } // namespace flutter diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java b/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java index a3a463be04553..2bfa379f39c1e 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java @@ -367,6 +367,8 @@ public FlutterEngine( this.renderer = new FlutterRenderer(flutterJNI); this.platformViewsController = platformViewsController; + this.platformViewsController.setDisableImageReaderPlatformViews( + flutterJNI.getDisableImageReaderPlatformViews()); this.platformViewsController.onAttachedToJNI(); this.pluginRegistry = diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index 1d66eeff9dc45..e4337e97b637d 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -237,6 +237,17 @@ public boolean getIsSoftwareRenderingEnabled() { return nativeGetIsSoftwareRenderingEnabled(); } + private native boolean nativeGetDisableImageReaderPlatformViews(); + + /** + * Checks launch settings for whether image reader platform views are disabled. + * + *

The value is the same per program. + */ + @UiThread + public boolean getDisableImageReaderPlatformViews() { + return nativeGetDisableImageReaderPlatformViews(); + } /** * VM Service URI for the VM instance. * diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterShellArgs.java b/shell/platform/android/io/flutter/embedding/engine/FlutterShellArgs.java index b3775217a86fe..b1b6bc139a7fc 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterShellArgs.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterShellArgs.java @@ -20,6 +20,7 @@ */ @SuppressWarnings({"WeakerAccess", "unused"}) public class FlutterShellArgs { + private static final String TAG = "FlutterShellArgs"; public static final String ARG_KEY_TRACE_STARTUP = "trace-startup"; public static final String ARG_TRACE_STARTUP = "--trace-startup"; public static final String ARG_KEY_START_PAUSED = "start-paused"; @@ -38,6 +39,10 @@ public class FlutterShellArgs { public static final String ARG_SKIA_DETERMINISTIC_RENDERING = "--skia-deterministic-rendering"; public static final String ARG_KEY_TRACE_SKIA = "trace-skia"; public static final String ARG_TRACE_SKIA = "--trace-skia"; + public static final String ARG_KEY_DISABLE_IMAGE_READER_PLATFORM_VIEWS = + "disable-image-reader-platform-views"; + public static final String ARG_DISABLE_IMAGE_READER_PLATFORM_VIEWS = + "--disable-image-reader-platform-views"; public static final String ARG_KEY_TRACE_SKIA_ALLOWLIST = "trace-skia-allowlist"; public static final String ARG_TRACE_SKIA_ALLOWLIST = "--trace-skia-allowlist="; public static final String ARG_KEY_TRACE_SYSTRACE = "trace-systrace"; @@ -128,6 +133,9 @@ public static FlutterShellArgs fromIntent(@NonNull Intent intent) { if (intent.getBooleanExtra(ARG_KEY_ENABLE_IMPELLER, false)) { args.add(ARG_ENABLE_IMPELLER); } + if (intent.getBooleanExtra(ARG_KEY_DISABLE_IMAGE_READER_PLATFORM_VIEWS, false)) { + args.add(ARG_DISABLE_IMAGE_READER_PLATFORM_VIEWS); + } if (intent.getBooleanExtra(ARG_KEY_ENABLE_VULKAN_VALIDATION, false)) { args.add(ARG_ENABLE_VULKAN_VALIDATION); } 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 2b880ba3e9883..da114ae3978d7 100644 --- a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java +++ b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java @@ -45,6 +45,8 @@ public class FlutterLoader { "io.flutter.embedding.android.EnableVulkanValidation"; private static final String IMPELLER_BACKEND_META_DATA_KEY = "io.flutter.embedding.android.ImpellerBackend"; + private static final String DISABLE_IMAGE_READER_PLATFORM_VIEWS_KEY = + "io.flutter.embedding.android.DisableImageReaderPlatformViews"; /** * Set whether leave or clean up the VM after the last shell shuts down. It can be set from app's @@ -331,6 +333,9 @@ public void ensureInitializationComplete( if (metaData.getBoolean(ENABLE_IMPELLER_META_DATA_KEY, false)) { shellArgs.add("--enable-impeller"); } + if (metaData.getBoolean(DISABLE_IMAGE_READER_PLATFORM_VIEWS_KEY, false)) { + shellArgs.add("--disable-image-reader-platform-views"); + } if (metaData.getBoolean( ENABLE_VULKAN_VALIDATION_META_DATA_KEY, areValidationLayersOnByDefault())) { shellArgs.add("--enable-vulkan-validation"); diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index 0e7ad70aee29d..dc78859137226 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -773,6 +773,10 @@ public void setSoftwareRendering(boolean useSoftwareRendering) { usesSoftwareRendering = useSoftwareRendering; } + public void setDisableImageReaderPlatformViews(boolean disableImageReaderPlatformViews) { + enableHardwareBufferRenderingTarget = !disableImageReaderPlatformViews; + } + /** * Detaches this platform views controller. * @@ -972,9 +976,11 @@ private static PlatformViewRenderTarget makePlatformViewRenderTarget( TextureRegistry textureRegistry) { if (enableHardwareBufferRenderingTarget && Build.VERSION.SDK_INT >= 29) { final TextureRegistry.ImageTextureEntry textureEntry = textureRegistry.createImageTexture(); + Log.i(TAG, "PlatformView is using ImageReader backend"); return new ImageReaderPlatformViewRenderTarget(textureEntry); } final TextureRegistry.SurfaceTextureEntry textureEntry = textureRegistry.createSurfaceTexture(); + Log.i(TAG, "PlatformView is using SurfaceTexture backend"); return new SurfaceTexturePlatformViewRenderTarget(textureEntry); } diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index aefb58e6a1da0..43a2f63fa378c 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -483,6 +483,11 @@ static jboolean GetIsSoftwareRendering(JNIEnv* env, jobject jcaller) { return FlutterMain::Get().GetSettings().enable_software_rendering; } +static jboolean GetDisableImageReaderPlatformViews(JNIEnv* env, + jobject jcaller) { + return FlutterMain::Get().GetSettings().disable_image_reader_platform_views; +} + static void RegisterTexture(JNIEnv* env, jobject jcaller, jlong shell_holder, @@ -778,6 +783,11 @@ bool RegisterApi(JNIEnv* env) { .signature = "()Z", .fnPtr = reinterpret_cast(&GetIsSoftwareRendering), }, + { + .name = "nativeGetDisableImageReaderPlatformViews", + .signature = "()Z", + .fnPtr = reinterpret_cast(&GetDisableImageReaderPlatformViews), + }, { .name = "nativeRegisterTexture", .signature = "(JJLjava/lang/ref/"