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

Commit bc69130

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

File tree

4 files changed

+374
-79
lines changed

4 files changed

+374
-79
lines changed

shell/common/shell.cc

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

43-
std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
43+
std::future<std::unique_ptr<Shell::ShellHolder>>
44+
Shell::CreateShellOnPlatformThread(
4445
DartVMRef vm,
4546
TaskRunners task_runners,
4647
const WindowData window_data,
4748
Settings settings,
4849
fml::RefPtr<const DartSnapshot> isolate_snapshot,
4950
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
5051
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();
5154
if (!task_runners.IsValid()) {
5255
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;
5459
}
5560

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

5964
// 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+
6468
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 {
7074
TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem");
7175
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));
7477
});
7578

7679
// Create the platform view on the platform thread (this thread).
7780
auto platform_view = on_create_platform_view(*shell.get());
7881
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;
8085
}
8186

8287
// Ask the platform view for the vsync waiter. This will be used by the engine
8388
// to create the animator.
8489
auto vsync_waiter = platform_view->CreateVSyncWaiter();
8590
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;
8794
}
8895

8996
// Create the IO manager on the IO thread. The IO manager must be initialized
9097
// first because it has state that the other subsystems depend on. It must
9198
// first be booted and the necessary references obtained to initialize the
9299
// 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>>>();
99104
auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner();
100105

101106
// TODO(gw280): The WeakPtr here asserts that we are derefing it on the
@@ -106,73 +111,71 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
106111
// https://github.com/flutter/flutter/issues/42948
107112
fml::TaskRunner::RunNowOrPostTask(
108113
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(), //
114118
is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch() //
115-
]() {
119+
]() mutable {
116120
TRACE_EVENT0("flutter", "ShellSetupIOSubsystem");
117121
auto io_manager = std::make_unique<ShellIOManager>(
118-
platform_view.getUnsafe()->CreateResourceContext(),
122+
weak_platform_view.getUnsafe()->CreateResourceContext(),
119123
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));
123126
});
124127

125128
// Send dispatcher_maker to the engine constructor because shell won't have
126129
// platform_view set until Shell::Setup is called later.
127130
auto dispatcher_maker = platform_view->GetDispatcherMaker();
128131

129132
// Create the engine on the UI thread.
130-
std::promise<std::unique_ptr<Engine>> engine_promise;
131-
auto engine_future = engine_promise.get_future();
132133
fml::TaskRunner::RunNowOrPostTask(
133134
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), //
138140
isolate_snapshot = std::move(isolate_snapshot), //
139141
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 //
143145
]() mutable {
144146
TRACE_EVENT0("flutter", "ShellSetupUISubsystem");
145147
const auto& task_runners = shell->GetTaskRunners();
146148

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

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)));
165177
}));
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;
176179
}
177180

178181
static void RecordStartupTimestamp() {
@@ -253,6 +256,21 @@ std::unique_ptr<Shell> Shell::Create(
253256
);
254257
}
255258

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+
256274
std::unique_ptr<Shell> Shell::Create(
257275
TaskRunners task_runners,
258276
const WindowData window_data,
@@ -287,42 +305,66 @@ std::unique_ptr<Shell> Shell::Create(
287305
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
288306
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
289307
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) {
290327
PerformInitializationTasks(settings);
291328
PersistentCache::SetCacheSkSL(settings.cache_sksl);
292329

293330
TRACE_EVENT0("flutter", "Shell::CreateWithSnapshots");
294331

295332
if (!task_runners.IsValid() || !on_create_platform_view ||
296333
!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();
298338
}
299339

300340
fml::AutoResetWaitableEvent latch;
301-
std::unique_ptr<Shell> shell;
341+
std::future<std::unique_ptr<Shell::ShellHolder>> shell_holder_future;
342+
302343
fml::TaskRunner::RunNowOrPostTask(
303344
task_runners.GetPlatformTaskRunner(),
304-
fml::MakeCopyable([&latch, //
345+
fml::MakeCopyable([&latch,
305346
vm = std::move(vm), //
306-
&shell, //
347+
&shell_holder_future, //
307348
task_runners = std::move(task_runners), //
308349
window_data, //
309350
settings, //
310351
isolate_snapshot = std::move(isolate_snapshot), //
311352
on_create_platform_view, //
312353
on_create_rasterizer //
313354
]() 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+
);
322364
latch.Signal();
323365
}));
324366
latch.Wait();
325-
return shell;
367+
return shell_holder_future;
326368
}
327369

328370
Shell::Shell(DartVMRef vm, TaskRunners task_runners, Settings settings)
@@ -1506,4 +1548,27 @@ std::shared_ptr<fml::SyncSwitch> Shell::GetIsGpuDisabledSyncSwitch() const {
15061548
return is_gpu_disabled_sync_switch_;
15071549
}
15081550

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

0 commit comments

Comments
 (0)