From c0ce97ffe08642bfbc4410a2d53c011f6f706e9c Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Fri, 26 Jul 2019 13:35:18 -0700 Subject: [PATCH 1/8] Made flutter startup faster by allowing initialization to be parallelized. --- shell/common/shell.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 0377cc91e839d..0aa3bbb125ce8 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -83,7 +83,6 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( platform_view->CreateResourceContext(), io_task_runner); io_latch.Signal(); }); - io_latch.Wait(); // Create the rasterizer on the GPU thread. fml::AutoResetWaitableEvent gpu_latch; @@ -101,8 +100,6 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( gpu_latch.Signal(); }); - gpu_latch.Wait(); - // Create the engine on the UI thread. fml::AutoResetWaitableEvent ui_latch; std::unique_ptr engine; @@ -114,7 +111,8 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( isolate_snapshot = std::move(isolate_snapshot), // shared_snapshot = std::move(shared_snapshot), // vsync_waiter = std::move(vsync_waiter), // - io_manager = io_manager->GetWeakPtr() // + &io_latch, + &io_manager // ]() mutable { TRACE_EVENT0("flutter", "ShellSetupUISubsystem"); const auto& task_runners = shell->GetTaskRunners(); @@ -124,6 +122,8 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( auto animator = std::make_unique(*shell, task_runners, std::move(vsync_waiter)); + io_latch.Wait(); + engine = std::make_unique(*shell, // *shell->GetDartVM(), // std::move(isolate_snapshot), // @@ -131,12 +131,14 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( task_runners, // shell->GetSettings(), // std::move(animator), // - std::move(io_manager) // + io_manager->GetWeakPtr() // ); ui_latch.Signal(); })); ui_latch.Wait(); + gpu_latch.Wait(); + // We are already on the platform thread. So there is no platform latch to // wait on. From 7edae5810a54f27f967bcacab74ab3e3b9ab1827 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 16 Sep 2019 10:50:51 -0700 Subject: [PATCH 2/8] Moved shell construction to futures. --- shell/common/shell.cc | 66 ++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 39 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 7f7ea9c22a836..684a534586ca9 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -67,50 +67,46 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( // 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. - fml::AutoResetWaitableEvent io_latch; - std::unique_ptr io_manager; + std::promise> io_manager_promise; + auto io_manager = io_manager_promise.get_future(); auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner(); fml::TaskRunner::RunNowOrPostTask( io_task_runner, - [&io_latch, // - &io_manager, // + [&io_manager_promise, // &platform_view, // io_task_runner // ]() { TRACE_EVENT0("flutter", "ShellSetupIOSubsystem"); - io_manager = std::make_unique( - platform_view->CreateResourceContext(), io_task_runner); - io_latch.Signal(); + io_manager_promise.set_value(std::make_unique( + platform_view->CreateResourceContext(), io_task_runner)); }); // Create the rasterizer on the GPU thread. - fml::AutoResetWaitableEvent gpu_latch; - std::unique_ptr rasterizer; + std::promise> rasterizer_promise; + auto rasterizer = rasterizer_promise.get_future(); fml::TaskRunner::RunNowOrPostTask( - task_runners.GetGPUTaskRunner(), [&gpu_latch, // - &rasterizer, // + task_runners.GetGPUTaskRunner(), [&rasterizer_promise, // on_create_rasterizer, // shell = shell.get() // ]() { TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem"); if (auto new_rasterizer = on_create_rasterizer(*shell)) { - rasterizer = std::move(new_rasterizer); + rasterizer_promise.set_value(std::move(new_rasterizer)); + } else { + rasterizer_promise.set_value(std::unique_ptr()); } - gpu_latch.Signal(); }); // Create the engine on the UI thread. - fml::AutoResetWaitableEvent ui_latch; - std::unique_ptr engine; + std::promise> engine_promise; + auto engine = engine_promise.get_future(); fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetUITaskRunner(), - fml::MakeCopyable([&ui_latch, // - &engine, // + fml::MakeCopyable([&engine_promise, // shell = shell.get(), // isolate_snapshot = std::move(isolate_snapshot), // shared_snapshot = std::move(shared_snapshot), // vsync_waiter = std::move(vsync_waiter), // - &io_latch, &io_manager // ]() mutable { TRACE_EVENT0("flutter", "ShellSetupUISubsystem"); @@ -121,30 +117,22 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( auto animator = std::make_unique(*shell, task_runners, std::move(vsync_waiter)); - io_latch.Wait(); - - engine = std::make_unique(*shell, // - *shell->GetDartVM(), // - std::move(isolate_snapshot), // - std::move(shared_snapshot), // - task_runners, // - shell->GetSettings(), // - std::move(animator), // - io_manager->GetWeakPtr() // - ); - ui_latch.Signal(); + engine_promise.set_value(std::make_unique( + *shell, // + *shell->GetDartVM(), // + std::move(isolate_snapshot), // + std::move(shared_snapshot), // + task_runners, // + shell->GetSettings(), // + std::move(animator), // + io_manager.get()->GetWeakPtr() // + )); })); - ui_latch.Wait(); - gpu_latch.Wait(); - - // We are already on the platform thread. So there is no platform latch to - // wait on. - if (!shell->Setup(std::move(platform_view), // - std::move(engine), // - std::move(rasterizer), // - std::move(io_manager)) // + engine.get(), // + rasterizer.get(), // + io_manager.get()) // ) { return nullptr; } From b51dc213ecb698b45891915732c8b4b4421fae54 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 16 Sep 2019 11:59:54 -0700 Subject: [PATCH 3/8] Fixed multiple std::move's from one unique_ptr future. --- shell/common/shell.cc | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 684a534586ca9..94caf18d261ba 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -69,16 +69,21 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( // other subsystems. std::promise> io_manager_promise; auto io_manager = io_manager_promise.get_future(); + std::promise> weak_io_manager_promise; + auto weak_io_manager = weak_io_manager_promise.get_future(); auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner(); fml::TaskRunner::RunNowOrPostTask( io_task_runner, - [&io_manager_promise, // - &platform_view, // - io_task_runner // + [&io_manager_promise, // + &weak_io_manager_promise, // + &platform_view, // + io_task_runner // ]() { TRACE_EVENT0("flutter", "ShellSetupIOSubsystem"); - io_manager_promise.set_value(std::make_unique( - platform_view->CreateResourceContext(), io_task_runner)); + auto io_manager = std::make_unique( + platform_view->CreateResourceContext(), io_task_runner); + weak_io_manager_promise.set_value(io_manager->GetWeakPtr()); + io_manager_promise.set_value(std::move(io_manager)); }); // Create the rasterizer on the GPU thread. @@ -107,7 +112,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( isolate_snapshot = std::move(isolate_snapshot), // shared_snapshot = std::move(shared_snapshot), // vsync_waiter = std::move(vsync_waiter), // - &io_manager // + &weak_io_manager // ]() mutable { TRACE_EVENT0("flutter", "ShellSetupUISubsystem"); const auto& task_runners = shell->GetTaskRunners(); @@ -118,14 +123,14 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( std::move(vsync_waiter)); engine_promise.set_value(std::make_unique( - *shell, // - *shell->GetDartVM(), // - std::move(isolate_snapshot), // - std::move(shared_snapshot), // - task_runners, // - shell->GetSettings(), // - std::move(animator), // - io_manager.get()->GetWeakPtr() // + *shell, // + *shell->GetDartVM(), // + std::move(isolate_snapshot), // + std::move(shared_snapshot), // + task_runners, // + shell->GetSettings(), // + std::move(animator), // + weak_io_manager.get() // )); })); From e8a6e408290b02f6ef11dc55dc50abb8f241af0b Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 16 Sep 2019 12:02:13 -0700 Subject: [PATCH 4/8] fixed formatting --- shell/common/shell.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 94caf18d261ba..60a297f4dae39 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -123,14 +123,14 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( std::move(vsync_waiter)); engine_promise.set_value(std::make_unique( - *shell, // - *shell->GetDartVM(), // - std::move(isolate_snapshot), // - std::move(shared_snapshot), // - task_runners, // - shell->GetSettings(), // - std::move(animator), // - weak_io_manager.get() // + *shell, // + *shell->GetDartVM(), // + std::move(isolate_snapshot), // + std::move(shared_snapshot), // + task_runners, // + shell->GetSettings(), // + std::move(animator), // + weak_io_manager.get() // )); })); From 9d6b8136ddb621753470c02845ce4176ae551c94 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 16 Sep 2019 12:49:54 -0700 Subject: [PATCH 5/8] added _future postfix --- shell/common/shell.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 48f616a424b05..4c8705b5c1f76 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -68,9 +68,9 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( // first be booted and the necessary references obtained to initialize the // other subsystems. std::promise> io_manager_promise; - auto io_manager = io_manager_promise.get_future(); + auto io_manager_future = io_manager_promise.get_future(); std::promise> weak_io_manager_promise; - auto weak_io_manager = weak_io_manager_promise.get_future(); + auto weak_io_manager_future = weak_io_manager_promise.get_future(); auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner(); fml::TaskRunner::RunNowOrPostTask( io_task_runner, @@ -88,7 +88,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( // Create the rasterizer on the GPU thread. std::promise> rasterizer_promise; - auto rasterizer = rasterizer_promise.get_future(); + auto rasterizer_future = rasterizer_promise.get_future(); fml::TaskRunner::RunNowOrPostTask( task_runners.GetGPUTaskRunner(), [&rasterizer_promise, // on_create_rasterizer, // @@ -108,7 +108,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( // Create the engine on the UI thread. std::promise> engine_promise; - auto engine = engine_promise.get_future(); + auto engine_future = engine_promise.get_future(); fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetUITaskRunner(), fml::MakeCopyable([&engine_promise, // @@ -117,7 +117,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( isolate_snapshot = std::move(isolate_snapshot), // shared_snapshot = std::move(shared_snapshot), // vsync_waiter = std::move(vsync_waiter), // - &weak_io_manager // + &weak_io_manager_future // ]() mutable { TRACE_EVENT0("flutter", "ShellSetupUISubsystem"); const auto& task_runners = shell->GetTaskRunners(); @@ -136,14 +136,14 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( task_runners, // shell->GetSettings(), // std::move(animator), // - weak_io_manager.get() // + weak_io_manager_future.get() // )); })); if (!shell->Setup(std::move(platform_view), // - engine.get(), // - rasterizer.get(), // - io_manager.get()) // + engine_future.get(), // + rasterizer_future.get(), // + io_manager_future.get()) // ) { return nullptr; } From 1b62816595f4ed231f330052a7084e114b85ba6f Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 16 Sep 2019 12:53:42 -0700 Subject: [PATCH 6/8] simplified promise setter --- shell/common/shell.cc | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 4c8705b5c1f76..d9c193086b217 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -95,11 +95,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( shell = shell.get() // ]() { TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem"); - if (auto new_rasterizer = on_create_rasterizer(*shell)) { - rasterizer_promise.set_value(std::move(new_rasterizer)); - } else { - rasterizer_promise.set_value(std::unique_ptr()); - } + rasterizer_promise.set_value(on_create_rasterizer(*shell)); }); // Send dispatcher_maker to the engine constructor because shell won't have From 4541f9a91719e8ac6712c358e76d3982f7e009c3 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 16 Sep 2019 12:56:25 -0700 Subject: [PATCH 7/8] Moved rasterization creation earlier to help parallelization. --- shell/common/shell.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index d9c193086b217..f92baf070326e 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -50,6 +50,18 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( auto shell = std::unique_ptr(new Shell(std::move(vm), task_runners, settings)); + // Create the rasterizer on the GPU thread. + std::promise> rasterizer_promise; + auto rasterizer_future = rasterizer_promise.get_future(); + fml::TaskRunner::RunNowOrPostTask( + task_runners.GetGPUTaskRunner(), [&rasterizer_promise, // + on_create_rasterizer, // + shell = shell.get() // + ]() { + TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem"); + rasterizer_promise.set_value(on_create_rasterizer(*shell)); + }); + // 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()) { @@ -86,18 +98,6 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( io_manager_promise.set_value(std::move(io_manager)); }); - // Create the rasterizer on the GPU thread. - std::promise> rasterizer_promise; - auto rasterizer_future = rasterizer_promise.get_future(); - fml::TaskRunner::RunNowOrPostTask( - task_runners.GetGPUTaskRunner(), [&rasterizer_promise, // - on_create_rasterizer, // - shell = shell.get() // - ]() { - TRACE_EVENT0("flutter", "ShellSetupGPUSubsystem"); - rasterizer_promise.set_value(on_create_rasterizer(*shell)); - }); - // 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(); From 799d3140691759213e947f17bcce7a8e674539fa Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Mon, 16 Sep 2019 13:23:24 -0700 Subject: [PATCH 8/8] fixed race condition where we were capturing a unique_ptr by reference and it was getted std::moved under the covers. --- shell/common/shell.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index f92baf070326e..e115a73d36282 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -86,10 +86,10 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( auto io_task_runner = shell->GetTaskRunners().GetIOTaskRunner(); fml::TaskRunner::RunNowOrPostTask( io_task_runner, - [&io_manager_promise, // - &weak_io_manager_promise, // - &platform_view, // - io_task_runner // + [&io_manager_promise, // + &weak_io_manager_promise, // + platform_view = platform_view->GetWeakPtr(), // + io_task_runner // ]() { TRACE_EVENT0("flutter", "ShellSetupIOSubsystem"); auto io_manager = std::make_unique(