Skip to content

Commit

Permalink
Android platform view static thread merging (flutter#19242)
Browse files Browse the repository at this point in the history
  • Loading branch information
Chris Yang authored Jun 24, 2020
1 parent 24d2143 commit a11c398
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 18 deletions.
9 changes: 9 additions & 0 deletions common/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,15 @@ struct Settings {
/// to log a timeline event that tracks the latency of engine startup.
std::chrono::microseconds engine_start_timestamp = {};

/// Whether the application claims that it uses the android embedded view for
/// platform views.
///
/// A `true` value will result the raster task runner always run on the
/// platform thread.
// TODO(cyanlaz): Remove this when dynamic thread merging is done.
// https://github.com/flutter/flutter/issues/59930
bool use_embedded_view = false;

std::string ToString() const;
};

Expand Down
3 changes: 3 additions & 0 deletions shell/common/switches.cc
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ Settings SettingsFromCommandLine(const fml::CommandLine& command_line) {
: "127.0.0.1";
}

settings.use_embedded_view =
command_line.HasOption(FlagForSwitch(Switch::UseEmbeddedView));

// Set Observatory Port
if (command_line.HasOption(FlagForSwitch(Switch::DeviceObservatoryPort))) {
if (!GetSwitchValue(command_line, Switch::DeviceObservatoryPort,
Expand Down
9 changes: 9 additions & 0 deletions shell/common/switches.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,15 @@ DEF_SWITCH(
"Uses separate threads for the platform, UI, GPU and IO task runners. "
"By default, a single thread is used for all task runners. Only available "
"in the flutter_tester.")
// TODO(cyanlaz): Remove this when dynamic thread merging is done.
// https://github.com/flutter/flutter/issues/59930
DEF_SWITCH(UseEmbeddedView,
"use-embedded-view",
"Whether an android application uses embedded views."
"This is a temporary flag to make the raster task runner runs on "
"the platform thread."
"This flag should be removed once the dynamic thread merging is "
"enabled on android.")
DEF_SWITCHES_END

void PrintUsage(const std::string& executable_name);
Expand Down
61 changes: 45 additions & 16 deletions shell/platform/android/android_shell_holder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ static WindowData GetDefaultWindowData() {
return window_data;
}

bool AndroidShellHolder::use_embedded_view;

AndroidShellHolder::AndroidShellHolder(
flutter::Settings settings,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
Expand Down Expand Up @@ -101,28 +103,55 @@ AndroidShellHolder::AndroidShellHolder(
ui_runner = thread_host_.ui_thread->GetTaskRunner();
io_runner = thread_host_.io_thread->GetTaskRunner();
}
flutter::TaskRunners task_runners(thread_label, // label
platform_runner, // platform
gpu_runner, // raster
ui_runner, // ui
io_runner // io
);

shell_ =
Shell::Create(task_runners, // task runners
GetDefaultWindowData(), // window data
settings_, // settings
on_create_platform_view, // platform view create callback
on_create_rasterizer // rasterizer create callback
);
if (settings.use_embedded_view) {
use_embedded_view = true;
// Embedded views requires the gpu and the platform views to be the same.
// The plan is to eventually dynamically merge the threads when there's a
// platform view in the layer tree.
// For now we use a fixed thread configuration with the same thread used as
// the gpu and platform task runner.
// TODO(amirh/chinmaygarde): remove this, and dynamically change the thread
// configuration. https://github.com/flutter/flutter/issues/23975
// https://github.com/flutter/flutter/issues/59930
flutter::TaskRunners task_runners(thread_label, // label
platform_runner, // platform
platform_runner, // raster
ui_runner, // ui
io_runner // io
);

shell_ =
Shell::Create(task_runners, // task runners
GetDefaultWindowData(), // window data
settings_, // settings
on_create_platform_view, // platform view create callback
on_create_rasterizer // rasterizer create callback
);
} else {
use_embedded_view = false;
flutter::TaskRunners task_runners(thread_label, // label
platform_runner, // platform
gpu_runner, // raster
ui_runner, // ui
io_runner // io
);

shell_ =
Shell::Create(task_runners, // task runners
GetDefaultWindowData(), // window data
settings_, // settings
on_create_platform_view, // platform view create callback
on_create_rasterizer // rasterizer create callback
);
}

platform_view_ = weak_platform_view;
FML_DCHECK(platform_view_);

is_valid_ = shell_ != nullptr;

if (is_valid_) {
task_runners.GetRasterTaskRunner()->PostTask([]() {
shell_->GetTaskRunners().GetRasterTaskRunner()->PostTask([]() {
// Android describes -8 as "most important display threads, for
// compositing the screen and retrieving input events". Conservatively
// set the raster thread to slightly lower priority than it.
Expand All @@ -134,7 +163,7 @@ AndroidShellHolder::AndroidShellHolder(
}
}
});
task_runners.GetUITaskRunner()->PostTask([]() {
shell_->GetTaskRunners().GetUITaskRunner()->PostTask([]() {
if (::setpriority(PRIO_PROCESS, gettid(), -1) != 0) {
FML_LOG(ERROR) << "Failed to set UI task runner priority";
}
Expand Down
8 changes: 8 additions & 0 deletions shell/platform/android/android_shell_holder.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ namespace flutter {

class AndroidShellHolder {
public:
// Whether the application sets to use embedded_view view
// `io.flutter.embedded_views_preview` flag. This can be static because it is
// determined by the application and it is safe when there are multiple
// `AndroidSurface`s.
// TODO(cyanglaz): remove this when dynamic thread merging is enabled on
// android. https://github.com/flutter/flutter/issues/59930
static bool use_embedded_view;

AndroidShellHolder(flutter::Settings settings,
std::shared_ptr<PlatformViewAndroidJNI> jni_facade,
bool is_background_view);
Expand Down
4 changes: 4 additions & 0 deletions shell/platform/android/android_surface_gl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "flutter/fml/logging.h"
#include "flutter/fml/memory/ref_ptr.h"
#include "flutter/shell/platform/android/android_shell_holder.h"

namespace flutter {

Expand Down Expand Up @@ -122,6 +123,9 @@ intptr_t AndroidSurfaceGL::GLContextFBO() const {

// |GPUSurfaceGLDelegate|
ExternalViewEmbedder* AndroidSurfaceGL::GetExternalViewEmbedder() {
if (!AndroidShellHolder::use_embedded_view) {
return nullptr;
}
return external_view_embedder_.get();
}

Expand Down
4 changes: 4 additions & 0 deletions shell/platform/android/android_surface_software.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "flutter/fml/platform/android/jni_weak_ref.h"
#include "flutter/fml/platform/android/scoped_java_ref.h"
#include "flutter/fml/trace_event.h"
#include "flutter/shell/platform/android/android_shell_holder.h"
#include "flutter/shell/platform/android/jni/platform_view_android_jni.h"

namespace flutter {
Expand Down Expand Up @@ -145,6 +146,9 @@ bool AndroidSurfaceSoftware::PresentBackingStore(

// |GPUSurfaceSoftwareDelegate|
ExternalViewEmbedder* AndroidSurfaceSoftware::GetExternalViewEmbedder() {
if (!AndroidShellHolder::use_embedded_view) {
return nullptr;
}
return external_view_embedder_.get();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,6 @@ public void ensureInitializationComplete(
+ applicationInfo.nativeLibraryDir
+ File.separator
+ DEFAULT_LIBRARY);

if (args != null) {
Collections.addAll(shellArgs, args);
}
Expand Down Expand Up @@ -234,6 +233,17 @@ public void ensureInitializationComplete(
}

long initTimeMillis = SystemClock.uptimeMillis() - initStartTimestampMillis;

// TODO(cyanlaz): Remove this when dynamic thread merging is done.
// https://github.com/flutter/flutter/issues/59930
Bundle bundle = applicationInfo.metaData;
if (bundle != null) {
boolean use_embedded_view = bundle.getBoolean("io.flutter.embedded_views_preview");
if (use_embedded_view) {
shellArgs.add("--use-embedded-view");
}
}

FlutterJNI.nativeInit(
applicationContext,
shellArgs.toArray(new String[0]),
Expand Down
1 change: 0 additions & 1 deletion shell/platform/android/platform_view_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,6 @@ class PlatformViewAndroid final : public PlatformView {

FML_DISALLOW_COPY_AND_ASSIGN(PlatformViewAndroid);
};

} // namespace flutter

#endif // SHELL_PLATFORM_ANDROID_PLATFORM_VIEW_ANDROID_H_
3 changes: 3 additions & 0 deletions testing/scenario_app/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="io.flutter.embedded_views_preview"
android:value="true" />
</application>

<uses-permission android:name="android.permission.INTERNET" />
Expand Down

0 comments on commit a11c398

Please sign in to comment.