diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index d5527b2bc0678..b92f5b4f8cae6 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -563,6 +563,8 @@ class PlatformView { ComputePlatformResolvedLocales( const std::vector& supported_locale_data); + virtual std::shared_ptr CreateExternalViewEmbedder(); + protected: PlatformView::Delegate& delegate_; const TaskRunners task_runners_; @@ -575,8 +577,6 @@ class PlatformView { // GPU task runner. virtual std::unique_ptr CreateRenderingSurface(); - virtual std::shared_ptr CreateExternalViewEmbedder(); - private: FML_DISALLOW_COPY_AND_ASSIGN(PlatformView); }; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index f316363859de7..adc09eedc0232 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -76,8 +76,8 @@ void Rasterizer::Setup(std::unique_ptr surface) { user_override_resource_cache_bytes_); } compositor_context_->OnGrContextCreated(); - if (surface_->GetExternalViewEmbedder() && - surface_->GetExternalViewEmbedder()->SupportsDynamicThreadMerging() && + if (external_view_embedder_ && + external_view_embedder_->SupportsDynamicThreadMerging() && !raster_thread_merger_) { const auto platform_id = delegate_.GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId(); @@ -191,9 +191,9 @@ void Rasterizer::Draw(fml::RefPtr> pipeline, } // EndFrame should perform cleanups for the external_view_embedder. - if (surface_ != nullptr && surface_->GetExternalViewEmbedder() != nullptr) { - surface_->GetExternalViewEmbedder()->EndFrame(should_resubmit_frame, - raster_thread_merger_); + if (external_view_embedder_) { + external_view_embedder_->EndFrame(should_resubmit_frame, + raster_thread_merger_); } // Consume as many pipeline items as possible. But yield the event loop @@ -423,14 +423,12 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) { // for instrumentation. compositor_context_->ui_time().SetLapTime(layer_tree.build_time()); - auto* external_view_embedder = surface_->GetExternalViewEmbedder(); - SkCanvas* embedder_root_canvas = nullptr; - if (external_view_embedder != nullptr) { - external_view_embedder->BeginFrame( + if (external_view_embedder_) { + external_view_embedder_->BeginFrame( layer_tree.frame_size(), surface_->GetContext(), layer_tree.device_pixel_ratio(), raster_thread_merger_); - embedder_root_canvas = external_view_embedder->GetRootCanvas(); + embedder_root_canvas = external_view_embedder_->GetRootCanvas(); } // On Android, the external view embedder deletes surfaces in `BeginFrame`. @@ -453,13 +451,13 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) { embedder_root_canvas ? embedder_root_canvas : frame->SkiaCanvas(); auto compositor_frame = compositor_context_->AcquireFrame( - surface_->GetContext(), // skia GrContext - root_surface_canvas, // root surface canvas - external_view_embedder, // external view embedder - root_surface_transformation, // root surface transformation - true, // instrumentation enabled - frame->supports_readback(), // surface supports pixel reads - raster_thread_merger_ // thread merger + surface_->GetContext(), // skia GrContext + root_surface_canvas, // root surface canvas + external_view_embedder_.get(), // external view embedder + root_surface_transformation, // root surface transformation + true, // instrumentation enabled + frame->supports_readback(), // surface supports pixel reads + raster_thread_merger_ // thread merger ); if (compositor_frame) { @@ -468,11 +466,11 @@ RasterStatus Rasterizer::DrawToSurface(flutter::LayerTree& layer_tree) { raster_status == RasterStatus::kSkipAndRetry) { return raster_status; } - if (external_view_embedder != nullptr && + if (external_view_embedder_ && (!raster_thread_merger_ || raster_thread_merger_->IsMerged())) { FML_DCHECK(!frame->IsSubmitted()); - external_view_embedder->SubmitFrame(surface_->GetContext(), - std::move(frame)); + external_view_embedder_->SubmitFrame(surface_->GetContext(), + std::move(frame)); } else { frame->Submit(); } @@ -653,6 +651,11 @@ void Rasterizer::SetNextFrameCallback(const fml::closure& callback) { next_frame_callback_ = callback; } +void Rasterizer::SetExternalViewEmbedder( + const std::shared_ptr& view_embedder) { + external_view_embedder_ = view_embedder; +} + void Rasterizer::FireNextFrameCallbackIfPresent() { if (!next_frame_callback_) { return; diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index b658f18e0674c..0637ad37ca955 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -8,6 +8,7 @@ #include #include +#include "flow/embedded_views.h" #include "flutter/common/settings.h" #include "flutter/common/task_runners.h" #include "flutter/flow/compositor_context.h" @@ -349,6 +350,16 @@ class Rasterizer final : public SnapshotDelegate { /// void SetNextFrameCallback(const fml::closure& callback); + //---------------------------------------------------------------------------- + /// @brief Set the External View Embedder. This is done on shell + /// initialization. This is non-null on platforms that support + /// embedding externally composited views. + /// + /// @param[in] view_embedder The external view embedder object. + /// + void SetExternalViewEmbedder( + const std::shared_ptr& view_embedder); + //---------------------------------------------------------------------------- /// @brief Returns a pointer to the compositor context used by this /// rasterizer. This pointer will never be `nullptr`. @@ -437,6 +448,7 @@ class Rasterizer final : public SnapshotDelegate { std::optional max_cache_bytes_; fml::RefPtr raster_thread_merger_; fml::TaskRunnerAffineWeakPtrFactory weak_factory_; + std::shared_ptr external_view_embedder_; // |SnapshotDelegate| sk_sp MakeRasterSnapshot(sk_sp picture, diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 2ccc9ca706bbb..f4f2589a8bb12 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -113,9 +113,9 @@ TEST(RasterizerTest, auto rasterizer = std::make_unique(delegate); auto surface = std::make_unique(); - MockExternalViewEmbedder external_view_embedder; - EXPECT_CALL(*surface, GetExternalViewEmbedder()) - .WillRepeatedly(Return(&external_view_embedder)); + std::shared_ptr external_view_embedder = + std::make_shared(); + rasterizer->SetExternalViewEmbedder(external_view_embedder); auto surface_frame = std::make_unique( /*surface=*/nullptr, /*supports_readback=*/true, @@ -123,15 +123,15 @@ TEST(RasterizerTest, EXPECT_CALL(*surface, AcquireFrame(SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); - EXPECT_CALL(external_view_embedder, + EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, /*device_pixel_ratio=*/2.0, /*raster_thread_merger=*/ fml::RefPtr(nullptr))) .Times(1); - EXPECT_CALL(external_view_embedder, SubmitFrame).Times(1); + EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(1); EXPECT_CALL( - external_view_embedder, + *external_view_embedder, EndFrame(/*should_resubmit_frame=*/false, /*raster_thread_merger=*/fml::RefPtr( nullptr))) @@ -170,10 +170,10 @@ TEST( EXPECT_CALL(delegate, OnFrameRasterized(_)); auto rasterizer = std::make_unique(delegate); auto surface = std::make_unique(); - MockExternalViewEmbedder external_view_embedder; - EXPECT_CALL(*surface, GetExternalViewEmbedder()) - .WillRepeatedly(Return(&external_view_embedder)); - EXPECT_CALL(external_view_embedder, SupportsDynamicThreadMerging) + std::shared_ptr external_view_embedder = + std::make_shared(); + rasterizer->SetExternalViewEmbedder(external_view_embedder); + EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging) .WillRepeatedly(Return(true)); auto surface_frame = std::make_unique( /*surface=*/nullptr, /*supports_readback=*/true, @@ -181,14 +181,14 @@ TEST( EXPECT_CALL(*surface, AcquireFrame(SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); - EXPECT_CALL(external_view_embedder, + EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, /*device_pixel_ratio=*/2.0, /*raster_thread_merger=*/_)) .Times(1); - EXPECT_CALL(external_view_embedder, SubmitFrame).Times(0); - EXPECT_CALL(external_view_embedder, EndFrame(/*should_resubmit_frame=*/false, - /*raster_thread_merger=*/_)) + EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(0); + EXPECT_CALL(*external_view_embedder, EndFrame(/*should_resubmit_frame=*/false, + /*raster_thread_merger=*/_)) .Times(1); rasterizer->Setup(std::move(surface)); @@ -229,26 +229,26 @@ TEST( auto rasterizer = std::make_unique(delegate); auto surface = std::make_unique(); - MockExternalViewEmbedder external_view_embedder; - EXPECT_CALL(*surface, GetExternalViewEmbedder()) - .WillRepeatedly(Return(&external_view_embedder)); + std::shared_ptr external_view_embedder = + std::make_shared(); + rasterizer->SetExternalViewEmbedder(external_view_embedder); auto surface_frame = std::make_unique( /*surface=*/nullptr, /*supports_readback=*/true, /*submit_callback=*/[](const SurfaceFrame&, SkCanvas*) { return true; }); EXPECT_CALL(*surface, AcquireFrame(SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); - EXPECT_CALL(external_view_embedder, SupportsDynamicThreadMerging) + EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging) .WillRepeatedly(Return(true)); - EXPECT_CALL(external_view_embedder, + EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, /*device_pixel_ratio=*/2.0, /*raster_thread_merger=*/_)) .Times(1); - EXPECT_CALL(external_view_embedder, SubmitFrame).Times(1); - EXPECT_CALL(external_view_embedder, EndFrame(/*should_resubmit_frame=*/false, - /*raster_thread_merger=*/_)) + EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(1); + EXPECT_CALL(*external_view_embedder, EndFrame(/*should_resubmit_frame=*/false, + /*raster_thread_merger=*/_)) .Times(1); rasterizer->Setup(std::move(surface)); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 2a21ef7ee1280..1c0c6a4b8a5bc 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -547,6 +547,10 @@ bool Shell::Setup(std::unique_ptr platform_view, rasterizer_ = std::move(rasterizer); io_manager_ = std::move(io_manager); + // Set the external view embedder for the rasterizer. + auto view_embedder = platform_view_->CreateExternalViewEmbedder(); + rasterizer_->SetExternalViewEmbedder(view_embedder); + // The weak ptr must be generated in the platform thread which owns the unique // ptr. weak_engine_ = engine_->GetWeakPtr();