Add an AndroidManifest.xml flag to disable ImageReader backed Platform Views (flutter/engine#46430)

An internal customer is seeing flickering on some high FPS phones.

While we try and reproduce / gain more knowledge of this problem this PR adds a AndroidManifest.xml flag to disable their usage.

The boolean flag is:
```
"io.flutter.embedding.android.DisableImageReaderPlatformViews"
```

Adding the following to your manifest will disable their usage:

```
<meta-data
  android:name="io.flutter.embedding.android.DisableImageReaderPlatformViews"
  android:value="true" />
```
This commit is contained in:
John McCutchan 2023-09-29 17:33:33 -07:00 committed by GitHub
parent 32907c3110
commit af107ceba5
10 changed files with 78 additions and 0 deletions

View File

@ -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<std::string> impeller_backend;

View File

@ -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),

View File

@ -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",

View File

@ -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

View File

@ -367,6 +367,8 @@ public class FlutterEngine implements ViewUtils.DisplayUpdater {
this.renderer = new FlutterRenderer(flutterJNI);
this.platformViewsController = platformViewsController;
this.platformViewsController.setDisableImageReaderPlatformViews(
flutterJNI.getDisableImageReaderPlatformViews());
this.platformViewsController.onAttachedToJNI();
this.pluginRegistry =

View File

@ -237,6 +237,17 @@ public class FlutterJNI {
return nativeGetIsSoftwareRenderingEnabled();
}
private native boolean nativeGetDisableImageReaderPlatformViews();
/**
* Checks launch settings for whether image reader platform views are disabled.
*
* <p>The value is the same per program.
*/
@UiThread
public boolean getDisableImageReaderPlatformViews() {
return nativeGetDisableImageReaderPlatformViews();
}
/**
* VM Service URI for the VM instance.
*

View File

@ -20,6 +20,7 @@ import java.util.*;
*/
@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 class FlutterShellArgs {
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);
}

View File

@ -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 class FlutterLoader {
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");

View File

@ -773,6 +773,10 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega
usesSoftwareRendering = useSoftwareRendering;
}
public void setDisableImageReaderPlatformViews(boolean disableImageReaderPlatformViews) {
enableHardwareBufferRenderingTarget = !disableImageReaderPlatformViews;
}
/**
* Detaches this platform views controller.
*
@ -972,9 +976,11 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega
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);
}

View File

@ -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<void*>(&GetIsSoftwareRendering),
},
{
.name = "nativeGetDisableImageReaderPlatformViews",
.signature = "()Z",
.fnPtr = reinterpret_cast<void*>(&GetDisableImageReaderPlatformViews),
},
{
.name = "nativeRegisterTexture",
.signature = "(JJLjava/lang/ref/"