@@ -39,62 +39,70 @@ constexpr char kSystemChannel[] = "flutter/system";
39
39
constexpr char kTypeKey [] = " type" ;
40
40
constexpr char kFontChange [] = " fontsChange" ;
41
41
42
- std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread (
42
+ std::future<std::unique_ptr<Shell::ShellHolder>>
43
+ Shell::CreateShellOnPlatformThread (
43
44
DartVMRef vm,
44
45
TaskRunners task_runners,
45
46
const WindowData window_data,
46
47
Settings settings,
47
48
fml::RefPtr<const DartSnapshot> isolate_snapshot,
48
49
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
49
50
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
51
+ std::promise<std::unique_ptr<Shell::ShellHolder>> shell_holder_promise;
52
+ auto shell_holder_future = shell_holder_promise.get_future ();
50
53
if (!task_runners.IsValid ()) {
51
54
FML_LOG (ERROR) << " Task runners to run the shell were invalid." ;
52
- return nullptr ;
55
+ std::unique_ptr<Shell::ShellHolder> empty;
56
+ shell_holder_promise.set_value (std::move (empty));
57
+ return shell_holder_future;
53
58
}
54
59
55
60
auto shell =
56
61
std::unique_ptr<Shell>(new Shell (std::move (vm), task_runners, settings));
57
62
58
63
// Create the rasterizer on the raster thread.
59
- std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise;
60
- auto rasterizer_future = rasterizer_promise.get_future ();
61
- std::promise<fml::WeakPtr<SnapshotDelegate>> snapshot_delegate_promise;
62
- auto snapshot_delegate_future = snapshot_delegate_promise.get_future ();
64
+ auto rasterizer_promise =
65
+ std::make_shared<std::promise<std::unique_ptr<Rasterizer>>>();
66
+ auto snapshot_delegate_promise =
67
+ std::make_shared<std::promise<fml::WeakPtr<SnapshotDelegate>>>();
68
+
63
69
fml::TaskRunner::RunNowOrPostTask (
64
- task_runners.GetRasterTaskRunner (), [&rasterizer_promise, //
65
- & snapshot_delegate_promise,
66
- on_create_rasterizer, //
67
- shell = shell. get () //
68
- ]() {
70
+ task_runners.GetRasterTaskRunner (),
71
+ [rasterizer_promise, snapshot_delegate_promise,
72
+ on_create_rasterizer = std::move ( on_create_rasterizer) , //
73
+ shell = shell. get () //
74
+ ]() mutable {
69
75
TRACE_EVENT0 (" flutter" , " ShellSetupGPUSubsystem" );
70
76
std::unique_ptr<Rasterizer> rasterizer (on_create_rasterizer (*shell));
71
- snapshot_delegate_promise. set_value (rasterizer->GetSnapshotDelegate ());
72
- rasterizer_promise. set_value (std::move (rasterizer));
77
+ snapshot_delegate_promise-> set_value (rasterizer->GetSnapshotDelegate ());
78
+ rasterizer_promise-> set_value (std::move (rasterizer));
73
79
});
74
80
75
81
// Create the platform view on the platform thread (this thread).
76
82
auto platform_view = on_create_platform_view (*shell.get ());
77
83
if (!platform_view || !platform_view->GetWeakPtr ()) {
78
- return nullptr ;
84
+ std::unique_ptr<Shell::ShellHolder> empty;
85
+ shell_holder_promise.set_value (std::move (empty));
86
+ return shell_holder_future;
79
87
}
80
88
81
89
// Ask the platform view for the vsync waiter. This will be used by the engine
82
90
// to create the animator.
83
91
auto vsync_waiter = platform_view->CreateVSyncWaiter ();
84
92
if (!vsync_waiter) {
85
- return nullptr ;
93
+ std::unique_ptr<Shell::ShellHolder> empty;
94
+ shell_holder_promise.set_value (std::move (empty));
95
+ return shell_holder_future;
86
96
}
87
97
88
98
// Create the IO manager on the IO thread. The IO manager must be initialized
89
99
// first because it has state that the other subsystems depend on. It must
90
100
// first be booted and the necessary references obtained to initialize the
91
101
// other subsystems.
92
- std::promise<std::unique_ptr<ShellIOManager>> io_manager_promise;
93
- auto io_manager_future = io_manager_promise.get_future ();
94
- std::promise<fml::WeakPtr<ShellIOManager>> weak_io_manager_promise;
95
- auto weak_io_manager_future = weak_io_manager_promise.get_future ();
96
- std::promise<fml::RefPtr<SkiaUnrefQueue>> unref_queue_promise;
97
- auto unref_queue_future = unref_queue_promise.get_future ();
102
+ auto io_manager_promise =
103
+ std::make_shared<std::promise<std::unique_ptr<ShellIOManager>>>();
104
+ auto weak_io_manager_promise =
105
+ std::make_shared<std::promise<fml::WeakPtr<ShellIOManager>>>();
98
106
auto io_task_runner = shell->GetTaskRunners ().GetIOTaskRunner ();
99
107
100
108
// TODO(gw280): The WeakPtr here asserts that we are derefing it on the
@@ -105,73 +113,72 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
105
113
// https://github.com/flutter/flutter/issues/42948
106
114
fml::TaskRunner::RunNowOrPostTask (
107
115
io_task_runner,
108
- [&io_manager_promise, //
109
- &weak_io_manager_promise, //
110
- &unref_queue_promise, //
111
- platform_view = platform_view->GetWeakPtr (), //
112
- io_task_runner, //
116
+ [io_task_runner,
117
+ io_manager_promise, //
118
+ weak_io_manager_promise,
119
+ weak_platform_view = platform_view->GetWeakPtr (), //
113
120
is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch () //
114
- ]() {
121
+ ]() mutable {
115
122
TRACE_EVENT0 (" flutter" , " ShellSetupIOSubsystem" );
116
123
auto io_manager = std::make_unique<ShellIOManager>(
117
- platform_view .getUnsafe ()->CreateResourceContext (),
124
+ weak_platform_view .getUnsafe ()->CreateResourceContext (),
118
125
is_backgrounded_sync_switch, io_task_runner);
119
- weak_io_manager_promise.set_value (io_manager->GetWeakPtr ());
120
- unref_queue_promise.set_value (io_manager->GetSkiaUnrefQueue ());
121
- io_manager_promise.set_value (std::move (io_manager));
126
+ weak_io_manager_promise->set_value (io_manager->GetWeakPtr ());
127
+ io_manager_promise->set_value (std::move (io_manager));
122
128
});
123
129
124
130
// Send dispatcher_maker to the engine constructor because shell won't have
125
131
// platform_view set until Shell::Setup is called later.
126
132
auto dispatcher_maker = platform_view->GetDispatcherMaker ();
127
133
128
134
// Create the engine on the UI thread.
129
- std::promise<std::unique_ptr<Engine>> engine_promise;
130
- auto engine_future = engine_promise.get_future ();
131
135
fml::TaskRunner::RunNowOrPostTask (
132
136
shell->GetTaskRunners ().GetUITaskRunner (),
133
- fml::MakeCopyable ([&engine_promise, //
134
- shell = shell.get (), //
135
- &dispatcher_maker, //
136
- &window_data, //
137
+ fml::MakeCopyable ([shell = std::move (shell), //
138
+ shell_holder_promise = std::move (shell_holder_promise),
139
+ platform_view = std::move (platform_view),
140
+ dispatcher_in = std::move (dispatcher_maker), //
141
+ window_data = std::move (window_data), //
137
142
isolate_snapshot = std::move (isolate_snapshot), //
138
143
vsync_waiter = std::move (vsync_waiter), //
139
- &weak_io_manager_future, //
140
- &snapshot_delegate_future, //
141
- &unref_queue_future //
142
- ]() mutable {
144
+ io_manager_promise, //
145
+ rasterizer_promise, //
146
+ weak_io_manager_promise, //
147
+ snapshot_delegate_promise ]() mutable {
143
148
TRACE_EVENT0 (" flutter" , " ShellSetupUISubsystem" );
144
149
const auto & task_runners = shell->GetTaskRunners ();
145
150
146
- // The animator is owned by the UI thread but it gets its vsync pulses
147
- // from the platform.
151
+ // The animator is owned by the UI thread but it gets its vsync
152
+ // pulses from the platform.
148
153
auto animator = std::make_unique<Animator>(*shell, task_runners,
149
154
std::move (vsync_waiter));
150
155
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
- ));
156
+ // wait params(io、gpu task end)
157
+ auto rasterizer = rasterizer_promise->get_future ().get ();
158
+ auto snapshot_delegate = snapshot_delegate_promise->get_future ().get ();
159
+ auto io_manager = io_manager_promise->get_future ().get ();
160
+ auto weak_io_manager = weak_io_manager_promise->get_future ().get ();
161
+
162
+ auto unref_queue = io_manager->GetSkiaUnrefQueue ();
163
+
164
+ auto engine_ref =
165
+ std::make_unique<Engine>(*(shell.get ()), //
166
+ dispatcher_in, //
167
+ *shell->GetDartVM (), //
168
+ std::move (isolate_snapshot), //
169
+ task_runners, //
170
+ window_data, //
171
+ shell->GetSettings (), //
172
+ std::move (animator), //
173
+ std::move (weak_io_manager), //
174
+ std::move (unref_queue), //
175
+ std::move (snapshot_delegate) //
176
+ );
177
+ shell_holder_promise.set_value (std::make_unique<Shell::ShellHolder>(
178
+ std::move (shell), std::move (platform_view), std::move (engine_ref),
179
+ std::move (rasterizer), std::move (io_manager)));
164
180
}));
165
-
166
- if (!shell->Setup (std::move (platform_view), //
167
- engine_future.get (), //
168
- rasterizer_future.get (), //
169
- io_manager_future.get ()) //
170
- ) {
171
- return nullptr ;
172
- }
173
-
174
- return shell;
181
+ return shell_holder_future;
175
182
}
176
183
177
184
static void Tokenize (const std::string& input,
@@ -249,6 +256,21 @@ std::unique_ptr<Shell> Shell::Create(
249
256
);
250
257
}
251
258
259
+ std::future<std::unique_ptr<Shell::ShellHolder>> Shell::CreateShellHolder (
260
+ std::unique_ptr<ShellCreateParams> params) {
261
+ PerformInitializationTasks (params->settings );
262
+ PersistentCache::SetCacheSkSL (params->settings .cache_sksl );
263
+ TRACE_EVENT0 (" flutter" , " Shell::Create" );
264
+ auto vm = DartVMRef::Create (params->settings );
265
+ FML_CHECK (vm) << " Must be able to initialize the VM." ;
266
+ auto vm_data = vm->GetVMData ();
267
+ return Shell::initShellEnv (
268
+ std::move (params->task_runners ), std::move (params->window_data ),
269
+ std::move (params->settings ), vm_data->GetIsolateSnapshot (),
270
+ std::move (params->on_create_platform_view ),
271
+ std::move (params->on_create_rasterizer ), std::move (vm));
272
+ }
273
+
252
274
std::unique_ptr<Shell> Shell::Create (
253
275
TaskRunners task_runners,
254
276
const WindowData window_data,
@@ -283,42 +305,66 @@ std::unique_ptr<Shell> Shell::Create(
283
305
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
284
306
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
285
307
DartVMRef vm) {
308
+ auto shell_holder_future = Shell::initShellEnv (
309
+ std::move (task_runners), window_data, settings,
310
+ std::move (isolate_snapshot), std::move (on_create_platform_view),
311
+ std::move (on_create_rasterizer), std::move (vm));
312
+ auto shell_holder = shell_holder_future.get ();
313
+ if (!shell_holder) {
314
+ return nullptr ;
315
+ }
316
+ return shell_holder->makeShell ();
317
+ }
318
+
319
+ std::future<std::unique_ptr<Shell::ShellHolder>> Shell::initShellEnv (
320
+ TaskRunners task_runners,
321
+ const WindowData window_data,
322
+ Settings settings,
323
+ fml::RefPtr<const DartSnapshot> isolate_snapshot,
324
+ const Shell::CreateCallback<PlatformView>& on_create_platform_view,
325
+ const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
326
+ DartVMRef vm) {
286
327
PerformInitializationTasks (settings);
287
328
PersistentCache::SetCacheSkSL (settings.cache_sksl );
288
329
289
330
TRACE_EVENT0 (" flutter" , " Shell::CreateWithSnapshots" );
290
331
291
332
if (!task_runners.IsValid () || !on_create_platform_view ||
292
333
!on_create_rasterizer) {
293
- return nullptr ;
334
+ std::promise<std::unique_ptr<Shell::ShellHolder>> shell_holder_promise;
335
+ std::unique_ptr<Shell::ShellHolder> empty;
336
+ shell_holder_promise.set_value (std::move (empty));
337
+ return shell_holder_promise.get_future ();
294
338
}
295
339
296
340
fml::AutoResetWaitableEvent latch;
297
- std::unique_ptr<Shell> shell;
341
+ std::future<std::unique_ptr<Shell::ShellHolder>> shell_holder_future;
342
+
298
343
fml::TaskRunner::RunNowOrPostTask (
299
344
task_runners.GetPlatformTaskRunner (),
300
- fml::MakeCopyable ([&latch, //
345
+ fml::MakeCopyable ([&latch,
301
346
vm = std::move (vm), //
302
- &shell, //
347
+ &shell_holder_future, //
303
348
task_runners = std::move (task_runners), //
304
349
window_data, //
305
350
settings, //
306
351
isolate_snapshot = std::move (isolate_snapshot), //
307
352
on_create_platform_view, //
308
353
on_create_rasterizer //
309
354
]() mutable {
310
- shell = CreateShellOnPlatformThread (std::move (vm),
311
- std::move (task_runners), //
312
- window_data, //
313
- settings, //
314
- std::move (isolate_snapshot), //
315
- on_create_platform_view, //
316
- on_create_rasterizer //
317
- );
355
+ shell_holder_future =
356
+ CreateShellOnPlatformThread (std::move (vm),
357
+ std::move (task_runners), //
358
+ window_data, //
359
+ settings, //
360
+ std::move (isolate_snapshot), //
361
+ on_create_platform_view, //
362
+ on_create_rasterizer //
363
+ );
318
364
latch.Signal ();
319
365
}));
320
366
latch.Wait ();
321
- return shell ;
367
+ return shell_holder_future ;
322
368
}
323
369
324
370
Shell::Shell (DartVMRef vm, TaskRunners task_runners, Settings settings)
@@ -1511,4 +1557,27 @@ std::shared_ptr<fml::SyncSwitch> Shell::GetIsGpuDisabledSyncSwitch() const {
1511
1557
return is_gpu_disabled_sync_switch_;
1512
1558
}
1513
1559
1560
+ std::unique_ptr<Shell> Shell::ShellHolder::makeShell () {
1561
+ if (is_consumed_) {
1562
+ return nullptr ;
1563
+ }
1564
+ is_consumed_ = true ;
1565
+ fml::AutoResetWaitableEvent latch;
1566
+ std::unique_ptr<Shell> shell_res;
1567
+
1568
+ // make sure `shell.setup` executed on platformthread
1569
+ fml::TaskRunner::RunNowOrPostTask (
1570
+ shell_->GetTaskRunners ().GetPlatformTaskRunner (),
1571
+ fml::MakeCopyable ([this , &latch, &shell_res]() mutable {
1572
+ if (this ->shell_ ->Setup (
1573
+ std::move (this ->platform_view_ ), std::move (this ->engine_ ),
1574
+ std::move (this ->rasterizer_ ), std::move (this ->io_manager_ ))) {
1575
+ shell_res = std::move (this ->shell_ );
1576
+ }
1577
+ latch.Signal ();
1578
+ }));
1579
+ latch.Wait ();
1580
+ return shell_res;
1581
+ }
1582
+
1514
1583
} // namespace flutter
0 commit comments