diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index d48442604ff5c..cef4d99848808 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -141,6 +141,10 @@ std::unique_ptr PlatformView::CreateRenderingSurface() { return nullptr; } +void PlatformView::ReleaseSurfaceContext() { + // Do nothing by default +} + std::shared_ptr PlatformView::CreateExternalViewEmbedder() { FML_DLOG(WARNING) diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 1cbf73ce4abea..28fd5994e06b9 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -812,6 +812,16 @@ class PlatformView { virtual std::unique_ptr CreateSnapshotSurfaceProducer(); + //---------------------------------------------------------------------------- + /// @brief Used by the shell to notify the embedder that all the + /// rendering surface previously obtained via a call to + /// `CreateRenderingSurface()` are being collected. The embedder + /// should collect the shared context of surfaces + /// + /// @attention This should be called on the rasterizer task runner. + /// + virtual void ReleaseSurfaceContext(); + protected: PlatformView::Delegate& delegate_; const TaskRunners task_runners_; diff --git a/shell/common/shell.cc b/shell/common/shell.cc index f9666183608b6..bd39a7b226a3c 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -443,12 +443,16 @@ Shell::~Shell() { fml::TaskRunner::RunNowOrPostTask( task_runners_.GetRasterTaskRunner(), - fml::MakeCopyable( - [this, rasterizer = std::move(rasterizer_), &gpu_latch]() mutable { - rasterizer.reset(); - this->weak_factory_gpu_.reset(); - gpu_latch.Signal(); - })); + fml::MakeCopyable([this, rasterizer = std::move(rasterizer_), + platform_view = platform_view_.get(), + &gpu_latch]() mutable { + rasterizer.reset(); + this->weak_factory_gpu_.reset(); + if (platform_view) { + platform_view->ReleaseSurfaceContext(); + } + gpu_latch.Signal(); + })); gpu_latch.Wait(); fml::TaskRunner::RunNowOrPostTask( diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index 899870961c639..02a03102e1f5d 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -35,9 +35,11 @@ AndroidSurfaceFactoryImpl::~AndroidSurfaceFactoryImpl() = default; std::unique_ptr AndroidSurfaceFactoryImpl::CreateSurface() { switch (android_context_->RenderingApi()) { case AndroidRenderingAPI::kSoftware: + FML_DCHECK(android_context_); return std::make_unique(android_context_, jni_facade_); case AndroidRenderingAPI::kOpenGLES: + FML_DCHECK(android_context_); return std::make_unique(android_context_, jni_facade_); default: FML_DCHECK(false); @@ -290,16 +292,25 @@ std::unique_ptr PlatformViewAndroid::CreateVSyncWaiter() { // |PlatformView| std::unique_ptr PlatformViewAndroid::CreateRenderingSurface() { - if (!android_surface_) { + if (!android_surface_ || !android_context_) { return nullptr; } return android_surface_->CreateGPUSurface( android_context_->GetMainSkiaContext().get()); } +// |PlatformView| +void PlatformViewAndroid::ReleaseSurfaceContext() { + FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); + if (android_context_) { + android_context_.reset(); + } +} + // |PlatformView| std::shared_ptr PlatformViewAndroid::CreateExternalViewEmbedder() { + FML_DCHECK(android_context_); return std::make_shared( *android_context_, jni_facade_, surface_factory_); } diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index 3bb4195126373..62553f4ac38fe 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -149,6 +149,9 @@ class PlatformViewAndroid final : public PlatformView { // |PlatformView| std::unique_ptr CreateRenderingSurface() override; + // |PlatformView| + void ReleaseSurfaceContext() override; + // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index 4010da254bd1d..d3dc35940c0fe 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -152,6 +152,9 @@ class PlatformViewIOS final : public PlatformView { // |PlatformView| std::unique_ptr CreateRenderingSurface() override; + // |PlatformView| + void ReleaseSurfaceContext() override; + // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 081bbe0db130a..44a37f1c77935 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -113,6 +113,7 @@ void PlatformViewIOS::attachView() { FML_DCHECK(owner_controller_); + FML_DCHECK(ios_context_); FML_DCHECK(owner_controller_.get().isViewLoaded) << "FlutterViewController's view should be loaded " "before attaching to PlatformViewIOS."; @@ -135,6 +136,7 @@ void PlatformViewIOS::RegisterExternalTexture(int64_t texture_id, NSObject* texture) { + FML_DCHECK(ios_context_); RegisterTexture(ios_context_->CreateExternalTexture( texture_id, fml::scoped_nsobject>{[texture retain]})); } @@ -142,6 +144,7 @@ // |PlatformView| std::unique_ptr PlatformViewIOS::CreateRenderingSurface() { FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); + FML_DCHECK(ios_context_); std::lock_guard guard(ios_surface_mutex_); if (!ios_surface_) { FML_DLOG(INFO) << "Could not CreateRenderingSurface, this PlatformViewIOS " @@ -151,13 +154,23 @@ return ios_surface_->CreateGPUSurface(ios_context_->GetMainContext().get()); } +// |PlatformView| +void PlatformViewIOS::ReleaseSurfaceContext() { + FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); + if (ios_context_) { + ios_context_.reset(); + } +} + // |PlatformView| std::shared_ptr PlatformViewIOS::CreateExternalViewEmbedder() { + FML_DCHECK(ios_context_); return std::make_shared(platform_views_controller_, ios_context_); } // |PlatformView| sk_sp PlatformViewIOS::CreateResourceContext() const { + FML_DCHECK(ios_context_); return ios_context_->CreateResourceContext(); }