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

Commit 881036e

Browse files
lucky-chenpeihan.cph
authored and
peihan.cph
committed
future: engine supprot create shell with aysnc mode
use promise/future
1 parent ea78055 commit 881036e

File tree

4 files changed

+379
-80
lines changed

4 files changed

+379
-80
lines changed

shell/common/shell.cc

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

42-
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
42+
std::future<std::unique_ptr<Shell::ShellHolder>>
43+
Shell::CreateShellOnPlatformThread(
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+
std::promise<std::unique_ptr<Shell::ShellHolder>> shell_holder_promise;
52+
auto shell_holder_future = shell_holder_promise.get_future();
5053
if (!task_runners.IsValid()) {
5154
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;
5358
}
5459

5560
auto shell =
5661
std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings));
5762

5863
// 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+
6369
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 {
6975
TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem");
7076
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));
7379
});
7480

7581
// Create the platform view on the platform thread (this thread).
7682
auto platform_view = on_create_platform_view(*shell.get());
7783
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;
7987
}
8088

8189
// Ask the platform view for the vsync waiter. This will be used by the engine
8290
// to create the animator.
8391
auto vsync_waiter = platform_view->CreateVSyncWaiter();
8492
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;
8696
}
8797

8898
// Create the IO manager on the IO thread. The IO manager must be initialized
8999
// first because it has state that the other subsystems depend on. It must
90100
// first be booted and the necessary references obtained to initialize the
91101
// 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>>>();
98106
auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();
99107

100108
// TODO(gw280): The WeakPtr here asserts that we are derefing it on the
@@ -105,73 +113,72 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
105113
// https://github.com/flutter/flutter/issues/42948
106114
fml::TaskRunner::RunNowOrPostTask(
107115
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(), //
113120
is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch() //
114-
]() {
121+
]() mutable {
115122
TRACE_EVENT0("flutter", "ShellSetupIOSubsystem");
116123
auto io_manager = std::make_unique<ShellIOManager>(
117-
platform_view.getUnsafe()->CreateResourceContext(),
124+
weak_platform_view.getUnsafe()->CreateResourceContext(),
118125
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));
122128
});
123129

124130
// Send dispatcher_maker to the engine constructor because shell won't have
125131
// platform_view set until Shell::Setup is called later.
126132
auto dispatcher_maker = platform_view->GetDispatcherMaker();
127133

128134
// Create the engine on the UI thread.
129-
std::promise<std::unique_ptr<Engine>> engine_promise;
130-
auto engine_future = engine_promise.get_future();
131135
fml::TaskRunner::RunNowOrPostTask(
132136
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), //
137142
isolate_snapshot = std::move(isolate_snapshot), //
138143
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 {
143148
TRACE_EVENT0("flutter", "ShellSetupUISubsystem");
144149
const auto& task_runners = shell->GetTaskRunners();
145150

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.
148153
auto animator = std::make_unique<Animator>(*shell, task_runners,
149154
std::move(vsync_waiter));
150155

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)));
164180
}));
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;
175182
}
176183

177184
static void Tokenize(const std::string& input,
@@ -249,6 +256,21 @@ std::unique_ptr<Shell> Shell::Create(
249256
);
250257
}
251258

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+
252274
std::unique_ptr<Shell> Shell::Create(
253275
TaskRunners task_runners,
254276
const WindowData window_data,
@@ -283,42 +305,66 @@ std::unique_ptr<Shell> Shell::Create(
283305
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
284306
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
285307
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) {
286327
PerformInitializationTasks(settings);
287328
PersistentCache::SetCacheSkSL(settings.cache_sksl);
288329

289330
TRACE_EVENT0("flutter", "Shell::CreateWithSnapshots");
290331

291332
if (!task_runners.IsValid() || !on_create_platform_view ||
292333
!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();
294338
}
295339

296340
fml::AutoResetWaitableEvent latch;
297-
std::unique_ptr<Shell> shell;
341+
std::future<std::unique_ptr<Shell::ShellHolder>> shell_holder_future;
342+
298343
fml::TaskRunner::RunNowOrPostTask(
299344
task_runners.GetPlatformTaskRunner(),
300-
fml::MakeCopyable([&latch, //
345+
fml::MakeCopyable([&latch,
301346
vm = std::move(vm), //
302-
&shell, //
347+
&shell_holder_future, //
303348
task_runners = std::move(task_runners), //
304349
window_data, //
305350
settings, //
306351
isolate_snapshot = std::move(isolate_snapshot), //
307352
on_create_platform_view, //
308353
on_create_rasterizer //
309354
]() 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+
);
318364
latch.Signal();
319365
}));
320366
latch.Wait();
321-
return shell;
367+
return shell_holder_future;
322368
}
323369

324370
Shell::Shell(DartVMRef vm, TaskRunners task_runners, Settings settings)
@@ -1511,4 +1557,27 @@ std::shared_ptr<fml::SyncSwitch> Shell::GetIsGpuDisabledSyncSwitch() const {
15111557
return is_gpu_disabled_sync_switch_;
15121558
}
15131559

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+
15141583
} // namespace flutter

0 commit comments

Comments
 (0)