diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc index e1936d1af7d20..1907762ca0584 100644 --- a/flow/embedded_views.cc +++ b/flow/embedded_views.cc @@ -42,13 +42,19 @@ bool DisplayListEmbedderViewSlice::recording_ended() { return builder_ == nullptr; } -void ExternalViewEmbedder::SubmitFrame( +void ExternalViewEmbedder::SubmitFlutterView( GrDirectContext* context, const std::shared_ptr& aiks_context, std::unique_ptr frame) { frame->Submit(); } +bool ExternalViewEmbedder::SupportsDynamicThreadMerging() { + return false; +} + +void ExternalViewEmbedder::Teardown() {} + void MutatorsStack::PushClipRect(const SkRect& rect) { std::shared_ptr element = std::make_shared(rect); vector_.push_back(element); @@ -112,10 +118,4 @@ const std::vector>::const_iterator MutatorsStack::End() return vector_.end(); } -bool ExternalViewEmbedder::SupportsDynamicThreadMerging() { - return false; -} - -void ExternalViewEmbedder::Teardown() {} - } // namespace flutter diff --git a/flow/embedded_views.h b/flow/embedded_views.h index ed414ed678e35..745c91d9dd2f5 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -369,6 +369,29 @@ class DisplayListEmbedderViewSlice : public EmbedderViewSlice { // // Used on iOS, Android (hybrid composite mode), and on embedded platforms // that provide a system compositor as part of the project arguments. +// +// There are two kinds of "view IDs" in the context of ExternalViewEmbedder, and +// specific names are used to avoid ambiguation: +// +// * ExternalViewEmbedder composites a stack of layers. Each layer's content +// might be from Flutter widgets, or a platform view, which displays platform +// native components. Each platform view is labeled by a view ID, which +// corresponds to the ID from `PlatformViewsRegistry.getNextPlatformViewId` +// from the framework. In the context of `ExternalViewEmbedder`, this ID is +// called platform_view_id. +// * The layers are compositied into a single rectangular surface, displayed by +// taking up an entire native window or part of a window. Each such surface +// is labeled by a view ID, which corresponds to `FlutterView.viewID` from +// dart:ui. In the context of `ExternalViewEmbedder`, this ID is called +// flutter_view_id. +// +// The lifecycle of drawing a frame using ExternalViewEmbedder is: +// +// 1. At the start of a frame, call |BeginFrame|, then |SetUsedThisFrame| to +// true. +// 2. For each view to be drawn, call |PrepareFlutterView|, then +// |SubmitFlutterView|. +// 3. At the end of a frame, if |GetUsedThisFrame| is true, call |EndFrame|. class ExternalViewEmbedder { // TODO(cyanglaz): Make embedder own the `EmbeddedViewParams`. @@ -383,7 +406,7 @@ class ExternalViewEmbedder { // from the on-screen render target. virtual DlCanvas* GetRootCanvas() = 0; - // Call this in-lieu of |SubmitFrame| to clear pre-roll state and + // Call this in-lieu of |SubmitFlutterView| to clear pre-roll state and // sets the stage for the next pre-roll. virtual void CancelFrame() = 0; @@ -392,13 +415,11 @@ class ExternalViewEmbedder { // The `raster_thread_merger` will be null if |SupportsDynamicThreadMerging| // returns false. virtual void BeginFrame( - SkISize frame_size, GrDirectContext* context, - double device_pixel_ratio, const fml::RefPtr& raster_thread_merger) = 0; virtual void PrerollCompositeEmbeddedView( - int64_t view_id, + int64_t platform_view_id, std::unique_ptr params) = 0; // This needs to get called after |Preroll| finishes on the layer tree. @@ -411,14 +432,19 @@ class ExternalViewEmbedder { } // Must be called on the UI thread. - virtual DlCanvas* CompositeEmbeddedView(int64_t view_id) = 0; + virtual DlCanvas* CompositeEmbeddedView(int64_t platform_view_id) = 0; + + // Prepare for a view to be drawn. + virtual void PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) = 0; // Implementers must submit the frame by calling frame.Submit(). // // This method can mutate the root Skia canvas before submitting the frame. // // It can also allocate frames for overlay surfaces to compose hybrid views. - virtual void SubmitFrame( + virtual void SubmitFlutterView( GrDirectContext* context, const std::shared_ptr& aiks_context, std::unique_ptr frame); @@ -462,7 +488,7 @@ class ExternalViewEmbedder { // Pushes the platform view id of a visited platform view to a list of // visited platform views. - virtual void PushVisitedPlatformView(int64_t view_id) {} + virtual void PushVisitedPlatformView(int64_t platform_view_id) {} // Pushes a DlImageFilter object to each platform view within a list of // visited platform views. diff --git a/flow/testing/mock_embedder.cc b/flow/testing/mock_embedder.cc index 1f86912fdc549..3cec9fecdbf34 100644 --- a/flow/testing/mock_embedder.cc +++ b/flow/testing/mock_embedder.cc @@ -25,11 +25,14 @@ void MockViewEmbedder::CancelFrame() {} // |ExternalViewEmbedder| void MockViewEmbedder::BeginFrame( - SkISize frame_size, GrDirectContext* context, - double device_pixel_ratio, const fml::RefPtr& raster_thread_merger) {} +// |ExternalViewEmbedder| +void MockViewEmbedder::PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) {} + // |ExternalViewEmbedder| void MockViewEmbedder::PrerollCompositeEmbeddedView( int64_t view_id, diff --git a/flow/testing/mock_embedder.h b/flow/testing/mock_embedder.h index 5ea8fdf8a7cbc..cd16358234095 100644 --- a/flow/testing/mock_embedder.h +++ b/flow/testing/mock_embedder.h @@ -25,12 +25,15 @@ class MockViewEmbedder : public ExternalViewEmbedder { void CancelFrame() override; // |ExternalViewEmbedder| - void BeginFrame(SkISize frame_size, - GrDirectContext* context, - double device_pixel_ratio, + void BeginFrame(GrDirectContext* context, const fml::RefPtr& raster_thread_merger) override; + // |ExternalViewEmbedder| + void PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) override; + // |ExternalViewEmbedder| void PrerollCompositeEmbeddedView( int64_t view_id, diff --git a/lib/web_ui/test/engine/hash_codes_test.dart b/lib/web_ui/test/engine/hash_codes_test.dart index 7e34ed20db30d..7c0c7afbbdc93 100644 --- a/lib/web_ui/test/engine/hash_codes_test.dart +++ b/lib/web_ui/test/engine/hash_codes_test.dart @@ -16,6 +16,10 @@ void main() { internalBootstrapBrowserTest(() => testMain); } +// Ignoring the deprecated member use because we're specifically testing +// deprecated API. +// ignore: deprecated_member_use + void testMain() { test('hashValues and hashList can hash lots of huge values effectively', () { final int hashValueFromArgs = hashValues( diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 7106a8aaae534..24d975ed5c0bc 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -562,13 +562,6 @@ Rasterizer::DoDrawResult Rasterizer::DrawToSurfaces( std::unique_ptr Rasterizer::DrawToSurfacesUnsafe( FrameTimingsRecorder& frame_timings_recorder, std::vector> tasks) { - // TODO(dkwingsmt): The rasterizer only supports rendering a single view - // and that view must be the implicit view. Properly support multi-view - // in the future. - // See https://github.com/flutter/flutter/issues/135530, item 2 & 4. - FML_CHECK(tasks.size() == 1u) << "Unexpected size of " << tasks.size(); - FML_DCHECK(tasks.front()->view_id == kFlutterImplicitViewId); - compositor_context_->ui_time().SetLapTime( frame_timings_recorder.GetBuildDuration()); @@ -593,11 +586,8 @@ std::unique_ptr Rasterizer::DrawToSurfacesUnsafe( if (external_view_embedder_) { FML_DCHECK(!external_view_embedder_->GetUsedThisFrame()); external_view_embedder_->SetUsedThisFrame(true); - external_view_embedder_->BeginFrame( - // TODO(dkwingsmt): Add all views here. - // See https://github.com/flutter/flutter/issues/135530, item 4. - tasks.front()->layer_tree->frame_size(), surface_->GetContext(), - tasks.front()->device_pixel_ratio, raster_thread_merger_); + external_view_embedder_->BeginFrame(surface_->GetContext(), + raster_thread_merger_); } std::optional presentation_time = std::nullopt; @@ -664,6 +654,8 @@ DrawSurfaceStatus Rasterizer::DrawToSurfaceUnsafe( DlCanvas* embedder_root_canvas = nullptr; if (external_view_embedder_) { + external_view_embedder_->PrepareFlutterView( + view_id, layer_tree.frame_size(), device_pixel_ratio); // TODO(dkwingsmt): Add view ID here. embedder_root_canvas = external_view_embedder_->GetRootCanvas(); } @@ -704,7 +696,7 @@ DrawSurfaceStatus Rasterizer::DrawToSurfaceUnsafe( // for accurate performance metrics. if (frame->framebuffer_info().supports_partial_repaint && !layer_tree.is_leaf_layer_tracing_enabled()) { - // Disable partial repaint if external_view_embedder_ SubmitFrame is + // Disable partial repaint if external_view_embedder_ SubmitFlutterView is // involved - ExternalViewEmbedder unconditionally clears the entire // surface and also partial repaint with platform view present is // something that still need to be figured out. @@ -750,7 +742,7 @@ DrawSurfaceStatus Rasterizer::DrawToSurfaceUnsafe( if (external_view_embedder_ && (!raster_thread_merger_ || raster_thread_merger_->IsMerged())) { FML_DCHECK(!frame->IsSubmitted()); - external_view_embedder_->SubmitFrame( + external_view_embedder_->SubmitFlutterView( surface_->GetContext(), surface_->GetAiksContext(), std::move(frame)); } else { frame->Submit(); diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index d800bbdb3a5ed..7265bb887578f 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -92,11 +92,15 @@ class MockExternalViewEmbedder : public ExternalViewEmbedder { MOCK_METHOD( void, BeginFrame, - (SkISize frame_size, - GrDirectContext* context, - double device_pixel_ratio, + (GrDirectContext * context, const fml::RefPtr& raster_thread_merger), (override)); + MOCK_METHOD(void, + PrepareFlutterView, + (int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio), + (override)); MOCK_METHOD(void, PrerollCompositeEmbeddedView, (int64_t view_id, std::unique_ptr params), @@ -108,7 +112,7 @@ class MockExternalViewEmbedder : public ExternalViewEmbedder { (override)); MOCK_METHOD(DlCanvas*, CompositeEmbeddedView, (int64_t view_id), (override)); MOCK_METHOD(void, - SubmitFrame, + SubmitFlutterView, (GrDirectContext * context, const std::shared_ptr& aiks_context, std::unique_ptr frame), @@ -215,12 +219,16 @@ TEST(RasterizerTest, .WillOnce(Return(ByMove(std::make_unique(true)))); EXPECT_CALL(*external_view_embedder, - BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, - /*device_pixel_ratio=*/2.0, + BeginFrame(/*context=*/nullptr, /*raster_thread_merger=*/ fml::RefPtr(nullptr))) .Times(1); - EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(1); + EXPECT_CALL(*external_view_embedder, + PrepareFlutterView(/*flutter_view_id=*/kImplicitViewId, + /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0)) + .Times(1); + EXPECT_CALL(*external_view_embedder, SubmitFlutterView).Times(1); EXPECT_CALL( *external_view_embedder, EndFrame(/*should_resubmit_frame=*/false, @@ -288,12 +296,15 @@ TEST( EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); + EXPECT_CALL(*external_view_embedder, BeginFrame(/*context=*/nullptr, + /*raster_thread_merger=*/_)) + .Times(1); EXPECT_CALL(*external_view_embedder, - BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, - /*device_pixel_ratio=*/2.0, - /*raster_thread_merger=*/_)) + PrepareFlutterView(/*flutter_view_id=*/kImplicitViewId, + /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0)) .Times(1); - EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(0); + EXPECT_CALL(*external_view_embedder, SubmitFlutterView).Times(0); EXPECT_CALL(*external_view_embedder, EndFrame(/*should_resubmit_frame=*/false, /*raster_thread_merger=*/_)) .Times(1); @@ -364,12 +375,15 @@ TEST( EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging) .WillRepeatedly(Return(true)); + EXPECT_CALL(*external_view_embedder, BeginFrame(/*context=*/nullptr, + /*raster_thread_merger=*/_)) + .Times(1); EXPECT_CALL(*external_view_embedder, - BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, - /*device_pixel_ratio=*/2.0, - /*raster_thread_merger=*/_)) + PrepareFlutterView(/*flutter_view_id=*/kImplicitViewId, + /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0)) .Times(1); - EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(1); + EXPECT_CALL(*external_view_embedder, SubmitFlutterView).Times(1); EXPECT_CALL(*external_view_embedder, EndFrame(/*should_resubmit_frame=*/false, /*raster_thread_merger=*/_)) .Times(1); @@ -443,12 +457,15 @@ TEST(RasterizerTest, EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging) .WillRepeatedly(Return(true)); + EXPECT_CALL(*external_view_embedder, BeginFrame(/*context=*/nullptr, + /*raster_thread_merger=*/_)) + .Times(2); EXPECT_CALL(*external_view_embedder, - BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, - /*device_pixel_ratio=*/2.0, - /*raster_thread_merger=*/_)) + PrepareFlutterView(/*flutter_view_id=*/kImplicitViewId, + /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0)) .Times(2); - EXPECT_CALL(*external_view_embedder, SubmitFrame).Times(2); + EXPECT_CALL(*external_view_embedder, SubmitFlutterView).Times(2); EXPECT_CALL(*external_view_embedder, EndFrame(/*should_resubmit_frame=*/false, /*raster_thread_merger=*/_)) .Times(2); @@ -466,13 +483,13 @@ TEST(RasterizerTest, pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - // The Draw() will respectively call BeginFrame(), SubmitFrame() and + // The Draw() will respectively call BeginFrame(), SubmitFlutterView() and // EndFrame() one time. ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); rasterizer->Draw(pipeline); - // The DrawLastLayerTrees() will respectively call BeginFrame(), SubmitFrame() - // and EndFrame() one more time, totally 2 times. + // The DrawLastLayerTrees() will respectively call BeginFrame(), + // SubmitFlutterView() and EndFrame() one more time, totally 2 times. rasterizer->DrawLastLayerTrees(CreateFinishedBuildRecorder()); } @@ -555,10 +572,13 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(surface)); + EXPECT_CALL(*external_view_embedder, BeginFrame(/*context=*/nullptr, + /*raster_thread_merger=*/_)) + .Times(0); EXPECT_CALL(*external_view_embedder, - BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, - /*device_pixel_ratio=*/2.0, - /*raster_thread_merger=*/_)) + PrepareFlutterView(/*flutter_view_id=*/kImplicitViewId, + /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0)) .Times(0); EXPECT_CALL( *external_view_embedder, @@ -635,6 +655,83 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { latch.Wait(); } +TEST(RasterizerTest, drawMultipleViewsWithExternalViewEmbedder) { + std::string test_name = + ::testing::UnitTest::GetInstance()->current_test_info()->name(); + ThreadHost thread_host("io.flutter.test." + test_name + ".", + ThreadHost::Type::kPlatform | + ThreadHost::Type::kRaster | ThreadHost::Type::kIo | + ThreadHost::Type::kUi); + TaskRunners task_runners("test", thread_host.platform_thread->GetTaskRunner(), + thread_host.raster_thread->GetTaskRunner(), + thread_host.ui_thread->GetTaskRunner(), + thread_host.io_thread->GetTaskRunner()); + NiceMock delegate; + Settings settings; + ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings)); + EXPECT_CALL(delegate, GetTaskRunners()) + .WillRepeatedly(ReturnRef(task_runners)); + EXPECT_CALL(delegate, OnFrameRasterized(_)); + auto rasterizer = std::make_unique(delegate); + auto surface = std::make_unique>(); + std::shared_ptr> external_view_embedder = + std::make_shared>(); + rasterizer->SetExternalViewEmbedder(external_view_embedder); + EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging) + .WillRepeatedly(Return(false)); + EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); + EXPECT_CALL(*surface, AcquireFrame(SkISize())).Times(2); + ON_CALL(*surface, AcquireFrame).WillByDefault([](const SkISize& size) { + SurfaceFrame::FramebufferInfo framebuffer_info; + framebuffer_info.supports_readback = true; + return std::make_unique( + /*surface=*/ + nullptr, framebuffer_info, + /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, + /*frame_size=*/SkISize::Make(800, 600)); + }); + EXPECT_CALL(*surface, MakeRenderContextCurrent()) + .WillOnce(Return(ByMove(std::make_unique(true)))); + + EXPECT_CALL(*external_view_embedder, BeginFrame(/*context=*/nullptr, + /*raster_thread_merger=*/_)) + .Times(1); + EXPECT_CALL( + *external_view_embedder, + PrepareFlutterView(/*flutter_view_id=*/0, /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/1.5)) + .Times(1); + EXPECT_CALL( + *external_view_embedder, + PrepareFlutterView(/*flutter_view_id=*/1, /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0)) + .Times(1); + EXPECT_CALL(*external_view_embedder, SubmitFlutterView).Times(2); + EXPECT_CALL(*external_view_embedder, EndFrame(/*should_resubmit_frame=*/false, + /*raster_thread_merger=*/_)) + .Times(1); + + rasterizer->Setup(std::move(surface)); + fml::AutoResetWaitableEvent latch; + thread_host.raster_thread->GetTaskRunner()->PostTask([&] { + auto pipeline = std::make_shared(/*depth=*/10); + std::vector> tasks; + tasks.push_back(std::make_unique( + 0, std::make_unique(LayerTree::Config(), SkISize()), 1.5)); + tasks.push_back(std::make_unique( + 1, std::make_unique(LayerTree::Config(), SkISize()), 2.0)); + auto layer_tree_item = std::make_unique( + std::move(tasks), CreateFinishedBuildRecorder()); + PipelineProduceResult result = + pipeline->Produce().Complete(std::move(layer_tree_item)); + EXPECT_TRUE(result.success); + ON_CALL(delegate, ShouldDiscardLayerTree).WillByDefault(Return(false)); + rasterizer->Draw(pipeline); + latch.Signal(); + }); + latch.Wait(); +} + TEST(RasterizerTest, drawWithGpuEnabledAndSurfaceAllowsDrawingWhenGpuDisabledDoesAcquireFrame) { std::string test_name = diff --git a/shell/common/shell_test_external_view_embedder.cc b/shell/common/shell_test_external_view_embedder.cc index 6c87e734982c2..d03a2a57cde89 100644 --- a/shell/common/shell_test_external_view_embedder.cc +++ b/shell/common/shell_test_external_view_embedder.cc @@ -41,10 +41,14 @@ void ShellTestExternalViewEmbedder::CancelFrame() {} // |ExternalViewEmbedder| void ShellTestExternalViewEmbedder::BeginFrame( - SkISize frame_size, GrDirectContext* context, - double device_pixel_ratio, - const fml::RefPtr& raster_thread_merger) { + const fml::RefPtr& raster_thread_merger) {} + +// |ExternalViewEmbedder| +void ShellTestExternalViewEmbedder::PrepareFlutterView( + int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) { visited_platform_views_.clear(); mutators_stacks_.clear(); current_composition_params_.clear(); @@ -89,7 +93,7 @@ DlCanvas* ShellTestExternalViewEmbedder::CompositeEmbeddedView( } // |ExternalViewEmbedder| -void ShellTestExternalViewEmbedder::SubmitFrame( +void ShellTestExternalViewEmbedder::SubmitFlutterView( GrDirectContext* context, const std::shared_ptr& aiks_context, std::unique_ptr frame) { diff --git a/shell/common/shell_test_external_view_embedder.h b/shell/common/shell_test_external_view_embedder.h index 93aca8578f0d3..f378dce348555 100644 --- a/shell/common/shell_test_external_view_embedder.h +++ b/shell/common/shell_test_external_view_embedder.h @@ -28,7 +28,7 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder { // returns the new `post_preroll_result`. void UpdatePostPrerollResult(PostPrerollResult post_preroll_result); - // Gets the number of times the SubmitFrame method has been called in + // Gets the number of times the SubmitFlutterView method has been called in // the external view embedder. int GetSubmittedFrameCount(); @@ -46,12 +46,15 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder { void CancelFrame() override; // |ExternalViewEmbedder| - void BeginFrame(SkISize frame_size, - GrDirectContext* context, - double device_pixel_ratio, + void BeginFrame(GrDirectContext* context, const fml::RefPtr& raster_thread_merger) override; + // |ExternalViewEmbedder| + void PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) override; + // |ExternalViewEmbedder| void PrerollCompositeEmbeddedView( int64_t view_id, @@ -74,9 +77,10 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder { const SkRect& filter_rect) override; // |ExternalViewEmbedder| - void SubmitFrame(GrDirectContext* context, - const std::shared_ptr& aiks_context, - std::unique_ptr frame) override; + void SubmitFlutterView( + GrDirectContext* context, + const std::shared_ptr& aiks_context, + std::unique_ptr frame) override; // |ExternalViewEmbedder| void EndFrame(bool should_resubmit_frame, diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.cc b/shell/platform/android/external_view_embedder/external_view_embedder.cc index e92edbca5996e..2ec5a9ac198a7 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "flutter/shell/platform/android/external_view_embedder/external_view_embedder.h" +#include "flutter/common/constants.h" #include "flutter/fml/synchronization/waitable_event.h" #include "flutter/fml/trace_event.h" @@ -62,11 +63,11 @@ SkRect AndroidExternalViewEmbedder::GetViewRect(int64_t view_id) const { } // |ExternalViewEmbedder| -void AndroidExternalViewEmbedder::SubmitFrame( +void AndroidExternalViewEmbedder::SubmitFlutterView( GrDirectContext* context, const std::shared_ptr& aiks_context, std::unique_ptr frame) { - TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFrame"); + TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFlutterView"); if (!FrameHasPlatformLayers()) { frame->Submit(); @@ -257,10 +258,22 @@ void AndroidExternalViewEmbedder::Reset() { // |ExternalViewEmbedder| void AndroidExternalViewEmbedder::BeginFrame( - SkISize frame_size, GrDirectContext* context, - double device_pixel_ratio, const fml::RefPtr& raster_thread_merger) { + // JNI method must be called on the platform thread. + if (raster_thread_merger->IsOnPlatformThread()) { + jni_facade_->FlutterViewBeginFrame(); + } +} + +// |ExternalViewEmbedder| +void AndroidExternalViewEmbedder::PrepareFlutterView( + int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) { + // TODO(dkwingsmt): This class only supports rendering into the implicit view. + // Properly support multi-view in the future. + FML_DCHECK(flutter_view_id == kFlutterImplicitViewId); Reset(); // The surface size changed. Therefore, destroy existing surfaces as @@ -269,10 +282,6 @@ void AndroidExternalViewEmbedder::BeginFrame( DestroySurfaces(); } surface_pool_->SetFrameSize(frame_size); - // JNI method must be called on the platform thread. - if (raster_thread_merger->IsOnPlatformThread()) { - jni_facade_->FlutterViewBeginFrame(); - } frame_size_ = frame_size; device_pixel_ratio_ = device_pixel_ratio; diff --git a/shell/platform/android/external_view_embedder/external_view_embedder.h b/shell/platform/android/external_view_embedder/external_view_embedder.h index a84681ab098d5..98b02daa80b7e 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.h +++ b/shell/platform/android/external_view_embedder/external_view_embedder.h @@ -43,9 +43,10 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder { DlCanvas* CompositeEmbeddedView(int64_t view_id) override; // |ExternalViewEmbedder| - void SubmitFrame(GrDirectContext* context, - const std::shared_ptr& aiks_context, - std::unique_ptr frame) override; + void SubmitFlutterView( + GrDirectContext* context, + const std::shared_ptr& aiks_context, + std::unique_ptr frame) override; // |ExternalViewEmbedder| PostPrerollResult PostPrerollAction( @@ -56,12 +57,15 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder { DlCanvas* GetRootCanvas() override; // |ExternalViewEmbedder| - void BeginFrame(SkISize frame_size, - GrDirectContext* context, - double device_pixel_ratio, + void BeginFrame(GrDirectContext* context, const fml::RefPtr& raster_thread_merger) override; + // |ExternalViewEmbedder| + void PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) override; + // |ExternalViewEmbedder| void CancelFrame() override; diff --git a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc index e6417a08f0800..0cb9f7ac11824 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder_unittests.cc @@ -27,6 +27,8 @@ namespace testing { using ::testing::ByMove; using ::testing::Return; +constexpr int64_t kImplicitViewId = 0; + class TestAndroidSurfaceFactory : public AndroidSurfaceFactory { public: using TestSurfaceProducer = @@ -144,8 +146,9 @@ TEST(AndroidExternalViewEmbedder, RasterizerRunsOnPlatformThread) { ASSERT_FALSE(raster_thread_merger->IsMerged()); EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); - embedder->BeginFrame(SkISize::Make(10, 20), nullptr, 1.0, - raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, SkISize::Make(10, 20), 1.0); + // Push a platform view. embedder->PrerollCompositeEmbeddedView( 0, std::make_unique()); @@ -197,8 +200,8 @@ TEST(AndroidExternalViewEmbedder, PlatformViewRect) { GetThreadMergerFromPlatformThread(&rasterizer_thread); EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); - embedder->BeginFrame(SkISize::Make(100, 100), nullptr, 1.5, - raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, SkISize::Make(100, 100), 1.5); MutatorsStack stack; SkMatrix matrix; @@ -225,8 +228,8 @@ TEST(AndroidExternalViewEmbedder, PlatformViewRectChangedParams) { GetThreadMergerFromPlatformThread(&rasterizer_thread); EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); - embedder->BeginFrame(SkISize::Make(100, 100), nullptr, 1.5, - raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, SkISize::Make(100, 100), 1.5); auto view_id = 0; @@ -254,7 +257,7 @@ TEST(AndroidExternalViewEmbedder, PlatformViewRectChangedParams) { ASSERT_EQ(SkRect::MakeXYWH(75, 90, 105, 120), embedder->GetViewRect(view_id)); } -TEST(AndroidExternalViewEmbedder, SubmitFrame) { +TEST(AndroidExternalViewEmbedder, SubmitFlutterView) { auto jni_mock = std::make_shared(); auto android_context = std::make_shared(AndroidRenderingAPI::kSoftware); @@ -313,7 +316,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); + embedder->SubmitFlutterView(gr_context.get(), nullptr, + std::move(surface_frame)); // Submits frame if no Android view in the current frame. EXPECT_TRUE(did_submit_frame); // Doesn't resubmit frame. @@ -327,7 +331,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { // ------------------ Second frame ------------------ // { EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); - embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, frame_size, 1.5); // Add an Android view. MutatorsStack stack1; @@ -381,7 +386,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); + embedder->SubmitFlutterView(gr_context.get(), nullptr, + std::move(surface_frame)); // Doesn't submit frame if there aren't Android views in the previous frame. EXPECT_FALSE(did_submit_frame); // Resubmits frame. @@ -395,7 +401,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { // ------------------ Third frame ------------------ // { EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); - embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, frame_size, 1.5); // Add an Android view. MutatorsStack stack1; @@ -446,7 +453,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); + embedder->SubmitFlutterView(gr_context.get(), nullptr, + std::move(surface_frame)); // Submits frame if there are Android views in the previous frame. EXPECT_TRUE(did_submit_frame); // Doesn't resubmit frame. @@ -499,7 +507,8 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) { auto raster_thread_merger = GetThreadMergerFromPlatformThread(); EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); - embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, frame_size, 1.5); { // Add first Android view. @@ -553,7 +562,8 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); + embedder->SubmitFlutterView(gr_context.get(), nullptr, + std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -597,7 +607,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) { auto raster_thread_merger = GetThreadMergerFromPlatformThread(); EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); - embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, frame_size, 1.5); { // Add first Android view. @@ -656,7 +667,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); + embedder->SubmitFlutterView(gr_context.get(), nullptr, + std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -700,7 +712,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) { auto raster_thread_merger = GetThreadMergerFromPlatformThread(); EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); - embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, frame_size, 1.5); { // Add Android view. @@ -724,7 +737,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); + embedder->SubmitFlutterView(gr_context.get(), nullptr, + std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -743,8 +757,8 @@ TEST(AndroidExternalViewEmbedder, DoesNotCallJNIPlatformThreadOnlyMethods) { auto raster_thread_merger = GetThreadMergerFromRasterThread(&platform_thread); EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()).Times(0); - embedder->BeginFrame(SkISize::Make(10, 20), nullptr, 1.0, - raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, SkISize::Make(10, 20), 1.0); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()).Times(0); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -792,7 +806,8 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) { // ------------------ First frame ------------------ // { EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); - embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, frame_size, 1.5); // Add an Android view. MutatorsStack stack1; @@ -825,7 +840,8 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); + embedder->SubmitFlutterView(gr_context.get(), nullptr, + std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -834,8 +850,8 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) { EXPECT_CALL(*jni_mock, FlutterViewDestroyOverlaySurfaces()); EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); // Change the frame size. - embedder->BeginFrame(SkISize::Make(30, 40), nullptr, 1.0, - raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, SkISize::Make(30, 40), 1.0); } TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { @@ -880,7 +896,8 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { auto raster_thread_merger = GetThreadMergerFromPlatformThread(&rasterizer_thread); EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()); - embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, frame_size, 1.5); // Add an Android view. MutatorsStack stack1; @@ -912,7 +929,8 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); + embedder->SubmitFlutterView(gr_context.get(), nullptr, + std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -922,8 +940,9 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()).Times(0); fml::Thread platform_thread("platform"); - embedder->BeginFrame(SkISize::Make(30, 40), nullptr, 1.0, + embedder->BeginFrame(nullptr, GetThreadMergerFromRasterThread(&platform_thread)); + embedder->PrepareFlutterView(kImplicitViewId, SkISize::Make(30, 40), 1.0); } TEST(AndroidExternalViewEmbedder, SupportsDynamicThreadMerging) { @@ -949,8 +968,8 @@ TEST(AndroidExternalViewEmbedder, DisableThreadMerger) { EXPECT_CALL(*jni_mock, FlutterViewBeginFrame()).Times(0); - embedder->BeginFrame(SkISize::Make(10, 20), nullptr, 1.0, - raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, SkISize::Make(10, 20), 1.0); // Push a platform view. embedder->PrerollCompositeEmbeddedView( 0, std::make_unique()); @@ -999,7 +1018,8 @@ TEST(AndroidExternalViewEmbedder, Teardown) { auto raster_thread_merger = GetThreadMergerFromPlatformThread(&rasterizer_thread); - embedder->BeginFrame(frame_size, nullptr, 1.5, raster_thread_merger); + embedder->BeginFrame(nullptr, raster_thread_merger); + embedder->PrepareFlutterView(kImplicitViewId, frame_size, 1.5); // Add an Android view. MutatorsStack stack; @@ -1023,7 +1043,8 @@ TEST(AndroidExternalViewEmbedder, Teardown) { SkSurfaces::Null(1000, 1000), framebuffer_info, [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), nullptr, std::move(surface_frame)); + embedder->SubmitFlutterView(gr_context.get(), nullptr, + std::move(surface_frame)); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.h b/shell/platform/darwin/ios/ios_external_view_embedder.h index 1aa67890d6117..8a47eaea31639 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.h +++ b/shell/platform/darwin/ios/ios_external_view_embedder.h @@ -31,12 +31,15 @@ class IOSExternalViewEmbedder : public ExternalViewEmbedder { void CancelFrame() override; // |ExternalViewEmbedder| - void BeginFrame(SkISize frame_size, - GrDirectContext* context, - double device_pixel_ratio, + void BeginFrame(GrDirectContext* context, const fml::RefPtr& raster_thread_merger) override; + // |ExternalViewEmbedder| + void PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) override; + // |ExternalViewEmbedder| void PrerollCompositeEmbeddedView( int64_t view_id, @@ -51,9 +54,10 @@ class IOSExternalViewEmbedder : public ExternalViewEmbedder { DlCanvas* CompositeEmbeddedView(int64_t view_id) override; // |ExternalViewEmbedder| - void SubmitFrame(GrDirectContext* context, - const std::shared_ptr& aiks_context, - std::unique_ptr frame) override; + void SubmitFlutterView( + GrDirectContext* context, + const std::shared_ptr& aiks_context, + std::unique_ptr frame) override; // |ExternalViewEmbedder| void EndFrame(bool should_resubmit_frame, diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.mm b/shell/platform/darwin/ios/ios_external_view_embedder.mm index 3f4edffdd8c6f..2e13055c2de01 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.mm +++ b/shell/platform/darwin/ios/ios_external_view_embedder.mm @@ -4,6 +4,8 @@ #import "flutter/shell/platform/darwin/ios/ios_external_view_embedder.h" +#include "flutter/common/constants.h" + namespace flutter { IOSExternalViewEmbedder::IOSExternalViewEmbedder( @@ -31,11 +33,16 @@ // |ExternalViewEmbedder| void IOSExternalViewEmbedder::BeginFrame( - SkISize frame_size, GrDirectContext* context, - double device_pixel_ratio, - const fml::RefPtr& raster_thread_merger) { - TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::BeginFrame"); + const fml::RefPtr& raster_thread_merger) {} + +// |ExternalViewEmbedder| +void IOSExternalViewEmbedder::PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) { + // TODO(dkwingsmt): This class only supports rendering into the implicit view. + // Properly support multi-view in the future. + FML_DCHECK(flutter_view_id == kFlutterImplicitViewId); FML_CHECK(platform_views_controller_); platform_views_controller_->BeginFrame(frame_size); } @@ -66,11 +73,11 @@ } // |ExternalViewEmbedder| -void IOSExternalViewEmbedder::SubmitFrame( +void IOSExternalViewEmbedder::SubmitFlutterView( GrDirectContext* context, const std::shared_ptr& aiks_context, std::unique_ptr frame) { - TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::SubmitFrame"); + TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::SubmitFlutterView"); FML_CHECK(platform_views_controller_); platform_views_controller_->SubmitFrame(context, ios_context_, std::move(frame)); TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::DidSubmitFrame"); diff --git a/shell/platform/embedder/embedder_external_view_embedder.cc b/shell/platform/embedder/embedder_external_view_embedder.cc index f0462b19c2068..aaf78f6e75c27 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.cc +++ b/shell/platform/embedder/embedder_external_view_embedder.cc @@ -7,6 +7,7 @@ #include #include +#include "flutter/common/constants.h" #include "flutter/shell/platform/embedder/embedder_layers.h" #include "flutter/shell/platform/embedder/embedder_render_target.h" #include "third_party/skia/include/gpu/GrDirectContext.h" @@ -53,10 +54,18 @@ void EmbedderExternalViewEmbedder::CancelFrame() { // |ExternalViewEmbedder| void EmbedderExternalViewEmbedder::BeginFrame( - SkISize frame_size, GrDirectContext* context, - double device_pixel_ratio, - const fml::RefPtr& raster_thread_merger) { + const fml::RefPtr& raster_thread_merger) {} + +// |ExternalViewEmbedder| +void EmbedderExternalViewEmbedder::PrepareFlutterView( + int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) { + // TODO(dkwingsmt): This class only supports rendering into the implicit + // view. Properly support multi-view in the future. + // https://github.com/flutter/flutter/issues/135530 item 4 + FML_DCHECK(flutter_view_id == kFlutterImplicitViewId); Reset(); pending_frame_size_ = frame_size; @@ -407,7 +416,7 @@ class LayerBuilder { }; // namespace -void EmbedderExternalViewEmbedder::SubmitFrame( +void EmbedderExternalViewEmbedder::SubmitFlutterView( GrDirectContext* context, const std::shared_ptr& aiks_context, std::unique_ptr frame) { @@ -436,15 +445,15 @@ void EmbedderExternalViewEmbedder::SubmitFrame( return create_render_target_callback_(context, aiks_context, config); }); - // This is where unused render targets will be collected. Control may flow to - // the embedder. Here, the embedder has the opportunity to trample on the + // This is where unused render targets will be collected. Control may flow + // to the embedder. Here, the embedder has the opportunity to trample on the // OpenGL context. // // For optimum performance, we should tell the render target cache to clear - // its unused entries before allocating new ones. This collection step before - // allocating new render targets ameliorates peak memory usage within the - // frame. But, this causes an issue in a known internal embedder. To work - // around this issue while that embedder migrates, collection of render + // its unused entries before allocating new ones. This collection step + // before allocating new render targets ameliorates peak memory usage within + // the frame. But, this causes an issue in a known internal embedder. To + // work around this issue while that embedder migrates, collection of render // targets is deferred after the presentation. // // @warning: Embedder may trample on our OpenGL context here. @@ -460,9 +469,9 @@ void EmbedderExternalViewEmbedder::SubmitFrame( builder.Render(); - // We are going to be transferring control back over to the embedder there the - // context may be trampled upon again. Flush all operations to the underlying - // rendering API. + // We are going to be transferring control back over to the embedder there + // the context may be trampled upon again. Flush all operations to the + // underlying rendering API. // // @warning: Embedder may trample on our OpenGL context here. if (context) { @@ -482,7 +491,8 @@ void EmbedderExternalViewEmbedder::SubmitFrame( presented_layers.InvokePresentCallback(present_callback_); } - // See why this is necessary in the comment where this collection in realized. + // See why this is necessary in the comment where this collection in + // realized. // // @warning: Embedder may trample on our OpenGL context here. deferred_cleanup_render_targets.clear(); diff --git a/shell/platform/embedder/embedder_external_view_embedder.h b/shell/platform/embedder/embedder_external_view_embedder.h index 31b1f4cf6f22b..ae7cd4fecd318 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.h +++ b/shell/platform/embedder/embedder_external_view_embedder.h @@ -81,12 +81,15 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { void CancelFrame() override; // |ExternalViewEmbedder| - void BeginFrame(SkISize frame_size, - GrDirectContext* context, - double device_pixel_ratio, + void BeginFrame(GrDirectContext* context, const fml::RefPtr& raster_thread_merger) override; + // |ExternalViewEmbedder| + void PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) override; + // |ExternalViewEmbedder| void PrerollCompositeEmbeddedView( int64_t view_id, @@ -96,9 +99,10 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { DlCanvas* CompositeEmbeddedView(int64_t view_id) override; // |ExternalViewEmbedder| - void SubmitFrame(GrDirectContext* context, - const std::shared_ptr& aiks_context, - std::unique_ptr frame) override; + void SubmitFlutterView( + GrDirectContext* context, + const std::shared_ptr& aiks_context, + std::unique_ptr frame) override; // |ExternalViewEmbedder| DlCanvas* GetRootCanvas() override; diff --git a/shell/platform/fuchsia/flutter/external_view_embedder.cc b/shell/platform/fuchsia/flutter/external_view_embedder.cc index 789270c81053d..5900799c8c577 100644 --- a/shell/platform/fuchsia/flutter/external_view_embedder.cc +++ b/shell/platform/fuchsia/flutter/external_view_embedder.cc @@ -108,13 +108,14 @@ flutter::PostPrerollResult ExternalViewEmbedder::PostPrerollAction( } void ExternalViewEmbedder::BeginFrame( - SkISize frame_size, GrDirectContext* context, - double device_pixel_ratio, - const fml::RefPtr& raster_thread_merger) { - TRACE_EVENT0("flutter", "ExternalViewEmbedder::BeginFrame"); + const fml::RefPtr& raster_thread_merger) {} - // Reset for new frame. +// |ExternalViewEmbedder| +void ExternalViewEmbedder::PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) { + // Reset for new view. Reset(); frame_size_ = frame_size; frame_dpr_ = device_pixel_ratio; @@ -132,11 +133,11 @@ void ExternalViewEmbedder::EndFrame( TRACE_EVENT0("flutter", "ExternalViewEmbedder::EndFrame"); } -void ExternalViewEmbedder::SubmitFrame( +void ExternalViewEmbedder::SubmitFlutterView( GrDirectContext* context, const std::shared_ptr& aiks_context, std::unique_ptr frame) { - TRACE_EVENT0("flutter", "ExternalViewEmbedder::SubmitFrame"); + TRACE_EVENT0("flutter", "ExternalViewEmbedder::SubmitFlutterView"); std::vector> frame_surfaces; std::unordered_map frame_surface_indices; diff --git a/shell/platform/fuchsia/flutter/external_view_embedder.h b/shell/platform/fuchsia/flutter/external_view_embedder.h index 4e5afd151ba86..382cadce9c0a2 100644 --- a/shell/platform/fuchsia/flutter/external_view_embedder.h +++ b/shell/platform/fuchsia/flutter/external_view_embedder.h @@ -72,21 +72,25 @@ class ExternalViewEmbedder final : public flutter::ExternalViewEmbedder { override; // |ExternalViewEmbedder| - void BeginFrame(SkISize frame_size, - GrDirectContext* context, - double device_pixel_ratio, + void BeginFrame(GrDirectContext* context, const fml::RefPtr& raster_thread_merger) override; + // |ExternalViewEmbedder| + void PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) override; + // |ExternalViewEmbedder| void EndFrame(bool should_resubmit_frame, const fml::RefPtr& raster_thread_merger) override; // |ExternalViewEmbedder| - void SubmitFrame(GrDirectContext* context, - const std::shared_ptr& aiks_context, - std::unique_ptr frame) override; + void SubmitFlutterView( + GrDirectContext* context, + const std::shared_ptr& aiks_context, + std::unique_ptr frame) override; // |ExternalViewEmbedder| void CancelFrame() override { Reset(); } diff --git a/shell/platform/fuchsia/flutter/tests/external_view_embedder_unittests.cc b/shell/platform/fuchsia/flutter/tests/external_view_embedder_unittests.cc index 97581fa2a0464..93b20a5edc6c8 100644 --- a/shell/platform/fuchsia/flutter/tests/external_view_embedder_unittests.cc +++ b/shell/platform/fuchsia/flutter/tests/external_view_embedder_unittests.cc @@ -58,6 +58,7 @@ constexpr static fuchsia::ui::composition::BlendMode kFirstLayerBlendMode{ fuchsia::ui::composition::BlendMode::SRC}; constexpr static fuchsia::ui::composition::BlendMode kUpperLayerBlendMode{ fuchsia::ui::composition::BlendMode::SRC_OVER}; +constexpr static int64_t kImplicitViewId = 0; class FakeSurfaceProducerSurface : public SurfaceProducerSurface { public: @@ -326,7 +327,9 @@ void DrawSimpleFrame(ExternalViewEmbedder& external_view_embedder, SkISize frame_size, float frame_dpr, std::function draw_callback) { - external_view_embedder.BeginFrame(frame_size, nullptr, frame_dpr, nullptr); + external_view_embedder.BeginFrame(nullptr, nullptr); + external_view_embedder.PrepareFlutterView(kImplicitViewId, frame_size, + frame_dpr); { flutter::DlCanvas* root_canvas = external_view_embedder.GetRootCanvas(); external_view_embedder.PostPrerollAction(nullptr); @@ -335,7 +338,7 @@ void DrawSimpleFrame(ExternalViewEmbedder& external_view_embedder, external_view_embedder.EndFrame(false, nullptr); flutter::SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; - external_view_embedder.SubmitFrame( + external_view_embedder.SubmitFlutterView( nullptr, nullptr, std::make_unique( nullptr, std::move(framebuffer_info), @@ -352,7 +355,9 @@ void DrawFrameWithView( flutter::EmbeddedViewParams& view_params, std::function background_draw_callback, std::function overlay_draw_callback) { - external_view_embedder.BeginFrame(frame_size, nullptr, frame_dpr, nullptr); + external_view_embedder.BeginFrame(nullptr, nullptr); + external_view_embedder.PrepareFlutterView(kImplicitViewId, frame_size, + frame_dpr); { flutter::DlCanvas* root_canvas = external_view_embedder.GetRootCanvas(); external_view_embedder.PrerollCompositeEmbeddedView( @@ -366,7 +371,7 @@ void DrawFrameWithView( external_view_embedder.EndFrame(false, nullptr); flutter::SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; - external_view_embedder.SubmitFrame( + external_view_embedder.SubmitFlutterView( nullptr, nullptr, std::make_unique( nullptr, std::move(framebuffer_info), diff --git a/shell/platform/fuchsia/flutter/tests/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/platform_view_unittest.cc index 274818de22669..ec494d2bf5320 100644 --- a/shell/platform/fuchsia/flutter/tests/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/platform_view_unittest.cc @@ -45,15 +45,18 @@ class MockExternalViewEmbedder : public flutter::ExternalViewEmbedder { flutter::DlCanvas* GetRootCanvas() override { return nullptr; } void CancelFrame() override {} - void BeginFrame(SkISize frame_size, - GrDirectContext* context, - double device_pixel_ratio, + void BeginFrame(GrDirectContext* context, const fml::RefPtr& raster_thread_merger) override {} - void SubmitFrame(GrDirectContext* context, - const std::shared_ptr& aiks_context, - std::unique_ptr frame) override {} + void PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) override {} + + void SubmitFlutterView( + GrDirectContext* context, + const std::shared_ptr& aiks_context, + std::unique_ptr frame) override {} void PrerollCompositeEmbeddedView( int64_t view_id, diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index d7027ed096fe2..f04cbde7f9700 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -138,12 +138,15 @@ class TesterExternalViewEmbedder : public ExternalViewEmbedder { void CancelFrame() override {} // |ExternalViewEmbedder| - void BeginFrame(SkISize frame_size, - GrDirectContext* context, - double device_pixel_ratio, + void BeginFrame(GrDirectContext* context, const fml::RefPtr& raster_thread_merger) override {} + // |ExternalViewEmbedder| + void PrepareFlutterView(int64_t flutter_view_id, + SkISize frame_size, + double device_pixel_ratio) override {} + // |ExternalViewEmbedder| void PrerollCompositeEmbeddedView( int64_t view_id,