-
Notifications
You must be signed in to change notification settings - Fork 6k
future: support engine create shell with aysnc mode #18047
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,62 +39,67 @@ constexpr char kSystemChannel[] = "flutter/system"; | |
| constexpr char kTypeKey[] = "type"; | ||
| constexpr char kFontChange[] = "fontsChange"; | ||
|
|
||
| std::unique_ptr<Shell> Shell::CreateShellOnPlatformThread( | ||
| void Shell::CreateShellOnPlatformThread( | ||
| std::promise<std::unique_ptr<Shell::ShellHolder>> shell_holder_promise, | ||
| DartVMRef vm, | ||
| TaskRunners task_runners, | ||
| const WindowData window_data, | ||
| Settings settings, | ||
| fml::RefPtr<const DartSnapshot> isolate_snapshot, | ||
| const Shell::CreateCallback<PlatformView>& on_create_platform_view, | ||
| const Shell::CreateCallback<Rasterizer>& on_create_rasterizer) { | ||
| FML_CHECK(task_runners.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()) | ||
| << "CreateShellOnPlatformThread() must run in platformThread!"; | ||
| if (!task_runners.IsValid()) { | ||
| FML_LOG(ERROR) << "Task runners to run the shell were invalid."; | ||
| return nullptr; | ||
| shell_holder_promise.set_value(nullptr); | ||
| return; | ||
| } | ||
|
|
||
| auto shell = | ||
| std::unique_ptr<Shell>(new Shell(std::move(vm), task_runners, settings)); | ||
|
|
||
| // Create the rasterizer on the raster thread. | ||
| std::promise<std::unique_ptr<Rasterizer>> rasterizer_promise; | ||
| auto rasterizer_future = rasterizer_promise.get_future(); | ||
| std::promise<fml::WeakPtr<SnapshotDelegate>> snapshot_delegate_promise; | ||
| auto snapshot_delegate_future = snapshot_delegate_promise.get_future(); | ||
| auto rasterizer_promise = | ||
| std::make_shared<std::promise<std::unique_ptr<Rasterizer>>>(); | ||
| auto snapshot_delegate_promise = | ||
| std::make_shared<std::promise<fml::WeakPtr<SnapshotDelegate>>>(); | ||
|
|
||
| fml::TaskRunner::RunNowOrPostTask( | ||
| task_runners.GetRasterTaskRunner(), [&rasterizer_promise, // | ||
| &snapshot_delegate_promise, | ||
| on_create_rasterizer, // | ||
| shell = shell.get() // | ||
| ]() { | ||
| task_runners.GetRasterTaskRunner(), | ||
| [rasterizer_promise, 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)); | ||
| 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()); | ||
| if (!platform_view || !platform_view->GetWeakPtr()) { | ||
| return nullptr; | ||
| shell_holder_promise.set_value(nullptr); | ||
| return; | ||
| } | ||
|
|
||
| // Ask the platform view for the vsync waiter. This will be used by the engine | ||
| // to create the animator. | ||
| auto vsync_waiter = platform_view->CreateVSyncWaiter(); | ||
| if (!vsync_waiter) { | ||
| return nullptr; | ||
| shell_holder_promise.set_value(nullptr); | ||
| return; | ||
| } | ||
|
|
||
| // Create the IO manager on the IO thread. The IO manager must be initialized | ||
| // first because it has state that the other subsystems depend on. It must | ||
| // first be booted and the necessary references obtained to initialize the | ||
| // other subsystems. | ||
| std::promise<std::unique_ptr<ShellIOManager>> io_manager_promise; | ||
| auto io_manager_future = io_manager_promise.get_future(); | ||
| std::promise<fml::WeakPtr<ShellIOManager>> weak_io_manager_promise; | ||
| auto weak_io_manager_future = weak_io_manager_promise.get_future(); | ||
| std::promise<fml::RefPtr<SkiaUnrefQueue>> unref_queue_promise; | ||
| auto unref_queue_future = unref_queue_promise.get_future(); | ||
| auto io_manager_promise = | ||
| std::make_shared<std::promise<std::unique_ptr<ShellIOManager>>>(); | ||
| auto weak_io_manager_promise = | ||
| std::make_shared<std::promise<fml::WeakPtr<ShellIOManager>>>(); | ||
| auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner(); | ||
|
|
||
| // TODO(gw280): The WeakPtr here asserts that we are derefing it on the | ||
|
|
@@ -105,73 +110,70 @@ 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, // | ||
| [io_task_runner, io_manager_promise, weak_io_manager_promise, | ||
| weak_platform_view = platform_view->GetWeakPtr(), // | ||
| is_backgrounded_sync_switch = shell->GetIsGpuDisabledSyncSwitch() // | ||
| ]() { | ||
| ]() mutable { | ||
| TRACE_EVENT0("flutter", "ShellSetupIOSubsystem"); | ||
| auto io_manager = std::make_unique<ShellIOManager>( | ||
| platform_view.getUnsafe()->CreateResourceContext(), | ||
| weak_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)); | ||
| weak_io_manager_promise->set_value(io_manager->GetWeakPtr()); | ||
| 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. | ||
| auto dispatcher_maker = platform_view->GetDispatcherMaker(); | ||
|
|
||
| // Create the engine on the UI thread. | ||
| std::promise<std::unique_ptr<Engine>> engine_promise; | ||
| auto engine_future = engine_promise.get_future(); | ||
| fml::TaskRunner::RunNowOrPostTask( | ||
| shell->GetTaskRunners().GetUITaskRunner(), | ||
| fml::MakeCopyable([&engine_promise, // | ||
| shell = shell.get(), // | ||
| &dispatcher_maker, // | ||
| &window_data, // | ||
| fml::MakeCopyable([shell = std::move(shell), // | ||
| shell_holder_promise = std::move(shell_holder_promise), | ||
| platform_view = std::move(platform_view), | ||
| dispatcher_in = std::move(dispatcher_maker), // | ||
| window_data = std::move(window_data), // | ||
| isolate_snapshot = std::move(isolate_snapshot), // | ||
| vsync_waiter = std::move(vsync_waiter), // | ||
| &weak_io_manager_future, // | ||
| &snapshot_delegate_future, // | ||
| &unref_queue_future // | ||
| ]() mutable { | ||
| io_manager_promise, // | ||
| rasterizer_promise, // | ||
| weak_io_manager_promise, // | ||
| snapshot_delegate_promise]() mutable { | ||
| TRACE_EVENT0("flutter", "ShellSetupUISubsystem"); | ||
| const auto& task_runners = shell->GetTaskRunners(); | ||
|
|
||
| // The animator is owned by the UI thread but it gets its vsync pulses | ||
| // from the platform. | ||
| // The animator is owned by the UI thread but it gets its vsync | ||
| // pulses from the platform. | ||
| auto animator = std::make_unique<Animator>(*shell, task_runners, | ||
| std::move(vsync_waiter)); | ||
|
|
||
| engine_promise.set_value(std::make_unique<Engine>( | ||
| *shell, // | ||
| dispatcher_maker, // | ||
| *shell->GetDartVM(), // | ||
| std::move(isolate_snapshot), // | ||
| task_runners, // | ||
| window_data, // | ||
| shell->GetSettings(), // | ||
| std::move(animator), // | ||
| weak_io_manager_future.get(), // | ||
| unref_queue_future.get(), // | ||
| snapshot_delegate_future.get() // | ||
| )); | ||
| // wait params(io、gpu task end) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| auto rasterizer = rasterizer_promise->get_future().get(); | ||
| auto snapshot_delegate = snapshot_delegate_promise->get_future().get(); | ||
| auto io_manager = io_manager_promise->get_future().get(); | ||
| auto weak_io_manager = weak_io_manager_promise->get_future().get(); | ||
|
|
||
| auto unref_queue = io_manager->GetSkiaUnrefQueue(); | ||
|
|
||
| auto engine_ref = | ||
| std::make_unique<Engine>(*(shell.get()), // | ||
| dispatcher_in, // | ||
| *shell->GetDartVM(), // | ||
| std::move(isolate_snapshot), // | ||
| task_runners, // | ||
| window_data, // | ||
| shell->GetSettings(), // | ||
| std::move(animator), // | ||
| std::move(weak_io_manager), // | ||
| std::move(unref_queue), // | ||
| std::move(snapshot_delegate) // | ||
| ); | ||
| shell_holder_promise.set_value(std::make_unique<Shell::ShellHolder>( | ||
| std::move(shell), std::move(platform_view), std::move(engine_ref), | ||
| std::move(rasterizer), std::move(io_manager))); | ||
| })); | ||
|
|
||
| if (!shell->Setup(std::move(platform_view), // | ||
| engine_future.get(), // | ||
| rasterizer_future.get(), // | ||
| io_manager_future.get()) // | ||
| ) { | ||
| return nullptr; | ||
| } | ||
|
|
||
| return shell; | ||
| return; | ||
| } | ||
|
|
||
| static void Tokenize(const std::string& input, | ||
|
|
@@ -249,6 +251,21 @@ std::unique_ptr<Shell> Shell::Create( | |
| ); | ||
| } | ||
|
|
||
| std::future<std::unique_ptr<Shell::ShellHolder>> Shell::CreateShellHolder( | ||
| std::unique_ptr<ShellCreateParams> params) { | ||
| PerformInitializationTasks(params->settings); | ||
| PersistentCache::SetCacheSkSL(params->settings.cache_sksl); | ||
| TRACE_EVENT0("flutter", "Shell::Create"); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put |
||
| auto vm = DartVMRef::Create(params->settings); | ||
| FML_CHECK(vm) << "Must be able to initialize the VM."; | ||
| auto vm_data = vm->GetVMData(); | ||
| return Shell::InitShellEnv( | ||
| std::move(params->task_runners), std::move(params->window_data), | ||
| std::move(params->settings), vm_data->GetIsolateSnapshot(), | ||
| std::move(params->on_create_platform_view), | ||
| std::move(params->on_create_rasterizer), std::move(vm)); | ||
| } | ||
|
|
||
| std::unique_ptr<Shell> Shell::Create( | ||
| TaskRunners task_runners, | ||
| const WindowData window_data, | ||
|
|
@@ -283,42 +300,76 @@ std::unique_ptr<Shell> Shell::Create( | |
| const Shell::CreateCallback<PlatformView>& on_create_platform_view, | ||
| const Shell::CreateCallback<Rasterizer>& on_create_rasterizer, | ||
| DartVMRef vm) { | ||
| auto shell_holder_future = Shell::InitShellEnv( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Put |
||
| std::move(task_runners), window_data, settings, | ||
| std::move(isolate_snapshot), std::move(on_create_platform_view), | ||
| std::move(on_create_rasterizer), std::move(vm)); | ||
| auto shell_holder = shell_holder_future.get(); | ||
| if (!shell_holder) { | ||
| return nullptr; | ||
| } | ||
|
|
||
| fml::AutoResetWaitableEvent latch; | ||
| std::unique_ptr<Shell> shell; | ||
| fml::TaskRunner::RunNowOrPostTask( | ||
| task_runners.GetPlatformTaskRunner(), | ||
| fml::MakeCopyable([&latch, &shell, &shell_holder | ||
|
|
||
| ]() mutable { | ||
| shell = Shell::MakeShellFromHolder(std::move(shell_holder)); | ||
| latch.Signal(); | ||
| })); | ||
| latch.Wait(); | ||
|
|
||
| return shell; | ||
| } | ||
|
|
||
| std::future<std::unique_ptr<Shell::ShellHolder>> Shell::InitShellEnv( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: |
||
| TaskRunners task_runners, | ||
| const WindowData window_data, | ||
| Settings settings, | ||
| fml::RefPtr<const DartSnapshot> isolate_snapshot, | ||
| const Shell::CreateCallback<PlatformView>& on_create_platform_view, | ||
| const Shell::CreateCallback<Rasterizer>& on_create_rasterizer, | ||
| DartVMRef vm) { | ||
| PerformInitializationTasks(settings); | ||
| PersistentCache::SetCacheSkSL(settings.cache_sksl); | ||
|
|
||
| TRACE_EVENT0("flutter", "Shell::CreateWithSnapshots"); | ||
|
|
||
| if (!task_runners.IsValid() || !on_create_platform_view || | ||
| !on_create_rasterizer) { | ||
| return nullptr; | ||
| std::promise<std::unique_ptr<Shell::ShellHolder>> shell_holder_promise; | ||
| shell_holder_promise.set_value(nullptr); | ||
| return shell_holder_promise.get_future(); | ||
| } | ||
|
|
||
| fml::AutoResetWaitableEvent latch; | ||
| std::unique_ptr<Shell> shell; | ||
| // fml::AutoResetWaitableEvent latch; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove |
||
| std::promise<std::unique_ptr<Shell::ShellHolder>> shell_holder_promise; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can |
||
| auto shell_holder_future = shell_holder_promise.get_future(); | ||
|
|
||
| fml::TaskRunner::RunNowOrPostTask( | ||
| task_runners.GetPlatformTaskRunner(), | ||
| fml::MakeCopyable([&latch, // | ||
| fml::MakeCopyable([shell_holder_promise = std::move(shell_holder_promise), | ||
| vm = std::move(vm), // | ||
| &shell, // | ||
| task_runners = std::move(task_runners), // | ||
| window_data, // | ||
| settings, // | ||
| isolate_snapshot = std::move(isolate_snapshot), // | ||
| on_create_platform_view, // | ||
| on_create_rasterizer // | ||
| ]() mutable { | ||
| shell = CreateShellOnPlatformThread(std::move(vm), | ||
| std::move(task_runners), // | ||
| window_data, // | ||
| settings, // | ||
| std::move(isolate_snapshot), // | ||
| on_create_platform_view, // | ||
| on_create_rasterizer // | ||
| CreateShellOnPlatformThread(std::move(shell_holder_promise), | ||
| std::move(vm), // | ||
| std::move(task_runners), // | ||
| window_data, // | ||
| settings, // | ||
| std::move(isolate_snapshot), // | ||
| on_create_platform_view, // | ||
| on_create_rasterizer // | ||
| ); | ||
| latch.Signal(); | ||
| })); | ||
| latch.Wait(); | ||
| return shell; | ||
| return shell_holder_future; | ||
| } | ||
|
|
||
| Shell::Shell(DartVMRef vm, TaskRunners task_runners, Settings settings) | ||
|
|
@@ -1537,4 +1588,16 @@ std::shared_ptr<fml::SyncSwitch> Shell::GetIsGpuDisabledSyncSwitch() const { | |
| return is_gpu_disabled_sync_switch_; | ||
| } | ||
|
|
||
| std::unique_ptr<Shell> Shell::MakeShellFromHolder( | ||
| std::unique_ptr<ShellHolder> holder) { | ||
| FML_CHECK(holder->shell->GetTaskRunners() | ||
| .GetPlatformTaskRunner() | ||
| ->RunsTasksOnCurrentThread()) | ||
| << "MakeShellFromHolder() must run in platformThread!"; | ||
| holder->shell->Setup(std::move(holder->platform_view), | ||
| std::move(holder->engine), std::move(holder->rasterizer), | ||
| std::move(holder->io_manager)); | ||
| return std::move(holder->shell); | ||
| } | ||
|
|
||
| } // namespace flutter | ||
Uh oh!
There was an error while loading. Please reload this page.