Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support init engine asynchronous #20433

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 86 additions & 36 deletions shell/common/shell.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
Settings settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) {
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
const InitedCallback& on_create_inited) {
if (!task_runners.IsValid()) {
FML_LOG(ERROR) << "Task runners to run the shell were invalid.";
return nullptr;
Expand All @@ -62,16 +63,17 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
std::promise<fml::WeakPtr<SnapshotDelegate>> snapshot_delegate_promise;
auto snapshot_delegate_future = snapshot_delegate_promise.get_future();
fml::TaskRunner::RunNowOrPostTask(
task_runners.GetRasterTaskRunner(), [&rasterizer_promise, //
&snapshot_delegate_promise,
task_runners.GetRasterTaskRunner(), fml::MakeCopyable([
rasterizer_promise = std::move(rasterizer_promise), //
snapshot_delegate_promise = std::move(snapshot_delegate_promise),
on_create_rasterizer, //
shell = shell.get() //
]() {
]() mutable {
TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem");
std::unique_ptr<Rasterizer> rasterizer(on_create_rasterizer(*shell));
snapshot_delegate_promise.set_value(rasterizer->GetSnapshotDelegate());
rasterizer_promise.set_value(std::move(rasterizer));
});
}));

// Create the platform view on the platform thread (this thread).
auto platform_view = on_create_platform_view(*shell.get());
Expand Down Expand Up @@ -106,21 +108,21 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
// https://github.com/flutter/flutter/issues/42948
fml::TaskRunner::RunNowOrPostTask(
io_task_runner,
[&io_manager_promise, //
&weak_io_manager_promise, //
&unref_queue_promise, //
platform_view = platform_view->GetWeakPtr(), //
io_task_runner, //
is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch() //
]() {
fml::MakeCopyable([io_manager_promise = std::move(io_manager_promise), //
weak_io_manager_promise = std::move(weak_io_manager_promise), //
unref_queue_promise = std::move(unref_queue_promise), //
platform_view = platform_view->GetWeakPtr(), //
io_task_runner, //
is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch() //
]() mutable {
TRACE_EVENT0("flutter", "ShellSetupIOSubsystem");
auto io_manager = std::make_unique<ShellIOManager>(
platform_view.getUnsafe()->CreateResourceContext(),
is_backgrounded_sync_switch, io_task_runner);
weak_io_manager_promise.set_value(io_manager->GetWeakPtr());
unref_queue_promise.set_value(io_manager->GetSkiaUnrefQueue());
io_manager_promise.set_value(std::move(io_manager));
});
}));

// Send dispatcher_maker to the engine constructor because shell won't have
// platform_view set until Shell::Setup is called later.
Expand All @@ -131,15 +133,20 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
auto engine_future = engine_promise.get_future();
fml::TaskRunner::RunNowOrPostTask(
shell->GetTaskRunners().GetUITaskRunner(),
fml::MakeCopyable([&engine_promise, //
shell = shell.get(), //
&dispatcher_maker, //
&platform_data, //
isolate_snapshot = std::move(isolate_snapshot), //
vsync_waiter = std::move(vsync_waiter), //
&weak_io_manager_future, //
&snapshot_delegate_future, //
&unref_queue_future //
fml::MakeCopyable([engine_promise = std::move(engine_promise), //
shell = shell.get(), //
dispatcher_maker = std::move(dispatcher_maker), //
platform_data = std::move(platform_data), //
isolate_snapshot = std::move(isolate_snapshot), //
vsync_waiter = std::move(vsync_waiter), //
weak_io_manager_future = std::move(weak_io_manager_future), //
snapshot_delegate_future = std::move(snapshot_delegate_future), //
unref_queue_future = std::move(unref_queue_future), //
platform_view = std::move(platform_view),
engine_future = std::move(engine_future),
rasterizer_future = std::move(rasterizer_future),
io_manager_future = std::move(io_manager_future),
on_create_inited
]() mutable {
TRACE_EVENT0("flutter", "ShellSetupUISubsystem");
const auto& task_runners = shell->GetTaskRunners();
Expand All @@ -162,16 +169,27 @@ std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread(
unref_queue_future.get(), //
snapshot_delegate_future.get() //
));
}));

if (!shell->Setup(std::move(platform_view), //
engine_future.get(), //
rasterizer_future.get(), //
io_manager_future.get()) //
) {
return nullptr;
}
auto engine = engine_future.get();
auto rasterizer = rasterizer_future.get();
auto io_manager = io_manager_future.get();

shell->platform_view_ = std::move(platform_view);
shell->engine_ = std::move(engine);
shell->rasterizer_ = std::move(rasterizer);
shell->io_manager_ = std::move(io_manager);

if (on_create_inited) {
fml::TaskRunner::RunNowOrPostTask(shell->GetTaskRunners().GetPlatformTaskRunner(),
[on_create_inited]() {
on_create_inited(true);
});
}

shell->initialized_promise_.set_value(true);
}));

shell->initialized_future_ = shell->initialized_promise_.get_future();
return shell;
}

Expand Down Expand Up @@ -255,7 +273,8 @@ std::unique_ptr<Shell> Shell::Create(
const PlatformData platform_data,
Settings settings,
Shell::CreateCallback<PlatformView> on_create_platform_view,
Shell::CreateCallback<Rasterizer> on_create_rasterizer) {
Shell::CreateCallback<Rasterizer> on_create_rasterizer,
const InitedCallback on_create_inited) {
PerformInitializationTasks(settings);
PersistentCache::SetCacheSkSL(settings.cache_sksl);

Expand All @@ -272,7 +291,8 @@ std::unique_ptr<Shell> Shell::Create(
vm_data->GetIsolateSnapshot(), // isolate snapshot
on_create_platform_view, //
on_create_rasterizer, //
std::move(vm) //
std::move(vm), //
on_create_inited
);
}

Expand All @@ -283,7 +303,7 @@ std::unique_ptr<Shell> Shell::Create(
fml::RefPtr<const DartSnapshot> isolate_snapshot,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
DartVMRef vm) {
DartVMRef vm, const Shell::InitedCallback& on_create_inited) {
PerformInitializationTasks(settings);
PersistentCache::SetCacheSkSL(settings.cache_sksl);

Expand All @@ -306,15 +326,17 @@ std::unique_ptr<Shell> Shell::Create(
settings, //
isolate_snapshot = std::move(isolate_snapshot), //
on_create_platform_view, //
on_create_rasterizer //
on_create_rasterizer, //
on_create_inited
]() mutable {
shell = CreateShellOnPlatformThread(std::move(vm),
std::move(task_runners), //
platform_data, //
settings, //
std::move(isolate_snapshot), //
on_create_platform_view, //
on_create_rasterizer //
on_create_rasterizer, //
on_create_inited
);
latch.Signal();
}));
Expand Down Expand Up @@ -468,6 +490,10 @@ void Shell::RunEngine(
platform_runner->PostTask(
[result_callback, run_result]() { result_callback(run_result); });
};

ensureInitialized();
ensureSetupped();

FML_DCHECK(is_setup_);
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());

Expand Down Expand Up @@ -581,6 +607,23 @@ bool Shell::Setup(std::unique_ptr<PlatformView> platform_view,
return true;
}

void Shell::ensureInitialized() {
bool valid = initialized_future_.valid();
if (valid) {
bool initialized = initialized_future_.get();
FML_DCHECK(initialized);
}
}

void Shell::ensureSetupped() {
if (!is_setup_) {
Setup(std::move(platform_view_),
std::move(engine_),
std::move(rasterizer_),
std::move(io_manager_));
}
}

const Settings& Shell::GetSettings() const {
return settings_;
}
Expand All @@ -589,17 +632,21 @@ const TaskRunners& Shell::GetTaskRunners() const {
return task_runners_;
}

fml::TaskRunnerAffineWeakPtr<Rasterizer> Shell::GetRasterizer() const {
fml::TaskRunnerAffineWeakPtr<Rasterizer> Shell::GetRasterizer() const{
FML_DCHECK(is_setup_);
return weak_rasterizer_;
}

fml::WeakPtr<Engine> Shell::GetEngine() {
ensureInitialized();
ensureSetupped();
FML_DCHECK(is_setup_);
return weak_engine_;
}

fml::WeakPtr<PlatformView> Shell::GetPlatformView() {
ensureInitialized();
ensureSetupped();
FML_DCHECK(is_setup_);
return weak_platform_view_;
}
Expand Down Expand Up @@ -800,6 +847,9 @@ void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) {
// |PlatformView::Delegate|
void Shell::OnPlatformViewDispatchPlatformMessage(
fml::RefPtr<PlatformMessage> message) {
ensureInitialized();
ensureSetupped();

FML_DCHECK(is_setup_);
FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread());

Expand Down
16 changes: 13 additions & 3 deletions shell/common/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ class Shell final : public PlatformView::Delegate,
template <class T>
using CreateCallback = std::function<std::unique_ptr<T>(Shell&)>;

using InitedCallback = std::function<void(bool)>;

//----------------------------------------------------------------------------
/// @brief Creates a shell instance using the provided settings. The
/// callbacks to create the various shell subcomponents will be
Expand Down Expand Up @@ -164,7 +166,8 @@ class Shell final : public PlatformView::Delegate,
const PlatformData platform_data,
Settings settings,
CreateCallback<PlatformView> on_create_platform_view,
CreateCallback<Rasterizer> on_create_rasterizer);
CreateCallback<Rasterizer> on_create_rasterizer,
const InitedCallback on_create_inited = nullptr);

//----------------------------------------------------------------------------
/// @brief Creates a shell instance using the provided settings. The
Expand Down Expand Up @@ -208,7 +211,7 @@ class Shell final : public PlatformView::Delegate,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
const CreateCallback<PlatformView>& on_create_platform_view,
const CreateCallback<Rasterizer>& on_create_rasterizer,
DartVMRef vm);
DartVMRef vm, const InitedCallback& on_create_inited = nullptr);

//----------------------------------------------------------------------------
/// @brief Destroys the shell. This is a synchronous operation and
Expand Down Expand Up @@ -391,6 +394,8 @@ class Shell final : public PlatformView::Delegate,
>
service_protocol_handlers_;
bool is_setup_ = false;
std::promise<bool> initialized_promise_;
std::future<bool> initialized_future_;
uint64_t next_pointer_flow_id_ = 0;

bool first_frame_rasterized_ = false;
Expand Down Expand Up @@ -430,13 +435,18 @@ class Shell final : public PlatformView::Delegate,
Settings settings,
fml::RefPtr<const DartSnapshot> isolate_snapshot,
const Shell::CreateCallback<PlatformView>& on_create_platform_view,
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer);
const Shell::CreateCallback<Rasterizer>& on_create_rasterizer,
const InitedCallback& on_create_inited = nullptr);

bool Setup(std::unique_ptr<PlatformView> platform_view,
std::unique_ptr<Engine> engine,
std::unique_ptr<Rasterizer> rasterizer,
std::unique_ptr<ShellIOManager> io_manager);

void ensureInitialized();

void ensureSetupped();

void ReportTimings();

// |PlatformView::Delegate|
Expand Down
37 changes: 26 additions & 11 deletions shell/platform/darwin/ios/framework/Source/FlutterEngine.mm
Original file line number Diff line number Diff line change
Expand Up @@ -509,12 +509,21 @@ - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI {
_threadHost.ui_thread->GetTaskRunner(), // ui
_threadHost.io_thread->GetTaskRunner() // io
);
// Create the shell. This is a blocking operation.
// Create the shell. This is a asynchronous operation.
_shell = flutter::Shell::Create(std::move(task_runners), // task runners
std::move(platformData), // platform data
std::move(settings), // settings
on_create_platform_view, // platform view creation
on_create_rasterizer // rasterizer creation
on_create_rasterizer, // rasterizer creation
[self, entrypoint = entrypoint,
profilerEnabled = profilerEnabled,
threadLabel = [threadLabel copy]](bool initialized) {
if (initialized) {
[self postInitialized:profilerEnabled threadLabel:threadLabel];
} else {
FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " << entrypoint.UTF8String;
}
}
);
} else {
flutter::TaskRunners task_runners(threadLabel.UTF8String, // label
Expand All @@ -523,19 +532,28 @@ - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI {
_threadHost.ui_thread->GetTaskRunner(), // ui
_threadHost.io_thread->GetTaskRunner() // io
);
// Create the shell. This is a blocking operation.
// Create the shell. This is a asynchronous operation.
_shell = flutter::Shell::Create(std::move(task_runners), // task runners
std::move(platformData), // platform data
std::move(settings), // settings
on_create_platform_view, // platform view creation
on_create_rasterizer // rasterizer creation
on_create_rasterizer, // rasterizer creation
[self, entrypoint = entrypoint,
profilerEnabled,
threadLabel = [threadLabel copy]](bool initialized) {
if (initialized) {
[self postInitialized:profilerEnabled threadLabel:threadLabel];
} else {
FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " << entrypoint.UTF8String;
}
}
);
}

if (_shell == nullptr) {
FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: "
<< entrypoint.UTF8String;
} else {
return _shell != nullptr;
}

- (void)postInitialized:(BOOL)profilerEnabled threadLabel:(NSString*)threadLabel {
[self setupChannels];
[self onLocaleUpdated:nil];
if (!_platformViewsController) {
Expand All @@ -547,9 +565,6 @@ - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI {
if (profilerEnabled) {
[self startProfiler:threadLabel];
}
}

return _shell != nullptr;
}

- (BOOL)run {
Expand Down