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