Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit d1aabd7

Browse files
author
peihan.cph
committed
peformance improvement : reduce engine init time 50%off at least
- supprot android && ios - use new api like asyncrun() to reduce mainthead block time - add code comment - add testcase for async init method - clang-format
1 parent 4196207 commit d1aabd7

File tree

13 files changed

+278
-45
lines changed

13 files changed

+278
-45
lines changed

shell/common/shell.cc

Lines changed: 76 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,24 @@ constexpr char kSystemChannel[] = "flutter/system";
3939
constexpr char kTypeKey[] = "type";
4040
constexpr char kFontChange[] = "fontsChange";
4141

42+
void Shell::OnEngineInit(std::unique_ptr<Engine> engine) {
43+
Setup(std::move(platform_view_), //
44+
std::move(engine), //
45+
std::move(rasterizer_), //
46+
std::move(io_manager_)); //
47+
}
48+
49+
void Shell::BindParams(std::unique_ptr<PlatformView> platform_view,
50+
std::unique_ptr<Rasterizer> rasterizer,
51+
std::unique_ptr<ShellIOManager> io_manager) {
52+
platform_view_ = std::move(platform_view);
53+
// engine_ = std::move(engine);
54+
rasterizer_ = std::move(rasterizer);
55+
io_manager_ = std::move(io_manager);
56+
}
57+
4258
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
59+
fml::closure& async_init_callback,
4360
DartVMRef vm,
4461
TaskRunners task_runners,
4562
const WindowData window_data,
@@ -126,13 +143,21 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
126143
auto dispatcher_maker = platform_view->GetDispatcherMaker();
127144

128145
// Create the engine on the UI thread.
146+
bool do_async_init = false;
147+
if (async_init_callback) {
148+
do_async_init = true;
149+
}
129150
std::promise<std::unique_ptr<Engine>> engine_promise;
130151
auto engine_future = engine_promise.get_future();
152+
std::promise<void> async_init_promise;
153+
std::future<void> async_init_future = async_init_promise.get_future();
131154
fml::TaskRunner::RunNowOrPostTask(
132155
shell->GetTaskRunners().GetUITaskRunner(),
133156
fml::MakeCopyable([&engine_promise, //
134157
shell = shell.get(), //
135-
&dispatcher_maker, //
158+
&async_init_promise, //
159+
callback_in = std::move(async_init_callback), //
160+
dispatcher_in = std::move(dispatcher_maker), //
136161
&window_data, //
137162
isolate_snapshot = std::move(isolate_snapshot), //
138163
vsync_waiter = std::move(vsync_waiter), //
@@ -148,21 +173,47 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
148173
auto animator = std::make_unique<Animator>(*shell, task_runners,
149174
std::move(vsync_waiter));
150175

151-
engine_promise.set_value(std::make_unique<Engine>(
152-
*shell, //
153-
dispatcher_maker, //
154-
*shell->GetDartVM(), //
155-
std::move(isolate_snapshot), //
156-
task_runners, //
157-
window_data, //
158-
shell->GetSettings(), //
159-
std::move(animator), //
160-
weak_io_manager_future.get(), //
161-
unref_queue_future.get(), //
162-
snapshot_delegate_future.get() //
163-
));
176+
// wait params
177+
auto snapshot_delegate = snapshot_delegate_future.get();
178+
auto unref_queue = unref_queue_future.get();
179+
auto io_manager = weak_io_manager_future.get();
180+
if (callback_in) {
181+
async_init_promise.set_value();
182+
}
183+
auto engine_ref =
184+
std::make_unique<Engine>(*shell, //
185+
dispatcher_in, //
186+
*shell->GetDartVM(), //
187+
std::move(isolate_snapshot), //
188+
task_runners, //
189+
window_data, //
190+
shell->GetSettings(), //
191+
std::move(animator), //
192+
std::move(io_manager), //
193+
std::move(unref_queue), //
194+
std::move(snapshot_delegate) //
195+
);
196+
197+
if (callback_in) {
198+
fml::TaskRunner::RunNowOrPostTask(
199+
shell->GetTaskRunners().GetPlatformTaskRunner(),
200+
fml::MakeCopyable(
201+
[async_init_callback_func = std::move(callback_in),
202+
shell_inner = shell,
203+
engine_inner = std::move(engine_ref)]() mutable {
204+
shell_inner->OnEngineInit(std::move(engine_inner));
205+
async_init_callback_func();
206+
}));
207+
} else {
208+
engine_promise.set_value(std::move(engine_ref));
209+
}
164210
}));
165-
211+
if (do_async_init) {
212+
async_init_future.get();
213+
shell->BindParams(std::move(platform_view), rasterizer_future.get(),
214+
io_manager_future.get());
215+
return shell;
216+
}
166217
if (!shell->Setup(std::move(platform_view), //
167218
engine_future.get(), //
168219
rasterizer_future.get(), //
@@ -240,11 +291,13 @@ static void PerformInitializationTasks(const Settings& settings) {
240291
}
241292

242293
std::unique_ptr<Shell> Shell::Create(
294+
fml::closure& async_init_callback,
243295
TaskRunners task_runners,
244296
Settings settings,
245297
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
246298
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
247-
return Shell::Create(std::move(task_runners), //
299+
return Shell::Create(async_init_callback, //
300+
std::move(task_runners), //
248301
WindowData{/* default window data */}, //
249302
std::move(settings), //
250303
std::move(on_create_platform_view), //
@@ -253,6 +306,7 @@ std::unique_ptr<Shell> Shell::Create(
253306
}
254307

255308
std::unique_ptr<Shell> Shell::Create(
309+
fml::closure& async_init_callback,
256310
TaskRunners task_runners,
257311
const WindowData window_data,
258312
Settings settings,
@@ -268,7 +322,8 @@ std::unique_ptr<Shell> Shell::Create(
268322

269323
auto vm_data = vm->GetVMData();
270324

271-
return Shell::Create(std::move(task_runners), //
325+
return Shell::Create(async_init_callback,
326+
std::move(task_runners), //
272327
std::move(window_data), //
273328
std::move(settings), //
274329
vm_data->GetIsolateSnapshot(), // isolate snapshot
@@ -279,6 +334,7 @@ std::unique_ptr<Shell> Shell::Create(
279334
}
280335

281336
std::unique_ptr<Shell> Shell::Create(
337+
fml::closure& async_init_callback,
282338
TaskRunners task_runners,
283339
const WindowData window_data,
284340
Settings settings,
@@ -303,14 +359,16 @@ std::unique_ptr<Shell> Shell::Create(
303359
fml::MakeCopyable([&latch, //
304360
vm = std::move(vm), //
305361
&shell, //
362+
&async_init_callback, //
306363
task_runners = std::move(task_runners), //
307364
window_data, //
308365
settings, //
309366
isolate_snapshot = std::move(isolate_snapshot), //
310367
on_create_platform_view, //
311368
on_create_rasterizer //
312369
]() mutable {
313-
shell = CreateShellOnPlatformThread(std::move(vm),
370+
shell = CreateShellOnPlatformThread(async_init_callback, //
371+
std::move(vm), //
314372
std::move(task_runners), //
315373
window_data, //
316374
settings, //

shell/common/shell.h

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,9 @@ class Shell final : public PlatformView::Delegate,
101101
/// If this is the first instance of a shell in the process, this
102102
/// call also bootstraps the Dart VM.
103103
///
104+
/// @param[in] async_init_callback if null,init sync.
105+
/// else init async.and called when
106+
/// asyncInit end
104107
/// @param[in] task_runners The task runners
105108
/// @param[in] settings The settings
106109
/// @param[in] on_create_platform_view The callback that must return a
@@ -121,6 +124,7 @@ class Shell final : public PlatformView::Delegate,
121124
/// immediately after getting a pointer to it.
122125
///
123126
static std::unique_ptr<Shell> Create(
127+
fml::closure& async_init_callback,
124128
TaskRunners task_runners,
125129
Settings settings,
126130
const CreateCallback<PlatformView>& on_create_platform_view,
@@ -134,7 +138,9 @@ class Shell final : public PlatformView::Delegate,
134138
/// allows for specification of window data. If this is the first
135139
/// instance of a shell in the process, this call also bootstraps
136140
/// the Dart VM.
137-
///
141+
/// @param[in] async_init_callback if null,init sync.
142+
/// else init async.and called when
143+
/// asyncInit end
138144
/// @param[in] task_runners The task runners
139145
/// @param[in] window_data The default data for setting up
140146
/// ui.Window that attached to this
@@ -158,6 +164,7 @@ class Shell final : public PlatformView::Delegate,
158164
/// immediately after getting a pointer to it.
159165
///
160166
static std::unique_ptr<Shell> Create(
167+
fml::closure& async_init_callback,
161168
TaskRunners task_runners,
162169
const WindowData window_data,
163170
Settings settings,
@@ -172,7 +179,9 @@ class Shell final : public PlatformView::Delegate,
172179
/// allows for the specification of an isolate snapshot that
173180
/// cannot be adequately described in the settings. This call also
174181
/// requires the specification of a running VM instance.
175-
///
182+
/// @param[in] async_init_callback if null,init sync.
183+
/// else init async.and called when
184+
/// asyncInit end
176185
/// @param[in] task_runners The task runners
177186
/// @param[in] window_data The default data for setting up
178187
/// ui.Window that attached to this
@@ -200,6 +209,7 @@ class Shell final : public PlatformView::Delegate,
200209
/// immediately after getting a pointer to it.
201210
///
202211
static std::unique_ptr<Shell> Create(
212+
fml::closure& async_init_callback,
203213
TaskRunners task_runners,
204214
const WindowData window_data,
205215
Settings settings,
@@ -419,6 +429,7 @@ class Shell final : public PlatformView::Delegate,
419429
Shell(DartVMRef vm, TaskRunners task_runners, Settings settings);
420430

421431
static std::unique_ptr<Shell> CreateShellOnPlatformThread(
432+
fml::closure& async_init_callback,
422433
DartVMRef vm,
423434
TaskRunners task_runners,
424435
const WindowData window_data,
@@ -432,6 +443,14 @@ class Shell final : public PlatformView::Delegate,
432443
std::unique_ptr<Rasterizer> rasterizer,
433444
std::unique_ptr<ShellIOManager> io_manager);
434445

446+
// called on asyncInit mode,set params
447+
void BindParams(std::unique_ptr<PlatformView> platform_view,
448+
std::unique_ptr<Rasterizer> rasterizer,
449+
std::unique_ptr<ShellIOManager> io_manager);
450+
451+
// called on asyncInit mode,setup env
452+
void OnEngineInit(std::unique_ptr<Engine> engine);
453+
435454
void ReportTimings();
436455

437456
// |PlatformView::Delegate|

shell/platform/android/android_shell_holder.cc

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "flutter/fml/message_loop.h"
1919
#include "flutter/shell/common/rasterizer.h"
2020
#include "flutter/shell/platform/android/platform_view_android.h"
21+
#include "flutter/shell/platform/android/platform_view_android_jni.h"
2122

2223
namespace flutter {
2324

@@ -30,7 +31,8 @@ static WindowData GetDefaultWindowData() {
3031
AndroidShellHolder::AndroidShellHolder(
3132
flutter::Settings settings,
3233
fml::jni::JavaObjectWeakGlobalRef java_object,
33-
bool is_background_view)
34+
bool is_background_view,
35+
bool init_async_mode)
3436
: settings_(std::move(settings)), java_object_(java_object) {
3537
static size_t shell_count = 1;
3638
auto thread_label = std::to_string(shell_count++);
@@ -106,9 +108,18 @@ AndroidShellHolder::AndroidShellHolder(
106108
ui_runner, // ui
107109
io_runner // io
108110
);
111+
fml::closure asyncInitCallback;
112+
if (init_async_mode) {
113+
asyncInitCallback = [java_object]() {
114+
JNIEnv* env = fml::jni::AttachCurrentThread();
115+
auto scoped_jni_obj = java_object.get(env);
116+
FlutterViewHandleEngineInit(env, scoped_jni_obj.obj());
117+
};
118+
}
109119

110120
shell_ =
111-
Shell::Create(task_runners, // task runners
121+
Shell::Create(asyncInitCallback, // callback
122+
task_runners, // task runners
112123
GetDefaultWindowData(), // window data
113124
settings_, // settings
114125
on_create_platform_view, // platform view create callback

shell/platform/android/android_shell_holder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ class AndroidShellHolder {
2323
public:
2424
AndroidShellHolder(flutter::Settings settings,
2525
fml::jni::JavaObjectWeakGlobalRef java_object,
26-
bool is_background_view);
26+
bool is_background_view,
27+
bool async_init);
2728

2829
~AndroidShellHolder();
2930

shell/platform/android/io/flutter/embedding/engine/FlutterEngine.java

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,13 @@ public void onPreEngineRestart() {
101101

102102
platformViewsController.onPreEngineRestart();
103103
}
104-
};
104+
// new api,called when engine init success for aync mode
105+
public void onEngineInit() {
106+
for (EngineLifecycleListener lifecycleListener : engineLifecycleListeners) {
107+
lifecycleListener.onEngineInit();
108+
}
109+
}
110+
};
105111

106112
/**
107113
* Constructs a new {@code FlutterEngine}.
@@ -200,12 +206,53 @@ public FlutterEngine(
200206
@NonNull PlatformViewsController platformViewsController,
201207
@Nullable String[] dartVmArgs,
202208
boolean automaticallyRegisterPlugins) {
209+
this (context,
210+
flutterLoader,
211+
flutterJNI,
212+
platformViewsController,
213+
dartVmArgs,
214+
automaticallyRegisterPlugins,
215+
null);
216+
}
217+
218+
/**
219+
* Same as {@link #FlutterEngine(Context, FlutterLoader, FlutterJNI)},
220+
* but init native env with async mode
221+
* {@code asyncInitListener} async init callback, called when async init finish
222+
*/
223+
public static FlutterEngine createEngineAndinitAsync(
224+
@NonNull Context context,
225+
@NonNull EngineLifecycleListener asyncInitListener){
226+
return new FlutterEngine(
227+
context,
228+
FlutterLoader.getInstance(),
229+
new FlutterJNI(),
230+
new PlatformViewsController(),
231+
null,
232+
true,
233+
asyncInitListener);
234+
}
235+
236+
/**
237+
* Fully configurable {@code FlutterEngine} constructor.
238+
* {@code asyncInitListener} if null,init native env sycnc,
239+
* if not null,will init native env async, and called when async init end
240+
*/
241+
public FlutterEngine(
242+
@NonNull Context context,
243+
@NonNull FlutterLoader flutterLoader,
244+
@NonNull FlutterJNI flutterJNI,
245+
@NonNull PlatformViewsController platformViewsController,
246+
@Nullable String[] dartVmArgs,
247+
boolean automaticallyRegisterPlugins,
248+
EngineLifecycleListener asyncInitListener) {
203249
this.flutterJNI = flutterJNI;
204250
flutterLoader.startInitialization(context.getApplicationContext());
205251
flutterLoader.ensureInitializationComplete(context, dartVmArgs);
206252

207253
flutterJNI.addEngineLifecycleListener(engineLifecycleListener);
208-
attachToJni();
254+
addEngineLifecycleListener(asyncInitListener);
255+
attachToJni(asyncInitListener != null);
209256

210257
this.dartExecutor = new DartExecutor(flutterJNI, context.getAssets());
211258
this.dartExecutor.onAttachedToJNI();
@@ -234,10 +281,10 @@ public FlutterEngine(
234281
}
235282
}
236283

237-
private void attachToJni() {
284+
private void attachToJni(boolean asyncInitMode) {
238285
Log.v(TAG, "Attaching to JNI.");
239286
// TODO(mattcarroll): update native call to not take in "isBackgroundView"
240-
flutterJNI.attachToNative(false);
287+
flutterJNI.attachToNative(false,asyncInitMode);
241288

242289
if (!isAttachedToJni()) {
243290
throw new RuntimeException("FlutterEngine failed to attach to its native Object reference.");
@@ -436,5 +483,7 @@ public ContentProviderControlSurface getContentProviderControlSurface() {
436483
public interface EngineLifecycleListener {
437484
/** Lifecycle callback invoked before a hot restart of the Flutter engine. */
438485
void onPreEngineRestart();
486+
/** Lifecycle callback invoked after flutter engine async init success .*/
487+
void onEngineInit();
439488
}
440489
}

0 commit comments

Comments
 (0)