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

Commit 74c0c2c

Browse files
committed
future: engine supprot create shell with aysnc mode
use promise/future op update doc
1 parent e5845af commit 74c0c2c

File tree

4 files changed

+403
-82
lines changed

4 files changed

+403
-82
lines changed

shell/common/shell.cc

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

42-
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
42+
void Shell::CreateShellOnPlatformThread(
43+
std::promise<std::unique_ptr<Shell::ShellHolder>> shell_holder_promise,
4344
DartVMRef vm,
4445
TaskRunners task_runners,
4546
const WindowData window_data,
4647
Settings settings,
4748
fml::RefPtr<const DartSnapshot> isolate_snapshot,
4849
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
4950
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
51+
FML_CHECK(task_runners.GetPlatformTaskRunner()->RunsTasksOnCurrentThread())
52+
<< "CreateShellOnPlatformThread() must run in platformThread!";
5053
if (!task_runners.IsValid()) {
5154
FML_LOG(ERROR) << "Task runners to run the shell were invalid.";
52-
return nullptr;
55+
shell_holder_promise.set_value(nullptr);
56+
return;
5357
}
5458

5559
auto shell =
5660
std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings));
5761

5862
// 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();
63+
auto rasterizer_promise =
64+
std::make_shared<std::promise<std::unique_ptr<Rasterizer>>>();
65+
auto snapshot_delegate_promise =
66+
std::make_shared<std::promise<fml::WeakPtr<SnapshotDelegate>>>();
67+
6368
fml::TaskRunner::RunNowOrPostTask(
64-
task_runners.GetRasterTaskRunner(), [&rasterizer_promise, //
65-
&snapshot_delegate_promise,
66-
on_create_rasterizer, //
67-
shell = shell.get() //
68-
]() {
69+
task_runners.GetRasterTaskRunner(),
70+
[rasterizer_promise, snapshot_delegate_promise,
71+
on_create_rasterizer, //
72+
shell = shell.get() //
73+
]() mutable {
6974
TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem");
7075
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));
76+
snapshot_delegate_promise->set_value(rasterizer->GetSnapshotDelegate());
77+
rasterizer_promise->set_value(std::move(rasterizer));
7378
});
7479

7580
// Create the platform view on the platform thread (this thread).
7681
auto platform_view = on_create_platform_view(*shell.get());
7782
if (!platform_view || !platform_view->GetWeakPtr()) {
78-
return nullptr;
83+
shell_holder_promise.set_value(nullptr);
84+
return;
7985
}
8086

8187
// Ask the platform view for the vsync waiter. This will be used by the engine
8288
// to create the animator.
8389
auto vsync_waiter = platform_view->CreateVSyncWaiter();
8490
if (!vsync_waiter) {
85-
return nullptr;
91+
shell_holder_promise.set_value(nullptr);
92+
return;
8693
}
8794

8895
// Create the IO manager on the IO thread. The IO manager must be initialized
8996
// first because it has state that the other subsystems depend on. It must
9097
// first be booted and the necessary references obtained to initialize the
9198
// 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();
99+
auto io_manager_promise =
100+
std::make_shared<std::promise<std::unique_ptr<ShellIOManager>>>();
101+
auto weak_io_manager_promise =
102+
std::make_shared<std::promise<fml::WeakPtr<ShellIOManager>>>();
98103
auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();
99104

100105
// TODO(gw280): The WeakPtr here asserts that we are derefing it on the
@@ -105,73 +110,70 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
105110
// https://github.com/flutter/flutter/issues/42948
106111
fml::TaskRunner::RunNowOrPostTask(
107112
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, //
113+
[io_task_runner, io_manager_promise, weak_io_manager_promise,
114+
weak_platform_view = platform_view->GetWeakPtr(), //
113115
is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch() //
114-
]() {
116+
]() mutable {
115117
TRACE_EVENT0("flutter", "ShellSetupIOSubsystem");
116118
auto io_manager = std::make_unique<ShellIOManager>(
117-
platform_view.getUnsafe()->CreateResourceContext(),
119+
weak_platform_view.getUnsafe()->CreateResourceContext(),
118120
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));
121+
weak_io_manager_promise->set_value(io_manager->GetWeakPtr());
122+
io_manager_promise->set_value(std::move(io_manager));
122123
});
123124

124125
// Send dispatcher_maker to the engine constructor because shell won't have
125126
// platform_view set until Shell::Setup is called later.
126127
auto dispatcher_maker = platform_view->GetDispatcherMaker();
127128

128129
// Create the engine on the UI thread.
129-
std::promise<std::unique_ptr<Engine>> engine_promise;
130-
auto engine_future = engine_promise.get_future();
131130
fml::TaskRunner::RunNowOrPostTask(
132131
shell->GetTaskRunners().GetUITaskRunner(),
133-
fml::MakeCopyable([&engine_promise, //
134-
shell = shell.get(), //
135-
&dispatcher_maker, //
136-
&window_data, //
132+
fml::MakeCopyable([shell = std::move(shell), //
133+
shell_holder_promise = std::move(shell_holder_promise),
134+
platform_view = std::move(platform_view),
135+
dispatcher_in = std::move(dispatcher_maker), //
136+
window_data = std::move(window_data), //
137137
isolate_snapshot = std::move(isolate_snapshot), //
138138
vsync_waiter = std::move(vsync_waiter), //
139-
&weak_io_manager_future, //
140-
&snapshot_delegate_future, //
141-
&unref_queue_future //
142-
]() mutable {
139+
io_manager_promise, //
140+
rasterizer_promise, //
141+
weak_io_manager_promise, //
142+
snapshot_delegate_promise]() mutable {
143143
TRACE_EVENT0("flutter", "ShellSetupUISubsystem");
144144
const auto& task_runners = shell->GetTaskRunners();
145145

146-
// The animator is owned by the UI thread but it gets its vsync pulses
147-
// from the platform.
146+
// The animator is owned by the UI thread but it gets its vsync
147+
// pulses from the platform.
148148
auto animator = std::make_unique<Animator>(*shell, task_runners,
149149
std::move(vsync_waiter));
150150

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-
));
151+
// wait params(io、gpu task end)
152+
auto rasterizer = rasterizer_promise->get_future().get();
153+
auto snapshot_delegate = snapshot_delegate_promise->get_future().get();
154+
auto io_manager = io_manager_promise->get_future().get();
155+
auto weak_io_manager = weak_io_manager_promise->get_future().get();
156+
157+
auto unref_queue = io_manager->GetSkiaUnrefQueue();
158+
159+
auto engine_ref =
160+
std::make_unique<Engine>(*(shell.get()), //
161+
dispatcher_in, //
162+
*shell->GetDartVM(), //
163+
std::move(isolate_snapshot), //
164+
task_runners, //
165+
window_data, //
166+
shell->GetSettings(), //
167+
std::move(animator), //
168+
std::move(weak_io_manager), //
169+
std::move(unref_queue), //
170+
std::move(snapshot_delegate) //
171+
);
172+
shell_holder_promise.set_value(std::make_unique<Shell::ShellHolder>(
173+
std::move(shell), std::move(platform_view), std::move(engine_ref),
174+
std::move(rasterizer), std::move(io_manager)));
164175
}));
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;
176+
return;
175177
}
176178

177179
static void Tokenize(const std::string& input,
@@ -249,6 +251,21 @@ std::unique_ptr<Shell> Shell::Create(
249251
);
250252
}
251253

254+
std::future<std::unique_ptr<Shell::ShellHolder>> Shell::CreateShellHolder(
255+
std::unique_ptr<ShellCreateParams> params) {
256+
PerformInitializationTasks(params->settings);
257+
PersistentCache::SetCacheSkSL(params->settings.cache_sksl);
258+
TRACE_EVENT0("flutter", "Shell::Create");
259+
auto vm = DartVMRef::Create(params->settings);
260+
FML_CHECK(vm) << "Must be able to initialize the VM.";
261+
auto vm_data = vm->GetVMData();
262+
return Shell::InitShellEnv(
263+
std::move(params->task_runners), std::move(params->window_data),
264+
std::move(params->settings), vm_data->GetIsolateSnapshot(),
265+
std::move(params->on_create_platform_view),
266+
std::move(params->on_create_rasterizer), std::move(vm));
267+
}
268+
252269
std::unique_ptr<Shell> Shell::Create(
253270
TaskRunners task_runners,
254271
const WindowData window_data,
@@ -283,42 +300,76 @@ std::unique_ptr<Shell> Shell::Create(
283300
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
284301
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
285302
DartVMRef vm) {
303+
auto shell_holder_future = Shell::InitShellEnv(
304+
std::move(task_runners), window_data, settings,
305+
std::move(isolate_snapshot), std::move(on_create_platform_view),
306+
std::move(on_create_rasterizer), std::move(vm));
307+
auto shell_holder = shell_holder_future.get();
308+
if (!shell_holder) {
309+
return nullptr;
310+
}
311+
312+
fml::AutoResetWaitableEvent latch;
313+
std::unique_ptr<Shell> shell;
314+
fml::TaskRunner::RunNowOrPostTask(
315+
task_runners.GetPlatformTaskRunner(),
316+
fml::MakeCopyable([&latch, &shell, &shell_holder
317+
318+
]() mutable {
319+
shell = Shell::MakeShellFromHolder(std::move(shell_holder));
320+
latch.Signal();
321+
}));
322+
latch.Wait();
323+
324+
return shell;
325+
}
326+
327+
std::future<std::unique_ptr<Shell::ShellHolder>> Shell::InitShellEnv(
328+
TaskRunners task_runners,
329+
const WindowData window_data,
330+
Settings settings,
331+
fml::RefPtr<const DartSnapshot> isolate_snapshot,
332+
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
333+
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
334+
DartVMRef vm) {
286335
PerformInitializationTasks(settings);
287336
PersistentCache::SetCacheSkSL(settings.cache_sksl);
288337

289338
TRACE_EVENT0("flutter", "Shell::CreateWithSnapshots");
290339

291340
if (!task_runners.IsValid() || !on_create_platform_view ||
292341
!on_create_rasterizer) {
293-
return nullptr;
342+
std::promise<std::unique_ptr<Shell::ShellHolder>> shell_holder_promise;
343+
shell_holder_promise.set_value(nullptr);
344+
return shell_holder_promise.get_future();
294345
}
295346

296-
fml::AutoResetWaitableEvent latch;
297-
std::unique_ptr<Shell> shell;
347+
// fml::AutoResetWaitableEvent latch;
348+
std::promise<std::unique_ptr<Shell::ShellHolder>> shell_holder_promise;
349+
auto shell_holder_future = shell_holder_promise.get_future();
350+
298351
fml::TaskRunner::RunNowOrPostTask(
299352
task_runners.GetPlatformTaskRunner(),
300-
fml::MakeCopyable([&latch, //
353+
fml::MakeCopyable([shell_holder_promise = std::move(shell_holder_promise),
301354
vm = std::move(vm), //
302-
&shell, //
303355
task_runners = std::move(task_runners), //
304356
window_data, //
305357
settings, //
306358
isolate_snapshot = std::move(isolate_snapshot), //
307359
on_create_platform_view, //
308360
on_create_rasterizer //
309361
]() 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 //
362+
CreateShellOnPlatformThread(std::move(shell_holder_promise),
363+
std::move(vm), //
364+
std::move(task_runners), //
365+
window_data, //
366+
settings, //
367+
std::move(isolate_snapshot), //
368+
on_create_platform_view, //
369+
on_create_rasterizer //
317370
);
318-
latch.Signal();
319371
}));
320-
latch.Wait();
321-
return shell;
372+
return shell_holder_future;
322373
}
323374

324375
Shell::Shell(DartVMRef vm, TaskRunners task_runners, Settings settings)
@@ -1518,4 +1569,16 @@ std::shared_ptr<fml::SyncSwitch> Shell::GetIsGpuDisabledSyncSwitch() const {
15181569
return is_gpu_disabled_sync_switch_;
15191570
}
15201571

1572+
std::unique_ptr<Shell> Shell::MakeShellFromHolder(
1573+
std::unique_ptr<ShellHolder> holder) {
1574+
FML_CHECK(holder->shell->GetTaskRunners()
1575+
.GetPlatformTaskRunner()
1576+
->RunsTasksOnCurrentThread())
1577+
<< "MakeShellFromHolder() must run in platformThread!";
1578+
holder->shell->Setup(std::move(holder->platform_view),
1579+
std::move(holder->engine), std::move(holder->rasterizer),
1580+
std::move(holder->io_manager));
1581+
return std::move(holder->shell);
1582+
}
1583+
15211584
} // namespace flutter

0 commit comments

Comments
 (0)