From 8d11eeea32159115c7331de0c4c05cecc97adf98 Mon Sep 17 00:00:00 2001 From: lybeen Date: Tue, 11 Aug 2020 23:59:46 +0800 Subject: [PATCH 1/3] support engine init asynchronous --- shell/common/shell.cc | 124 +++++++++++++----- shell/common/shell.h | 18 ++- .../ios/framework/Source/FlutterEngine.mm | 33 +++-- 3 files changed, 124 insertions(+), 51 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index d11a14f06b4e2..c82d0516a99bb 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -47,7 +47,8 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( Settings settings, fml::RefPtr isolate_snapshot, const Shell::CreateCallback& on_create_platform_view, - const Shell::CreateCallback& on_create_rasterizer) { + const Shell::CreateCallback& 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; @@ -62,16 +63,17 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( std::promise> 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(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()); @@ -106,13 +108,13 @@ std::unique_ptr 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( platform_view.getUnsafe()->CreateResourceContext(), @@ -120,7 +122,7 @@ std::unique_ptr Shell::CreateShellOnPlatformThread( 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. @@ -131,15 +133,20 @@ std::unique_ptr 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(); @@ -162,16 +169,27 @@ std::unique_ptr 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; } @@ -255,7 +273,8 @@ std::unique_ptr Shell::Create( const PlatformData platform_data, Settings settings, Shell::CreateCallback on_create_platform_view, - Shell::CreateCallback on_create_rasterizer) { + Shell::CreateCallback on_create_rasterizer, + const InitedCallback on_create_inited) { PerformInitializationTasks(settings); PersistentCache::SetCacheSkSL(settings.cache_sksl); @@ -272,7 +291,8 @@ std::unique_ptr Shell::Create( vm_data->GetIsolateSnapshot(), // isolate snapshot on_create_platform_view, // on_create_rasterizer, // - std::move(vm) // + std::move(vm), // + on_create_inited ); } @@ -283,7 +303,7 @@ std::unique_ptr Shell::Create( fml::RefPtr isolate_snapshot, const Shell::CreateCallback& on_create_platform_view, const Shell::CreateCallback& on_create_rasterizer, - DartVMRef vm) { + DartVMRef vm, const Shell::InitedCallback& on_create_inited) { PerformInitializationTasks(settings); PersistentCache::SetCacheSkSL(settings.cache_sksl); @@ -306,7 +326,8 @@ std::unique_ptr 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), // @@ -314,7 +335,8 @@ std::unique_ptr Shell::Create( settings, // std::move(isolate_snapshot), // on_create_platform_view, // - on_create_rasterizer // + on_create_rasterizer, // + on_create_inited ); latch.Signal(); })); @@ -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()); @@ -581,6 +607,23 @@ bool Shell::Setup(std::unique_ptr 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_; } @@ -589,17 +632,23 @@ const TaskRunners& Shell::GetTaskRunners() const { return task_runners_; } -fml::TaskRunnerAffineWeakPtr Shell::GetRasterizer() const { +fml::TaskRunnerAffineWeakPtr Shell::GetRasterizer() { + ensureInitialized(); + ensureSetupped(); FML_DCHECK(is_setup_); return weak_rasterizer_; } fml::WeakPtr Shell::GetEngine() { + ensureInitialized(); + ensureSetupped(); FML_DCHECK(is_setup_); return weak_engine_; } fml::WeakPtr Shell::GetPlatformView() { + ensureInitialized(); + ensureSetupped(); FML_DCHECK(is_setup_); return weak_platform_view_; } @@ -800,6 +849,9 @@ void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) { // |PlatformView::Delegate| void Shell::OnPlatformViewDispatchPlatformMessage( fml::RefPtr message) { + ensureInitialized(); + ensureSetupped(); + FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); diff --git a/shell/common/shell.h b/shell/common/shell.h index e0288bf99ea01..1ea5153fa2b42 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -96,6 +96,8 @@ class Shell final : public PlatformView::Delegate, template using CreateCallback = std::function(Shell&)>; + using InitedCallback = std::function; + //---------------------------------------------------------------------------- /// @brief Creates a shell instance using the provided settings. The /// callbacks to create the various shell subcomponents will be @@ -164,7 +166,8 @@ class Shell final : public PlatformView::Delegate, const PlatformData platform_data, Settings settings, CreateCallback on_create_platform_view, - CreateCallback on_create_rasterizer); + CreateCallback on_create_rasterizer, + const InitedCallback on_create_inited = nullptr); //---------------------------------------------------------------------------- /// @brief Creates a shell instance using the provided settings. The @@ -208,7 +211,7 @@ class Shell final : public PlatformView::Delegate, fml::RefPtr isolate_snapshot, const CreateCallback& on_create_platform_view, const CreateCallback& on_create_rasterizer, - DartVMRef vm); + DartVMRef vm, const InitedCallback& on_create_inited = nullptr); //---------------------------------------------------------------------------- /// @brief Destroys the shell. This is a synchronous operation and @@ -255,7 +258,7 @@ class Shell final : public PlatformView::Delegate, /// /// @return A weak pointer to the rasterizer. /// - fml::TaskRunnerAffineWeakPtr GetRasterizer() const; + fml::TaskRunnerAffineWeakPtr GetRasterizer(); //------------------------------------------------------------------------------ /// @brief Engines may only be accessed on the UI thread. This method is @@ -391,6 +394,8 @@ class Shell final : public PlatformView::Delegate, > service_protocol_handlers_; bool is_setup_ = false; + std::promise initialized_promise_; + std::future initialized_future_; uint64_t next_pointer_flow_id_ = 0; bool first_frame_rasterized_ = false; @@ -430,13 +435,18 @@ class Shell final : public PlatformView::Delegate, Settings settings, fml::RefPtr isolate_snapshot, const Shell::CreateCallback& on_create_platform_view, - const Shell::CreateCallback& on_create_rasterizer); + const Shell::CreateCallback& on_create_rasterizer, + const InitedCallback& on_create_inited = nullptr); bool Setup(std::unique_ptr platform_view, std::unique_ptr engine, std::unique_ptr rasterizer, std::unique_ptr io_manager); + void ensureInitialized(); + + void ensureSetupped(); + void ReportTimings(); // |PlatformView::Delegate| diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 51a741fa4109f..2313e9bd384c4 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -509,12 +509,19 @@ - (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](bool initialized) { + if (initialized) { + [self postInitialized]; + } else { + FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " << entrypoint.UTF8String; + } + } ); } else { flutter::TaskRunners task_runners(threadLabel.UTF8String, // label @@ -523,19 +530,26 @@ - (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](bool initialized) { + if (initialized) { + [self postInitialized]; + } 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 { [self setupChannels]; [self onLocaleUpdated:nil]; if (!_platformViewsController) { @@ -547,9 +561,6 @@ - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI { if (profilerEnabled) { [self startProfiler:threadLabel]; } - } - - return _shell != nullptr; } - (BOOL)run { From 8ee1615a948970a8b39af59e87b888214a186385 Mon Sep 17 00:00:00 2001 From: lybeen Date: Wed, 12 Aug 2020 00:38:54 +0800 Subject: [PATCH 2/3] fix params capture --- .../ios/framework/Source/FlutterEngine.mm | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 2313e9bd384c4..9850bf1894e2f 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -515,9 +515,14 @@ - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI { std::move(settings), // settings on_create_platform_view, // platform view creation on_create_rasterizer, // rasterizer creation - [self, entrypoint = entrypoint](bool initialized) { + [self, entrypoint = entrypoint, + profilerEnabled = profilerEnabled, + threadLabel = threadLabel](bool initialized) { if (initialized) { [self postInitialized]; + if (profilerEnabled) { + [self startProfiler:threadLabel]; + } } else { FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " << entrypoint.UTF8String; } @@ -536,9 +541,14 @@ - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI { std::move(settings), // settings on_create_platform_view, // platform view creation on_create_rasterizer, // rasterizer creation - [self, entrypoint = entrypoint](bool initialized) { + [self, entrypoint = entrypoint, + profilerEnabled = profilerEnabled, + threadLabel = threadLabel](bool initialized) { if (initialized) { [self postInitialized]; + if (profilerEnabled) { + [self startProfiler:threadLabel]; + } } else { FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " << entrypoint.UTF8String; } @@ -558,9 +568,6 @@ - (void)postInitialized { _publisher.reset([[FlutterObservatoryPublisher alloc] init]); [self maybeSetupPlatformViewChannels]; _shell->GetIsGpuDisabledSyncSwitch()->SetSwitch(_isGpuDisabled ? true : false); - if (profilerEnabled) { - [self startProfiler:threadLabel]; - } } - (BOOL)run { From 7269b8316a21c482ff005db4eeca73879118f9af Mon Sep 17 00:00:00 2001 From: laiyi Date: Wed, 12 Aug 2020 11:09:48 +0800 Subject: [PATCH 3/3] fix nsstring in capture --- shell/common/shell.cc | 4 +--- shell/common/shell.h | 2 +- .../ios/framework/Source/FlutterEngine.mm | 21 ++++++++----------- 3 files changed, 11 insertions(+), 16 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index c82d0516a99bb..c6a756d1e50b9 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -632,9 +632,7 @@ const TaskRunners& Shell::GetTaskRunners() const { return task_runners_; } -fml::TaskRunnerAffineWeakPtr Shell::GetRasterizer() { - ensureInitialized(); - ensureSetupped(); +fml::TaskRunnerAffineWeakPtr Shell::GetRasterizer() const{ FML_DCHECK(is_setup_); return weak_rasterizer_; } diff --git a/shell/common/shell.h b/shell/common/shell.h index 1ea5153fa2b42..0a8433892c988 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -258,7 +258,7 @@ class Shell final : public PlatformView::Delegate, /// /// @return A weak pointer to the rasterizer. /// - fml::TaskRunnerAffineWeakPtr GetRasterizer(); + fml::TaskRunnerAffineWeakPtr GetRasterizer() const; //------------------------------------------------------------------------------ /// @brief Engines may only be accessed on the UI thread. This method is diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 9850bf1894e2f..b5d20e56ae2dd 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -517,12 +517,9 @@ - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI { on_create_rasterizer, // rasterizer creation [self, entrypoint = entrypoint, profilerEnabled = profilerEnabled, - threadLabel = threadLabel](bool initialized) { + threadLabel = [threadLabel copy]](bool initialized) { if (initialized) { - [self postInitialized]; - if (profilerEnabled) { - [self startProfiler:threadLabel]; - } + [self postInitialized:profilerEnabled threadLabel:threadLabel]; } else { FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " << entrypoint.UTF8String; } @@ -542,13 +539,10 @@ - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI { on_create_platform_view, // platform view creation on_create_rasterizer, // rasterizer creation [self, entrypoint = entrypoint, - profilerEnabled = profilerEnabled, - threadLabel = threadLabel](bool initialized) { + profilerEnabled, + threadLabel = [threadLabel copy]](bool initialized) { if (initialized) { - [self postInitialized]; - if (profilerEnabled) { - [self startProfiler:threadLabel]; - } + [self postInitialized:profilerEnabled threadLabel:threadLabel]; } else { FML_LOG(ERROR) << "Could not start a shell FlutterEngine with entrypoint: " << entrypoint.UTF8String; } @@ -559,7 +553,7 @@ - (BOOL)createShell:(NSString*)entrypoint libraryURI:(NSString*)libraryURI { return _shell != nullptr; } -- (void)postInitialized { +- (void)postInitialized:(BOOL)profilerEnabled threadLabel:(NSString*)threadLabel { [self setupChannels]; [self onLocaleUpdated:nil]; if (!_platformViewsController) { @@ -568,6 +562,9 @@ - (void)postInitialized { _publisher.reset([[FlutterObservatoryPublisher alloc] init]); [self maybeSetupPlatformViewChannels]; _shell->GetIsGpuDisabledSyncSwitch()->SetSwitch(_isGpuDisabled ? true : false); + if (profilerEnabled) { + [self startProfiler:threadLabel]; + } } - (BOOL)run {