diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index aeb36b9ccabff..ad7cfc263ee5d 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -154,6 +154,11 @@ - (void)dispatchPointerDataPacket:(std::unique_ptr)p return _shell->GetTaskRunners().GetPlatformTaskRunner(); } +- (fml::RefPtr)GPUTaskRunner { + FML_DCHECK(_shell); + return _shell->GetTaskRunners().GetGPUTaskRunner(); +} + - (void)ensureSemanticsEnabled { self.iosPlatformView->SetSemanticsEnabled(true); } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h index 4994814d84415..868d2176a309b 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine_Internal.h @@ -32,6 +32,7 @@ - (void)dispatchPointerDataPacket:(std::unique_ptr)packet; - (fml::RefPtr)platformTaskRunner; +- (fml::RefPtr)GPUTaskRunner; - (fml::WeakPtr)platformView; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm index 74f604d69fa1b..2457cecad9960 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterViewController.mm @@ -308,27 +308,27 @@ - (void)removeSplashScreenView:(dispatch_block_t _Nullable)onComplete { } - (void)installFirstFrameCallback { - auto weak_platform_view = [_engine.get() platformView]; - if (!weak_platform_view) { + fml::WeakPtr weakPlatformView = [_engine.get() platformView]; + if (!weakPlatformView) { return; } - __unsafe_unretained auto weak_flutter_view_controller = self; - // This is on the platform thread. - weak_platform_view->SetNextFrameCallback([weak_platform_view, weak_flutter_view_controller, - task_runner = [_engine.get() platformTaskRunner]]() { - // This is on the GPU thread. - task_runner->PostTask([weak_platform_view, weak_flutter_view_controller]() { - // We check if the weak platform view is alive. If it is alive, then the view controller - // also has to be alive since the view controller owns the platform view via the shell - // association. Thus, we are not convinced that the unsafe unretained weak object is in - // fact alive. - if (weak_platform_view) { - if (weak_flutter_view_controller->_splashScreenView) { - [weak_flutter_view_controller removeSplashScreenView:^{ - [weak_flutter_view_controller callViewRenderedCallback]; + + // Start on the platform thread. + weakPlatformView->SetNextFrameCallback([weakSelf = [self getWeakPtr], + platformTaskRunner = [_engine.get() platformTaskRunner], + gpuTaskRunner = [_engine.get() GPUTaskRunner]]() { + FML_DCHECK(gpuTaskRunner->RunsTasksOnCurrentThread()); + // Get callback on GPU thread and jump back to platform thread. + platformTaskRunner->PostTask([weakSelf]() { + fml::scoped_nsobject flutterViewController( + [(FlutterViewController*)weakSelf.get() retain]); + if (flutterViewController) { + if (flutterViewController.get()->_splashScreenView) { + [flutterViewController removeSplashScreenView:^{ + [flutterViewController callViewRenderedCallback]; }]; } else { - [weak_flutter_view_controller callViewRenderedCallback]; + [flutterViewController callViewRenderedCallback]; } } });