From 79e470d970b5506b515e43d105ed07dadc4edc39 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 6 Mar 2023 17:33:57 -0800 Subject: [PATCH 001/142] Move context out --- shell/common/shell_test_platform_view_gl.cc | 2 +- shell/gpu/gpu_surface_gl_skia.cc | 6 ------ shell/gpu/gpu_surface_gl_skia.h | 3 --- shell/platform/embedder/embedder_surface_gl.cc | 4 ++++ shell/platform/embedder/embedder_surface_gl.h | 1 + 5 files changed, 6 insertions(+), 10 deletions(-) diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index 98323108fac44..ce9ba2ae292c7 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -38,7 +38,7 @@ void ShellTestPlatformViewGL::SimulateVSync() { // |PlatformView| std::unique_ptr ShellTestPlatformViewGL::CreateRenderingSurface() { - return std::make_unique(this, true); + return std::make_unique(GPUSurfaceGLSkia::MakeGLContext(this), this, true); } // |PlatformView| diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index cdd8a24455d9f..ab8b62c4995ab 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -62,12 +62,6 @@ sk_sp GPUSurfaceGLSkia::MakeGLContext( return context; } -GPUSurfaceGLSkia::GPUSurfaceGLSkia(GPUSurfaceGLDelegate* delegate, - bool render_to_surface) - : GPUSurfaceGLSkia(MakeGLContext(delegate), delegate, render_to_surface) { - context_owner_ = true; -} - GPUSurfaceGLSkia::GPUSurfaceGLSkia(const sk_sp& gr_context, GPUSurfaceGLDelegate* delegate, bool render_to_surface) diff --git a/shell/gpu/gpu_surface_gl_skia.h b/shell/gpu/gpu_surface_gl_skia.h index 6aef2096f94df..2b40e53f27055 100644 --- a/shell/gpu/gpu_surface_gl_skia.h +++ b/shell/gpu/gpu_surface_gl_skia.h @@ -24,9 +24,6 @@ class GPUSurfaceGLSkia : public Surface { public: static sk_sp MakeGLContext(GPUSurfaceGLDelegate* delegate); - GPUSurfaceGLSkia(GPUSurfaceGLDelegate* delegate, bool render_to_surface); - - // Creates a new GL surface reusing an existing GrDirectContext. GPUSurfaceGLSkia(const sk_sp& gr_context, GPUSurfaceGLDelegate* delegate, bool render_to_surface); diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index 44b1fddf808fb..a5dff2c28c31a 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -95,8 +95,12 @@ SurfaceFrame::FramebufferInfo EmbedderSurfaceGL::GLContextFramebufferInfo() // |EmbedderSurface| std::unique_ptr EmbedderSurfaceGL::CreateGPUSurface() { + if (!main_context_) { + main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); + } const bool render_to_surface = !external_view_embedder_; return std::make_unique( + main_context_, this, // GPU surface GL delegate render_to_surface // render to surface ); diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index 695aeea84b860..10d3c8c75b671 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -38,6 +38,7 @@ class EmbedderSurfaceGL final : public EmbedderSurface, bool valid_ = false; GLDispatchTable gl_dispatch_table_; bool fbo_reset_after_present_; + sk_sp main_context_; std::shared_ptr external_view_embedder_; From 3e211d5db0f62aea470aa8a5aa1774e77b8a9f78 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 6 Mar 2023 17:34:25 -0800 Subject: [PATCH 002/142] Format --- shell/common/shell_test_platform_view_gl.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index ce9ba2ae292c7..3173e2946b83c 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -38,7 +38,8 @@ void ShellTestPlatformViewGL::SimulateVSync() { // |PlatformView| std::unique_ptr ShellTestPlatformViewGL::CreateRenderingSurface() { - return std::make_unique(GPUSurfaceGLSkia::MakeGLContext(this), this, true); + return std::make_unique( + GPUSurfaceGLSkia::MakeGLContext(this), this, true); } // |PlatformView| From c59b47d5e436c32e22367a3a0dcbace214a0f831 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 13 Mar 2023 12:07:22 -0700 Subject: [PATCH 003/142] Release main_context_ --- shell/gpu/gpu_surface_gl_skia.cc | 3 --- shell/platform/embedder/embedder_surface_gl.cc | 6 +++++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index ab8b62c4995ab..e5662366b1ea6 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -95,9 +95,6 @@ GPUSurfaceGLSkia::~GPUSurfaceGLSkia() { onscreen_surface_ = nullptr; fbo_id_ = 0; - if (context_owner_) { - context_->releaseResourcesAndAbandonContext(); - } context_ = nullptr; delegate_->GLContextClearCurrent(); diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index a5dff2c28c31a..9742dd0e4779b 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -29,7 +29,11 @@ EmbedderSurfaceGL::EmbedderSurfaceGL( valid_ = true; } -EmbedderSurfaceGL::~EmbedderSurfaceGL() = default; +EmbedderSurfaceGL::~EmbedderSurfaceGL() { + if (main_context_ != nullptr) { + main_context_->releaseResourcesAndAbandonContext(); + } +} // |EmbedderSurface| bool EmbedderSurfaceGL::IsValid() const { From 691e9437ac11ccde7053d8c6268921c69e724622 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 13 Mar 2023 12:46:31 -0700 Subject: [PATCH 004/142] Split out CreateSurface --- shell/common/platform_view.cc | 16 ++++++++++------ shell/common/platform_view.h | 13 +++++-------- shell/common/shell.cc | 4 +++- shell/common/shell.h | 2 +- shell/common/shell_unittests.cc | 2 +- .../Source/FlutterEnginePlatformViewTest.mm | 2 +- .../framework/Source/FlutterPlatformViewsTest.mm | 2 +- .../Source/accessibility_bridge_test.mm | 2 +- .../embedder/platform_view_embedder_unittests.cc | 2 +- .../fuchsia/flutter/platform_view_unittest.cc | 8 +------- .../tests/flatland_platform_view_unittest.cc | 11 +++-------- 11 files changed, 28 insertions(+), 36 deletions(-) diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 7cb0b091d5bcd..ee0b2d1850c15 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -56,6 +56,14 @@ void PlatformView::SetViewportMetrics(const ViewportMetrics& metrics) { } void PlatformView::NotifyCreated() { + delegate_.OnPlatformViewCreated(); +} + +void PlatformView::NotifyDestroyed() { + delegate_.OnPlatformViewDestroyed(); +} + +std::unique_ptr PlatformView::CreateSurface() { std::unique_ptr surface; // Threading: We want to use the platform view on the non-platform thread. // Using the weak pointer is illegal. But, we are going to introduce a latch @@ -73,13 +81,9 @@ void PlatformView::NotifyCreated() { latch.Wait(); if (!surface) { FML_LOG(ERROR) << "Failed to create platform view rendering surface"; - return; + return nullptr; } - delegate_.OnPlatformViewCreated(std::move(surface)); -} - -void PlatformView::NotifyDestroyed() { - delegate_.OnPlatformViewDestroyed(); + return surface; } void PlatformView::ScheduleFrame() { diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 9ec848e34568d..35625a1383c8a 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -60,15 +60,10 @@ class PlatformView { public: using KeyDataResponse = std::function; //-------------------------------------------------------------------------- - /// @brief Notifies the delegate that the platform view was created - /// with the given render surface. This surface is platform - /// (iOS, Android) and client-rendering API (OpenGL, Software, - /// Metal, Vulkan) specific. This is usually a sign to the - /// rasterizer to set up and begin rendering to that surface. + /// @brief Notifies the delegate that the platform view was created. + /// This is usually a sign to the rasterizer to set up. /// - /// @param[in] surface The surface - /// - virtual void OnPlatformViewCreated(std::unique_ptr surface) = 0; + virtual void OnPlatformViewCreated() = 0; //-------------------------------------------------------------------------- /// @brief Notifies the delegate that the platform view was destroyed. @@ -498,6 +493,8 @@ class PlatformView { /// virtual void NotifyDestroyed(); + std::unique_ptr CreateSurface(); + //---------------------------------------------------------------------------- /// @brief Used by embedders to schedule a frame. In response to this /// call, the framework may need to start generating a new frame. diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 32a777d3583ba..86fe018df6a31 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -745,7 +745,7 @@ DartVM* Shell::GetDartVM() { } // |PlatformView::Delegate| -void Shell::OnPlatformViewCreated(std::unique_ptr surface) { +void Shell::OnPlatformViewCreated() { TRACE_EVENT0("flutter", "Shell::OnPlatformViewCreated"); FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); @@ -774,6 +774,8 @@ void Shell::OnPlatformViewCreated(std::unique_ptr surface) { const bool should_post_raster_task = !task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread(); + std::unique_ptr surface = platform_view_->CreateSurface(); + fml::AutoResetWaitableEvent latch; auto raster_task = fml::MakeCopyable([&waiting_for_first_frame = waiting_for_first_frame_, diff --git a/shell/common/shell.h b/shell/common/shell.h index 2ecf71dac6559..6a1c9852e233b 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -524,7 +524,7 @@ class Shell final : public PlatformView::Delegate, void ReportTimings(); // |PlatformView::Delegate| - void OnPlatformViewCreated(std::unique_ptr surface) override; + void OnPlatformViewCreated() override; // |PlatformView::Delegate| void OnPlatformViewDestroyed() override; diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 2d1b4f01f9259..2a6533b5caff5 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -62,7 +62,7 @@ using ::testing::Return; namespace { class MockPlatformViewDelegate : public PlatformView::Delegate { - MOCK_METHOD1(OnPlatformViewCreated, void(std::unique_ptr surface)); + MOCK_METHOD0(OnPlatformViewCreated, void()); MOCK_METHOD0(OnPlatformViewDestroyed, void()); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm index e34a4ffc05af4..61c3fdcb6ef52 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm @@ -20,7 +20,7 @@ class FakeDelegate : public PlatformView::Delegate { public: - void OnPlatformViewCreated(std::unique_ptr surface) override {} + void OnPlatformViewCreated() override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index ebae0c59d2e9c..729bdae523d4a 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -89,7 +89,7 @@ @implementation FlutterPlatformViewsTestMockFlutterPlatformFactory namespace flutter { namespace { class FlutterPlatformViewsTestMockPlatformViewDelegate : public PlatformView::Delegate { - void OnPlatformViewCreated(std::unique_ptr surface) override {} + void OnPlatformViewCreated() override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm index 67dc27901fe16..4f90606a9cfd4 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -73,7 +73,7 @@ @implementation MockFlutterPlatformFactory namespace flutter { namespace { class MockDelegate : public PlatformView::Delegate { - void OnPlatformViewCreated(std::unique_ptr surface) override {} + void OnPlatformViewCreated() override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} diff --git a/shell/platform/embedder/platform_view_embedder_unittests.cc b/shell/platform/embedder/platform_view_embedder_unittests.cc index 3e795f1fb530f..d98dcaa195555 100644 --- a/shell/platform/embedder/platform_view_embedder_unittests.cc +++ b/shell/platform/embedder/platform_view_embedder_unittests.cc @@ -16,7 +16,7 @@ namespace flutter { namespace testing { namespace { class MockDelegate : public PlatformView::Delegate { - MOCK_METHOD1(OnPlatformViewCreated, void(std::unique_ptr)); + MOCK_METHOD0(OnPlatformViewCreated, void()); MOCK_METHOD0(OnPlatformViewDestroyed, void()); MOCK_METHOD0(OnPlatformViewScheduleFrame, void()); MOCK_METHOD1(OnPlatformViewSetNextFrameCallback, diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index 624ad33b51699..032a7544ba2e9 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -76,11 +76,7 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { } // |flutter::PlatformView::Delegate| - void OnPlatformViewCreated(std::unique_ptr surface) { - ASSERT_EQ(surface_.get(), nullptr); - - surface_ = std::move(surface); - } + void OnPlatformViewCreated() {} // |flutter::PlatformView::Delegate| void OnPlatformViewDestroyed() {} // |flutter::PlatformView::Delegate| @@ -144,7 +140,6 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { std::unique_ptr updated_asset_resolver, flutter::AssetResolver::AssetResolverType type) {} - flutter::Surface* surface() const { return surface_.get(); } flutter::PlatformMessage* message() const { return message_.get(); } const flutter::ViewportMetrics& metrics() const { return metrics_; } int32_t semantics_features() const { return semantics_features_; } @@ -161,7 +156,6 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { } private: - std::unique_ptr surface_; std::unique_ptr message_; flutter::ViewportMetrics metrics_; std::vector> pointer_packets_; diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index c1ffbcd96ab66..262ab27af1700 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -75,11 +75,7 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { } // |flutter::PlatformView::Delegate| - void OnPlatformViewCreated(std::unique_ptr surface) { - ASSERT_EQ(surface_.get(), nullptr); - - surface_ = std::move(surface); - } + void OnPlatformViewCreated() {} // |flutter::PlatformView::Delegate| void OnPlatformViewDestroyed() {} // |flutter::PlatformView::Delegate| @@ -147,7 +143,6 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { std::unique_ptr updated_asset_resolver, flutter::AssetResolver::AssetResolverType type) {} - flutter::Surface* surface() const { return surface_.get(); } flutter::PlatformMessage* message() const { return message_.get(); } const flutter::ViewportMetrics& metrics() const { return metrics_; } int32_t semantics_features() const { return semantics_features_; } @@ -164,7 +159,6 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { } private: - std::unique_ptr surface_; std::unique_ptr message_; flutter::ViewportMetrics metrics_; std::vector> pointer_packets_; @@ -630,7 +624,8 @@ TEST_F(FlatlandPlatformViewTests, CreateSurfaceTest) { RunLoopUntilIdle(); - EXPECT_EQ(gr_context.get(), delegate.surface()->GetContext()); + // TODO(dkwingsmt) + // EXPECT_EQ(gr_context.get(), delegate.surface()->GetContext()); EXPECT_EQ(external_view_embedder.get(), platform_view.CreateExternalViewEmbedder().get()); } From 7d95498ddaadee9fdd4239759861dc977ecbe782 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 13 Mar 2023 12:59:21 -0700 Subject: [PATCH 005/142] Fix fuchsia test --- shell/platform/fuchsia/flutter/platform_view_unittest.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index 032a7544ba2e9..64902116300ac 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -506,7 +506,8 @@ TEST_F(PlatformViewTests, CreateSurfaceTest) { RunLoopUntilIdle(); - EXPECT_EQ(gr_context.get(), delegate.surface()->GetContext()); + // TODO(dkwingsmt) + // EXPECT_EQ(gr_context.get(), delegate.surface()->GetContext()); EXPECT_EQ(external_view_embedder.get(), platform_view.CreateExternalViewEmbedder().get()); } From 3a3ad87a999eea483423b34c43dc23fbe3e3c9ca Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 14 Mar 2023 00:48:41 -0700 Subject: [PATCH 006/142] Fix windows test --- shell/common/shell.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 86fe018df6a31..3c468d6195cb9 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -750,6 +750,13 @@ void Shell::OnPlatformViewCreated() { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); + std::unique_ptr surface = platform_view_->CreateSurface(); + if (surface == nullptr) { + // TODO(dkwingsmt): This case is observed in windows unit tests. Anyway, + // we're probably not creating the surface in this callback eventually. + return; + } + // Prevent any request to change the thread configuration for raster and // platform queues while the platform view is being created. // From e3ce91751e13afa07fb1dc25867c7580f7795120 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 14 Mar 2023 10:45:36 -0700 Subject: [PATCH 007/142] Update shell.cc --- shell/common/shell.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 3c468d6195cb9..01c8d123d6c9f 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -781,8 +781,6 @@ void Shell::OnPlatformViewCreated() { const bool should_post_raster_task = !task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread(); - std::unique_ptr surface = platform_view_->CreateSurface(); - fml::AutoResetWaitableEvent latch; auto raster_task = fml::MakeCopyable([&waiting_for_first_frame = waiting_for_first_frame_, From caac3d9723216f22d453fdf0458296638f9d08e9 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 14 Mar 2023 16:42:31 -0700 Subject: [PATCH 008/142] Remove unused CreateSnapshotSurface --- shell/common/rasterizer_unittests.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 6ab77b53401ba..a9ebaff8f2f0c 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -37,7 +37,6 @@ class MockDelegate : public Rasterizer::Delegate { const fml::RefPtr()); MOCK_CONST_METHOD0(GetIsGpuDisabledSyncSwitch, std::shared_ptr()); - MOCK_METHOD0(CreateSnapshotSurface, std::unique_ptr()); MOCK_CONST_METHOD0(GetSettings, const Settings&()); }; From 98d358796c52818680da3c5bfbf971fea78fef23 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 15 Mar 2023 16:50:43 -0700 Subject: [PATCH 009/142] Extract studio and platformview's ctor --- shell/common/platform_view.cc | 6 +- shell/common/platform_view.h | 2 +- shell/platform/embedder/embedder.cc | 117 ++++++++++-------- shell/platform/embedder/embedder_studio.h | 34 +++++ .../embedder/platform_view_embedder.cc | 59 +-------- .../embedder/platform_view_embedder.h | 11 +- 6 files changed, 116 insertions(+), 113 deletions(-) create mode 100644 shell/platform/embedder/embedder_studio.h diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index ee0b2d1850c15..4e6df69e823d2 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -63,6 +63,8 @@ void PlatformView::NotifyDestroyed() { delegate_.OnPlatformViewDestroyed(); } +constexpr int64_t kFlutterDefaultViewId = 0; + std::unique_ptr PlatformView::CreateSurface() { std::unique_ptr surface; // Threading: We want to use the platform view on the non-platform thread. @@ -72,7 +74,7 @@ std::unique_ptr PlatformView::CreateSurface() { fml::ManualResetWaitableEvent latch; fml::TaskRunner::RunNowOrPostTask( task_runners_.GetRasterTaskRunner(), [platform_view, &surface, &latch]() { - surface = platform_view->CreateRenderingSurface(); + surface = platform_view->CreateRenderingSurface(kFlutterDefaultViewId); if (surface && !surface->IsValid()) { surface.reset(); } @@ -138,7 +140,7 @@ void PlatformView::MarkTextureFrameAvailable(int64_t texture_id) { delegate_.OnPlatformViewMarkTextureFrameAvailable(texture_id); } -std::unique_ptr PlatformView::CreateRenderingSurface() { +std::unique_ptr PlatformView::CreateRenderingSurface(int64_t view_id) { // We have a default implementation because tests create a platform view but // never a rendering surface. FML_DCHECK(false) << "This platform does not provide a rendering surface but " diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 35625a1383c8a..cd8c15a838162 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -830,7 +830,7 @@ class PlatformView { protected: // This is the only method called on the raster task runner. - virtual std::unique_ptr CreateRenderingSurface(); + virtual std::unique_ptr CreateRenderingSurface(int64_t view_id); PlatformView::Delegate& delegate_; const TaskRunners task_runners_; diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 39815333f7ba0..4ff2fbe2fa24f 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -435,6 +435,14 @@ InferOpenGLPlatformViewCreationCallback( shell.GetTaskRunners(), // task runners gl_dispatch_table, // embedder GL dispatch table fbo_reset_after_present, // fbo reset after present + std::make_unique( + [gl_dispatch_table, fbo_reset_after_present]( + std::shared_ptr + external_view_embedder) { + return std::make_unique( + gl_dispatch_table, fbo_reset_after_present, + external_view_embedder); + }), platform_dispatch_table, // embedder platform dispatch table std::move(external_view_embedder) // external view embedder ); @@ -490,29 +498,29 @@ InferMetalPlatformViewCreationCallback( .get_texture = metal_get_texture, }; - std::shared_ptr view_embedder = - std::move(external_view_embedder); - - std::unique_ptr embedder_surface = - std::make_unique( - const_cast(config->metal.device), - const_cast( - config->metal.present_command_queue), - metal_dispatch_table, view_embedder); - // The static leak checker gets confused by the use of fml::MakeCopyable. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - return fml::MakeCopyable( - [embedder_surface = std::move(embedder_surface), platform_dispatch_table, - external_view_embedder = view_embedder](flutter::Shell& shell) mutable { - return std::make_unique( - shell, // delegate - shell.GetTaskRunners(), // task runners - std::move(embedder_surface), // embedder surface - platform_dispatch_table, // platform dispatch table - std::move(external_view_embedder) // external view embedder - ); - }); + return fml::MakeCopyable([embedder_surface = std::move(embedder_surface), + platform_dispatch_table, + external_view_embedder = + view_embedder](flutter::Shell& shell) mutable { + return std::make_unique( + shell, // delegate + shell.GetTaskRunners(), // task runners + std::make_unique( + [config, + metal_dispatch_table](std::shared_ptr + external_view_embedder) { + return std::make_unique( + const_cast(config->metal.device), + const_cast( + config->metal.present_command_queue), + metal_dispatch_table, external_view_embedder); + }), + platform_dispatch_table, // platform dispatch table + std::move(external_view_embedder) // external view embedder + ); + }); #else return nullptr; #endif @@ -572,34 +580,33 @@ InferVulkanPlatformViewCreationCallback( .present_image = vulkan_present_image_callback, }; - std::shared_ptr view_embedder = - std::move(external_view_embedder); - - std::unique_ptr embedder_surface = - std::make_unique( - config->vulkan.version, vk_instance, - config->vulkan.enabled_instance_extension_count, - config->vulkan.enabled_instance_extensions, - config->vulkan.enabled_device_extension_count, - config->vulkan.enabled_device_extensions, - static_cast(config->vulkan.physical_device), - static_cast(config->vulkan.device), - config->vulkan.queue_family_index, - static_cast(config->vulkan.queue), vulkan_dispatch_table, - view_embedder); - - return fml::MakeCopyable( - [embedder_surface = std::move(embedder_surface), platform_dispatch_table, - external_view_embedder = - std::move(view_embedder)](flutter::Shell& shell) mutable { - return std::make_unique( - shell, // delegate - shell.GetTaskRunners(), // task runners - std::move(embedder_surface), // embedder surface - platform_dispatch_table, // platform dispatch table - std::move(external_view_embedder) // external view embedder - ); - }); + return fml::MakeCopyable([embedder_surface = std::move(embedder_surface), + platform_dispatch_table, + external_view_embedder = std::move(view_embedder)]( + flutter::Shell& shell) mutable { + return std::make_unique( + shell, // delegate + shell.GetTaskRunners(), // task runners + std::make_unique( + [config, vulkan_dispatch_table]( + std::shared_ptr + external_view_embedder) { + return std::make_unique( + config->vulkan.version, vk_instance, + config->vulkan.enabled_instance_extension_count, + config->vulkan.enabled_instance_extensions, + config->vulkan.enabled_device_extension_count, + config->vulkan.enabled_device_extensions, + static_cast(config->vulkan.physical_device), + static_cast(config->vulkan.device), + config->vulkan.queue_family_index, + static_cast(config->vulkan.queue), + vulkan_dispatch_table, external_view_embedder); + }), + platform_dispatch_table, // platform dispatch table + std::move(external_view_embedder) // external view embedder + ); + }); #else return nullptr; #endif @@ -633,9 +640,15 @@ InferSoftwarePlatformViewCreationCallback( external_view_embedder = std::move(external_view_embedder)](flutter::Shell& shell) mutable { return std::make_unique( - shell, // delegate - shell.GetTaskRunners(), // task runners - software_dispatch_table, // software dispatch table + shell, // delegate + shell.GetTaskRunners(), // task runners + std::make_unique( + [software_dispatch_table]( + std::shared_ptr + external_view_embedder) { + return std::make_unique( + software_dispatch_table, external_view_embedder); + }), platform_dispatch_table, // platform dispatch table std::move(external_view_embedder) // external view embedder ); diff --git a/shell/platform/embedder/embedder_studio.h b/shell/platform/embedder/embedder_studio.h new file mode 100644 index 0000000000000..01e51ccd3e40d --- /dev/null +++ b/shell/platform/embedder/embedder_studio.h @@ -0,0 +1,34 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_H_ + +#include + +#include "flutter/flow/external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_surface.h" + +namespace flutter { + +class EmbedderStudio { + public: + using Builder = std::function( + std::shared_ptr external_view_embedder)>; + + EmbedderStudio(Builder builder) : builder_(std::move(builder)) {} + + virtual ~EmbedderStudio() = default; + + virtual std::unique_ptr CreateSurface(std::shared_ptr external_view_embedder) { + return builder_(external_view_embedder); + } + + private: + Builder builder_; +} + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_H_ diff --git a/shell/platform/embedder/platform_view_embedder.cc b/shell/platform/embedder/platform_view_embedder.cc index 1cedc22810a50..3b712e4073d4e 100644 --- a/shell/platform/embedder/platform_view_embedder.cc +++ b/shell/platform/embedder/platform_view_embedder.cc @@ -48,72 +48,17 @@ class PlatformViewEmbedder::EmbedderPlatformMessageHandler PlatformViewEmbedder::PlatformViewEmbedder( PlatformView::Delegate& delegate, const flutter::TaskRunners& task_runners, - const EmbedderSurfaceSoftware::SoftwareDispatchTable& - software_dispatch_table, + std::unique_ptr embedder_studio, PlatformDispatchTable platform_dispatch_table, std::shared_ptr external_view_embedder) : PlatformView(delegate, task_runners), external_view_embedder_(std::move(external_view_embedder)), - embedder_surface_( - std::make_unique(software_dispatch_table, - external_view_embedder_)), + embedder_studio_(std::move(embedder_studio_)), platform_message_handler_(new EmbedderPlatformMessageHandler( GetWeakPtr(), task_runners.GetPlatformTaskRunner())), platform_dispatch_table_(std::move(platform_dispatch_table)) {} -#ifdef SHELL_ENABLE_GL -PlatformViewEmbedder::PlatformViewEmbedder( - PlatformView::Delegate& delegate, - const flutter::TaskRunners& task_runners, - const EmbedderSurfaceGL::GLDispatchTable& gl_dispatch_table, - bool fbo_reset_after_present, - PlatformDispatchTable platform_dispatch_table, - std::shared_ptr external_view_embedder) - : PlatformView(delegate, task_runners), - external_view_embedder_(std::move(external_view_embedder)), - embedder_surface_( - std::make_unique(gl_dispatch_table, - fbo_reset_after_present, - external_view_embedder_)), - platform_message_handler_(new EmbedderPlatformMessageHandler( - GetWeakPtr(), - task_runners.GetPlatformTaskRunner())), - platform_dispatch_table_(std::move(platform_dispatch_table)) {} -#endif - -#ifdef SHELL_ENABLE_METAL -PlatformViewEmbedder::PlatformViewEmbedder( - PlatformView::Delegate& delegate, - const flutter::TaskRunners& task_runners, - std::unique_ptr embedder_surface, - PlatformDispatchTable platform_dispatch_table, - std::shared_ptr external_view_embedder) - : PlatformView(delegate, task_runners), - external_view_embedder_(std::move(external_view_embedder)), - embedder_surface_(std::move(embedder_surface)), - platform_message_handler_(new EmbedderPlatformMessageHandler( - GetWeakPtr(), - task_runners.GetPlatformTaskRunner())), - platform_dispatch_table_(std::move(platform_dispatch_table)) {} -#endif - -#ifdef SHELL_ENABLE_VULKAN -PlatformViewEmbedder::PlatformViewEmbedder( - PlatformView::Delegate& delegate, - const flutter::TaskRunners& task_runners, - std::unique_ptr embedder_surface, - PlatformDispatchTable platform_dispatch_table, - std::shared_ptr external_view_embedder) - : PlatformView(delegate, task_runners), - external_view_embedder_(std::move(external_view_embedder)), - embedder_surface_(std::move(embedder_surface)), - platform_message_handler_(new EmbedderPlatformMessageHandler( - GetWeakPtr(), - task_runners.GetPlatformTaskRunner())), - platform_dispatch_table_(std::move(platform_dispatch_table)) {} -#endif - PlatformViewEmbedder::~PlatformViewEmbedder() = default; void PlatformViewEmbedder::UpdateSemantics( diff --git a/shell/platform/embedder/platform_view_embedder.h b/shell/platform/embedder/platform_view_embedder.h index 20f4dc139875b..f4ae8f0406b19 100644 --- a/shell/platform/embedder/platform_view_embedder.h +++ b/shell/platform/embedder/platform_view_embedder.h @@ -6,6 +6,7 @@ #define FLUTTER_SHELL_PLATFORM_EMBEDDER_PLATFORM_VIEW_EMBEDDER_H_ #include +#include #include "flow/embedded_views.h" #include "flutter/fml/macros.h" @@ -51,6 +52,12 @@ class PlatformViewEmbedder final : public PlatformView { OnPreEngineRestartCallback on_pre_engine_restart_callback; // optional }; + PlatformViewEmbedder( + PlatformView::Delegate& delegate, + const flutter::TaskRunners& task_runners, + std::unique_ptr embedder_studio, + std::shared_ptr external_view_embedder); + // Create a platform view that sets up a software rasterizer. PlatformViewEmbedder( PlatformView::Delegate& delegate, @@ -108,7 +115,9 @@ class PlatformViewEmbedder final : public PlatformView { private: class EmbedderPlatformMessageHandler; std::shared_ptr external_view_embedder_; - std::unique_ptr embedder_surface_; + std::unique_ptr embedder_studio_; + std::unordered_map> + embedder_surfaces_; std::shared_ptr platform_message_handler_; PlatformDispatchTable platform_dispatch_table_; From f27fe7057e180261f4a61685edf6835d743e271f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 16 Mar 2023 15:19:43 -0700 Subject: [PATCH 010/142] Create studio, compilable --- shell/common/shell_test_platform_view_gl.cc | 3 +- shell/common/shell_test_platform_view_gl.h | 2 +- shell/common/shell_test_platform_view_metal.h | 2 +- .../common/shell_test_platform_view_metal.mm | 2 +- .../common/shell_test_platform_view_vulkan.cc | 3 +- .../common/shell_test_platform_view_vulkan.h | 2 +- shell/common/shell_unittests.cc | 18 +-- .../platform/android/platform_view_android.cc | 3 +- .../platform/android/platform_view_android.h | 2 +- shell/platform/darwin/ios/platform_view_ios.h | 2 +- .../platform/darwin/ios/platform_view_ios.mm | 2 +- shell/platform/embedder/embedder.cc | 143 +++++++++--------- shell/platform/embedder/embedder_studio.h | 12 +- .../embedder/platform_view_embedder.cc | 20 +-- .../embedder/platform_view_embedder.h | 42 +---- .../platform_view_embedder_unittests.cc | 57 ++++--- .../platform/fuchsia/flutter/platform_view.cc | 3 +- .../platform/fuchsia/flutter/platform_view.h | 3 +- shell/testing/tester_main.cc | 2 +- 19 files changed, 156 insertions(+), 167 deletions(-) diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index 3173e2946b83c..170b285604c5b 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -37,7 +37,8 @@ void ShellTestPlatformViewGL::SimulateVSync() { } // |PlatformView| -std::unique_ptr ShellTestPlatformViewGL::CreateRenderingSurface() { +std::unique_ptr ShellTestPlatformViewGL::CreateRenderingSurface( + int64_t view_id) { return std::make_unique( GPUSurfaceGLSkia::MakeGLContext(this), this, true); } diff --git a/shell/common/shell_test_platform_view_gl.h b/shell/common/shell_test_platform_view_gl.h index 4dca801da3c34..e403e380a5d24 100644 --- a/shell/common/shell_test_platform_view_gl.h +++ b/shell/common/shell_test_platform_view_gl.h @@ -40,7 +40,7 @@ class ShellTestPlatformViewGL : public ShellTestPlatformView, shell_test_external_view_embedder_; // |PlatformView| - std::unique_ptr CreateRenderingSurface() override; + std::unique_ptr CreateRenderingSurface(int64_t view_id) override; // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; diff --git a/shell/common/shell_test_platform_view_metal.h b/shell/common/shell_test_platform_view_metal.h index be9dc9ebd4de2..84f8e07f92240 100644 --- a/shell/common/shell_test_platform_view_metal.h +++ b/shell/common/shell_test_platform_view_metal.h @@ -47,7 +47,7 @@ class ShellTestPlatformViewMetal final : public ShellTestPlatformView, PointerDataDispatcherMaker GetDispatcherMaker() override; // |PlatformView| - std::unique_ptr CreateRenderingSurface() override; + std::unique_ptr CreateRenderingSurface(int64_t view_id) override; // |GPUSurfaceMetalDelegate| GPUCAMetalLayerHandle GetCAMetalLayer( diff --git a/shell/common/shell_test_platform_view_metal.mm b/shell/common/shell_test_platform_view_metal.mm index 814e67e6f3933..77c54ce4e4c2f 100644 --- a/shell/common/shell_test_platform_view_metal.mm +++ b/shell/common/shell_test_platform_view_metal.mm @@ -92,7 +92,7 @@ GPUMTLTextureInfo offscreen_texture_info() const { } // |PlatformView| -std::unique_ptr ShellTestPlatformViewMetal::CreateRenderingSurface() { +std::unique_ptr ShellTestPlatformViewMetal::CreateRenderingSurface(int64_t view_id) { return std::make_unique(this, [metal_context_->context() mainContext], MsaaSampleCount::kNone); } diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 210bd0837a6a1..ce40fcb496c1f 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -52,7 +52,8 @@ void ShellTestPlatformViewVulkan::SimulateVSync() { } // |PlatformView| -std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface() { +std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface( + int64_t view_id) { return std::make_unique(proc_table_, shell_test_external_view_embedder_); } diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 718f7fe6dec06..323112ceba3ad 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -74,7 +74,7 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { shell_test_external_view_embedder_; // |PlatformView| - std::unique_ptr CreateRenderingSurface() override; + std::unique_ptr CreateRenderingSurface(int64_t view_id) override; // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 2a6533b5caff5..07d6d500b3d7b 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -138,7 +138,7 @@ class MockPlatformView : public PlatformView { MockPlatformView(MockPlatformViewDelegate& delegate, const TaskRunners& task_runners) : PlatformView(delegate, task_runners) {} - MOCK_METHOD0(CreateRenderingSurface, std::unique_ptr()); + MOCK_METHOD1(CreateRenderingSurface, std::unique_ptr(int64_t)); MOCK_CONST_METHOD0(GetPlatformMessageHandler, std::shared_ptr()); }; @@ -147,7 +147,7 @@ class TestPlatformView : public PlatformView { public: TestPlatformView(Shell& shell, const TaskRunners& task_runners) : PlatformView(shell, task_runners) {} - MOCK_METHOD0(CreateRenderingSurface, std::unique_ptr()); + MOCK_METHOD1(CreateRenderingSurface, std::unique_ptr(int64_t)); }; class MockPlatformMessageHandler : public PlatformMessageHandler { @@ -1596,7 +1596,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { Shell::CreateCallback platform_view_create_callback = [task_runners, main_context](flutter::Shell& shell) { auto result = std::make_unique(shell, task_runners); - ON_CALL(*result, CreateRenderingSurface()) + ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke([main_context] { auto surface = std::make_unique(); ON_CALL(*surface, GetContext()) @@ -3050,7 +3050,7 @@ TEST_F(ShellTest, Spawn) { [&platform_view_delegate](Shell& shell) { auto result = std::make_unique( platform_view_delegate, shell.GetTaskRunners()); - ON_CALL(*result, CreateRenderingSurface()) + ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke( [] { return std::make_unique(); })); return result; @@ -3162,7 +3162,7 @@ TEST_F(ShellTest, SpawnWithDartEntrypointArgs) { [&platform_view_delegate](Shell& shell) { auto result = std::make_unique( platform_view_delegate, shell.GetTaskRunners()); - ON_CALL(*result, CreateRenderingSurface()) + ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke( [] { return std::make_unique(); })); return result; @@ -3225,7 +3225,7 @@ TEST_F(ShellTest, IOManagerIsSharedBetweenParentAndSpawnedShell) { [&platform_view_delegate](Shell& shell) { auto result = std::make_unique( platform_view_delegate, shell.GetTaskRunners()); - ON_CALL(*result, CreateRenderingSurface()) + ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke( [] { return std::make_unique(); })); return result; @@ -3279,7 +3279,7 @@ TEST_F(ShellTest, IOManagerInSpawnedShellIsNotNullAfterParentShellDestroyed) { [&platform_view_delegate](Shell& shell) { auto result = std::make_unique( platform_view_delegate, shell.GetTaskRunners()); - ON_CALL(*result, CreateRenderingSurface()) + ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke( [] { return std::make_unique(); })); return result; @@ -3327,7 +3327,7 @@ TEST_F(ShellTest, ImageGeneratorRegistryNotNullAfterParentShellDestroyed) { [&platform_view_delegate](Shell& shell) { auto result = std::make_unique( platform_view_delegate, shell.GetTaskRunners()); - ON_CALL(*result, CreateRenderingSurface()) + ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke( [] { return std::make_unique(); })); return result; @@ -3825,7 +3825,7 @@ TEST_F(ShellTest, SpawnWorksWithOnError) { auto result = std::make_unique<::testing::NiceMock>( platform_view_delegate, shell.GetTaskRunners()); - ON_CALL(*result, CreateRenderingSurface()) + ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke([] { return std::make_unique<::testing::NiceMock>(); })); diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index 1b9d440a2d4bd..4ba82e801df6d 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -281,7 +281,8 @@ std::unique_ptr PlatformViewAndroid::CreateVSyncWaiter() { } // |PlatformView| -std::unique_ptr PlatformViewAndroid::CreateRenderingSurface() { +std::unique_ptr PlatformViewAndroid::CreateRenderingSurface( + int64_t view_id) { if (!android_surface_) { return nullptr; } diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index 536cb1d20f722..1bcd8a6482631 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -143,7 +143,7 @@ class PlatformViewAndroid final : public PlatformView { std::unique_ptr CreateVSyncWaiter() override; // |PlatformView| - std::unique_ptr CreateRenderingSurface() override; + std::unique_ptr CreateRenderingSurface(int64_t view_id) 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 e9129350a4277..ba036bd6aa341 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -149,7 +149,7 @@ class PlatformViewIOS final : public PlatformView { void HandlePlatformMessage(std::unique_ptr message) override; // |PlatformView| - std::unique_ptr CreateRenderingSurface() override; + std::unique_ptr CreateRenderingSurface(int64_t view_id) 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 219dab4ec9c98..851e5ecdbad00 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -138,7 +138,7 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} } // |PlatformView| -std::unique_ptr PlatformViewIOS::CreateRenderingSurface() { +std::unique_ptr PlatformViewIOS::CreateRenderingSurface(int64_t view_id) { FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); std::lock_guard guard(ios_surface_mutex_); if (!ios_surface_) { diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 4ff2fbe2fa24f..9b7e895eb02db 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -426,23 +426,22 @@ InferOpenGLPlatformViewCreationCallback( gl_populate_existing_damage, // gl_populate_existing_damage }; + auto surface_builder = + [gl_dispatch_table, fbo_reset_after_present]( + std::shared_ptr + external_view_embedder) { + return std::make_unique( + gl_dispatch_table, fbo_reset_after_present, external_view_embedder); + }; + return fml::MakeCopyable( - [gl_dispatch_table, fbo_reset_after_present, platform_dispatch_table, + [surface_builder, platform_dispatch_table, external_view_embedder = std::move(external_view_embedder)](flutter::Shell& shell) mutable { return std::make_unique( - shell, // delegate - shell.GetTaskRunners(), // task runners - gl_dispatch_table, // embedder GL dispatch table - fbo_reset_after_present, // fbo reset after present - std::make_unique( - [gl_dispatch_table, fbo_reset_after_present]( - std::shared_ptr - external_view_embedder) { - return std::make_unique( - gl_dispatch_table, fbo_reset_after_present, - external_view_embedder); - }), + shell, // delegate + shell.GetTaskRunners(), // task runners + std::make_unique(surface_builder), platform_dispatch_table, // embedder platform dispatch table std::move(external_view_embedder) // external view embedder ); @@ -498,29 +497,31 @@ InferMetalPlatformViewCreationCallback( .get_texture = metal_get_texture, }; + auto surface_builder = + [config, metal_dispatch_table]( + std::shared_ptr + external_view_embedder) { + return std::make_unique( + const_cast(config->metal.device), + const_cast( + config->metal.present_command_queue), + metal_dispatch_table, external_view_embedder); + }; + // The static leak checker gets confused by the use of fml::MakeCopyable. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) - return fml::MakeCopyable([embedder_surface = std::move(embedder_surface), - platform_dispatch_table, - external_view_embedder = - view_embedder](flutter::Shell& shell) mutable { - return std::make_unique( - shell, // delegate - shell.GetTaskRunners(), // task runners - std::make_unique( - [config, - metal_dispatch_table](std::shared_ptr - external_view_embedder) { - return std::make_unique( - const_cast(config->metal.device), - const_cast( - config->metal.present_command_queue), - metal_dispatch_table, external_view_embedder); - }), - platform_dispatch_table, // platform dispatch table - std::move(external_view_embedder) // external view embedder - ); - }); + return fml::MakeCopyable( + [surface_builder, platform_dispatch_table, + external_view_embedder = + std::move(external_view_embedder)](flutter::Shell& shell) mutable { + return std::make_unique( + shell, // delegate + shell.GetTaskRunners(), // task runners + std::make_unique(surface_builder), + platform_dispatch_table, // platform dispatch table + std::move(external_view_embedder) // external view embedder + ); + }); #else return nullptr; #endif @@ -580,33 +581,35 @@ InferVulkanPlatformViewCreationCallback( .present_image = vulkan_present_image_callback, }; - return fml::MakeCopyable([embedder_surface = std::move(embedder_surface), - platform_dispatch_table, - external_view_embedder = std::move(view_embedder)]( - flutter::Shell& shell) mutable { - return std::make_unique( - shell, // delegate - shell.GetTaskRunners(), // task runners - std::make_unique( - [config, vulkan_dispatch_table]( - std::shared_ptr - external_view_embedder) { - return std::make_unique( - config->vulkan.version, vk_instance, - config->vulkan.enabled_instance_extension_count, - config->vulkan.enabled_instance_extensions, - config->vulkan.enabled_device_extension_count, - config->vulkan.enabled_device_extensions, - static_cast(config->vulkan.physical_device), - static_cast(config->vulkan.device), - config->vulkan.queue_family_index, - static_cast(config->vulkan.queue), - vulkan_dispatch_table, external_view_embedder); - }), - platform_dispatch_table, // platform dispatch table - std::move(external_view_embedder) // external view embedder - ); - }); + auto surface_builder = + [config, vulkan_dispatch_table, + vk_instance](std::shared_ptr + external_view_embedder) { + return std::make_unique( + config->vulkan.version, vk_instance, + config->vulkan.enabled_instance_extension_count, + config->vulkan.enabled_instance_extensions, + config->vulkan.enabled_device_extension_count, + config->vulkan.enabled_device_extensions, + static_cast(config->vulkan.physical_device), + static_cast(config->vulkan.device), + config->vulkan.queue_family_index, + static_cast(config->vulkan.queue), vulkan_dispatch_table, + external_view_embedder); + }; + + return fml::MakeCopyable( + [surface_builder, platform_dispatch_table, + external_view_embedder = + std::move(external_view_embedder)](flutter::Shell& shell) mutable { + return std::make_unique( + shell, // delegate + shell.GetTaskRunners(), // task runners + std::make_unique(surface_builder), + platform_dispatch_table, // platform dispatch table + std::move(external_view_embedder) // external view embedder + ); + }); #else return nullptr; #endif @@ -635,20 +638,22 @@ InferSoftwarePlatformViewCreationCallback( software_present_backing_store, // required }; + auto surface_builder = + [software_dispatch_table]( + std::shared_ptr + external_view_embedder) { + return std::make_unique( + software_dispatch_table, external_view_embedder); + }; + return fml::MakeCopyable( - [software_dispatch_table, platform_dispatch_table, + [software_dispatch_table, surface_builder, platform_dispatch_table, external_view_embedder = std::move(external_view_embedder)](flutter::Shell& shell) mutable { return std::make_unique( shell, // delegate shell.GetTaskRunners(), // task runners - std::make_unique( - [software_dispatch_table]( - std::shared_ptr - external_view_embedder) { - return std::make_unique( - software_dispatch_table, external_view_embedder); - }), + std::make_unique(surface_builder), platform_dispatch_table, // platform dispatch table std::move(external_view_embedder) // external view embedder ); diff --git a/shell/platform/embedder/embedder_studio.h b/shell/platform/embedder/embedder_studio.h index 01e51ccd3e40d..d8ce7a6dbcbf9 100644 --- a/shell/platform/embedder/embedder_studio.h +++ b/shell/platform/embedder/embedder_studio.h @@ -7,7 +7,7 @@ #include -#include "flutter/flow/external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" #include "flutter/shell/platform/embedder/embedder_surface.h" namespace flutter { @@ -21,13 +21,19 @@ class EmbedderStudio { virtual ~EmbedderStudio() = default; - virtual std::unique_ptr CreateSurface(std::shared_ptr external_view_embedder) { + virtual std::unique_ptr CreateSurface( + std::shared_ptr external_view_embedder) { return builder_(external_view_embedder); } + virtual sk_sp CreateResourceContext() const { + // TODO(dkwingsmt) + return nullptr; + } + private: Builder builder_; -} +}; } // namespace flutter diff --git a/shell/platform/embedder/platform_view_embedder.cc b/shell/platform/embedder/platform_view_embedder.cc index 3b712e4073d4e..b31914ee6743d 100644 --- a/shell/platform/embedder/platform_view_embedder.cc +++ b/shell/platform/embedder/platform_view_embedder.cc @@ -53,7 +53,7 @@ PlatformViewEmbedder::PlatformViewEmbedder( std::shared_ptr external_view_embedder) : PlatformView(delegate, task_runners), external_view_embedder_(std::move(external_view_embedder)), - embedder_studio_(std::move(embedder_studio_)), + embedder_studio_(std::move(embedder_studio)), platform_message_handler_(new EmbedderPlatformMessageHandler( GetWeakPtr(), task_runners.GetPlatformTaskRunner())), @@ -88,12 +88,16 @@ void PlatformViewEmbedder::HandlePlatformMessage( } // |PlatformView| -std::unique_ptr PlatformViewEmbedder::CreateRenderingSurface() { - if (embedder_surface_ == nullptr) { - FML_LOG(ERROR) << "Embedder surface was null."; +std::unique_ptr PlatformViewEmbedder::CreateRenderingSurface( + int64_t view_id) { + auto found_iter = embedder_surfaces_.find(view_id); + if (found_iter != embedder_surfaces_.end()) { + FML_LOG(ERROR) << "Embedder surface " << view_id << " already exists."; return nullptr; } - return embedder_surface_->CreateGPUSurface(); + auto& embedder_surface = embedder_surfaces_[view_id] = + embedder_studio_->CreateSurface(external_view_embedder_); + return embedder_surface->CreateGPUSurface(); } // |PlatformView| @@ -104,11 +108,7 @@ PlatformViewEmbedder::CreateExternalViewEmbedder() { // |PlatformView| sk_sp PlatformViewEmbedder::CreateResourceContext() const { - if (embedder_surface_ == nullptr) { - FML_LOG(ERROR) << "Embedder surface was null."; - return nullptr; - } - return embedder_surface_->CreateResourceContext(); + return embedder_studio_->CreateResourceContext(); } // |PlatformView| diff --git a/shell/platform/embedder/platform_view_embedder.h b/shell/platform/embedder/platform_view_embedder.h index f4ae8f0406b19..d870268cc4e7f 100644 --- a/shell/platform/embedder/platform_view_embedder.h +++ b/shell/platform/embedder/platform_view_embedder.h @@ -12,6 +12,7 @@ #include "flutter/fml/macros.h" #include "flutter/shell/common/platform_view.h" #include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/embedder/embedder_studio.h" #include "flutter/shell/platform/embedder/embedder_surface.h" #include "flutter/shell/platform/embedder/embedder_surface_software.h" #include "flutter/shell/platform/embedder/vsync_waiter_embedder.h" @@ -56,48 +57,9 @@ class PlatformViewEmbedder final : public PlatformView { PlatformView::Delegate& delegate, const flutter::TaskRunners& task_runners, std::unique_ptr embedder_studio, - std::shared_ptr external_view_embedder); - - // Create a platform view that sets up a software rasterizer. - PlatformViewEmbedder( - PlatformView::Delegate& delegate, - const flutter::TaskRunners& task_runners, - const EmbedderSurfaceSoftware::SoftwareDispatchTable& - software_dispatch_table, PlatformDispatchTable platform_dispatch_table, std::shared_ptr external_view_embedder); -#ifdef SHELL_ENABLE_GL - // Creates a platform view that sets up an OpenGL rasterizer. - PlatformViewEmbedder( - PlatformView::Delegate& delegate, - const flutter::TaskRunners& task_runners, - const EmbedderSurfaceGL::GLDispatchTable& gl_dispatch_table, - bool fbo_reset_after_present, - PlatformDispatchTable platform_dispatch_table, - std::shared_ptr external_view_embedder); -#endif - -#ifdef SHELL_ENABLE_METAL - // Creates a platform view that sets up an metal rasterizer. - PlatformViewEmbedder( - PlatformView::Delegate& delegate, - const flutter::TaskRunners& task_runners, - std::unique_ptr embedder_surface, - PlatformDispatchTable platform_dispatch_table, - std::shared_ptr external_view_embedder); -#endif - -#ifdef SHELL_ENABLE_VULKAN - // Creates a platform view that sets up an Vulkan rasterizer. - PlatformViewEmbedder( - PlatformView::Delegate& delegate, - const flutter::TaskRunners& task_runners, - std::unique_ptr embedder_surface, - PlatformDispatchTable platform_dispatch_table, - std::shared_ptr external_view_embedder); -#endif - ~PlatformViewEmbedder() override; // |PlatformView| @@ -122,7 +84,7 @@ class PlatformViewEmbedder final : public PlatformView { PlatformDispatchTable platform_dispatch_table_; // |PlatformView| - std::unique_ptr CreateRenderingSurface() override; + std::unique_ptr CreateRenderingSurface(int64_t view_id) override; // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; diff --git a/shell/platform/embedder/platform_view_embedder_unittests.cc b/shell/platform/embedder/platform_view_embedder_unittests.cc index d98dcaa195555..b587cf96104a1 100644 --- a/shell/platform/embedder/platform_view_embedder_unittests.cc +++ b/shell/platform/embedder/platform_view_embedder_unittests.cc @@ -5,6 +5,7 @@ #include "flutter/shell/platform/embedder/platform_view_embedder.h" #include "flutter/shell/common/thread_host.h" +#include "flutter/shell/platform/embedder/embedder_studio.h" #include "flutter/testing/testing.h" #include "gmock/gmock.h" @@ -57,6 +58,17 @@ class MockResponse : public PlatformMessageResponse { MOCK_METHOD1(Complete, void(std::unique_ptr data)); MOCK_METHOD0(CompleteEmpty, void()); }; + +class MockStudio : public EmbedderStudio { + public: + MockStudio() : EmbedderStudio(nullptr) {} + + MOCK_METHOD1(CreateSurface, + std::unique_ptr( + std::shared_ptr + external_view_embedder)); + MOCK_CONST_METHOD0(CreateResourceContext, sk_sp()); +}; } // namespace TEST(PlatformViewEmbedderTest, HasPlatformMessageHandler) { @@ -72,7 +84,7 @@ TEST(PlatformViewEmbedderTest, HasPlatformMessageHandler) { PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table; std::shared_ptr external_view_embedder; auto embedder = std::make_unique( - delegate, task_runners, software_dispatch_table, + delegate, task_runners, std::make_unique(), platform_dispatch_table, external_view_embedder); ASSERT_TRUE(embedder->GetPlatformMessageHandler()); @@ -91,27 +103,26 @@ TEST(PlatformViewEmbedderTest, Dispatches) { std::unique_ptr embedder; { fml::AutoResetWaitableEvent latch; - task_runners.GetPlatformTaskRunner()->PostTask([&latch, task_runners, - &did_call, &embedder] { - MockDelegate delegate; - EmbedderSurfaceSoftware::SoftwareDispatchTable software_dispatch_table; - PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table; - platform_dispatch_table.platform_message_response_callback = - [&did_call](std::unique_ptr message) { - did_call = true; - }; - std::shared_ptr external_view_embedder; - embedder = std::make_unique( - delegate, task_runners, software_dispatch_table, - platform_dispatch_table, external_view_embedder); - auto platform_message_handler = embedder->GetPlatformMessageHandler(); - fml::RefPtr response = - fml::MakeRefCounted(); - std::unique_ptr message = - std::make_unique("foo", response); - platform_message_handler->HandlePlatformMessage(std::move(message)); - latch.Signal(); - }); + task_runners.GetPlatformTaskRunner()->PostTask( + [&latch, task_runners, &did_call, &embedder] { + MockDelegate delegate; + PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table; + platform_dispatch_table.platform_message_response_callback = + [&did_call](std::unique_ptr message) { + did_call = true; + }; + std::shared_ptr external_view_embedder; + embedder = std::make_unique( + delegate, task_runners, std::make_unique(), + platform_dispatch_table, external_view_embedder); + auto platform_message_handler = embedder->GetPlatformMessageHandler(); + fml::RefPtr response = + fml::MakeRefCounted(); + std::unique_ptr message = + std::make_unique("foo", response); + platform_message_handler->HandlePlatformMessage(std::move(message)); + latch.Signal(); + }); latch.Wait(); } { @@ -146,7 +157,7 @@ TEST(PlatformViewEmbedderTest, DeletionDisabledDispatch) { }; std::shared_ptr external_view_embedder; auto embedder = std::make_unique( - delegate, task_runners, software_dispatch_table, + delegate, task_runners, std::make_unique(), platform_dispatch_table, external_view_embedder); auto platform_message_handler = embedder->GetPlatformMessageHandler(); fml::RefPtr response = diff --git a/shell/platform/fuchsia/flutter/platform_view.cc b/shell/platform/fuchsia/flutter/platform_view.cc index 42e4ca01858ca..e0238148c3029 100644 --- a/shell/platform/fuchsia/flutter/platform_view.cc +++ b/shell/platform/fuchsia/flutter/platform_view.cc @@ -315,7 +315,8 @@ std::unique_ptr PlatformView::CreateVSyncWaiter() { } // |flutter::PlatformView| -std::unique_ptr PlatformView::CreateRenderingSurface() { +std::unique_ptr PlatformView::CreateRenderingSurface( + int64_t view_id) { return on_create_surface_callback_ ? on_create_surface_callback_() : nullptr; } diff --git a/shell/platform/fuchsia/flutter/platform_view.h b/shell/platform/fuchsia/flutter/platform_view.h index 7c6aa98108ebe..5ae674f8d8fee 100644 --- a/shell/platform/fuchsia/flutter/platform_view.h +++ b/shell/platform/fuchsia/flutter/platform_view.h @@ -106,7 +106,8 @@ class PlatformView : public flutter::PlatformView { std::unique_ptr CreateVSyncWaiter() override; // |flutter::PlatformView| - std::unique_ptr CreateRenderingSurface() override; + std::unique_ptr CreateRenderingSurface( + int64_t view_id) override; // |flutter::PlatformView| void HandlePlatformMessage( diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index 7fb8fa1d523d3..c2e470e66ad64 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -83,7 +83,7 @@ class TesterPlatformView : public PlatformView, : PlatformView(delegate, task_runners) {} // |PlatformView| - std::unique_ptr CreateRenderingSurface() override { + std::unique_ptr CreateRenderingSurface(int64_t view_id) override { auto surface = std::make_unique( this, true /* render to surface */); FML_DCHECK(surface->IsValid()); From be3a14cadc0bcf21cc04a1230a2a5b729a578128 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 17 Mar 2023 11:33:55 -0700 Subject: [PATCH 011/142] Remove the arg in the callback --- shell/platform/embedder/embedder.cc | 109 +++++++++--------- shell/platform/embedder/embedder_studio.h | 8 +- .../embedder/platform_view_embedder.cc | 2 +- .../platform_view_embedder_unittests.cc | 5 +- 4 files changed, 59 insertions(+), 65 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 9b7e895eb02db..ce71900724097 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -426,24 +426,24 @@ InferOpenGLPlatformViewCreationCallback( gl_populate_existing_damage, // gl_populate_existing_damage }; - auto surface_builder = - [gl_dispatch_table, fbo_reset_after_present]( - std::shared_ptr - external_view_embedder) { - return std::make_unique( - gl_dispatch_table, fbo_reset_after_present, external_view_embedder); - }; + std::shared_ptr shared_view_embedder = + std::move(external_view_embedder); + + auto surface_builder = [gl_dispatch_table, fbo_reset_after_present, + shared_view_embedder]() { + return std::make_unique( + gl_dispatch_table, fbo_reset_after_present, shared_view_embedder); + }; return fml::MakeCopyable( [surface_builder, platform_dispatch_table, - external_view_embedder = - std::move(external_view_embedder)](flutter::Shell& shell) mutable { + shared_view_embedder](flutter::Shell& shell) mutable { return std::make_unique( shell, // delegate shell.GetTaskRunners(), // task runners std::make_unique(surface_builder), platform_dispatch_table, // embedder platform dispatch table - std::move(external_view_embedder) // external view embedder + shared_view_embedder // external view embedder ); }); #else @@ -497,29 +497,29 @@ InferMetalPlatformViewCreationCallback( .get_texture = metal_get_texture, }; - auto surface_builder = - [config, metal_dispatch_table]( - std::shared_ptr - external_view_embedder) { - return std::make_unique( - const_cast(config->metal.device), - const_cast( - config->metal.present_command_queue), - metal_dispatch_table, external_view_embedder); - }; + std::shared_ptr shared_view_embedder = + std::move(external_view_embedder); + + auto surface_builder = [config, metal_dispatch_table, + shared_view_embedder]() { + return std::make_unique( + const_cast(config->metal.device), + const_cast( + config->metal.present_command_queue), + metal_dispatch_table, shared_view_embedder); + }; // The static leak checker gets confused by the use of fml::MakeCopyable. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) return fml::MakeCopyable( [surface_builder, platform_dispatch_table, - external_view_embedder = - std::move(external_view_embedder)](flutter::Shell& shell) mutable { + shared_view_embedder](flutter::Shell& shell) mutable { return std::make_unique( shell, // delegate shell.GetTaskRunners(), // task runners std::make_unique(surface_builder), - platform_dispatch_table, // platform dispatch table - std::move(external_view_embedder) // external view embedder + platform_dispatch_table, // platform dispatch table + shared_view_embedder // external view embedder ); }); #else @@ -581,33 +581,33 @@ InferVulkanPlatformViewCreationCallback( .present_image = vulkan_present_image_callback, }; - auto surface_builder = - [config, vulkan_dispatch_table, - vk_instance](std::shared_ptr - external_view_embedder) { - return std::make_unique( - config->vulkan.version, vk_instance, - config->vulkan.enabled_instance_extension_count, - config->vulkan.enabled_instance_extensions, - config->vulkan.enabled_device_extension_count, - config->vulkan.enabled_device_extensions, - static_cast(config->vulkan.physical_device), - static_cast(config->vulkan.device), - config->vulkan.queue_family_index, - static_cast(config->vulkan.queue), vulkan_dispatch_table, - external_view_embedder); - }; + std::shared_ptr shared_view_embedder = + std::move(external_view_embedder); + + auto surface_builder = [config, vulkan_dispatch_table, vk_instance, + shared_view_embedder]() { + return std::make_unique( + config->vulkan.version, vk_instance, + config->vulkan.enabled_instance_extension_count, + config->vulkan.enabled_instance_extensions, + config->vulkan.enabled_device_extension_count, + config->vulkan.enabled_device_extensions, + static_cast(config->vulkan.physical_device), + static_cast(config->vulkan.device), + config->vulkan.queue_family_index, + static_cast(config->vulkan.queue), vulkan_dispatch_table, + shared_view_embedder); + }; return fml::MakeCopyable( [surface_builder, platform_dispatch_table, - external_view_embedder = - std::move(external_view_embedder)](flutter::Shell& shell) mutable { + shared_view_embedder](flutter::Shell& shell) mutable { return std::make_unique( shell, // delegate shell.GetTaskRunners(), // task runners std::make_unique(surface_builder), - platform_dispatch_table, // platform dispatch table - std::move(external_view_embedder) // external view embedder + platform_dispatch_table, // platform dispatch table + shared_view_embedder // external view embedder ); }); #else @@ -638,24 +638,23 @@ InferSoftwarePlatformViewCreationCallback( software_present_backing_store, // required }; - auto surface_builder = - [software_dispatch_table]( - std::shared_ptr - external_view_embedder) { - return std::make_unique( - software_dispatch_table, external_view_embedder); - }; + std::shared_ptr shared_view_embedder = + std::move(external_view_embedder); + + auto surface_builder = [software_dispatch_table, shared_view_embedder]() { + return std::make_unique( + software_dispatch_table, shared_view_embedder); + }; return fml::MakeCopyable( [software_dispatch_table, surface_builder, platform_dispatch_table, - external_view_embedder = - std::move(external_view_embedder)](flutter::Shell& shell) mutable { + shared_view_embedder](flutter::Shell& shell) mutable { return std::make_unique( shell, // delegate shell.GetTaskRunners(), // task runners std::make_unique(surface_builder), - platform_dispatch_table, // platform dispatch table - std::move(external_view_embedder) // external view embedder + platform_dispatch_table, // platform dispatch table + shared_view_embedder // external view embedder ); }); } diff --git a/shell/platform/embedder/embedder_studio.h b/shell/platform/embedder/embedder_studio.h index d8ce7a6dbcbf9..195c769967fcf 100644 --- a/shell/platform/embedder/embedder_studio.h +++ b/shell/platform/embedder/embedder_studio.h @@ -14,16 +14,14 @@ namespace flutter { class EmbedderStudio { public: - using Builder = std::function( - std::shared_ptr external_view_embedder)>; + using Builder = std::function()>; EmbedderStudio(Builder builder) : builder_(std::move(builder)) {} virtual ~EmbedderStudio() = default; - virtual std::unique_ptr CreateSurface( - std::shared_ptr external_view_embedder) { - return builder_(external_view_embedder); + virtual std::unique_ptr CreateSurface() { + return builder_(); } virtual sk_sp CreateResourceContext() const { diff --git a/shell/platform/embedder/platform_view_embedder.cc b/shell/platform/embedder/platform_view_embedder.cc index b31914ee6743d..09ae49db8210b 100644 --- a/shell/platform/embedder/platform_view_embedder.cc +++ b/shell/platform/embedder/platform_view_embedder.cc @@ -96,7 +96,7 @@ std::unique_ptr PlatformViewEmbedder::CreateRenderingSurface( return nullptr; } auto& embedder_surface = embedder_surfaces_[view_id] = - embedder_studio_->CreateSurface(external_view_embedder_); + embedder_studio_->CreateSurface(); return embedder_surface->CreateGPUSurface(); } diff --git a/shell/platform/embedder/platform_view_embedder_unittests.cc b/shell/platform/embedder/platform_view_embedder_unittests.cc index b587cf96104a1..3735e97eca2ea 100644 --- a/shell/platform/embedder/platform_view_embedder_unittests.cc +++ b/shell/platform/embedder/platform_view_embedder_unittests.cc @@ -63,10 +63,7 @@ class MockStudio : public EmbedderStudio { public: MockStudio() : EmbedderStudio(nullptr) {} - MOCK_METHOD1(CreateSurface, - std::unique_ptr( - std::shared_ptr - external_view_embedder)); + MOCK_METHOD0(CreateSurface, std::unique_ptr()); MOCK_CONST_METHOD0(CreateResourceContext, sk_sp()); }; } // namespace From d5d29e60f95072ede375b9002e631a57a281b8eb Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 17 Mar 2023 14:17:32 -0700 Subject: [PATCH 012/142] Split studio, compilable --- ci/licenses_golden/licenses_flutter | 18 ++ shell/platform/embedder/BUILD.gn | 9 + shell/platform/embedder/embedder.cc | 97 ++++------ shell/platform/embedder/embedder_studio.h | 17 +- shell/platform/embedder/embedder_studio_gl.cc | 137 ++++++++++++++ shell/platform/embedder/embedder_studio_gl.h | 83 ++++++++ .../platform/embedder/embedder_studio_metal.h | 70 +++++++ .../embedder/embedder_studio_metal.mm | 75 ++++++++ .../embedder/embedder_studio_software.cc | 117 ++++++++++++ .../embedder/embedder_studio_software.h | 57 ++++++ .../embedder/embedder_studio_vulkan.cc | 178 ++++++++++++++++++ .../embedder/embedder_studio_vulkan.h | 88 +++++++++ .../platform/embedder/embedder_surface_gl.cc | 119 ++---------- shell/platform/embedder/embedder_surface_gl.h | 60 +----- .../embedder/embedder_surface_metal.h | 44 +---- .../embedder/embedder_surface_metal.mm | 48 +---- .../embedder/embedder_surface_software.cc | 78 +------- .../embedder/embedder_surface_software.h | 30 +-- .../embedder/embedder_surface_vulkan.cc | 153 ++------------- .../embedder/embedder_surface_vulkan.h | 49 +---- .../embedder/platform_view_embedder.h | 20 +- .../platform_view_embedder_unittests.cc | 47 +++-- 22 files changed, 988 insertions(+), 606 deletions(-) create mode 100644 shell/platform/embedder/embedder_studio_gl.cc create mode 100644 shell/platform/embedder/embedder_studio_gl.h create mode 100644 shell/platform/embedder/embedder_studio_metal.h create mode 100644 shell/platform/embedder/embedder_studio_metal.mm create mode 100644 shell/platform/embedder/embedder_studio_software.cc create mode 100644 shell/platform/embedder/embedder_studio_software.h create mode 100644 shell/platform/embedder/embedder_studio_vulkan.cc create mode 100644 shell/platform/embedder/embedder_studio_vulkan.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index fdb72da12350e..921e1f84a9df7 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -2666,6 +2666,15 @@ ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target.h + ../. ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_cache.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_render_target_cache.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_struct_macros.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_studio.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_studio_gl.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_studio_gl.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_studio_metal.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_studio_metal.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_studio_software.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_studio_software.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_studio_vulkan.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/embedder/embedder_studio_vulkan.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/embedder/embedder_surface_gl.cc + ../../../flutter/LICENSE @@ -5213,6 +5222,15 @@ FILE: ../../../flutter/shell/platform/embedder/embedder_render_target.h FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_cache.cc FILE: ../../../flutter/shell/platform/embedder/embedder_render_target_cache.h FILE: ../../../flutter/shell/platform/embedder/embedder_struct_macros.h +FILE: ../../../flutter/shell/platform/embedder/embedder_studio.h +FILE: ../../../flutter/shell/platform/embedder/embedder_studio_gl.cc +FILE: ../../../flutter/shell/platform/embedder/embedder_studio_gl.h +FILE: ../../../flutter/shell/platform/embedder/embedder_studio_metal.h +FILE: ../../../flutter/shell/platform/embedder/embedder_studio_metal.mm +FILE: ../../../flutter/shell/platform/embedder/embedder_studio_software.cc +FILE: ../../../flutter/shell/platform/embedder/embedder_studio_software.h +FILE: ../../../flutter/shell/platform/embedder/embedder_studio_vulkan.cc +FILE: ../../../flutter/shell/platform/embedder/embedder_studio_vulkan.h FILE: ../../../flutter/shell/platform/embedder/embedder_surface.cc FILE: ../../../flutter/shell/platform/embedder/embedder_surface.h FILE: ../../../flutter/shell/platform/embedder/embedder_surface_gl.cc diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index ce4e1edea7880..4e5d46e6a03a2 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -76,6 +76,9 @@ template("embedder_source_set") { "embedder_render_target_cache.cc", "embedder_render_target_cache.h", "embedder_struct_macros.h", + "embedder_studio.h", + "embedder_studio_software.cc", + "embedder_studio_software.h", "embedder_surface.cc", "embedder_surface.h", "embedder_surface_software.cc", @@ -95,6 +98,8 @@ template("embedder_source_set") { sources += [ "embedder_external_texture_gl.cc", "embedder_external_texture_gl.h", + "embedder_studio_gl.cc", + "embedder_studio_gl.h", "embedder_surface_gl.cc", "embedder_surface_gl.h", ] @@ -120,6 +125,8 @@ template("embedder_source_set") { sources += [ "embedder_external_texture_metal.h", "embedder_external_texture_metal.mm", + "embedder_studio_metal.h", + "embedder_studio_metal.mm", "embedder_surface_metal.h", "embedder_surface_metal.mm", ] @@ -132,6 +139,8 @@ template("embedder_source_set") { if (embedder_enable_vulkan) { sources += [ + "embedder_studio_vulkan.cc", + "embedder_studio_vulkan.h", "embedder_surface_vulkan.cc", "embedder_surface_vulkan.h", ] diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index ce71900724097..b650355d4bcc1 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -54,6 +54,10 @@ extern const intptr_t kPlatformStrongDillSize; #include "flutter/shell/platform/embedder/embedder_platform_message_response.h" #include "flutter/shell/platform/embedder/embedder_render_target.h" #include "flutter/shell/platform/embedder/embedder_struct_macros.h" +#include "flutter/shell/platform/embedder/embedder_studio_gl.h" +#include "flutter/shell/platform/embedder/embedder_studio_metal.h" +#include "flutter/shell/platform/embedder/embedder_studio_software.h" +#include "flutter/shell/platform/embedder/embedder_studio_vulkan.h" #include "flutter/shell/platform/embedder/embedder_task_runner.h" #include "flutter/shell/platform/embedder/embedder_thread_host.h" #include "flutter/shell/platform/embedder/pixel_formats.h" @@ -415,7 +419,7 @@ InferOpenGLPlatformViewCreationCallback( bool fbo_reset_after_present = SAFE_ACCESS(open_gl_config, fbo_reset_after_present, false); - flutter::EmbedderSurfaceGL::GLDispatchTable gl_dispatch_table = { + flutter::EmbedderStudioGL::GLDispatchTable gl_dispatch_table = { gl_make_current, // gl_make_current_callback gl_clear_current, // gl_clear_current_callback gl_present, // gl_present_callback @@ -429,23 +433,18 @@ InferOpenGLPlatformViewCreationCallback( std::shared_ptr shared_view_embedder = std::move(external_view_embedder); - auto surface_builder = [gl_dispatch_table, fbo_reset_after_present, - shared_view_embedder]() { - return std::make_unique( - gl_dispatch_table, fbo_reset_after_present, shared_view_embedder); - }; - - return fml::MakeCopyable( - [surface_builder, platform_dispatch_table, - shared_view_embedder](flutter::Shell& shell) mutable { - return std::make_unique( - shell, // delegate - shell.GetTaskRunners(), // task runners - std::make_unique(surface_builder), - platform_dispatch_table, // embedder platform dispatch table - shared_view_embedder // external view embedder - ); - }); + return fml::MakeCopyable([gl_dispatch_table, fbo_reset_after_present, + platform_dispatch_table, shared_view_embedder]( + flutter::Shell& shell) mutable { + return std::make_unique( + shell, // delegate + shell.GetTaskRunners(), // task runners + std::make_unique( + gl_dispatch_table, fbo_reset_after_present, shared_view_embedder), + platform_dispatch_table, // embedder platform dispatch table + shared_view_embedder // external view embedder + ); + }); #else return nullptr; #endif @@ -492,7 +491,7 @@ InferMetalPlatformViewCreationCallback( return texture_info; }; - flutter::EmbedderSurfaceMetal::MetalDispatchTable metal_dispatch_table = { + flutter::EmbedderStudioMetal::MetalDispatchTable metal_dispatch_table = { .present = metal_present, .get_texture = metal_get_texture, }; @@ -500,24 +499,19 @@ InferMetalPlatformViewCreationCallback( std::shared_ptr shared_view_embedder = std::move(external_view_embedder); - auto surface_builder = [config, metal_dispatch_table, - shared_view_embedder]() { - return std::make_unique( - const_cast(config->metal.device), - const_cast( - config->metal.present_command_queue), - metal_dispatch_table, shared_view_embedder); - }; - // The static leak checker gets confused by the use of fml::MakeCopyable. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) return fml::MakeCopyable( - [surface_builder, platform_dispatch_table, + [config, metal_dispatch_table, platform_dispatch_table, shared_view_embedder](flutter::Shell& shell) mutable { return std::make_unique( shell, // delegate shell.GetTaskRunners(), // task runners - std::make_unique(surface_builder), + std::make_unique( + const_cast(config->metal.device), + const_cast( + config->metal.present_command_queue), + metal_dispatch_table, shared_view_embedder), platform_dispatch_table, // platform dispatch table shared_view_embedder // external view embedder ); @@ -574,7 +568,7 @@ InferVulkanPlatformViewCreationCallback( auto proc_addr = vulkan_get_instance_proc_address(vk_instance, "vkGetInstanceProcAddr"); - flutter::EmbedderSurfaceVulkan::VulkanDispatchTable vulkan_dispatch_table = { + flutter::EmbedderStudioVulkan::VulkanDispatchTable vulkan_dispatch_table = { .get_instance_proc_address = reinterpret_cast(proc_addr), .get_next_image = vulkan_get_next_image, @@ -584,28 +578,23 @@ InferVulkanPlatformViewCreationCallback( std::shared_ptr shared_view_embedder = std::move(external_view_embedder); - auto surface_builder = [config, vulkan_dispatch_table, vk_instance, - shared_view_embedder]() { - return std::make_unique( - config->vulkan.version, vk_instance, - config->vulkan.enabled_instance_extension_count, - config->vulkan.enabled_instance_extensions, - config->vulkan.enabled_device_extension_count, - config->vulkan.enabled_device_extensions, - static_cast(config->vulkan.physical_device), - static_cast(config->vulkan.device), - config->vulkan.queue_family_index, - static_cast(config->vulkan.queue), vulkan_dispatch_table, - shared_view_embedder); - }; - return fml::MakeCopyable( - [surface_builder, platform_dispatch_table, + [config, vulkan_dispatch_table, vk_instance, platform_dispatch_table, shared_view_embedder](flutter::Shell& shell) mutable { return std::make_unique( shell, // delegate shell.GetTaskRunners(), // task runners - std::make_unique(surface_builder), + std::make_unique( + config->vulkan.version, vk_instance, + config->vulkan.enabled_instance_extension_count, + config->vulkan.enabled_instance_extensions, + config->vulkan.enabled_device_extension_count, + config->vulkan.enabled_device_extensions, + static_cast(config->vulkan.physical_device), + static_cast(config->vulkan.device), + config->vulkan.queue_family_index, + static_cast(config->vulkan.queue), + vulkan_dispatch_table, shared_view_embedder), platform_dispatch_table, // platform dispatch table shared_view_embedder // external view embedder ); @@ -633,7 +622,7 @@ InferSoftwarePlatformViewCreationCallback( return ptr(user_data, allocation, row_bytes, height); }; - flutter::EmbedderSurfaceSoftware::SoftwareDispatchTable + flutter::EmbedderStudioSoftware::SoftwareDispatchTable software_dispatch_table = { software_present_backing_store, // required }; @@ -641,18 +630,14 @@ InferSoftwarePlatformViewCreationCallback( std::shared_ptr shared_view_embedder = std::move(external_view_embedder); - auto surface_builder = [software_dispatch_table, shared_view_embedder]() { - return std::make_unique( - software_dispatch_table, shared_view_embedder); - }; - return fml::MakeCopyable( - [software_dispatch_table, surface_builder, platform_dispatch_table, + [software_dispatch_table, platform_dispatch_table, shared_view_embedder](flutter::Shell& shell) mutable { return std::make_unique( shell, // delegate shell.GetTaskRunners(), // task runners - std::make_unique(surface_builder), + std::make_unique( + software_dispatch_table, shared_view_embedder), platform_dispatch_table, // platform dispatch table shared_view_embedder // external view embedder ); diff --git a/shell/platform/embedder/embedder_studio.h b/shell/platform/embedder/embedder_studio.h index 195c769967fcf..8f50d5d42c677 100644 --- a/shell/platform/embedder/embedder_studio.h +++ b/shell/platform/embedder/embedder_studio.h @@ -14,23 +14,18 @@ namespace flutter { class EmbedderStudio { public: - using Builder = std::function()>; - - EmbedderStudio(Builder builder) : builder_(std::move(builder)) {} + EmbedderStudio() {} virtual ~EmbedderStudio() = default; - virtual std::unique_ptr CreateSurface() { - return builder_(); - } + virtual bool IsValid() const = 0; + + virtual std::unique_ptr CreateSurface() = 0; - virtual sk_sp CreateResourceContext() const { - // TODO(dkwingsmt) - return nullptr; - } + virtual sk_sp CreateResourceContext() const = 0; private: - Builder builder_; + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderStudio); }; } // namespace flutter diff --git a/shell/platform/embedder/embedder_studio_gl.cc b/shell/platform/embedder/embedder_studio_gl.cc new file mode 100644 index 0000000000000..d89a1a69bd1f0 --- /dev/null +++ b/shell/platform/embedder/embedder_studio_gl.cc @@ -0,0 +1,137 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/embedder/embedder_studio_gl.h" + +#include + +#include "flutter/shell/platform/embedder/embedder_surface_gl.h" +#include "flutter/shell/common/shell_io_manager.h" + +namespace flutter { + +EmbedderStudioGL::EmbedderStudioGL( + GLDispatchTable gl_dispatch_table, + bool fbo_reset_after_present, + std::shared_ptr external_view_embedder) + : gl_dispatch_table_(std::move(gl_dispatch_table)), + fbo_reset_after_present_(fbo_reset_after_present), + external_view_embedder_(std::move(external_view_embedder)) { + // Make sure all required members of the dispatch table are checked. + if (!gl_dispatch_table_.gl_make_current_callback || + !gl_dispatch_table_.gl_clear_current_callback || + !gl_dispatch_table_.gl_present_callback || + !gl_dispatch_table_.gl_fbo_callback || + !gl_dispatch_table_.gl_populate_existing_damage) { + return; + } + + valid_ = true; +} + +EmbedderStudioGL::~EmbedderStudioGL() { + if (main_context_ != nullptr) { + main_context_->releaseResourcesAndAbandonContext(); + } +} + +// |EmbedderStudio| +bool EmbedderStudioGL::IsValid() const { + return valid_; +} + +// |GPUSurfaceGLDelegate| +std::unique_ptr EmbedderStudioGL::GLContextMakeCurrent() { + return std::make_unique( + gl_dispatch_table_.gl_make_current_callback()); +} + +// |GPUSurfaceGLDelegate| +bool EmbedderStudioGL::GLContextClearCurrent() { + return gl_dispatch_table_.gl_clear_current_callback(); +} + +// |GPUSurfaceGLDelegate| +bool EmbedderStudioGL::GLContextPresent(const GLPresentInfo& present_info) { + // Pass the present information to the embedder present callback. + return gl_dispatch_table_.gl_present_callback(present_info); +} + +// |GPUSurfaceGLDelegate| +GLFBOInfo EmbedderStudioGL::GLContextFBO(GLFrameInfo frame_info) const { + // Get the FBO ID using the gl_fbo_callback and then get exiting damage by + // passing that ID to the gl_populate_existing_damage. + return gl_dispatch_table_.gl_populate_existing_damage( + gl_dispatch_table_.gl_fbo_callback(frame_info)); +} + +// |GPUSurfaceGLDelegate| +bool EmbedderStudioGL::GLContextFBOResetAfterPresent() const { + return fbo_reset_after_present_; +} + +// |GPUSurfaceGLDelegate| +SkMatrix EmbedderStudioGL::GLContextSurfaceTransformation() const { + auto callback = gl_dispatch_table_.gl_surface_transformation_callback; + if (!callback) { + SkMatrix matrix; + matrix.setIdentity(); + return matrix; + } + return callback(); +} + +// |GPUSurfaceGLDelegate| +EmbedderStudioGL::GLProcResolver EmbedderStudioGL::GetGLProcResolver() const { + return gl_dispatch_table_.gl_proc_resolver; +} + +// |GPUSurfaceGLDelegate| +SurfaceFrame::FramebufferInfo EmbedderStudioGL::GLContextFramebufferInfo() + const { + // Enable partial repaint by default on the embedders. + auto info = SurfaceFrame::FramebufferInfo{}; + info.supports_readback = true; + info.supports_partial_repaint = + gl_dispatch_table_.gl_populate_existing_damage != nullptr; + return info; +} + +// |EmbedderStudio| +std::unique_ptr EmbedderStudioGL::CreateSurface() { + if (!main_context_) { + main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); + } + const bool render_to_surface = !external_view_embedder_; + return std::make_unique( + main_context_, + this, // GPU surface GL delegate + render_to_surface // render to surface + ); +} + +// |EmbedderStudio| +sk_sp EmbedderStudioGL::CreateResourceContext() const { + auto callback = gl_dispatch_table_.gl_make_resource_current_callback; + if (callback && callback()) { + if (auto context = ShellIOManager::CreateCompatibleResourceLoadingContext( + GrBackend::kOpenGL_GrBackend, GetGLInterface())) { + return context; + } else { + FML_LOG(ERROR) + << "Internal error: Resource context available but could not create " + "a compatible Skia context."; + return nullptr; + } + } + + // The callback was not available or failed. + FML_LOG(ERROR) + << "Could not create a resource context for async texture uploads. " + "Expect degraded performance. Set a valid make_resource_current " + "callback on FlutterOpenGLRendererConfig."; + return nullptr; +} + +} // namespace flutter diff --git a/shell/platform/embedder/embedder_studio_gl.h b/shell/platform/embedder/embedder_studio_gl.h new file mode 100644 index 0000000000000..1a0b227ad918d --- /dev/null +++ b/shell/platform/embedder/embedder_studio_gl.h @@ -0,0 +1,83 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_GL_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_GL_H_ + +#include "flutter/fml/macros.h" +#include "flutter/shell/gpu/gpu_surface_gl_skia.h" +#include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_studio.h" + +namespace flutter { + +class EmbedderStudioGL final : public EmbedderStudio, + public GPUSurfaceGLDelegate { + public: + struct GLDispatchTable { + std::function gl_make_current_callback; // required + std::function gl_clear_current_callback; // required + std::function gl_present_callback; // required + std::function gl_fbo_callback; // required + std::function gl_make_resource_current_callback; // optional + std::function + gl_surface_transformation_callback; // optional + std::function gl_proc_resolver; // optional + std::function gl_populate_existing_damage; // required + }; + + EmbedderStudioGL( + GLDispatchTable gl_dispatch_table, + bool fbo_reset_after_present, + std::shared_ptr external_view_embedder); + + ~EmbedderStudioGL() override; + + // |EmbedderStudio| + bool IsValid() const override; + + // |EmbedderStudio| + std::unique_ptr CreateSurface() override; + + // |EmbedderStudio| + sk_sp CreateResourceContext() const override; + + // |GPUSurfaceGLDelegate| + std::unique_ptr GLContextMakeCurrent() override; + + // |GPUSurfaceGLDelegate| + bool GLContextClearCurrent() override; + + // |GPUSurfaceGLDelegate| + bool GLContextPresent(const GLPresentInfo& present_info) override; + + // |GPUSurfaceGLDelegate| + GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const override; + + // |GPUSurfaceGLDelegate| + bool GLContextFBOResetAfterPresent() const override; + + // |GPUSurfaceGLDelegate| + SkMatrix GLContextSurfaceTransformation() const override; + + // |GPUSurfaceGLDelegate| + GLProcResolver GetGLProcResolver() const override; + + // |GPUSurfaceGLDelegate| + SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const override; + + private: + bool valid_ = false; + GLDispatchTable gl_dispatch_table_; + bool fbo_reset_after_present_; + sk_sp main_context_; + + std::shared_ptr external_view_embedder_; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderStudioGL); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_GL_H_ diff --git a/shell/platform/embedder/embedder_studio_metal.h b/shell/platform/embedder/embedder_studio_metal.h new file mode 100644 index 0000000000000..8dd0ab25b288c --- /dev/null +++ b/shell/platform/embedder/embedder_studio_metal.h @@ -0,0 +1,70 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_METAL_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_METAL_H_ + +#include "flutter/fml/macros.h" +#include "flutter/shell/gpu/gpu_surface_metal_delegate.h" +#include "flutter/shell/gpu/gpu_surface_metal_skia.h" +#include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_studio.h" + +#include "third_party/skia/include/core/SkSurface.h" + +namespace flutter { + +class EmbedderStudioMetal final : public EmbedderStudio, + public GPUSurfaceMetalDelegate { + public: + struct MetalDispatchTable { + std::function present; // required + std::function + get_texture; // required + }; + + EmbedderStudioMetal( + GPUMTLDeviceHandle device, + GPUMTLCommandQueueHandle command_queue, + MetalDispatchTable dispatch_table, + std::shared_ptr external_view_embedder); + + ~EmbedderStudioMetal() override; + + // |EmbedderStudio| + bool IsValid() const override; + + // |EmbedderStudio| + std::unique_ptr CreateSurface() override; + + // |EmbedderStudio| + sk_sp CreateResourceContext() const override; + + // |GPUSurfaceMetalDelegate| + GPUCAMetalLayerHandle GetCAMetalLayer( + const SkISize& frame_size) const override; + + // |GPUSurfaceMetalDelegate| + bool PresentDrawable(GrMTLHandle drawable) const override; + + // |GPUSurfaceMetalDelegate| + GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_size) const override; + + // |GPUSurfaceMetalDelegate| + bool PresentTexture(GPUMTLTextureInfo texture) const override; + + private: + bool valid_ = false; + MetalDispatchTable metal_dispatch_table_; + std::shared_ptr external_view_embedder_; + sk_sp surface_; + sk_sp main_context_; + sk_sp resource_context_; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderStudioMetal); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_METAL_H_ diff --git a/shell/platform/embedder/embedder_studio_metal.mm b/shell/platform/embedder/embedder_studio_metal.mm new file mode 100644 index 0000000000000..7400e454af1ff --- /dev/null +++ b/shell/platform/embedder/embedder_studio_metal.mm @@ -0,0 +1,75 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/embedder/embedder_studio_metal.h" + +#include + +#include "flutter/fml/logging.h" +#include "flutter/shell/gpu/gpu_surface_metal_delegate.h" +#include "flutter/shell/platform/embedder/embedder_surface_metal.h" +#import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h" +#include "third_party/skia/include/gpu/GrDirectContext.h" + +FLUTTER_ASSERT_NOT_ARC +namespace flutter { + +EmbedderStudioMetal::EmbedderStudioMetal( + GPUMTLDeviceHandle device, + GPUMTLCommandQueueHandle command_queue, + MetalDispatchTable metal_dispatch_table, + std::shared_ptr external_view_embedder) + : GPUSurfaceMetalDelegate(MTLRenderTargetType::kMTLTexture), + metal_dispatch_table_(std::move(metal_dispatch_table)), + external_view_embedder_(std::move(external_view_embedder)) { + main_context_ = + [FlutterDarwinContextMetalSkia createGrContext:(id)device + commandQueue:(id)command_queue]; + resource_context_ = + [FlutterDarwinContextMetalSkia createGrContext:(id)device + commandQueue:(id)command_queue]; + valid_ = main_context_ && resource_context_; +} + +EmbedderStudioMetal::~EmbedderStudioMetal() = default; + +bool EmbedderStudioMetal::IsValid() const { + return valid_; +} + +std::unique_ptr EmbedderStudioMetal::CreateSurface() { + if (!IsValid()) { + return nullptr; + } + const bool render_to_surface = !external_view_embedder_; + return std::make_unique( + main_context_, + this, // GPU surface GL delegate + render_to_surface // render to surface + ); +} + +sk_sp EmbedderStudioMetal::CreateResourceContext() const { + return resource_context_; +} + +GPUCAMetalLayerHandle EmbedderStudioMetal::GetCAMetalLayer(const SkISize& frame_info) const { + FML_CHECK(false) << "Only rendering to MTLTexture is supported."; + return nullptr; +} + +bool EmbedderStudioMetal::PresentDrawable(GrMTLHandle drawable) const { + FML_CHECK(false) << "Only rendering to MTLTexture is supported."; + return false; +} + +GPUMTLTextureInfo EmbedderStudioMetal::GetMTLTexture(const SkISize& frame_info) const { + return metal_dispatch_table_.get_texture(frame_info); +} + +bool EmbedderStudioMetal::PresentTexture(GPUMTLTextureInfo texture) const { + return metal_dispatch_table_.present(texture); +} + +} // namespace flutter diff --git a/shell/platform/embedder/embedder_studio_software.cc b/shell/platform/embedder/embedder_studio_software.cc new file mode 100644 index 0000000000000..a3d898b8c2b0d --- /dev/null +++ b/shell/platform/embedder/embedder_studio_software.cc @@ -0,0 +1,117 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/embedder/embedder_studio_software.h" + +#include + +#include "flutter/fml/trace_event.h" + +#include "flutter/shell/platform/embedder/embedder_studio_software.h" +#include "flutter/shell/platform/embedder/embedder_surface_software.h" +#include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkImageInfo.h" +#include "third_party/skia/include/core/SkSurface.h" +#include "third_party/skia/include/gpu/GrDirectContext.h" + +namespace flutter { + +EmbedderStudioSoftware::EmbedderStudioSoftware( + SoftwareDispatchTable software_dispatch_table, + std::shared_ptr external_view_embedder) + : software_dispatch_table_(std::move(software_dispatch_table)), + external_view_embedder_(std::move(external_view_embedder)) { + if (!software_dispatch_table_.software_present_backing_store) { + return; + } + valid_ = true; +} + +EmbedderStudioSoftware::~EmbedderStudioSoftware() = default; + +// |EmbedderStudio| +bool EmbedderStudioSoftware::IsValid() const { + return valid_; +} + +// |EmbedderStudio| +std::unique_ptr EmbedderStudioSoftware::CreateSurface() { + if (!IsValid()) { + return nullptr; + } + const bool render_to_surface = !external_view_embedder_; + auto surface = std::make_unique(this, render_to_surface); + + if (!surface->IsValid()) { + return nullptr; + } + + return surface; +} + +// |EmbedderStudio| +sk_sp EmbedderStudioSoftware::CreateResourceContext() const { + return nullptr; +} + +// |GPUSurfaceSoftwareDelegate| +sk_sp EmbedderStudioSoftware::AcquireBackingStore( + const SkISize& size) { + TRACE_EVENT0("flutter", "EmbedderStudioSoftware::AcquireBackingStore"); + if (!IsValid()) { + FML_LOG(ERROR) + << "Could not acquire backing store for the software surface."; + return nullptr; + } + + if (sk_surface_ != nullptr && + SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) { + // The old and new surface sizes are the same. Nothing to do here. + return sk_surface_; + } + + SkImageInfo info = SkImageInfo::MakeN32( + size.fWidth, size.fHeight, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()); + sk_surface_ = SkSurface::MakeRaster(info, nullptr); + + if (sk_surface_ == nullptr) { + FML_LOG(ERROR) << "Could not create backing store for software rendering."; + return nullptr; + } + + return sk_surface_; +} + +// |GPUSurfaceSoftwareDelegate| +bool EmbedderStudioSoftware::PresentBackingStore( + sk_sp backing_store) { + if (!IsValid()) { + FML_LOG(ERROR) << "Tried to present an invalid software surface."; + return false; + } + + SkPixmap pixmap; + if (!backing_store->peekPixels(&pixmap)) { + FML_LOG(ERROR) << "Could not peek the pixels of the backing store."; + return false; + } + + // Some basic sanity checking. + uint64_t expected_pixmap_data_size = pixmap.width() * pixmap.height() * 4; + + const size_t pixmap_size = pixmap.computeByteSize(); + + if (expected_pixmap_data_size != pixmap_size) { + FML_LOG(ERROR) << "Software backing store had unexpected size."; + return false; + } + + return software_dispatch_table_.software_present_backing_store( + pixmap.addr(), // + pixmap.rowBytes(), // + pixmap.height() // + ); +} + +} // namespace flutter diff --git a/shell/platform/embedder/embedder_studio_software.h b/shell/platform/embedder/embedder_studio_software.h new file mode 100644 index 0000000000000..7be884601f292 --- /dev/null +++ b/shell/platform/embedder/embedder_studio_software.h @@ -0,0 +1,57 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_SOFTWARE_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_SOFTWARE_H_ + +#include "flutter/fml/macros.h" +#include "flutter/shell/gpu/gpu_surface_software.h" +#include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_studio.h" + +#include "third_party/skia/include/core/SkSurface.h" + +namespace flutter { + +class EmbedderStudioSoftware final : public EmbedderStudio, + public GPUSurfaceSoftwareDelegate { + public: + struct SoftwareDispatchTable { + std::function + software_present_backing_store; // required + }; + + EmbedderStudioSoftware( + SoftwareDispatchTable software_dispatch_table, + std::shared_ptr external_view_embedder); + + ~EmbedderStudioSoftware() override; + + // |EmbedderStudio| + bool IsValid() const override; + + // |EmbedderStudio| + std::unique_ptr CreateSurface() override; + + // |EmbedderStudio| + sk_sp CreateResourceContext() const override; + + // |GPUSurfaceSoftwareDelegate| + sk_sp AcquireBackingStore(const SkISize& size) override; + + // |GPUSurfaceSoftwareDelegate| + bool PresentBackingStore(sk_sp backing_store) override; + + private: + bool valid_ = false; + SoftwareDispatchTable software_dispatch_table_; + sk_sp sk_surface_; + std::shared_ptr external_view_embedder_; + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderStudioSoftware); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_SOFTWARE_H_ diff --git a/shell/platform/embedder/embedder_studio_vulkan.cc b/shell/platform/embedder/embedder_studio_vulkan.cc new file mode 100644 index 0000000000000..dad77ce3b3ec5 --- /dev/null +++ b/shell/platform/embedder/embedder_studio_vulkan.cc @@ -0,0 +1,178 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/platform/embedder/embedder_studio_vulkan.h" + +#include + +#include "flutter/flutter_vma/flutter_skia_vma.h" +#include "flutter/shell/common/shell_io_manager.h" +#include "flutter/shell/gpu/gpu_surface_vulkan.h" +#include "flutter/shell/platform/embedder/embedder_surface_vulkan.h" +#include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" +#include "flutter/vulkan/vulkan_skia_proc_table.h" +#include "include/gpu/GrDirectContext.h" +#include "include/gpu/vk/GrVkBackendContext.h" +#include "include/gpu/vk/GrVkExtensions.h" + +namespace flutter { + +EmbedderStudioVulkan::EmbedderStudioVulkan( + uint32_t version, + VkInstance instance, + size_t instance_extension_count, + const char** instance_extensions, + size_t device_extension_count, + const char** device_extensions, + VkPhysicalDevice physical_device, + VkDevice device, + uint32_t queue_family_index, + VkQueue queue, + const VulkanDispatchTable& vulkan_dispatch_table, + std::shared_ptr external_view_embedder) + : vk_(fml::MakeRefCounted( + vulkan_dispatch_table.get_instance_proc_address)), + device_(*vk_, + vulkan::VulkanHandle{physical_device}, + vulkan::VulkanHandle{device}, + queue_family_index, + vulkan::VulkanHandle{queue}), + vulkan_dispatch_table_(vulkan_dispatch_table), + external_view_embedder_(std::move(external_view_embedder)) { + // Make sure all required members of the dispatch table are checked. + if (!vulkan_dispatch_table_.get_instance_proc_address || + !vulkan_dispatch_table_.get_next_image || + !vulkan_dispatch_table_.present_image) { + return; + } + + bool success = vk_->SetupInstanceProcAddresses( + vulkan::VulkanHandle{instance}); + if (!success) { + FML_LOG(ERROR) << "Could not setup instance proc addresses."; + return; + } + success = + vk_->SetupDeviceProcAddresses(vulkan::VulkanHandle{device}); + if (!success) { + FML_LOG(ERROR) << "Could not setup device proc addresses."; + return; + } + if (!vk_->IsValid()) { + FML_LOG(ERROR) << "VulkanProcTable invalid."; + return; + } + + main_context_ = CreateGrContext(instance, version, instance_extension_count, + instance_extensions, device_extension_count, + device_extensions, ContextType::kRender); + // TODO(96954): Add a second (optional) queue+family index to the Embedder API + // to allow embedders to specify a dedicated transfer queue for + // use by the resource context. Queue families with graphics + // capability can always be used for memory transferring, but it + // would be advantageous to use a dedicated transter queue here. + resource_context_ = CreateGrContext( + instance, version, instance_extension_count, instance_extensions, + device_extension_count, device_extensions, ContextType::kResource); + + valid_ = main_context_ && resource_context_; +} + +EmbedderStudioVulkan::~EmbedderStudioVulkan() { + if (main_context_) { + main_context_->releaseResourcesAndAbandonContext(); + } + if (resource_context_) { + resource_context_->releaseResourcesAndAbandonContext(); + } +} + +// |GPUSurfaceVulkanDelegate| +const vulkan::VulkanProcTable& EmbedderStudioVulkan::vk() { + return *vk_; +} + +// |GPUSurfaceVulkanDelegate| +FlutterVulkanImage EmbedderStudioVulkan::AcquireImage(const SkISize& size) { + return vulkan_dispatch_table_.get_next_image(size); +} + +// |GPUSurfaceVulkanDelegate| +bool EmbedderStudioVulkan::PresentImage(VkImage image, VkFormat format) { + return vulkan_dispatch_table_.present_image(image, format); +} + +// |EmbedderStudio| +bool EmbedderStudioVulkan::IsValid() const { + return valid_; +} + +// |EmbedderStudio| +std::unique_ptr EmbedderStudioVulkan::CreateSurface() { + const bool render_to_surface = !external_view_embedder_; + return std::make_unique(this, main_context_, + render_to_surface); +} + +// |EmbedderStudio| +sk_sp EmbedderStudioVulkan::CreateResourceContext() const { + return resource_context_; +} + +sk_sp EmbedderStudioVulkan::CreateGrContext( + VkInstance instance, + uint32_t version, + size_t instance_extension_count, + const char** instance_extensions, + size_t device_extension_count, + const char** device_extensions, + ContextType context_type) const { + uint32_t skia_features = 0; + if (!device_.GetPhysicalDeviceFeaturesSkia(&skia_features)) { + FML_LOG(ERROR) << "Failed to get physical device features."; + + return nullptr; + } + + auto get_proc = CreateSkiaGetProc(vk_); + if (get_proc == nullptr) { + FML_LOG(ERROR) << "Failed to create Vulkan getProc for Skia."; + return nullptr; + } + + GrVkExtensions extensions; + + GrVkBackendContext backend_context = {}; + backend_context.fInstance = instance; + backend_context.fPhysicalDevice = device_.GetPhysicalDeviceHandle(); + backend_context.fDevice = device_.GetHandle(); + backend_context.fQueue = device_.GetQueueHandle(); + backend_context.fGraphicsQueueIndex = device_.GetGraphicsQueueIndex(); + backend_context.fMinAPIVersion = version; + backend_context.fMaxAPIVersion = version; + backend_context.fFeatures = skia_features; + backend_context.fVkExtensions = &extensions; + backend_context.fGetProc = get_proc; + backend_context.fOwnsInstanceAndDevice = false; + + uint32_t vulkan_api_version = version; + sk_sp allocator = + flutter::FlutterSkiaVulkanMemoryAllocator::Make( + vulkan_api_version, instance, device_.GetPhysicalDeviceHandle(), + device_.GetHandle(), vk_, true); + + backend_context.fMemoryAllocator = allocator; + + extensions.init(backend_context.fGetProc, backend_context.fInstance, + backend_context.fPhysicalDevice, instance_extension_count, + instance_extensions, device_extension_count, + device_extensions); + + GrContextOptions options = + MakeDefaultContextOptions(context_type, GrBackendApi::kVulkan); + options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; + return GrDirectContext::MakeVulkan(backend_context, options); +} + +} // namespace flutter diff --git a/shell/platform/embedder/embedder_studio_vulkan.h b/shell/platform/embedder/embedder_studio_vulkan.h new file mode 100644 index 0000000000000..e161819591105 --- /dev/null +++ b/shell/platform/embedder/embedder_studio_vulkan.h @@ -0,0 +1,88 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_VULKAN_H_ +#define FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_VULKAN_H_ + +#include "flutter/fml/macros.h" +#include "flutter/shell/common/context_options.h" +#include "flutter/shell/gpu/gpu_surface_vulkan.h" +#include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" +#include "flutter/shell/platform/embedder/embedder.h" +#include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_studio.h" +#include "flutter/vulkan/procs/vulkan_proc_table.h" + +namespace flutter { + +class EmbedderStudioVulkan final : public EmbedderStudio, + public GPUSurfaceVulkanDelegate { + public: + struct VulkanDispatchTable { + PFN_vkGetInstanceProcAddr get_instance_proc_address; // required + std::function + get_next_image; // required + std::function + present_image; // required + }; + + EmbedderStudioVulkan( + uint32_t version, + VkInstance instance, + size_t instance_extension_count, + const char** instance_extensions, + size_t device_extension_count, + const char** device_extensions, + VkPhysicalDevice physical_device, + VkDevice device, + uint32_t queue_family_index, + VkQueue queue, + const VulkanDispatchTable& vulkan_dispatch_table, + std::shared_ptr external_view_embedder); + + ~EmbedderStudioVulkan() override; + + // |GPUSurfaceVulkanDelegate| + const vulkan::VulkanProcTable& vk() override; + + // |GPUSurfaceVulkanDelegate| + FlutterVulkanImage AcquireImage(const SkISize& size) override; + + // |GPUSurfaceVulkanDelegate| + bool PresentImage(VkImage image, VkFormat format) override; + + // |EmbedderStudio| + bool IsValid() const override; + + // |EmbedderStudio| + std::unique_ptr CreateSurface() override; + + // |EmbedderStudio| + sk_sp CreateResourceContext() const override; + + private: + bool valid_ = false; + fml::RefPtr vk_; + vulkan::VulkanDevice device_; + VulkanDispatchTable vulkan_dispatch_table_; + std::shared_ptr external_view_embedder_; + sk_sp main_context_; + sk_sp resource_context_; + + sk_sp CreateGrContext(VkInstance instance, + uint32_t version, + size_t instance_extension_count, + const char** instance_extensions, + size_t device_extension_count, + const char** device_extensions, + ContextType context_type) const; + + void* GetInstanceProcAddress(VkInstance instance, const char* proc_name); + + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderStudioVulkan); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_PLATFORM_EMBEDDER_EMBEDDER_STUDIO_VULKAN_H_ diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index 9742dd0e4779b..929f0e5092d95 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -7,130 +7,39 @@ #include #include "flutter/shell/common/shell_io_manager.h" +#include "flutter/shell/platform/embedder/embedder_studio_gl.h" namespace flutter { -EmbedderSurfaceGL::EmbedderSurfaceGL( - GLDispatchTable gl_dispatch_table, - bool fbo_reset_after_present, - std::shared_ptr external_view_embedder) - : gl_dispatch_table_(std::move(gl_dispatch_table)), - fbo_reset_after_present_(fbo_reset_after_present), - external_view_embedder_(std::move(external_view_embedder)) { - // Make sure all required members of the dispatch table are checked. - if (!gl_dispatch_table_.gl_make_current_callback || - !gl_dispatch_table_.gl_clear_current_callback || - !gl_dispatch_table_.gl_present_callback || - !gl_dispatch_table_.gl_fbo_callback || - !gl_dispatch_table_.gl_populate_existing_damage) { - return; - } - - valid_ = true; -} +EmbedderSurfaceGL::EmbedderSurfaceGL(sk_sp main_context, + EmbedderStudioGL* studio, + bool render_to_surface) + : main_context_(main_context), + studio_(studio), + render_to_surface_(render_to_surface) {} -EmbedderSurfaceGL::~EmbedderSurfaceGL() { - if (main_context_ != nullptr) { - main_context_->releaseResourcesAndAbandonContext(); - } -} +EmbedderSurfaceGL::~EmbedderSurfaceGL() {} // |EmbedderSurface| bool EmbedderSurfaceGL::IsValid() const { - return valid_; -} - -// |GPUSurfaceGLDelegate| -std::unique_ptr EmbedderSurfaceGL::GLContextMakeCurrent() { - return std::make_unique( - gl_dispatch_table_.gl_make_current_callback()); -} - -// |GPUSurfaceGLDelegate| -bool EmbedderSurfaceGL::GLContextClearCurrent() { - return gl_dispatch_table_.gl_clear_current_callback(); -} - -// |GPUSurfaceGLDelegate| -bool EmbedderSurfaceGL::GLContextPresent(const GLPresentInfo& present_info) { - // Pass the present information to the embedder present callback. - return gl_dispatch_table_.gl_present_callback(present_info); -} - -// |GPUSurfaceGLDelegate| -GLFBOInfo EmbedderSurfaceGL::GLContextFBO(GLFrameInfo frame_info) const { - // Get the FBO ID using the gl_fbo_callback and then get exiting damage by - // passing that ID to the gl_populate_existing_damage. - return gl_dispatch_table_.gl_populate_existing_damage( - gl_dispatch_table_.gl_fbo_callback(frame_info)); -} - -// |GPUSurfaceGLDelegate| -bool EmbedderSurfaceGL::GLContextFBOResetAfterPresent() const { - return fbo_reset_after_present_; -} - -// |GPUSurfaceGLDelegate| -SkMatrix EmbedderSurfaceGL::GLContextSurfaceTransformation() const { - auto callback = gl_dispatch_table_.gl_surface_transformation_callback; - if (!callback) { - SkMatrix matrix; - matrix.setIdentity(); - return matrix; - } - return callback(); -} - -// |GPUSurfaceGLDelegate| -EmbedderSurfaceGL::GLProcResolver EmbedderSurfaceGL::GetGLProcResolver() const { - return gl_dispatch_table_.gl_proc_resolver; -} - -// |GPUSurfaceGLDelegate| -SurfaceFrame::FramebufferInfo EmbedderSurfaceGL::GLContextFramebufferInfo() - const { - // Enable partial repaint by default on the embedders. - auto info = SurfaceFrame::FramebufferInfo{}; - info.supports_readback = true; - info.supports_partial_repaint = - gl_dispatch_table_.gl_populate_existing_damage != nullptr; - return info; + return studio_->IsValid(); } // |EmbedderSurface| std::unique_ptr EmbedderSurfaceGL::CreateGPUSurface() { - if (!main_context_) { - main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); + if (!IsValid()) { + return nullptr; } - const bool render_to_surface = !external_view_embedder_; return std::make_unique( main_context_, - this, // GPU surface GL delegate - render_to_surface // render to surface + studio_, // GPU surface GL delegate + render_to_surface_ // render to surface ); } // |EmbedderSurface| sk_sp EmbedderSurfaceGL::CreateResourceContext() const { - auto callback = gl_dispatch_table_.gl_make_resource_current_callback; - if (callback && callback()) { - if (auto context = ShellIOManager::CreateCompatibleResourceLoadingContext( - GrBackend::kOpenGL_GrBackend, GetGLInterface())) { - return context; - } else { - FML_LOG(ERROR) - << "Internal error: Resource context available but could not create " - "a compatible Skia context."; - return nullptr; - } - } - - // The callback was not available or failed. - FML_LOG(ERROR) - << "Could not create a resource context for async texture uploads. " - "Expect degraded performance. Set a valid make_resource_current " - "callback on FlutterOpenGLRendererConfig."; - return nullptr; + return studio_->CreateResourceContext(); } } // namespace flutter diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index 10d3c8c75b671..05456635661de 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -8,73 +8,33 @@ #include "flutter/fml/macros.h" #include "flutter/shell/gpu/gpu_surface_gl_skia.h" #include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_studio_gl.h" #include "flutter/shell/platform/embedder/embedder_surface.h" namespace flutter { -class EmbedderSurfaceGL final : public EmbedderSurface, - public GPUSurfaceGLDelegate { +class EmbedderSurfaceGL final : public EmbedderSurface { public: - struct GLDispatchTable { - std::function gl_make_current_callback; // required - std::function gl_clear_current_callback; // required - std::function gl_present_callback; // required - std::function gl_fbo_callback; // required - std::function gl_make_resource_current_callback; // optional - std::function - gl_surface_transformation_callback; // optional - std::function gl_proc_resolver; // optional - std::function gl_populate_existing_damage; // required - }; - - EmbedderSurfaceGL( - GLDispatchTable gl_dispatch_table, - bool fbo_reset_after_present, - std::shared_ptr external_view_embedder); + EmbedderSurfaceGL(sk_sp main_context, + EmbedderStudioGL* studio, + bool render_to_surface); ~EmbedderSurfaceGL() override; - private: - bool valid_ = false; - GLDispatchTable gl_dispatch_table_; - bool fbo_reset_after_present_; - sk_sp main_context_; - - std::shared_ptr external_view_embedder_; - // |EmbedderSurface| bool IsValid() const override; + private: + sk_sp main_context_; + EmbedderStudioGL* studio_; + bool render_to_surface_; + // |EmbedderSurface| std::unique_ptr CreateGPUSurface() override; // |EmbedderSurface| sk_sp CreateResourceContext() const override; - // |GPUSurfaceGLDelegate| - std::unique_ptr GLContextMakeCurrent() override; - - // |GPUSurfaceGLDelegate| - bool GLContextClearCurrent() override; - - // |GPUSurfaceGLDelegate| - bool GLContextPresent(const GLPresentInfo& present_info) override; - - // |GPUSurfaceGLDelegate| - GLFBOInfo GLContextFBO(GLFrameInfo frame_info) const override; - - // |GPUSurfaceGLDelegate| - bool GLContextFBOResetAfterPresent() const override; - - // |GPUSurfaceGLDelegate| - SkMatrix GLContextSurfaceTransformation() const override; - - // |GPUSurfaceGLDelegate| - GLProcResolver GetGLProcResolver() const override; - - // |GPUSurfaceGLDelegate| - SurfaceFrame::FramebufferInfo GLContextFramebufferInfo() const override; - FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceGL); }; diff --git a/shell/platform/embedder/embedder_surface_metal.h b/shell/platform/embedder/embedder_surface_metal.h index d835218103e02..54ad165e5e3c4 100644 --- a/shell/platform/embedder/embedder_surface_metal.h +++ b/shell/platform/embedder/embedder_surface_metal.h @@ -9,59 +9,35 @@ #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #include "flutter/shell/gpu/gpu_surface_metal_skia.h" #include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_studio_metal.h" #include "flutter/shell/platform/embedder/embedder_surface.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter { -class EmbedderSurfaceMetal final : public EmbedderSurface, - public GPUSurfaceMetalDelegate { +class EmbedderSurfaceMetal final : public EmbedderSurface { public: - struct MetalDispatchTable { - std::function present; // required - std::function - get_texture; // required - }; - - EmbedderSurfaceMetal( - GPUMTLDeviceHandle device, - GPUMTLCommandQueueHandle command_queue, - MetalDispatchTable dispatch_table, - std::shared_ptr external_view_embedder); + EmbedderSurfaceMetal(sk_sp main_context, + EmbedderStudioMetal* studio, + bool render_to_surface); ~EmbedderSurfaceMetal() override; - private: - bool valid_ = false; - MetalDispatchTable metal_dispatch_table_; - std::shared_ptr external_view_embedder_; - sk_sp surface_; - sk_sp main_context_; - sk_sp resource_context_; - // |EmbedderSurface| bool IsValid() const override; + private: + sk_sp main_context_; + EmbedderStudioMetal* studio_; + bool render_to_surface_; + // |EmbedderSurface| std::unique_ptr CreateGPUSurface() override; // |EmbedderSurface| sk_sp CreateResourceContext() const override; - // |GPUSurfaceMetalDelegate| - GPUCAMetalLayerHandle GetCAMetalLayer( - const SkISize& frame_size) const override; - - // |GPUSurfaceMetalDelegate| - bool PresentDrawable(GrMTLHandle drawable) const override; - - // |GPUSurfaceMetalDelegate| - GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_size) const override; - - // |GPUSurfaceMetalDelegate| - bool PresentTexture(GPUMTLTextureInfo texture) const override; - FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceMetal); }; diff --git a/shell/platform/embedder/embedder_surface_metal.mm b/shell/platform/embedder/embedder_surface_metal.mm index b7582d01b5c2c..b3cbd6c96a7ad 100644 --- a/shell/platform/embedder/embedder_surface_metal.mm +++ b/shell/platform/embedder/embedder_surface_metal.mm @@ -9,32 +9,21 @@ #include "flutter/fml/logging.h" #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h" +#include "flutter/shell/platform/embedder/embedder_studio_metal.h" #include "third_party/skia/include/gpu/GrDirectContext.h" FLUTTER_ASSERT_NOT_ARC namespace flutter { -EmbedderSurfaceMetal::EmbedderSurfaceMetal( - GPUMTLDeviceHandle device, - GPUMTLCommandQueueHandle command_queue, - MetalDispatchTable metal_dispatch_table, - std::shared_ptr external_view_embedder) - : GPUSurfaceMetalDelegate(MTLRenderTargetType::kMTLTexture), - metal_dispatch_table_(std::move(metal_dispatch_table)), - external_view_embedder_(std::move(external_view_embedder)) { - main_context_ = - [FlutterDarwinContextMetalSkia createGrContext:(id)device - commandQueue:(id)command_queue]; - resource_context_ = - [FlutterDarwinContextMetalSkia createGrContext:(id)device - commandQueue:(id)command_queue]; - valid_ = main_context_ && resource_context_; -} +EmbedderSurfaceMetal::EmbedderSurfaceMetal(sk_sp main_context, + EmbedderStudioMetal* studio, + bool render_to_surface) + : main_context_(main_context), studio_(studio), render_to_surface_(render_to_surface) {} EmbedderSurfaceMetal::~EmbedderSurfaceMetal() = default; bool EmbedderSurfaceMetal::IsValid() const { - return valid_; + return studio_->IsValid(); } std::unique_ptr EmbedderSurfaceMetal::CreateGPUSurface() API_AVAILABLE(ios(13.0)) { @@ -46,9 +35,8 @@ return nullptr; } - const bool render_to_surface = !external_view_embedder_; - auto surface = std::make_unique(this, main_context_, MsaaSampleCount::kNone, - render_to_surface); + auto surface = std::make_unique(studio_, main_context_, + MsaaSampleCount::kNone, render_to_surface_); if (!surface->IsValid()) { return nullptr; @@ -58,25 +46,7 @@ } sk_sp EmbedderSurfaceMetal::CreateResourceContext() const { - return resource_context_; -} - -GPUCAMetalLayerHandle EmbedderSurfaceMetal::GetCAMetalLayer(const SkISize& frame_info) const { - FML_CHECK(false) << "Only rendering to MTLTexture is supported."; - return nullptr; -} - -bool EmbedderSurfaceMetal::PresentDrawable(GrMTLHandle drawable) const { - FML_CHECK(false) << "Only rendering to MTLTexture is supported."; - return false; -} - -GPUMTLTextureInfo EmbedderSurfaceMetal::GetMTLTexture(const SkISize& frame_info) const { - return metal_dispatch_table_.get_texture(frame_info); -} - -bool EmbedderSurfaceMetal::PresentTexture(GPUMTLTextureInfo texture) const { - return metal_dispatch_table_.present(texture); + return studio_->CreateResourceContext(); } } // namespace flutter diff --git a/shell/platform/embedder/embedder_surface_software.cc b/shell/platform/embedder/embedder_surface_software.cc index 1f3735b521951..6db94313126b1 100644 --- a/shell/platform/embedder/embedder_surface_software.cc +++ b/shell/platform/embedder/embedder_surface_software.cc @@ -15,22 +15,15 @@ namespace flutter { -EmbedderSurfaceSoftware::EmbedderSurfaceSoftware( - SoftwareDispatchTable software_dispatch_table, - std::shared_ptr external_view_embedder) - : software_dispatch_table_(std::move(software_dispatch_table)), - external_view_embedder_(std::move(external_view_embedder)) { - if (!software_dispatch_table_.software_present_backing_store) { - return; - } - valid_ = true; -} +EmbedderSurfaceSoftware::EmbedderSurfaceSoftware(EmbedderStudioSoftware* studio, + bool render_to_surface) + : studio_(studio), render_to_surface_(render_to_surface) {} EmbedderSurfaceSoftware::~EmbedderSurfaceSoftware() = default; // |EmbedderSurface| bool EmbedderSurfaceSoftware::IsValid() const { - return valid_; + return true; } // |EmbedderSurface| @@ -38,8 +31,8 @@ std::unique_ptr EmbedderSurfaceSoftware::CreateGPUSurface() { if (!IsValid()) { return nullptr; } - const bool render_to_surface = !external_view_embedder_; - auto surface = std::make_unique(this, render_to_surface); + auto surface = + std::make_unique(studio_, render_to_surface_); if (!surface->IsValid()) { return nullptr; @@ -53,63 +46,4 @@ sk_sp EmbedderSurfaceSoftware::CreateResourceContext() const { return nullptr; } -// |GPUSurfaceSoftwareDelegate| -sk_sp EmbedderSurfaceSoftware::AcquireBackingStore( - const SkISize& size) { - TRACE_EVENT0("flutter", "EmbedderSurfaceSoftware::AcquireBackingStore"); - if (!IsValid()) { - FML_LOG(ERROR) - << "Could not acquire backing store for the software surface."; - return nullptr; - } - - if (sk_surface_ != nullptr && - SkISize::Make(sk_surface_->width(), sk_surface_->height()) == size) { - // The old and new surface sizes are the same. Nothing to do here. - return sk_surface_; - } - - SkImageInfo info = SkImageInfo::MakeN32( - size.fWidth, size.fHeight, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()); - sk_surface_ = SkSurface::MakeRaster(info, nullptr); - - if (sk_surface_ == nullptr) { - FML_LOG(ERROR) << "Could not create backing store for software rendering."; - return nullptr; - } - - return sk_surface_; -} - -// |GPUSurfaceSoftwareDelegate| -bool EmbedderSurfaceSoftware::PresentBackingStore( - sk_sp backing_store) { - if (!IsValid()) { - FML_LOG(ERROR) << "Tried to present an invalid software surface."; - return false; - } - - SkPixmap pixmap; - if (!backing_store->peekPixels(&pixmap)) { - FML_LOG(ERROR) << "Could not peek the pixels of the backing store."; - return false; - } - - // Some basic sanity checking. - uint64_t expected_pixmap_data_size = pixmap.width() * pixmap.height() * 4; - - const size_t pixmap_size = pixmap.computeByteSize(); - - if (expected_pixmap_data_size != pixmap_size) { - FML_LOG(ERROR) << "Software backing store had unexpected size."; - return false; - } - - return software_dispatch_table_.software_present_backing_store( - pixmap.addr(), // - pixmap.rowBytes(), // - pixmap.height() // - ); -} - } // namespace flutter diff --git a/shell/platform/embedder/embedder_surface_software.h b/shell/platform/embedder/embedder_surface_software.h index 5d52e63d76528..6d938b6627f29 100644 --- a/shell/platform/embedder/embedder_surface_software.h +++ b/shell/platform/embedder/embedder_surface_software.h @@ -8,47 +8,33 @@ #include "flutter/fml/macros.h" #include "flutter/shell/gpu/gpu_surface_software.h" #include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_studio_software.h" #include "flutter/shell/platform/embedder/embedder_surface.h" #include "third_party/skia/include/core/SkSurface.h" namespace flutter { -class EmbedderSurfaceSoftware final : public EmbedderSurface, - public GPUSurfaceSoftwareDelegate { +class EmbedderSurfaceSoftware final : public EmbedderSurface { public: - struct SoftwareDispatchTable { - std::function - software_present_backing_store; // required - }; - - EmbedderSurfaceSoftware( - SoftwareDispatchTable software_dispatch_table, - std::shared_ptr external_view_embedder); + EmbedderSurfaceSoftware(EmbedderStudioSoftware* studio, + bool render_to_surface); ~EmbedderSurfaceSoftware() override; - private: - bool valid_ = false; - SoftwareDispatchTable software_dispatch_table_; - sk_sp sk_surface_; - std::shared_ptr external_view_embedder_; - // |EmbedderSurface| bool IsValid() const override; + private: + EmbedderStudioSoftware* studio_; + bool render_to_surface_; + // |EmbedderSurface| std::unique_ptr CreateGPUSurface() override; // |EmbedderSurface| sk_sp CreateResourceContext() const override; - // |GPUSurfaceSoftwareDelegate| - sk_sp AcquireBackingStore(const SkISize& size) override; - - // |GPUSurfaceSoftwareDelegate| - bool PresentBackingStore(sk_sp backing_store) override; - FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceSoftware); }; diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index d7191770025de..09e55b309281a 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -18,160 +18,29 @@ namespace flutter { EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( - uint32_t version, - VkInstance instance, - size_t instance_extension_count, - const char** instance_extensions, - size_t device_extension_count, - const char** device_extensions, - VkPhysicalDevice physical_device, - VkDevice device, - uint32_t queue_family_index, - VkQueue queue, - const VulkanDispatchTable& vulkan_dispatch_table, - std::shared_ptr external_view_embedder) - : vk_(fml::MakeRefCounted( - vulkan_dispatch_table.get_instance_proc_address)), - device_(*vk_, - vulkan::VulkanHandle{physical_device}, - vulkan::VulkanHandle{device}, - queue_family_index, - vulkan::VulkanHandle{queue}), - vulkan_dispatch_table_(vulkan_dispatch_table), - external_view_embedder_(std::move(external_view_embedder)) { - // Make sure all required members of the dispatch table are checked. - if (!vulkan_dispatch_table_.get_instance_proc_address || - !vulkan_dispatch_table_.get_next_image || - !vulkan_dispatch_table_.present_image) { - return; - } + EmbedderStudioVulkan* studio, + sk_sp main_context, + bool render_to_surface) + : main_context_(main_context), + studio_(studio), + render_to_surface_(render_to_surface) {} - bool success = vk_->SetupInstanceProcAddresses( - vulkan::VulkanHandle{instance}); - if (!success) { - FML_LOG(ERROR) << "Could not setup instance proc addresses."; - return; - } - success = - vk_->SetupDeviceProcAddresses(vulkan::VulkanHandle{device}); - if (!success) { - FML_LOG(ERROR) << "Could not setup device proc addresses."; - return; - } - if (!vk_->IsValid()) { - FML_LOG(ERROR) << "VulkanProcTable invalid."; - return; - } - - main_context_ = CreateGrContext(instance, version, instance_extension_count, - instance_extensions, device_extension_count, - device_extensions, ContextType::kRender); - // TODO(96954): Add a second (optional) queue+family index to the Embedder API - // to allow embedders to specify a dedicated transfer queue for - // use by the resource context. Queue families with graphics - // capability can always be used for memory transferring, but it - // would be advantageous to use a dedicated transter queue here. - resource_context_ = CreateGrContext( - instance, version, instance_extension_count, instance_extensions, - device_extension_count, device_extensions, ContextType::kResource); - - valid_ = main_context_ && resource_context_; -} - -EmbedderSurfaceVulkan::~EmbedderSurfaceVulkan() { - if (main_context_) { - main_context_->releaseResourcesAndAbandonContext(); - } - if (resource_context_) { - resource_context_->releaseResourcesAndAbandonContext(); - } -} - -// |GPUSurfaceVulkanDelegate| -const vulkan::VulkanProcTable& EmbedderSurfaceVulkan::vk() { - return *vk_; -} - -// |GPUSurfaceVulkanDelegate| -FlutterVulkanImage EmbedderSurfaceVulkan::AcquireImage(const SkISize& size) { - return vulkan_dispatch_table_.get_next_image(size); -} - -// |GPUSurfaceVulkanDelegate| -bool EmbedderSurfaceVulkan::PresentImage(VkImage image, VkFormat format) { - return vulkan_dispatch_table_.present_image(image, format); -} +EmbedderSurfaceVulkan::~EmbedderSurfaceVulkan() {} // |EmbedderSurface| bool EmbedderSurfaceVulkan::IsValid() const { - return valid_; + return studio_->IsValid(); } // |EmbedderSurface| std::unique_ptr EmbedderSurfaceVulkan::CreateGPUSurface() { - const bool render_to_surface = !external_view_embedder_; - return std::make_unique(this, main_context_, - render_to_surface); + return std::make_unique(studio_, main_context_, + render_to_surface_); } // |EmbedderSurface| sk_sp EmbedderSurfaceVulkan::CreateResourceContext() const { - return resource_context_; -} - -sk_sp EmbedderSurfaceVulkan::CreateGrContext( - VkInstance instance, - uint32_t version, - size_t instance_extension_count, - const char** instance_extensions, - size_t device_extension_count, - const char** device_extensions, - ContextType context_type) const { - uint32_t skia_features = 0; - if (!device_.GetPhysicalDeviceFeaturesSkia(&skia_features)) { - FML_LOG(ERROR) << "Failed to get physical device features."; - - return nullptr; - } - - auto get_proc = CreateSkiaGetProc(vk_); - if (get_proc == nullptr) { - FML_LOG(ERROR) << "Failed to create Vulkan getProc for Skia."; - return nullptr; - } - - GrVkExtensions extensions; - - GrVkBackendContext backend_context = {}; - backend_context.fInstance = instance; - backend_context.fPhysicalDevice = device_.GetPhysicalDeviceHandle(); - backend_context.fDevice = device_.GetHandle(); - backend_context.fQueue = device_.GetQueueHandle(); - backend_context.fGraphicsQueueIndex = device_.GetGraphicsQueueIndex(); - backend_context.fMinAPIVersion = version; - backend_context.fMaxAPIVersion = version; - backend_context.fFeatures = skia_features; - backend_context.fVkExtensions = &extensions; - backend_context.fGetProc = get_proc; - backend_context.fOwnsInstanceAndDevice = false; - - uint32_t vulkan_api_version = version; - sk_sp allocator = - flutter::FlutterSkiaVulkanMemoryAllocator::Make( - vulkan_api_version, instance, device_.GetPhysicalDeviceHandle(), - device_.GetHandle(), vk_, true); - - backend_context.fMemoryAllocator = allocator; - - extensions.init(backend_context.fGetProc, backend_context.fInstance, - backend_context.fPhysicalDevice, instance_extension_count, - instance_extensions, device_extension_count, - device_extensions); - - GrContextOptions options = - MakeDefaultContextOptions(context_type, GrBackendApi::kVulkan); - options.fReduceOpsTaskSplitting = GrContextOptions::Enable::kNo; - return GrDirectContext::MakeVulkan(backend_context, options); + return studio_->CreateResourceContext(); } } // namespace flutter diff --git a/shell/platform/embedder/embedder_surface_vulkan.h b/shell/platform/embedder/embedder_surface_vulkan.h index 0e972d3723b74..f26a44591d407 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.h +++ b/shell/platform/embedder/embedder_surface_vulkan.h @@ -11,58 +11,27 @@ #include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" +#include "flutter/shell/platform/embedder/embedder_studio_vulkan.h" #include "flutter/shell/platform/embedder/embedder_surface.h" #include "flutter/vulkan/procs/vulkan_proc_table.h" namespace flutter { -class EmbedderSurfaceVulkan final : public EmbedderSurface, - public GPUSurfaceVulkanDelegate { +class EmbedderSurfaceVulkan final : public EmbedderSurface { public: - struct VulkanDispatchTable { - PFN_vkGetInstanceProcAddr get_instance_proc_address; // required - std::function - get_next_image; // required - std::function - present_image; // required - }; - - EmbedderSurfaceVulkan( - uint32_t version, - VkInstance instance, - size_t instance_extension_count, - const char** instance_extensions, - size_t device_extension_count, - const char** device_extensions, - VkPhysicalDevice physical_device, - VkDevice device, - uint32_t queue_family_index, - VkQueue queue, - const VulkanDispatchTable& vulkan_dispatch_table, - std::shared_ptr external_view_embedder); + EmbedderSurfaceVulkan(EmbedderStudioVulkan* studio, + sk_sp main_context, + bool render_to_surface); ~EmbedderSurfaceVulkan() override; - // |GPUSurfaceVulkanDelegate| - const vulkan::VulkanProcTable& vk() override; - - // |GPUSurfaceVulkanDelegate| - FlutterVulkanImage AcquireImage(const SkISize& size) override; - - // |GPUSurfaceVulkanDelegate| - bool PresentImage(VkImage image, VkFormat format) override; + // |EmbedderSurface| + bool IsValid() const override; private: - bool valid_ = false; - fml::RefPtr vk_; - vulkan::VulkanDevice device_; - VulkanDispatchTable vulkan_dispatch_table_; - std::shared_ptr external_view_embedder_; sk_sp main_context_; - sk_sp resource_context_; - - // |EmbedderSurface| - bool IsValid() const override; + EmbedderStudioVulkan* studio_; + bool render_to_surface_; // |EmbedderSurface| std::unique_ptr CreateGPUSurface() override; diff --git a/shell/platform/embedder/platform_view_embedder.h b/shell/platform/embedder/platform_view_embedder.h index d870268cc4e7f..3e30a33101b5b 100644 --- a/shell/platform/embedder/platform_view_embedder.h +++ b/shell/platform/embedder/platform_view_embedder.h @@ -14,20 +14,20 @@ #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/embedder/embedder_studio.h" #include "flutter/shell/platform/embedder/embedder_surface.h" -#include "flutter/shell/platform/embedder/embedder_surface_software.h" +// #include "flutter/shell/platform/embedder/embedder_surface_software.h" #include "flutter/shell/platform/embedder/vsync_waiter_embedder.h" -#ifdef SHELL_ENABLE_GL -#include "flutter/shell/platform/embedder/embedder_surface_gl.h" -#endif +// #ifdef SHELL_ENABLE_GL +// #include "flutter/shell/platform/embedder/embedder_surface_gl.h" +// #endif -#ifdef SHELL_ENABLE_METAL -#include "flutter/shell/platform/embedder/embedder_surface_metal.h" -#endif +// #ifdef SHELL_ENABLE_METAL +// #include "flutter/shell/platform/embedder/embedder_surface_metal.h" +// #endif -#ifdef SHELL_ENABLE_VULKAN -#include "flutter/shell/platform/embedder/embedder_surface_vulkan.h" -#endif +// #ifdef SHELL_ENABLE_VULKAN +// #include "flutter/shell/platform/embedder/embedder_surface_vulkan.h" +// #endif namespace flutter { diff --git a/shell/platform/embedder/platform_view_embedder_unittests.cc b/shell/platform/embedder/platform_view_embedder_unittests.cc index 3735e97eca2ea..04b4fb804b871 100644 --- a/shell/platform/embedder/platform_view_embedder_unittests.cc +++ b/shell/platform/embedder/platform_view_embedder_unittests.cc @@ -61,8 +61,7 @@ class MockResponse : public PlatformMessageResponse { class MockStudio : public EmbedderStudio { public: - MockStudio() : EmbedderStudio(nullptr) {} - + MOCK_CONST_METHOD0(IsValid, bool()); MOCK_METHOD0(CreateSurface, std::unique_ptr()); MOCK_CONST_METHOD0(CreateResourceContext, sk_sp()); }; @@ -77,7 +76,6 @@ TEST(PlatformViewEmbedderTest, HasPlatformMessageHandler) { fml::AutoResetWaitableEvent latch; task_runners.GetPlatformTaskRunner()->PostTask([&latch, task_runners] { MockDelegate delegate; - EmbedderSurfaceSoftware::SoftwareDispatchTable software_dispatch_table; PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table; std::shared_ptr external_view_embedder; auto embedder = std::make_unique( @@ -143,28 +141,27 @@ TEST(PlatformViewEmbedderTest, DeletionDisabledDispatch) { bool did_call = false; { fml::AutoResetWaitableEvent latch; - task_runners.GetPlatformTaskRunner()->PostTask([&latch, task_runners, - &did_call] { - MockDelegate delegate; - EmbedderSurfaceSoftware::SoftwareDispatchTable software_dispatch_table; - PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table; - platform_dispatch_table.platform_message_response_callback = - [&did_call](std::unique_ptr message) { - did_call = true; - }; - std::shared_ptr external_view_embedder; - auto embedder = std::make_unique( - delegate, task_runners, std::make_unique(), - platform_dispatch_table, external_view_embedder); - auto platform_message_handler = embedder->GetPlatformMessageHandler(); - fml::RefPtr response = - fml::MakeRefCounted(); - std::unique_ptr message = - std::make_unique("foo", response); - platform_message_handler->HandlePlatformMessage(std::move(message)); - embedder.reset(); - latch.Signal(); - }); + task_runners.GetPlatformTaskRunner()->PostTask( + [&latch, task_runners, &did_call] { + MockDelegate delegate; + PlatformViewEmbedder::PlatformDispatchTable platform_dispatch_table; + platform_dispatch_table.platform_message_response_callback = + [&did_call](std::unique_ptr message) { + did_call = true; + }; + std::shared_ptr external_view_embedder; + auto embedder = std::make_unique( + delegate, task_runners, std::make_unique(), + platform_dispatch_table, external_view_embedder); + auto platform_message_handler = embedder->GetPlatformMessageHandler(); + fml::RefPtr response = + fml::MakeRefCounted(); + std::unique_ptr message = + std::make_unique("foo", response); + platform_message_handler->HandlePlatformMessage(std::move(message)); + embedder.reset(); + latch.Signal(); + }); latch.Wait(); } { From 424d9a73184526b5429d5060aeb1b0b4444449be Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 17 Mar 2023 14:18:42 -0700 Subject: [PATCH 013/142] Format --- shell/platform/embedder/embedder_studio_gl.cc | 2 +- shell/platform/embedder/embedder_studio_gl.h | 2 +- shell/platform/embedder/embedder_studio_metal.h | 2 +- shell/platform/embedder/embedder_studio_metal.mm | 9 ++++----- shell/platform/embedder/embedder_studio_software.cc | 3 ++- shell/platform/embedder/embedder_studio_software.h | 2 +- shell/platform/embedder/embedder_studio_vulkan.cc | 4 ++-- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/shell/platform/embedder/embedder_studio_gl.cc b/shell/platform/embedder/embedder_studio_gl.cc index d89a1a69bd1f0..1f03fc815787f 100644 --- a/shell/platform/embedder/embedder_studio_gl.cc +++ b/shell/platform/embedder/embedder_studio_gl.cc @@ -6,8 +6,8 @@ #include -#include "flutter/shell/platform/embedder/embedder_surface_gl.h" #include "flutter/shell/common/shell_io_manager.h" +#include "flutter/shell/platform/embedder/embedder_surface_gl.h" namespace flutter { diff --git a/shell/platform/embedder/embedder_studio_gl.h b/shell/platform/embedder/embedder_studio_gl.h index 1a0b227ad918d..65ebda6855bcc 100644 --- a/shell/platform/embedder/embedder_studio_gl.h +++ b/shell/platform/embedder/embedder_studio_gl.h @@ -13,7 +13,7 @@ namespace flutter { class EmbedderStudioGL final : public EmbedderStudio, - public GPUSurfaceGLDelegate { + public GPUSurfaceGLDelegate { public: struct GLDispatchTable { std::function gl_make_current_callback; // required diff --git a/shell/platform/embedder/embedder_studio_metal.h b/shell/platform/embedder/embedder_studio_metal.h index 8dd0ab25b288c..db1d0bbf1a4be 100644 --- a/shell/platform/embedder/embedder_studio_metal.h +++ b/shell/platform/embedder/embedder_studio_metal.h @@ -16,7 +16,7 @@ namespace flutter { class EmbedderStudioMetal final : public EmbedderStudio, - public GPUSurfaceMetalDelegate { + public GPUSurfaceMetalDelegate { public: struct MetalDispatchTable { std::function present; // required diff --git a/shell/platform/embedder/embedder_studio_metal.mm b/shell/platform/embedder/embedder_studio_metal.mm index 7400e454af1ff..87ef747734042 100644 --- a/shell/platform/embedder/embedder_studio_metal.mm +++ b/shell/platform/embedder/embedder_studio_metal.mm @@ -8,8 +8,8 @@ #include "flutter/fml/logging.h" #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" -#include "flutter/shell/platform/embedder/embedder_surface_metal.h" #import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h" +#include "flutter/shell/platform/embedder/embedder_surface_metal.h" #include "third_party/skia/include/gpu/GrDirectContext.h" FLUTTER_ASSERT_NOT_ARC @@ -43,10 +43,9 @@ return nullptr; } const bool render_to_surface = !external_view_embedder_; - return std::make_unique( - main_context_, - this, // GPU surface GL delegate - render_to_surface // render to surface + return std::make_unique(main_context_, + this, // GPU surface GL delegate + render_to_surface // render to surface ); } diff --git a/shell/platform/embedder/embedder_studio_software.cc b/shell/platform/embedder/embedder_studio_software.cc index a3d898b8c2b0d..eceeda79fee89 100644 --- a/shell/platform/embedder/embedder_studio_software.cc +++ b/shell/platform/embedder/embedder_studio_software.cc @@ -41,7 +41,8 @@ std::unique_ptr EmbedderStudioSoftware::CreateSurface() { return nullptr; } const bool render_to_surface = !external_view_embedder_; - auto surface = std::make_unique(this, render_to_surface); + auto surface = + std::make_unique(this, render_to_surface); if (!surface->IsValid()) { return nullptr; diff --git a/shell/platform/embedder/embedder_studio_software.h b/shell/platform/embedder/embedder_studio_software.h index 7be884601f292..ce9ba6f9f8182 100644 --- a/shell/platform/embedder/embedder_studio_software.h +++ b/shell/platform/embedder/embedder_studio_software.h @@ -15,7 +15,7 @@ namespace flutter { class EmbedderStudioSoftware final : public EmbedderStudio, - public GPUSurfaceSoftwareDelegate { + public GPUSurfaceSoftwareDelegate { public: struct SoftwareDispatchTable { std::function diff --git a/shell/platform/embedder/embedder_studio_vulkan.cc b/shell/platform/embedder/embedder_studio_vulkan.cc index dad77ce3b3ec5..ba61e2217a209 100644 --- a/shell/platform/embedder/embedder_studio_vulkan.cc +++ b/shell/platform/embedder/embedder_studio_vulkan.cc @@ -9,8 +9,8 @@ #include "flutter/flutter_vma/flutter_skia_vma.h" #include "flutter/shell/common/shell_io_manager.h" #include "flutter/shell/gpu/gpu_surface_vulkan.h" -#include "flutter/shell/platform/embedder/embedder_surface_vulkan.h" #include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" +#include "flutter/shell/platform/embedder/embedder_surface_vulkan.h" #include "flutter/vulkan/vulkan_skia_proc_table.h" #include "include/gpu/GrDirectContext.h" #include "include/gpu/vk/GrVkBackendContext.h" @@ -112,7 +112,7 @@ bool EmbedderStudioVulkan::IsValid() const { std::unique_ptr EmbedderStudioVulkan::CreateSurface() { const bool render_to_surface = !external_view_embedder_; return std::make_unique(this, main_context_, - render_to_surface); + render_to_surface); } // |EmbedderStudio| From beb6db9935fedb80af114b9c167539155493f848 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 17 Mar 2023 14:48:38 -0700 Subject: [PATCH 014/142] conditional import --- shell/gpu/gpu_surface_gl_skia.h | 1 - shell/platform/embedder/embedder.cc | 10 ++++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/shell/gpu/gpu_surface_gl_skia.h b/shell/gpu/gpu_surface_gl_skia.h index 2b40e53f27055..1cbb4c50ecd29 100644 --- a/shell/gpu/gpu_surface_gl_skia.h +++ b/shell/gpu/gpu_surface_gl_skia.h @@ -70,7 +70,6 @@ class GPUSurfaceGLSkia : public Surface { // still have an option of overriding this damage with their own in // `GLContextFrameBufferInfo`. std::optional existing_damage_ = std::nullopt; - bool context_owner_ = false; // TODO(38466): Refactor GPU surface APIs take into account the fact that an // external view embedder may want to render to the root surface. This is a // hack to make avoid allocating resources for the root surface when an diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index b650355d4bcc1..573661ff1a674 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -54,10 +54,7 @@ extern const intptr_t kPlatformStrongDillSize; #include "flutter/shell/platform/embedder/embedder_platform_message_response.h" #include "flutter/shell/platform/embedder/embedder_render_target.h" #include "flutter/shell/platform/embedder/embedder_struct_macros.h" -#include "flutter/shell/platform/embedder/embedder_studio_gl.h" -#include "flutter/shell/platform/embedder/embedder_studio_metal.h" #include "flutter/shell/platform/embedder/embedder_studio_software.h" -#include "flutter/shell/platform/embedder/embedder_studio_vulkan.h" #include "flutter/shell/platform/embedder/embedder_task_runner.h" #include "flutter/shell/platform/embedder/embedder_thread_host.h" #include "flutter/shell/platform/embedder/pixel_formats.h" @@ -67,10 +64,15 @@ extern const intptr_t kPlatformStrongDillSize; #ifdef SHELL_ENABLE_GL #include "flutter/shell/platform/embedder/embedder_external_texture_gl.h" +#include "flutter/shell/platform/embedder/embedder_studio_gl.h" #endif #ifdef SHELL_ENABLE_METAL -#include "flutter/shell/platform/embedder/embedder_surface_metal.h" +#include "flutter/shell/platform/embedder/embedder_studio_metal.h" +#endif + +#ifdef SHELL_ENABLE_VULKAN +#include "flutter/shell/platform/embedder/embedder_studio_vulkan.h" #endif const int32_t kFlutterSemanticsNodeIdBatchEnd = -1; From 65f2fe7178ad0b8d576c037d6b4be3ff8fde911d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 17 Mar 2023 18:44:35 -0700 Subject: [PATCH 015/142] lint --- shell/platform/embedder/embedder_surface_gl.cc | 2 +- shell/platform/embedder/embedder_surface_metal.mm | 4 +++- shell/platform/embedder/embedder_surface_vulkan.cc | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index 929f0e5092d95..6159a15e68af5 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -14,7 +14,7 @@ namespace flutter { EmbedderSurfaceGL::EmbedderSurfaceGL(sk_sp main_context, EmbedderStudioGL* studio, bool render_to_surface) - : main_context_(main_context), + : main_context_(std::move(main_context)), studio_(studio), render_to_surface_(render_to_surface) {} diff --git a/shell/platform/embedder/embedder_surface_metal.mm b/shell/platform/embedder/embedder_surface_metal.mm index b3cbd6c96a7ad..8560c2e5d6174 100644 --- a/shell/platform/embedder/embedder_surface_metal.mm +++ b/shell/platform/embedder/embedder_surface_metal.mm @@ -18,7 +18,9 @@ EmbedderSurfaceMetal::EmbedderSurfaceMetal(sk_sp main_context, EmbedderStudioMetal* studio, bool render_to_surface) - : main_context_(main_context), studio_(studio), render_to_surface_(render_to_surface) {} + : main_context_(std::move(main_context)), + studio_(studio), + render_to_surface_(render_to_surface) {} EmbedderSurfaceMetal::~EmbedderSurfaceMetal() = default; diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index 09e55b309281a..de92ed3babc0c 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -21,7 +21,7 @@ EmbedderSurfaceVulkan::EmbedderSurfaceVulkan( EmbedderStudioVulkan* studio, sk_sp main_context, bool render_to_surface) - : main_context_(main_context), + : main_context_(std::move(main_context)), studio_(studio), render_to_surface_(render_to_surface) {} From 4ef438c8bc451f79a89be2c7db442de8f645856c Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sun, 19 Mar 2023 23:30:30 -0700 Subject: [PATCH 016/142] Add gpu studios --- ci/licenses_golden/licenses_flutter | 28 ++++ flow/studio.cc | 33 +++++ flow/studio.h | 47 +++++++ shell/gpu/BUILD.gn | 14 ++ shell/gpu/gpu_studio_gl_impeller.cc | 83 ++++++++++++ shell/gpu/gpu_studio_gl_impeller.h | 60 +++++++++ shell/gpu/gpu_studio_gl_skia.cc | 171 ++++++++++++++++++++++++ shell/gpu/gpu_studio_gl_skia.h | 74 ++++++++++ shell/gpu/gpu_studio_metal_impeller.h | 58 ++++++++ shell/gpu/gpu_studio_metal_impeller.mm | 109 +++++++++++++++ shell/gpu/gpu_studio_metal_skia.h | 62 +++++++++ shell/gpu/gpu_studio_metal_skia.mm | 106 +++++++++++++++ shell/gpu/gpu_studio_software.cc | 34 +++++ shell/gpu/gpu_studio_software.h | 41 ++++++ shell/gpu/gpu_studio_vulkan.cc | 48 +++++++ shell/gpu/gpu_studio_vulkan.h | 59 ++++++++ shell/gpu/gpu_studio_vulkan_impeller.cc | 68 ++++++++++ shell/gpu/gpu_studio_vulkan_impeller.h | 49 +++++++ 18 files changed, 1144 insertions(+) create mode 100644 flow/studio.cc create mode 100644 flow/studio.h create mode 100644 shell/gpu/gpu_studio_gl_impeller.cc create mode 100644 shell/gpu/gpu_studio_gl_impeller.h create mode 100644 shell/gpu/gpu_studio_gl_skia.cc create mode 100644 shell/gpu/gpu_studio_gl_skia.h create mode 100644 shell/gpu/gpu_studio_metal_impeller.h create mode 100644 shell/gpu/gpu_studio_metal_impeller.mm create mode 100644 shell/gpu/gpu_studio_metal_skia.h create mode 100644 shell/gpu/gpu_studio_metal_skia.mm create mode 100644 shell/gpu/gpu_studio_software.cc create mode 100644 shell/gpu/gpu_studio_software.h create mode 100644 shell/gpu/gpu_studio_vulkan.cc create mode 100644 shell/gpu/gpu_studio_vulkan.h create mode 100644 shell/gpu/gpu_studio_vulkan_impeller.cc create mode 100644 shell/gpu/gpu_studio_vulkan_impeller.h diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index c78d25f37c0df..45beef38f4281 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -2115,6 +2115,20 @@ ORIGIN: ../../../flutter/shell/common/vsync_waiter_fallback.cc + ../../../flutte ORIGIN: ../../../flutter/shell/common/vsync_waiter_fallback.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/common/vsync_waiters_test.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/common/vsync_waiters_test.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_gl_impeller.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_gl_impeller.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_gl_skia.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_gl_skia.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_metal_impeller.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_metal_impeller.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_metal_skia.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_metal_skia.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_software.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_software.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_vulkan.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_vulkan.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_vulkan_impeller.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/gpu/gpu_studio_vulkan_impeller.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/gpu/gpu_surface_gl_impeller.cc + ../../../flutter/LICENSE @@ -4659,6 +4673,20 @@ FILE: ../../../flutter/shell/common/vsync_waiter_fallback.cc FILE: ../../../flutter/shell/common/vsync_waiter_fallback.h FILE: ../../../flutter/shell/common/vsync_waiters_test.cc FILE: ../../../flutter/shell/common/vsync_waiters_test.h +FILE: ../../../flutter/shell/gpu/gpu_studio_gl_impeller.cc +FILE: ../../../flutter/shell/gpu/gpu_studio_gl_impeller.h +FILE: ../../../flutter/shell/gpu/gpu_studio_gl_skia.cc +FILE: ../../../flutter/shell/gpu/gpu_studio_gl_skia.h +FILE: ../../../flutter/shell/gpu/gpu_studio_metal_impeller.h +FILE: ../../../flutter/shell/gpu/gpu_studio_metal_impeller.mm +FILE: ../../../flutter/shell/gpu/gpu_studio_metal_skia.h +FILE: ../../../flutter/shell/gpu/gpu_studio_metal_skia.mm +FILE: ../../../flutter/shell/gpu/gpu_studio_software.cc +FILE: ../../../flutter/shell/gpu/gpu_studio_software.h +FILE: ../../../flutter/shell/gpu/gpu_studio_vulkan.cc +FILE: ../../../flutter/shell/gpu/gpu_studio_vulkan.h +FILE: ../../../flutter/shell/gpu/gpu_studio_vulkan_impeller.cc +FILE: ../../../flutter/shell/gpu/gpu_studio_vulkan_impeller.h FILE: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.cc FILE: ../../../flutter/shell/gpu/gpu_surface_gl_delegate.h FILE: ../../../flutter/shell/gpu/gpu_surface_gl_impeller.cc diff --git a/flow/studio.cc b/flow/studio.cc new file mode 100644 index 0000000000000..879281c59cf00 --- /dev/null +++ b/flow/studio.cc @@ -0,0 +1,33 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/flow/studio.h" + +namespace flutter { + +Studio::Studio() = default; + +Studio::~Studio() = default; + +std::unique_ptr Studio::MakeRenderContextCurrent() { + return std::make_unique(true); +} + +bool Studio::ClearRenderContext() { + return false; +} + +bool Studio::AllowsDrawingWhenGpuDisabled() const { + return true; +} + +bool Studio::EnableRasterCache() const { + return true; +} + +impeller::AiksContext* Studio::GetAiksContext() const { + return nullptr; +} + +} // namespace flutter diff --git a/flow/studio.h b/flow/studio.h new file mode 100644 index 0000000000000..7c746d1e7796a --- /dev/null +++ b/flow/studio.h @@ -0,0 +1,47 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_FLOW_STUDIO_H_ +#define FLUTTER_FLOW_STUDIO_H_ + +#include + +#include "flutter/common/graphics/gl_context_switch.h" +#include "flutter/fml/macros.h" + +class GrDirectContext; + +namespace impeller { +class AiksContext; +} // namespace impeller + +namespace flutter { + +class Studio { + public: + Studio(); + + virtual ~Studio(); + + virtual bool IsValid() = 0; + + virtual GrDirectContext* GetContext() = 0; + + virtual std::unique_ptr MakeRenderContextCurrent(); + + virtual bool ClearRenderContext(); + + virtual bool AllowsDrawingWhenGpuDisabled() const; + + virtual bool EnableRasterCache() const; + + virtual impeller::AiksContext* GetAiksContext() const; + + private: + FML_DISALLOW_COPY_AND_ASSIGN(Studio); +}; + +} // namespace flutter + +#endif // FLUTTER_FLOW_STUDIO_H_ diff --git a/shell/gpu/BUILD.gn b/shell/gpu/BUILD.gn index 5e5c1cce53a6c..ec7b2a25b3530 100644 --- a/shell/gpu/BUILD.gn +++ b/shell/gpu/BUILD.gn @@ -17,6 +17,8 @@ gpu_common_deps = [ source_set("gpu_surface_software") { sources = [ + "gpu_studio_software.cc", + "gpu_studio_software.h", "gpu_surface_software.cc", "gpu_surface_software.h", "gpu_surface_software_delegate.cc", @@ -28,6 +30,8 @@ source_set("gpu_surface_software") { source_set("gpu_surface_gl") { sources = [ + "gpu_studio_gl_skia.cc", + "gpu_studio_gl_skia.h", "gpu_surface_gl_delegate.cc", "gpu_surface_gl_delegate.h", "gpu_surface_gl_skia.cc", @@ -38,6 +42,8 @@ source_set("gpu_surface_gl") { if (impeller_enable_opengles) { sources += [ + "gpu_studio_gl_impeller.cc", + "gpu_studio_gl_impeller.h", "gpu_surface_gl_impeller.cc", "gpu_surface_gl_impeller.h", ] @@ -48,6 +54,8 @@ source_set("gpu_surface_gl") { source_set("gpu_surface_vulkan") { sources = [ + "gpu_studio_vulkan.cc", + "gpu_studio_vulkan.h", "gpu_surface_vulkan.cc", "gpu_surface_vulkan.h", "gpu_surface_vulkan_delegate.cc", @@ -61,6 +69,8 @@ source_set("gpu_surface_vulkan") { if (impeller_enable_vulkan) { sources += [ + "gpu_studio_vulkan_impeller.cc", + "gpu_studio_vulkan_impeller.h", "gpu_surface_vulkan_impeller.cc", "gpu_surface_vulkan_impeller.h", ] @@ -71,6 +81,8 @@ source_set("gpu_surface_vulkan") { source_set("gpu_surface_metal") { sources = [ + "gpu_studio_metal_skia.h", + "gpu_studio_metal_skia.mm", "gpu_surface_metal_delegate.cc", "gpu_surface_metal_delegate.h", "gpu_surface_metal_skia.h", @@ -81,6 +93,8 @@ source_set("gpu_surface_metal") { if (impeller_enable_metal) { sources += [ + "gpu_studio_metal_impeller.h", + "gpu_studio_metal_impeller.mm", "gpu_surface_metal_impeller.h", "gpu_surface_metal_impeller.mm", ] diff --git a/shell/gpu/gpu_studio_gl_impeller.cc b/shell/gpu/gpu_studio_gl_impeller.cc new file mode 100644 index 0000000000000..c7b443f4efe0e --- /dev/null +++ b/shell/gpu/gpu_studio_gl_impeller.cc @@ -0,0 +1,83 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/gpu/gpu_studio_gl_impeller.h" + +#include "flutter/fml/make_copyable.h" +#include "flutter/impeller/display_list/display_list_dispatcher.h" +#include "flutter/impeller/renderer/backend/gles/surface_gles.h" +#include "flutter/impeller/renderer/renderer.h" + +namespace flutter { + +GPUStudioGLImpeller::GPUStudioGLImpeller( + GPUStudioGLDelegate* delegate, + std::shared_ptr context) + : weak_factory_(this) { + if (delegate == nullptr) { + return; + } + + if (!context || !context->IsValid()) { + return; + } + + auto renderer = std::make_shared(context); + if (!renderer->IsValid()) { + return; + } + + auto aiks_context = std::make_shared(context); + + if (!aiks_context->IsValid()) { + return; + } + + delegate_ = delegate; + impeller_context_ = std::move(context); + impeller_renderer_ = std::move(renderer); + aiks_context_ = std::move(aiks_context); + is_valid_ = true; +} + +// |Studio| +GPUStudioGLImpeller::~GPUStudioGLImpeller() = default; + +// |Studio| +bool GPUStudioGLImpeller::IsValid() { + return is_valid_; +} + +// |Studio| +GrDirectContext* GPUStudioGLImpeller::GetContext() { + // Impeller != Skia. + return nullptr; +} + +// |Studio| +std::unique_ptr +GPUStudioGLImpeller::MakeRenderContextCurrent() { + return delegate_->GLContextMakeCurrent(); +} + +// |Studio| +bool GPUStudioGLImpeller::ClearRenderContext() { + return delegate_->GLContextClearCurrent(); +} + +bool GPUStudioGLImpeller::AllowsDrawingWhenGpuDisabled() const { + return delegate_->AllowsDrawingWhenGpuDisabled(); +} + +// |Studio| +bool GPUStudioGLImpeller::EnableRasterCache() const { + return false; +} + +// |Studio| +impeller::AiksContext* GPUStudioGLImpeller::GetAiksContext() const { + return aiks_context_.get(); +} + +} // namespace flutter diff --git a/shell/gpu/gpu_studio_gl_impeller.h b/shell/gpu/gpu_studio_gl_impeller.h new file mode 100644 index 0000000000000..2397cc89a1fd3 --- /dev/null +++ b/shell/gpu/gpu_studio_gl_impeller.h @@ -0,0 +1,60 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SHELL_GPU_GPU_SURFACE_GL_IMPELLER_H_ +#define SHELL_GPU_GPU_SURFACE_GL_IMPELLER_H_ + +#include "flutter/common/graphics/gl_context_switch.h" +#include "flutter/flow/surface.h" +#include "flutter/fml/macros.h" +#include "flutter/fml/memory/weak_ptr.h" +#include "flutter/impeller/aiks/aiks_context.h" +#include "flutter/impeller/renderer/context.h" +#include "flutter/shell/gpu/gpu_surface_gl_delegate.h" + +namespace flutter { + +class GPUStudioGLImpeller final : public Studio { + public: + explicit GPUStudioGLImpeller(GPUStudioGLDelegate* delegate, + std::shared_ptr context); + + // |Studio| + ~GPUStudioGLImpeller() override; + + // |Studio| + bool IsValid() override; + + private: + GPUStudioGLDelegate* delegate_ = nullptr; + std::shared_ptr impeller_context_; + std::shared_ptr impeller_renderer_; + std::shared_ptr aiks_context_; + bool is_valid_ = false; + fml::WeakPtrFactory weak_factory_; + + // |Studio| + GrDirectContext* GetContext() override; + + // |Studio| + std::unique_ptr MakeRenderContextCurrent() override; + + // |Studio| + bool ClearRenderContext() override; + + // |Studio| + bool AllowsDrawingWhenGpuDisabled() const override; + + // |Studio| + bool EnableRasterCache() const override; + + // |Studio| + impeller::AiksContext* GetAiksContext() const override; + + FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioGLImpeller); +}; + +} // namespace flutter + +#endif // SHELL_GPU_GPU_SURFACE_GL_IMPELLER_H_ diff --git a/shell/gpu/gpu_studio_gl_skia.cc b/shell/gpu/gpu_studio_gl_skia.cc new file mode 100644 index 0000000000000..227c9099175be --- /dev/null +++ b/shell/gpu/gpu_studio_gl_skia.cc @@ -0,0 +1,171 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/gpu/gpu_studio_gl_skia.h" + +#include "flutter/common/graphics/persistent_cache.h" +#include "flutter/fml/base32.h" +#include "flutter/fml/logging.h" +#include "flutter/fml/size.h" +#include "flutter/fml/trace_event.h" +#include "flutter/shell/common/context_options.h" +#include "flutter/shell/gpu/gpu_surface_gl_delegate.h" +#include "third_party/skia/include/core/SkAlphaType.h" +#include "third_party/skia/include/core/SkColorFilter.h" +#include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkColorType.h" +#include "third_party/skia/include/core/SkStudio.h" +#include "third_party/skia/include/gpu/GrBackendStudio.h" +#include "third_party/skia/include/gpu/GrContextOptions.h" + +// These are common defines present on all OpenGL headers. However, we don't +// want to perform GL header reasolution on each platform we support. So just +// define these upfront. It is unlikely we will need more. But, if we do, we can +// add the same here. +#define GPU_GL_RGBA8 0x8058 +#define GPU_GL_RGBA4 0x8056 +#define GPU_GL_RGB565 0x8D62 + +namespace flutter { + +// Default maximum number of bytes of GPU memory of budgeted resources in the +// cache. +// The shell will dynamically increase or decrease this cache based on the +// viewport size, unless a user has specifically requested a size on the Skia +// system channel. +static const size_t kGrCacheMaxByteSize = 24 * (1 << 20); + +sk_sp GPUStudioGLSkia::MakeGLContext( + GPUStudioGLDelegate* delegate) { + auto context_switch = delegate->GLContextMakeCurrent(); + if (!context_switch->GetResult()) { + FML_LOG(ERROR) + << "Could not make the context current to set up the Gr context."; + return nullptr; + } + + const auto options = + MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kOpenGL); + + auto context = GrDirectContext::MakeGL(delegate->GetGLInterface(), options); + + if (!context) { + FML_LOG(ERROR) << "Failed to set up Skia Gr context."; + return nullptr; + } + + context->setResourceCacheLimit(kGrCacheMaxByteSize); + + PersistentCache::GetCacheForProcess()->PrecompileKnownSkSLs(context.get()); + + return context; +} + +GPUStudioGLSkia::GPUStudioGLSkia(const sk_sp& gr_context, + GPUStudioGLDelegate* delegate, + bool render_to_surface) + : delegate_(delegate), + context_(gr_context), + + render_to_surface_(render_to_surface), + weak_factory_(this) { + auto context_switch = delegate_->GLContextMakeCurrent(); + if (!context_switch->GetResult()) { + FML_LOG(ERROR) + << "Could not make the context current to set up the Gr context."; + return; + } + + delegate_->GLContextClearCurrent(); + + valid_ = gr_context != nullptr; +} + +GPUStudioGLSkia::~GPUStudioGLSkia() { + if (!valid_) { + return; + } + auto context_switch = delegate_->GLContextMakeCurrent(); + if (!context_switch->GetResult()) { + FML_LOG(ERROR) << "Could not make the context current to destroy the " + "GrDirectContext resources."; + return; + } + + onscreen_surface_ = nullptr; + fbo_id_ = 0; + context_ = nullptr; + + delegate_->GLContextClearCurrent(); +} + +// |Studio| +bool GPUStudioGLSkia::IsValid() { + return valid_; +} + +static SkColorType FirstSupportedColorType(GrDirectContext* context, + GrGLenum* format) { +#define RETURN_IF_RENDERABLE(x, y) \ + if (context->colorTypeSupportedAsStudio((x))) { \ + *format = (y); \ + return (x); \ + } + RETURN_IF_RENDERABLE(kRGBA_8888_SkColorType, GPU_GL_RGBA8); + RETURN_IF_RENDERABLE(kARGB_4444_SkColorType, GPU_GL_RGBA4); + RETURN_IF_RENDERABLE(kRGB_565_SkColorType, GPU_GL_RGB565); + return kUnknown_SkColorType; +} + +static sk_sp WrapOnscreenStudio(GrDirectContext* context, + const SkISize& size, + intptr_t fbo) { + GrGLenum format = kUnknown_SkColorType; + const SkColorType color_type = FirstSupportedColorType(context, &format); + + GrGLFramebufferInfo framebuffer_info = {}; + framebuffer_info.fFBOID = static_cast(fbo); + framebuffer_info.fFormat = format; + + GrBackendRenderTarget render_target(size.width(), // width + size.height(), // height + 0, // sample count + 0, // stencil bits + framebuffer_info // framebuffer info + ); + + sk_sp colorspace = SkColorSpace::MakeSRGB(); + SkStudioProps surface_props(0, kUnknown_SkPixelGeometry); + + return SkStudio::MakeFromBackendRenderTarget( + context, // Gr context + render_target, // render target + GrStudioOrigin::kBottomLeft_GrStudioOrigin, // origin + color_type, // color type + colorspace, // colorspace + &surface_props // surface properties + ); +} + +// |Studio| +GrDirectContext* GPUStudioGLSkia::GetContext() { + return context_.get(); +} + +// |Studio| +std::unique_ptr GPUStudioGLSkia::MakeRenderContextCurrent() { + return delegate_->GLContextMakeCurrent(); +} + +// |Studio| +bool GPUStudioGLSkia::ClearRenderContext() { + return delegate_->GLContextClearCurrent(); +} + +// |Studio| +bool GPUStudioGLSkia::AllowsDrawingWhenGpuDisabled() const { + return delegate_->AllowsDrawingWhenGpuDisabled(); +} + +} // namespace flutter diff --git a/shell/gpu/gpu_studio_gl_skia.h b/shell/gpu/gpu_studio_gl_skia.h new file mode 100644 index 0000000000000..11429f0df3bc9 --- /dev/null +++ b/shell/gpu/gpu_studio_gl_skia.h @@ -0,0 +1,74 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SHELL_GPU_GPU_SURFACE_GL_SKIA_H_ +#define SHELL_GPU_GPU_SURFACE_GL_SKIA_H_ + +#include +#include + +#include "flutter/common/graphics/gl_context_switch.h" +#include "flutter/flow/embedded_views.h" +#include "flutter/flow/surface.h" +#include "flutter/fml/macros.h" +#include "flutter/fml/memory/weak_ptr.h" +#include "flutter/shell/gpu/gpu_surface_gl_delegate.h" + +#include "third_party/skia/include/core/SkStudio.h" +#include "third_party/skia/include/gpu/GrDirectContext.h" + +namespace flutter { + +class GPUStudioGLSkia : public Studio { + public: + static sk_sp MakeGLContext(GPUStudioGLDelegate* delegate); + + GPUStudioGLSkia(const sk_sp& gr_context, + GPUStudioGLDelegate* delegate, + bool render_to_surface); + + // |Studio| + ~GPUStudioGLSkia() override; + + // |Studio| + bool IsValid() override; + + // |Studio| + GrDirectContext* GetContext() override; + + // |Studio| + std::unique_ptr MakeRenderContextCurrent() override; + + // |Studio| + bool ClearRenderContext() override; + + // |Studio| + bool AllowsDrawingWhenGpuDisabled() const override; + + private: + + GPUStudioGLDelegate* delegate_; + sk_sp context_; + sk_sp onscreen_surface_; + /// FBO backing the current `onscreen_surface_`. + uint32_t fbo_id_ = 0; + // The current FBO's existing damage, as tracked by the GPU surface, delegates + // still have an option of overriding this damage with their own in + // `GLContextFrameBufferInfo`. + std::optional existing_damage_ = std::nullopt; + // TODO(38466): Refactor GPU surface APIs take into account the fact that an + // external view embedder may want to render to the root surface. This is a + // hack to make avoid allocating resources for the root surface when an + // external view embedder is present. + const bool render_to_surface_ = true; + bool valid_ = false; + + // WeakPtrFactory must be the last member. + fml::TaskRunnerAffineWeakPtrFactory weak_factory_; + FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioGLSkia); +}; + +} // namespace flutter + +#endif // SHELL_GPU_GPU_SURFACE_GL_SKIA_H_ diff --git a/shell/gpu/gpu_studio_metal_impeller.h b/shell/gpu/gpu_studio_metal_impeller.h new file mode 100644 index 0000000000000..7211da592dff7 --- /dev/null +++ b/shell/gpu/gpu_studio_metal_impeller.h @@ -0,0 +1,58 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_IMPELLER_H_ +#define FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_IMPELLER_H_ + +#include + +#include "flutter/flow/surface.h" +#include "flutter/fml/macros.h" +#include "flutter/fml/platform/darwin/scoped_nsobject.h" +#include "flutter/impeller/aiks/aiks_context.h" +#include "flutter/impeller/renderer/renderer.h" +#include "flutter/shell/gpu/gpu_surface_metal_delegate.h" + +namespace flutter { + +class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalImpeller : public Studio { + public: + GPUStudioMetalImpeller(GPUStudioMetalDelegate* delegate, + const std::shared_ptr& context); + + // |Studio| + ~GPUStudioMetalImpeller(); + + // |Studio| + bool IsValid() override; + + virtual Studio::StudioData GetStudioData() const override; + + private: + const GPUStudioMetalDelegate* delegate_; + std::shared_ptr impeller_renderer_; + std::shared_ptr aiks_context_; + fml::scoped_nsprotocol> last_drawable_; + + // |Studio| + GrDirectContext* GetContext() override; + + // |Studio| + std::unique_ptr MakeRenderContextCurrent() override; + + // |Studio| + bool AllowsDrawingWhenGpuDisabled() const override; + + // |Studio| + bool EnableRasterCache() const override; + + // |Studio| + impeller::AiksContext* GetAiksContext() const override; + + FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioMetalImpeller); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_IMPELLER_H_ diff --git a/shell/gpu/gpu_studio_metal_impeller.mm b/shell/gpu/gpu_studio_metal_impeller.mm new file mode 100644 index 0000000000000..8d2a3a04e3a22 --- /dev/null +++ b/shell/gpu/gpu_studio_metal_impeller.mm @@ -0,0 +1,109 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/gpu/gpu_studio_metal_impeller.h" + +#import +#import + +#include "flutter/common/settings.h" +#include "flutter/fml/make_copyable.h" +#include "flutter/fml/mapping.h" +#include "flutter/fml/trace_event.h" +#include "flutter/impeller/display_list/display_list_dispatcher.h" +#include "flutter/impeller/renderer/backend/metal/surface_mtl.h" + +static_assert(!__has_feature(objc_arc), "ARC must be disabled."); + +namespace flutter { + +static std::shared_ptr CreateImpellerRenderer( + std::shared_ptr context) { + auto renderer = std::make_shared(std::move(context)); + if (!renderer->IsValid()) { + FML_LOG(ERROR) << "Could not create valid Impeller Renderer."; + return nullptr; + } + return renderer; +} + +GPUStudioMetalImpeller::GPUStudioMetalImpeller(GPUStudioMetalDelegate* delegate, + const std::shared_ptr& context) + : delegate_(delegate), + impeller_renderer_(CreateImpellerRenderer(context)), + aiks_context_( + std::make_shared(impeller_renderer_ ? context : nullptr)) {} + +GPUStudioMetalImpeller::~GPUStudioMetalImpeller() = default; + +// |Studio| +bool GPUStudioMetalImpeller::IsValid() { + return !!aiks_context_; +} + +// |Studio| +GrDirectContext* GPUStudioMetalImpeller::GetContext() { + return nullptr; +} + +// |Studio| +std::unique_ptr GPUStudioMetalImpeller::MakeRenderContextCurrent() { + // This backend has no such concept. + return std::make_unique(true); +} + +bool GPUStudioMetalImpeller::AllowsDrawingWhenGpuDisabled() const { + return delegate_->AllowsDrawingWhenGpuDisabled(); +} + +// |Studio| +bool GPUStudioMetalImpeller::EnableRasterCache() const { + return false; +} + +// |Studio| +impeller::AiksContext* GPUStudioMetalImpeller::GetAiksContext() const { + return aiks_context_.get(); +} + +Studio::StudioData GPUStudioMetalImpeller::GetStudioData() const { + if (!(last_drawable_ && [last_drawable_ conformsToProtocol:@protocol(CAMetalDrawable)])) { + return {}; + } + id metal_drawable = static_cast>(last_drawable_); + id texture = metal_drawable.texture; + int bytesPerPixel = 0; + std::string pixel_format; + switch (texture.pixelFormat) { + case MTLPixelFormatBGR10_XR: + bytesPerPixel = 4; + pixel_format = "MTLPixelFormatBGR10_XR"; + break; + case MTLPixelFormatBGRA10_XR: + bytesPerPixel = 8; + pixel_format = "MTLPixelFormatBGRA10_XR"; + break; + case MTLPixelFormatBGRA8Unorm: + bytesPerPixel = 4; + pixel_format = "MTLPixelFormatBGRA8Unorm"; + break; + default: + return {}; + } + + // Zero initialized so that errors are easier to find at the cost of + // performance. + sk_sp result = + SkData::MakeZeroInitialized(texture.width * texture.height * bytesPerPixel); + [texture getBytes:result->writable_data() + bytesPerRow:texture.width * bytesPerPixel + fromRegion:MTLRegionMake2D(0, 0, texture.width, texture.height) + mipmapLevel:0]; + return { + .pixel_format = pixel_format, + .data = result, + }; +} + +} // namespace flutter diff --git a/shell/gpu/gpu_studio_metal_skia.h b/shell/gpu/gpu_studio_metal_skia.h new file mode 100644 index 0000000000000..ae18c1fc3e742 --- /dev/null +++ b/shell/gpu/gpu_studio_metal_skia.h @@ -0,0 +1,62 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_H_ +#define FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_H_ + +#include "flutter/common/graphics/msaa_sample_count.h" +#include "flutter/flow/surface.h" +#include "flutter/fml/macros.h" +#include "flutter/shell/gpu/gpu_surface_metal_delegate.h" +#include "third_party/skia/include/gpu/GrDirectContext.h" + +namespace flutter { + +class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalSkia : public Studio { + public: + GPUStudioMetalSkia(GPUStudioMetalDelegate* delegate, + sk_sp context, + MsaaSampleCount msaa_samples, + bool render_to_surface = true); + + // |Studio| + ~GPUStudioMetalSkia(); + + // |Studio| + bool IsValid() override; + + private: + const GPUStudioMetalDelegate* delegate_; + const MTLRenderTargetType render_target_type_; + sk_sp context_; + GrDirectContext* precompiled_sksl_context_ = nullptr; + MsaaSampleCount msaa_samples_ = MsaaSampleCount::kNone; + // TODO(38466): Refactor GPU surface APIs take into account the fact that an + // external view embedder may want to render to the root surface. This is a + // hack to make avoid allocating resources for the root surface when an + // external view embedder is present. + bool render_to_surface_ = true; + bool disable_partial_repaint_ = false; + + // Accumulated damage for each framebuffer; Key is address of underlying + // MTLTexture for each drawable + std::map damage_; + + // |Studio| + GrDirectContext* GetContext() override; + + // |Studio| + std::unique_ptr MakeRenderContextCurrent() override; + + // |Studio| + bool AllowsDrawingWhenGpuDisabled() const override; + + void PrecompileKnownSkSLsIfNecessary(); + + FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioMetalSkia); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_H_ diff --git a/shell/gpu/gpu_studio_metal_skia.mm b/shell/gpu/gpu_studio_metal_skia.mm new file mode 100644 index 0000000000000..11273546c9f1a --- /dev/null +++ b/shell/gpu/gpu_studio_metal_skia.mm @@ -0,0 +1,106 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/gpu/gpu_studio_metal_skia.h" + +#import +#import + +#include + +#include "flutter/common/graphics/persistent_cache.h" +#include "flutter/fml/make_copyable.h" +#include "flutter/fml/platform/darwin/cf_utils.h" +#include "flutter/fml/platform/darwin/scoped_nsobject.h" +#include "flutter/fml/trace_event.h" +#include "flutter/shell/gpu/gpu_surface_metal_delegate.h" +#include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkColorType.h" +#include "third_party/skia/include/core/SkMatrix.h" +#include "third_party/skia/include/core/SkRect.h" +#include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/include/core/SkSize.h" +#include "third_party/skia/include/core/SkStudio.h" +#include "third_party/skia/include/core/SkStudioProps.h" +#include "third_party/skia/include/gpu/GrBackendStudio.h" +#include "third_party/skia/include/ports/SkCFObject.h" + +static_assert(!__has_feature(objc_arc), "ARC must be disabled."); + +namespace flutter { + +namespace { +sk_sp CreateStudioFromMetalTexture(GrDirectContext* context, + id texture, + GrStudioOrigin origin, + MsaaSampleCount sample_cnt, + SkColorType color_type, + sk_sp color_space, + const SkStudioProps* props, + SkStudio::TextureReleaseProc release_proc, + SkStudio::ReleaseContext release_context) { + GrMtlTextureInfo info; + info.fTexture.reset([texture retain]); + GrBackendTexture backend_texture(texture.width, texture.height, GrMipmapped::kNo, info); + return SkStudio::MakeFromBackendTexture( + context, backend_texture, origin, static_cast(sample_cnt), color_type, + std::move(color_space), props, release_proc, release_context); +} +} // namespace + +GPUStudioMetalSkia::GPUStudioMetalSkia(GPUStudioMetalDelegate* delegate, + sk_sp context, + MsaaSampleCount msaa_samples, + bool render_to_surface) + : delegate_(delegate), + render_target_type_(delegate->GetRenderTargetType()), + context_(std::move(context)), + msaa_samples_(msaa_samples), + render_to_surface_(render_to_surface) { + // If this preference is explicitly set, we allow for disabling partial repaint. + NSNumber* disablePartialRepaint = + [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FLTDisablePartialRepaint"]; + if (disablePartialRepaint != nil) { + disable_partial_repaint_ = disablePartialRepaint.boolValue; + } +} + +GPUStudioMetalSkia::~GPUStudioMetalSkia() = default; + +// |Studio| +bool GPUStudioMetalSkia::IsValid() { + return context_ != nullptr; +} + +void GPUStudioMetalSkia::PrecompileKnownSkSLsIfNecessary() { + auto* current_context = GetContext(); + if (current_context == precompiled_sksl_context_) { + // Known SkSLs have already been prepared in this context. + return; + } + precompiled_sksl_context_ = current_context; + flutter::PersistentCache::GetCacheForProcess()->PrecompileKnownSkSLs(precompiled_sksl_context_); +} + +// |Studio| +GrDirectContext* GPUStudioMetalSkia::GetContext() { + return context_.get(); +} + +// |Studio| +std::unique_ptr GPUStudioMetalSkia::MakeRenderContextCurrent() { + // A context may either be necessary to render to the surface or to snapshot an offscreen + // surface. Either way, SkSL precompilation must be attempted. + PrecompileKnownSkSLsIfNecessary(); + + // This backend has no such concept. + return std::make_unique(true); +} + +bool GPUStudioMetalSkia::AllowsDrawingWhenGpuDisabled() const { + return delegate_->AllowsDrawingWhenGpuDisabled(); +} + +} // namespace flutter diff --git a/shell/gpu/gpu_studio_software.cc b/shell/gpu/gpu_studio_software.cc new file mode 100644 index 0000000000000..8bff529fdeec3 --- /dev/null +++ b/shell/gpu/gpu_studio_software.cc @@ -0,0 +1,34 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/gpu/gpu_studio_software.h" + +#include + +#include "flutter/fml/logging.h" + +#include "third_party/skia/include/core/SkStudio.h" + +namespace flutter { + +GPUStudioSoftware::GPUStudioSoftware(GPUStudioSoftwareDelegate* delegate, + bool render_to_surface) + : delegate_(delegate), + render_to_surface_(render_to_surface), + weak_factory_(this) {} + +GPUStudioSoftware::~GPUStudioSoftware() = default; + +// |Studio| +bool GPUStudioSoftware::IsValid() { + return delegate_ != nullptr; +} + +// |Studio| +GrDirectContext* GPUStudioSoftware::GetContext() { + // There is no GrContext associated with a software surface. + return nullptr; +} + +} // namespace flutter diff --git a/shell/gpu/gpu_studio_software.h b/shell/gpu/gpu_studio_software.h new file mode 100644 index 0000000000000..3c22ce6bb2b26 --- /dev/null +++ b/shell/gpu/gpu_studio_software.h @@ -0,0 +1,41 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef FLUTTER_SHELL_GPU_GPU_SURFACE_SOFTWARE_H_ +#define FLUTTER_SHELL_GPU_GPU_SURFACE_SOFTWARE_H_ + +#include "flutter/flow/surface.h" +#include "flutter/fml/macros.h" +#include "flutter/fml/memory/weak_ptr.h" +#include "flutter/shell/gpu/gpu_surface_software_delegate.h" + +namespace flutter { + +class GPUStudioSoftware : public Studio { + public: + GPUStudioSoftware(GPUStudioSoftwareDelegate* delegate, + bool render_to_surface); + + ~GPUStudioSoftware() override; + + // |Studio| + bool IsValid() override; + + // |Studio| + GrDirectContext* GetContext() override; + + private: + GPUStudioSoftwareDelegate* delegate_; + // TODO(38466): Refactor GPU surface APIs take into account the fact that an + // external view embedder may want to render to the root surface. This is a + // hack to make avoid allocating resources for the root surface when an + // external view embedder is present. + const bool render_to_surface_; + fml::TaskRunnerAffineWeakPtrFactory weak_factory_; + FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioSoftware); +}; + +} // namespace flutter + +#endif // FLUTTER_SHELL_GPU_GPU_SURFACE_SOFTWARE_H_ diff --git a/shell/gpu/gpu_studio_vulkan.cc b/shell/gpu/gpu_studio_vulkan.cc new file mode 100644 index 0000000000000..a666b61e201a3 --- /dev/null +++ b/shell/gpu/gpu_studio_vulkan.cc @@ -0,0 +1,48 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/gpu/gpu_studio_vulkan.h" + +#include "flutter/fml/logging.h" +#include "flutter/fml/trace_event.h" + +#include "third_party/skia/include/core/SkColorSpace.h" +#include "third_party/skia/include/core/SkSize.h" +#include "third_party/skia/include/core/SkStudio.h" +#include "vulkan/vulkan_core.h" + +namespace flutter { + +GPUStudioVulkan::GPUStudioVulkan(GPUStudioVulkanDelegate* delegate, + const sk_sp& skia_context, + bool render_to_surface) + : delegate_(delegate), + skia_context_(skia_context), + render_to_surface_(render_to_surface), + weak_factory_(this) {} + +GPUStudioVulkan::~GPUStudioVulkan() = default; + +bool GPUStudioVulkan::IsValid() { + return skia_context_ != nullptr; +} + +GrDirectContext* GPUStudioVulkan::GetContext() { + return skia_context_.get(); +} + +SkColorType GPUStudioVulkan::ColorTypeFromFormat(const VkFormat format) { + switch (format) { + case VK_FORMAT_R8G8B8A8_UNORM: + case VK_FORMAT_R8G8B8A8_SRGB: + return SkColorType::kRGBA_8888_SkColorType; + case VK_FORMAT_B8G8R8A8_UNORM: + case VK_FORMAT_B8G8R8A8_SRGB: + return SkColorType::kBGRA_8888_SkColorType; + default: + return SkColorType::kUnknown_SkColorType; + } +} + +} // namespace flutter diff --git a/shell/gpu/gpu_studio_vulkan.h b/shell/gpu/gpu_studio_vulkan.h new file mode 100644 index 0000000000000..6cd96406b7dc3 --- /dev/null +++ b/shell/gpu/gpu_studio_vulkan.h @@ -0,0 +1,59 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef SHELL_GPU_GPU_SURFACE_VULKAN_H_ +#define SHELL_GPU_GPU_SURFACE_VULKAN_H_ + +#include + +#include "flutter/flow/surface.h" +#include "flutter/fml/macros.h" +#include "flutter/fml/memory/weak_ptr.h" +#include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" +#include "flutter/vulkan/vulkan_backbuffer.h" +#include "flutter/vulkan/vulkan_native_surface.h" +#include "flutter/vulkan/vulkan_window.h" + +#include "third_party/skia/include/core/SkRefCnt.h" +#include "third_party/skia/include/core/SkStudio.h" + +namespace flutter { + +//------------------------------------------------------------------------------ +/// @brief A GPU surface backed by VkImages provided by a +/// GPUStudioVulkanDelegate. +/// +class GPUStudioVulkan : public Studio { + public: + //------------------------------------------------------------------------------ + /// @brief Create a GPUStudioVulkan while letting it reuse an existing + /// GrDirectContext. + /// + GPUStudioVulkan(GPUStudioVulkanDelegate* delegate, + const sk_sp& context, + bool render_to_surface); + + ~GPUStudioVulkan() override; + + // |Studio| + bool IsValid() override; + + // |Studio| + GrDirectContext* GetContext() override; + + static SkColorType ColorTypeFromFormat(const VkFormat format); + + private: + GPUStudioVulkanDelegate* delegate_; + sk_sp skia_context_; + bool render_to_surface_; + + fml::WeakPtrFactory weak_factory_; + + FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioVulkan); +}; + +} // namespace flutter + +#endif // SHELL_GPU_GPU_SURFACE_VULKAN_H_ diff --git a/shell/gpu/gpu_studio_vulkan_impeller.cc b/shell/gpu/gpu_studio_vulkan_impeller.cc new file mode 100644 index 0000000000000..6a843c0bbb02a --- /dev/null +++ b/shell/gpu/gpu_studio_vulkan_impeller.cc @@ -0,0 +1,68 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "flutter/shell/gpu/gpu_studio_vulkan_impeller.h" + +#include "flutter/fml/make_copyable.h" +#include "flutter/impeller/display_list/display_list_dispatcher.h" +#include "flutter/impeller/renderer/renderer.h" +#include "impeller/renderer/backend/vulkan/context_vk.h" + +namespace flutter { + +GPUStudioVulkanImpeller::GPUStudioVulkanImpeller( + std::shared_ptr context) + : weak_factory_(this) { + if (!context || !context->IsValid()) { + return; + } + + auto renderer = std::make_shared(context); + if (!renderer->IsValid()) { + return; + } + + auto aiks_context = std::make_shared(context); + if (!aiks_context->IsValid()) { + return; + } + + impeller_context_ = std::move(context); + impeller_renderer_ = std::move(renderer); + aiks_context_ = std::move(aiks_context); + is_valid_ = true; +} + +// |Studio| +GPUStudioVulkanImpeller::~GPUStudioVulkanImpeller() = default; + +// |Studio| +bool GPUStudioVulkanImpeller::IsValid() { + return is_valid_; +} + +// |Studio| +GrDirectContext* GPUStudioVulkanImpeller::GetContext() { + // Impeller != Skia. + return nullptr; +} + +// |Studio| +std::unique_ptr +GPUStudioVulkanImpeller::MakeRenderContextCurrent() { + // This backend has no such concept. + return std::make_unique(true); +} + +// |Studio| +bool GPUStudioVulkanImpeller::EnableRasterCache() const { + return false; +} + +// |Studio| +impeller::AiksContext* GPUStudioVulkanImpeller::GetAiksContext() const { + return aiks_context_.get(); +} + +} // namespace flutter diff --git a/shell/gpu/gpu_studio_vulkan_impeller.h b/shell/gpu/gpu_studio_vulkan_impeller.h new file mode 100644 index 0000000000000..645f3083dbb8b --- /dev/null +++ b/shell/gpu/gpu_studio_vulkan_impeller.h @@ -0,0 +1,49 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include "flutter/common/graphics/gl_context_switch.h" +#include "flutter/flow/surface.h" +#include "flutter/fml/macros.h" +#include "flutter/fml/memory/weak_ptr.h" +#include "flutter/impeller/aiks/aiks_context.h" +#include "flutter/impeller/renderer/context.h" +#include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" + +namespace flutter { + +class GPUStudioVulkanImpeller final : public Studio { + public: + explicit GPUStudioVulkanImpeller(std::shared_ptr context); + + // |Studio| + ~GPUStudioVulkanImpeller() override; + + // |Studio| + bool IsValid() override; + + private: + std::shared_ptr impeller_context_; + std::shared_ptr impeller_renderer_; + std::shared_ptr aiks_context_; + bool is_valid_ = false; + fml::WeakPtrFactory weak_factory_; + + // |Studio| + GrDirectContext* GetContext() override; + + // |Studio| + std::unique_ptr MakeRenderContextCurrent() override; + + // |Studio| + bool EnableRasterCache() const override; + + // |Studio| + impeller::AiksContext* GetAiksContext() const override; + + FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioVulkanImpeller); +}; + +} // namespace flutter From 2617c704e3d51d8730214b66dabfd41d174d519b Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 00:56:08 -0700 Subject: [PATCH 017/142] Add GPUStudios, compilable --- ci/licenses_golden/licenses_flutter | 4 + flow/BUILD.gn | 2 + shell/gpu/gpu_studio_gl_impeller.cc | 7 +- shell/gpu/gpu_studio_gl_impeller.h | 14 ++- shell/gpu/gpu_studio_gl_skia.cc | 88 +------------------ shell/gpu/gpu_studio_gl_skia.h | 29 ++---- shell/gpu/gpu_studio_metal_impeller.h | 14 ++- shell/gpu/gpu_studio_metal_impeller.mm | 41 +-------- shell/gpu/gpu_studio_metal_skia.h | 27 ++---- shell/gpu/gpu_studio_metal_skia.mm | 39 +------- shell/gpu/gpu_studio_software.cc | 9 +- shell/gpu/gpu_studio_software.h | 19 ++-- shell/gpu/gpu_studio_vulkan.cc | 7 +- shell/gpu/gpu_studio_vulkan.h | 20 ++--- shell/gpu/gpu_studio_vulkan_impeller.cc | 9 +- shell/gpu/gpu_studio_vulkan_impeller.h | 3 +- shell/platform/embedder/embedder_studio.h | 3 + shell/platform/embedder/embedder_studio_gl.cc | 15 ++++ shell/platform/embedder/embedder_studio_gl.h | 3 + .../platform/embedder/embedder_studio_metal.h | 3 + .../embedder/embedder_studio_metal.mm | 19 ++++ .../embedder/embedder_studio_software.cc | 15 ++++ .../embedder/embedder_studio_software.h | 3 + .../embedder/embedder_studio_vulkan.cc | 15 ++++ .../embedder/embedder_studio_vulkan.h | 3 + .../platform_view_embedder_unittests.cc | 1 + 26 files changed, 140 insertions(+), 272 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 45beef38f4281..8460892f4dcfd 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -836,6 +836,8 @@ ORIGIN: ../../../flutter/flow/raster_cache_util.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/rtree.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/rtree.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/skia_gpu_object.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/flow/studio.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/flow/studio.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/surface.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/surface.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/flow/surface_frame.cc + ../../../flutter/LICENSE @@ -3392,6 +3394,8 @@ FILE: ../../../flutter/flow/raster_cache_util.h FILE: ../../../flutter/flow/rtree.cc FILE: ../../../flutter/flow/rtree.h FILE: ../../../flutter/flow/skia_gpu_object.h +FILE: ../../../flutter/flow/studio.cc +FILE: ../../../flutter/flow/studio.h FILE: ../../../flutter/flow/surface.cc FILE: ../../../flutter/flow/surface.h FILE: ../../../flutter/flow/surface_frame.cc diff --git a/flow/BUILD.gn b/flow/BUILD.gn index 1adceefde4bc2..c72a56aca0150 100644 --- a/flow/BUILD.gn +++ b/flow/BUILD.gn @@ -80,6 +80,8 @@ source_set("flow") { "rtree.cc", "rtree.h", "skia_gpu_object.h", + "studio.cc", + "studio.h", "surface.cc", "surface.h", "surface_frame.cc", diff --git a/shell/gpu/gpu_studio_gl_impeller.cc b/shell/gpu/gpu_studio_gl_impeller.cc index c7b443f4efe0e..1ffb0e38ed2fb 100644 --- a/shell/gpu/gpu_studio_gl_impeller.cc +++ b/shell/gpu/gpu_studio_gl_impeller.cc @@ -12,9 +12,8 @@ namespace flutter { GPUStudioGLImpeller::GPUStudioGLImpeller( - GPUStudioGLDelegate* delegate, - std::shared_ptr context) - : weak_factory_(this) { + GPUSurfaceGLDelegate* delegate, + std::shared_ptr context) { if (delegate == nullptr) { return; } @@ -35,8 +34,6 @@ GPUStudioGLImpeller::GPUStudioGLImpeller( } delegate_ = delegate; - impeller_context_ = std::move(context); - impeller_renderer_ = std::move(renderer); aiks_context_ = std::move(aiks_context); is_valid_ = true; } diff --git a/shell/gpu/gpu_studio_gl_impeller.h b/shell/gpu/gpu_studio_gl_impeller.h index 2397cc89a1fd3..9c54d7eb18283 100644 --- a/shell/gpu/gpu_studio_gl_impeller.h +++ b/shell/gpu/gpu_studio_gl_impeller.h @@ -2,14 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_GPU_GPU_SURFACE_GL_IMPELLER_H_ -#define SHELL_GPU_GPU_SURFACE_GL_IMPELLER_H_ +#ifndef SHELL_GPU_GPU_STUDIO_GL_IMPELLER_H_ +#define SHELL_GPU_GPU_STUDIO_GL_IMPELLER_H_ #include "flutter/common/graphics/gl_context_switch.h" #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/impeller/aiks/aiks_context.h" +#include "flutter/flow/studio.h" #include "flutter/impeller/renderer/context.h" #include "flutter/shell/gpu/gpu_surface_gl_delegate.h" @@ -17,7 +18,7 @@ namespace flutter { class GPUStudioGLImpeller final : public Studio { public: - explicit GPUStudioGLImpeller(GPUStudioGLDelegate* delegate, + explicit GPUStudioGLImpeller(GPUSurfaceGLDelegate* delegate, std::shared_ptr context); // |Studio| @@ -27,12 +28,9 @@ class GPUStudioGLImpeller final : public Studio { bool IsValid() override; private: - GPUStudioGLDelegate* delegate_ = nullptr; - std::shared_ptr impeller_context_; - std::shared_ptr impeller_renderer_; + GPUSurfaceGLDelegate* delegate_ = nullptr; std::shared_ptr aiks_context_; bool is_valid_ = false; - fml::WeakPtrFactory weak_factory_; // |Studio| GrDirectContext* GetContext() override; @@ -57,4 +55,4 @@ class GPUStudioGLImpeller final : public Studio { } // namespace flutter -#endif // SHELL_GPU_GPU_SURFACE_GL_IMPELLER_H_ +#endif // SHELL_GPU_GPU_STUDIO_GL_IMPELLER_H_ diff --git a/shell/gpu/gpu_studio_gl_skia.cc b/shell/gpu/gpu_studio_gl_skia.cc index 227c9099175be..b4dce0fbc51d6 100644 --- a/shell/gpu/gpu_studio_gl_skia.cc +++ b/shell/gpu/gpu_studio_gl_skia.cc @@ -15,8 +15,6 @@ #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkColorType.h" -#include "third_party/skia/include/core/SkStudio.h" -#include "third_party/skia/include/gpu/GrBackendStudio.h" #include "third_party/skia/include/gpu/GrContextOptions.h" // These are common defines present on all OpenGL headers. However, we don't @@ -29,47 +27,10 @@ namespace flutter { -// Default maximum number of bytes of GPU memory of budgeted resources in the -// cache. -// The shell will dynamically increase or decrease this cache based on the -// viewport size, unless a user has specifically requested a size on the Skia -// system channel. -static const size_t kGrCacheMaxByteSize = 24 * (1 << 20); - -sk_sp GPUStudioGLSkia::MakeGLContext( - GPUStudioGLDelegate* delegate) { - auto context_switch = delegate->GLContextMakeCurrent(); - if (!context_switch->GetResult()) { - FML_LOG(ERROR) - << "Could not make the context current to set up the Gr context."; - return nullptr; - } - - const auto options = - MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kOpenGL); - - auto context = GrDirectContext::MakeGL(delegate->GetGLInterface(), options); - - if (!context) { - FML_LOG(ERROR) << "Failed to set up Skia Gr context."; - return nullptr; - } - - context->setResourceCacheLimit(kGrCacheMaxByteSize); - - PersistentCache::GetCacheForProcess()->PrecompileKnownSkSLs(context.get()); - - return context; -} - GPUStudioGLSkia::GPUStudioGLSkia(const sk_sp& gr_context, - GPUStudioGLDelegate* delegate, - bool render_to_surface) + GPUSurfaceGLDelegate* delegate) : delegate_(delegate), - context_(gr_context), - - render_to_surface_(render_to_surface), - weak_factory_(this) { + context_(gr_context) { auto context_switch = delegate_->GLContextMakeCurrent(); if (!context_switch->GetResult()) { FML_LOG(ERROR) @@ -93,8 +54,6 @@ GPUStudioGLSkia::~GPUStudioGLSkia() { return; } - onscreen_surface_ = nullptr; - fbo_id_ = 0; context_ = nullptr; delegate_->GLContextClearCurrent(); @@ -105,49 +64,6 @@ bool GPUStudioGLSkia::IsValid() { return valid_; } -static SkColorType FirstSupportedColorType(GrDirectContext* context, - GrGLenum* format) { -#define RETURN_IF_RENDERABLE(x, y) \ - if (context->colorTypeSupportedAsStudio((x))) { \ - *format = (y); \ - return (x); \ - } - RETURN_IF_RENDERABLE(kRGBA_8888_SkColorType, GPU_GL_RGBA8); - RETURN_IF_RENDERABLE(kARGB_4444_SkColorType, GPU_GL_RGBA4); - RETURN_IF_RENDERABLE(kRGB_565_SkColorType, GPU_GL_RGB565); - return kUnknown_SkColorType; -} - -static sk_sp WrapOnscreenStudio(GrDirectContext* context, - const SkISize& size, - intptr_t fbo) { - GrGLenum format = kUnknown_SkColorType; - const SkColorType color_type = FirstSupportedColorType(context, &format); - - GrGLFramebufferInfo framebuffer_info = {}; - framebuffer_info.fFBOID = static_cast(fbo); - framebuffer_info.fFormat = format; - - GrBackendRenderTarget render_target(size.width(), // width - size.height(), // height - 0, // sample count - 0, // stencil bits - framebuffer_info // framebuffer info - ); - - sk_sp colorspace = SkColorSpace::MakeSRGB(); - SkStudioProps surface_props(0, kUnknown_SkPixelGeometry); - - return SkStudio::MakeFromBackendRenderTarget( - context, // Gr context - render_target, // render target - GrStudioOrigin::kBottomLeft_GrStudioOrigin, // origin - color_type, // color type - colorspace, // colorspace - &surface_props // surface properties - ); -} - // |Studio| GrDirectContext* GPUStudioGLSkia::GetContext() { return context_.get(); diff --git a/shell/gpu/gpu_studio_gl_skia.h b/shell/gpu/gpu_studio_gl_skia.h index 11429f0df3bc9..9dbedb0b6d58e 100644 --- a/shell/gpu/gpu_studio_gl_skia.h +++ b/shell/gpu/gpu_studio_gl_skia.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_GPU_GPU_SURFACE_GL_SKIA_H_ -#define SHELL_GPU_GPU_SURFACE_GL_SKIA_H_ +#ifndef SHELL_GPU_GPU_STUDIO_GL_SKIA_H_ +#define SHELL_GPU_GPU_STUDIO_GL_SKIA_H_ #include #include @@ -11,22 +11,19 @@ #include "flutter/common/graphics/gl_context_switch.h" #include "flutter/flow/embedded_views.h" #include "flutter/flow/surface.h" +#include "flutter/flow/studio.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/shell/gpu/gpu_surface_gl_delegate.h" -#include "third_party/skia/include/core/SkStudio.h" #include "third_party/skia/include/gpu/GrDirectContext.h" namespace flutter { class GPUStudioGLSkia : public Studio { public: - static sk_sp MakeGLContext(GPUStudioGLDelegate* delegate); - GPUStudioGLSkia(const sk_sp& gr_context, - GPUStudioGLDelegate* delegate, - bool render_to_surface); + GPUSurfaceGLDelegate* delegate); // |Studio| ~GPUStudioGLSkia() override; @@ -48,27 +45,13 @@ class GPUStudioGLSkia : public Studio { private: - GPUStudioGLDelegate* delegate_; + GPUSurfaceGLDelegate* delegate_; sk_sp context_; - sk_sp onscreen_surface_; - /// FBO backing the current `onscreen_surface_`. - uint32_t fbo_id_ = 0; - // The current FBO's existing damage, as tracked by the GPU surface, delegates - // still have an option of overriding this damage with their own in - // `GLContextFrameBufferInfo`. - std::optional existing_damage_ = std::nullopt; - // TODO(38466): Refactor GPU surface APIs take into account the fact that an - // external view embedder may want to render to the root surface. This is a - // hack to make avoid allocating resources for the root surface when an - // external view embedder is present. - const bool render_to_surface_ = true; bool valid_ = false; - // WeakPtrFactory must be the last member. - fml::TaskRunnerAffineWeakPtrFactory weak_factory_; FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioGLSkia); }; } // namespace flutter -#endif // SHELL_GPU_GPU_SURFACE_GL_SKIA_H_ +#endif // SHELL_GPU_GPU_STUDIO_GL_SKIA_H_ diff --git a/shell/gpu/gpu_studio_metal_impeller.h b/shell/gpu/gpu_studio_metal_impeller.h index 7211da592dff7..d9b534c487540 100644 --- a/shell/gpu/gpu_studio_metal_impeller.h +++ b/shell/gpu/gpu_studio_metal_impeller.h @@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_IMPELLER_H_ -#define FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_IMPELLER_H_ +#ifndef FLUTTER_SHELL_GPU_GPU_STUDIO_METAL_IMPELLER_H_ +#define FLUTTER_SHELL_GPU_GPU_STUDIO_METAL_IMPELLER_H_ #include +#include "flutter/flow/studio.h" #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" @@ -18,7 +19,7 @@ namespace flutter { class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalImpeller : public Studio { public: - GPUStudioMetalImpeller(GPUStudioMetalDelegate* delegate, + GPUStudioMetalImpeller(GPUSurfaceMetalDelegate* delegate, const std::shared_ptr& context); // |Studio| @@ -27,13 +28,10 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalImpeller : public Studio { // |Studio| bool IsValid() override; - virtual Studio::StudioData GetStudioData() const override; - private: - const GPUStudioMetalDelegate* delegate_; + const GPUSurfaceMetalDelegate* delegate_; std::shared_ptr impeller_renderer_; std::shared_ptr aiks_context_; - fml::scoped_nsprotocol> last_drawable_; // |Studio| GrDirectContext* GetContext() override; @@ -55,4 +53,4 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalImpeller : public Studio { } // namespace flutter -#endif // FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_IMPELLER_H_ +#endif // FLUTTER_SHELL_GPU_GPU_STUDIO_METAL_IMPELLER_H_ diff --git a/shell/gpu/gpu_studio_metal_impeller.mm b/shell/gpu/gpu_studio_metal_impeller.mm index 8d2a3a04e3a22..b62425a694d49 100644 --- a/shell/gpu/gpu_studio_metal_impeller.mm +++ b/shell/gpu/gpu_studio_metal_impeller.mm @@ -28,7 +28,7 @@ return renderer; } -GPUStudioMetalImpeller::GPUStudioMetalImpeller(GPUStudioMetalDelegate* delegate, +GPUStudioMetalImpeller::GPUStudioMetalImpeller(GPUSurfaceMetalDelegate* delegate, const std::shared_ptr& context) : delegate_(delegate), impeller_renderer_(CreateImpellerRenderer(context)), @@ -67,43 +67,4 @@ return aiks_context_.get(); } -Studio::StudioData GPUStudioMetalImpeller::GetStudioData() const { - if (!(last_drawable_ && [last_drawable_ conformsToProtocol:@protocol(CAMetalDrawable)])) { - return {}; - } - id metal_drawable = static_cast>(last_drawable_); - id texture = metal_drawable.texture; - int bytesPerPixel = 0; - std::string pixel_format; - switch (texture.pixelFormat) { - case MTLPixelFormatBGR10_XR: - bytesPerPixel = 4; - pixel_format = "MTLPixelFormatBGR10_XR"; - break; - case MTLPixelFormatBGRA10_XR: - bytesPerPixel = 8; - pixel_format = "MTLPixelFormatBGRA10_XR"; - break; - case MTLPixelFormatBGRA8Unorm: - bytesPerPixel = 4; - pixel_format = "MTLPixelFormatBGRA8Unorm"; - break; - default: - return {}; - } - - // Zero initialized so that errors are easier to find at the cost of - // performance. - sk_sp result = - SkData::MakeZeroInitialized(texture.width * texture.height * bytesPerPixel); - [texture getBytes:result->writable_data() - bytesPerRow:texture.width * bytesPerPixel - fromRegion:MTLRegionMake2D(0, 0, texture.width, texture.height) - mipmapLevel:0]; - return { - .pixel_format = pixel_format, - .data = result, - }; -} - } // namespace flutter diff --git a/shell/gpu/gpu_studio_metal_skia.h b/shell/gpu/gpu_studio_metal_skia.h index ae18c1fc3e742..71d0c69351df0 100644 --- a/shell/gpu/gpu_studio_metal_skia.h +++ b/shell/gpu/gpu_studio_metal_skia.h @@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_H_ -#define FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_H_ +#ifndef FLUTTER_SHELL_GPU_GPU_STUDIO_METAL_H_ +#define FLUTTER_SHELL_GPU_GPU_STUDIO_METAL_H_ #include "flutter/common/graphics/msaa_sample_count.h" #include "flutter/flow/surface.h" +#include "flutter/flow/studio.h" #include "flutter/fml/macros.h" #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #include "third_party/skia/include/gpu/GrDirectContext.h" @@ -15,10 +16,8 @@ namespace flutter { class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalSkia : public Studio { public: - GPUStudioMetalSkia(GPUStudioMetalDelegate* delegate, - sk_sp context, - MsaaSampleCount msaa_samples, - bool render_to_surface = true); + GPUStudioMetalSkia(GPUSurfaceMetalDelegate* delegate, + sk_sp context); // |Studio| ~GPUStudioMetalSkia(); @@ -27,21 +26,9 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalSkia : public Studio { bool IsValid() override; private: - const GPUStudioMetalDelegate* delegate_; - const MTLRenderTargetType render_target_type_; + const GPUSurfaceMetalDelegate* delegate_; sk_sp context_; GrDirectContext* precompiled_sksl_context_ = nullptr; - MsaaSampleCount msaa_samples_ = MsaaSampleCount::kNone; - // TODO(38466): Refactor GPU surface APIs take into account the fact that an - // external view embedder may want to render to the root surface. This is a - // hack to make avoid allocating resources for the root surface when an - // external view embedder is present. - bool render_to_surface_ = true; - bool disable_partial_repaint_ = false; - - // Accumulated damage for each framebuffer; Key is address of underlying - // MTLTexture for each drawable - std::map damage_; // |Studio| GrDirectContext* GetContext() override; @@ -59,4 +46,4 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalSkia : public Studio { } // namespace flutter -#endif // FLUTTER_SHELL_GPU_GPU_SURFACE_METAL_H_ +#endif // FLUTTER_SHELL_GPU_GPU_STUDIO_METAL_H_ diff --git a/shell/gpu/gpu_studio_metal_skia.mm b/shell/gpu/gpu_studio_metal_skia.mm index 11273546c9f1a..6bc24ab95d5ef 100644 --- a/shell/gpu/gpu_studio_metal_skia.mm +++ b/shell/gpu/gpu_studio_metal_skia.mm @@ -22,49 +22,16 @@ #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkSize.h" -#include "third_party/skia/include/core/SkStudio.h" -#include "third_party/skia/include/core/SkStudioProps.h" -#include "third_party/skia/include/gpu/GrBackendStudio.h" #include "third_party/skia/include/ports/SkCFObject.h" static_assert(!__has_feature(objc_arc), "ARC must be disabled."); namespace flutter { -namespace { -sk_sp CreateStudioFromMetalTexture(GrDirectContext* context, - id texture, - GrStudioOrigin origin, - MsaaSampleCount sample_cnt, - SkColorType color_type, - sk_sp color_space, - const SkStudioProps* props, - SkStudio::TextureReleaseProc release_proc, - SkStudio::ReleaseContext release_context) { - GrMtlTextureInfo info; - info.fTexture.reset([texture retain]); - GrBackendTexture backend_texture(texture.width, texture.height, GrMipmapped::kNo, info); - return SkStudio::MakeFromBackendTexture( - context, backend_texture, origin, static_cast(sample_cnt), color_type, - std::move(color_space), props, release_proc, release_context); -} -} // namespace - -GPUStudioMetalSkia::GPUStudioMetalSkia(GPUStudioMetalDelegate* delegate, - sk_sp context, - MsaaSampleCount msaa_samples, - bool render_to_surface) +GPUStudioMetalSkia::GPUStudioMetalSkia(GPUSurfaceMetalDelegate* delegate, + sk_sp context) : delegate_(delegate), - render_target_type_(delegate->GetRenderTargetType()), - context_(std::move(context)), - msaa_samples_(msaa_samples), - render_to_surface_(render_to_surface) { - // If this preference is explicitly set, we allow for disabling partial repaint. - NSNumber* disablePartialRepaint = - [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FLTDisablePartialRepaint"]; - if (disablePartialRepaint != nil) { - disable_partial_repaint_ = disablePartialRepaint.boolValue; - } + context_(std::move(context)) { } GPUStudioMetalSkia::~GPUStudioMetalSkia() = default; diff --git a/shell/gpu/gpu_studio_software.cc b/shell/gpu/gpu_studio_software.cc index 8bff529fdeec3..be46c443b22f8 100644 --- a/shell/gpu/gpu_studio_software.cc +++ b/shell/gpu/gpu_studio_software.cc @@ -8,15 +8,10 @@ #include "flutter/fml/logging.h" -#include "third_party/skia/include/core/SkStudio.h" - namespace flutter { -GPUStudioSoftware::GPUStudioSoftware(GPUStudioSoftwareDelegate* delegate, - bool render_to_surface) - : delegate_(delegate), - render_to_surface_(render_to_surface), - weak_factory_(this) {} +GPUStudioSoftware::GPUStudioSoftware(GPUSurfaceSoftwareDelegate* delegate) + : delegate_(delegate) {} GPUStudioSoftware::~GPUStudioSoftware() = default; diff --git a/shell/gpu/gpu_studio_software.h b/shell/gpu/gpu_studio_software.h index 3c22ce6bb2b26..4eca32b8442f6 100644 --- a/shell/gpu/gpu_studio_software.h +++ b/shell/gpu/gpu_studio_software.h @@ -2,20 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef FLUTTER_SHELL_GPU_GPU_SURFACE_SOFTWARE_H_ -#define FLUTTER_SHELL_GPU_GPU_SURFACE_SOFTWARE_H_ +#ifndef FLUTTER_SHELL_GPU_GPU_STUDIO_SOFTWARE_H_ +#define FLUTTER_SHELL_GPU_GPU_STUDIO_SOFTWARE_H_ #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/shell/gpu/gpu_surface_software_delegate.h" +#include "flutter/flow/studio.h" namespace flutter { class GPUStudioSoftware : public Studio { public: - GPUStudioSoftware(GPUStudioSoftwareDelegate* delegate, - bool render_to_surface); + GPUStudioSoftware(GPUSurfaceSoftwareDelegate* delegate); ~GPUStudioSoftware() override; @@ -26,16 +26,11 @@ class GPUStudioSoftware : public Studio { GrDirectContext* GetContext() override; private: - GPUStudioSoftwareDelegate* delegate_; - // TODO(38466): Refactor GPU surface APIs take into account the fact that an - // external view embedder may want to render to the root surface. This is a - // hack to make avoid allocating resources for the root surface when an - // external view embedder is present. - const bool render_to_surface_; - fml::TaskRunnerAffineWeakPtrFactory weak_factory_; + GPUSurfaceSoftwareDelegate* delegate_; + FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioSoftware); }; } // namespace flutter -#endif // FLUTTER_SHELL_GPU_GPU_SURFACE_SOFTWARE_H_ +#endif // FLUTTER_SHELL_GPU_GPU_STUDIO_SOFTWARE_H_ diff --git a/shell/gpu/gpu_studio_vulkan.cc b/shell/gpu/gpu_studio_vulkan.cc index a666b61e201a3..245a6370f039f 100644 --- a/shell/gpu/gpu_studio_vulkan.cc +++ b/shell/gpu/gpu_studio_vulkan.cc @@ -9,17 +9,14 @@ #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkSize.h" -#include "third_party/skia/include/core/SkStudio.h" #include "vulkan/vulkan_core.h" namespace flutter { -GPUStudioVulkan::GPUStudioVulkan(GPUStudioVulkanDelegate* delegate, - const sk_sp& skia_context, - bool render_to_surface) +GPUStudioVulkan::GPUStudioVulkan(GPUSurfaceVulkanDelegate* delegate, + const sk_sp& skia_context) : delegate_(delegate), skia_context_(skia_context), - render_to_surface_(render_to_surface), weak_factory_(this) {} GPUStudioVulkan::~GPUStudioVulkan() = default; diff --git a/shell/gpu/gpu_studio_vulkan.h b/shell/gpu/gpu_studio_vulkan.h index 6cd96406b7dc3..ced9ae426bec5 100644 --- a/shell/gpu/gpu_studio_vulkan.h +++ b/shell/gpu/gpu_studio_vulkan.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef SHELL_GPU_GPU_SURFACE_VULKAN_H_ -#define SHELL_GPU_GPU_SURFACE_VULKAN_H_ +#ifndef SHELL_GPU_GPU_STUDIO_VULKAN_H_ +#define SHELL_GPU_GPU_STUDIO_VULKAN_H_ #include @@ -13,16 +13,16 @@ #include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" #include "flutter/vulkan/vulkan_backbuffer.h" #include "flutter/vulkan/vulkan_native_surface.h" +#include "flutter/flow/studio.h" #include "flutter/vulkan/vulkan_window.h" #include "third_party/skia/include/core/SkRefCnt.h" -#include "third_party/skia/include/core/SkStudio.h" namespace flutter { //------------------------------------------------------------------------------ /// @brief A GPU surface backed by VkImages provided by a -/// GPUStudioVulkanDelegate. +/// GPUSurfaceVulkanDelegate. /// class GPUStudioVulkan : public Studio { public: @@ -30,9 +30,8 @@ class GPUStudioVulkan : public Studio { /// @brief Create a GPUStudioVulkan while letting it reuse an existing /// GrDirectContext. /// - GPUStudioVulkan(GPUStudioVulkanDelegate* delegate, - const sk_sp& context, - bool render_to_surface); + GPUStudioVulkan(GPUSurfaceVulkanDelegate* delegate, + const sk_sp& context); ~GPUStudioVulkan() override; @@ -45,15 +44,12 @@ class GPUStudioVulkan : public Studio { static SkColorType ColorTypeFromFormat(const VkFormat format); private: - GPUStudioVulkanDelegate* delegate_; + GPUSurfaceVulkanDelegate* delegate_; sk_sp skia_context_; - bool render_to_surface_; - - fml::WeakPtrFactory weak_factory_; FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioVulkan); }; } // namespace flutter -#endif // SHELL_GPU_GPU_SURFACE_VULKAN_H_ +#endif // SHELL_GPU_GPU_STUDIO_VULKAN_H_ diff --git a/shell/gpu/gpu_studio_vulkan_impeller.cc b/shell/gpu/gpu_studio_vulkan_impeller.cc index 6a843c0bbb02a..17520fd6b0581 100644 --- a/shell/gpu/gpu_studio_vulkan_impeller.cc +++ b/shell/gpu/gpu_studio_vulkan_impeller.cc @@ -12,24 +12,17 @@ namespace flutter { GPUStudioVulkanImpeller::GPUStudioVulkanImpeller( - std::shared_ptr context) - : weak_factory_(this) { + std::shared_ptr context) { if (!context || !context->IsValid()) { return; } - auto renderer = std::make_shared(context); - if (!renderer->IsValid()) { - return; - } - auto aiks_context = std::make_shared(context); if (!aiks_context->IsValid()) { return; } impeller_context_ = std::move(context); - impeller_renderer_ = std::move(renderer); aiks_context_ = std::move(aiks_context); is_valid_ = true; } diff --git a/shell/gpu/gpu_studio_vulkan_impeller.h b/shell/gpu/gpu_studio_vulkan_impeller.h index 645f3083dbb8b..e25346a9e44de 100644 --- a/shell/gpu/gpu_studio_vulkan_impeller.h +++ b/shell/gpu/gpu_studio_vulkan_impeller.h @@ -6,6 +6,7 @@ #include "flutter/common/graphics/gl_context_switch.h" #include "flutter/flow/surface.h" +#include "flutter/flow/studio.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/impeller/aiks/aiks_context.h" @@ -26,10 +27,8 @@ class GPUStudioVulkanImpeller final : public Studio { private: std::shared_ptr impeller_context_; - std::shared_ptr impeller_renderer_; std::shared_ptr aiks_context_; bool is_valid_ = false; - fml::WeakPtrFactory weak_factory_; // |Studio| GrDirectContext* GetContext() override; diff --git a/shell/platform/embedder/embedder_studio.h b/shell/platform/embedder/embedder_studio.h index 8f50d5d42c677..2ebfa51eb36ae 100644 --- a/shell/platform/embedder/embedder_studio.h +++ b/shell/platform/embedder/embedder_studio.h @@ -7,6 +7,7 @@ #include +#include "flutter/flow/studio.h" #include "flutter/shell/platform/embedder/embedder_external_view_embedder.h" #include "flutter/shell/platform/embedder/embedder_surface.h" @@ -20,6 +21,8 @@ class EmbedderStudio { virtual bool IsValid() const = 0; + virtual std::unique_ptr CreateGPUStudio() = 0; + virtual std::unique_ptr CreateSurface() = 0; virtual sk_sp CreateResourceContext() const = 0; diff --git a/shell/platform/embedder/embedder_studio_gl.cc b/shell/platform/embedder/embedder_studio_gl.cc index 1f03fc815787f..ba0dc47c2ea60 100644 --- a/shell/platform/embedder/embedder_studio_gl.cc +++ b/shell/platform/embedder/embedder_studio_gl.cc @@ -8,6 +8,7 @@ #include "flutter/shell/common/shell_io_manager.h" #include "flutter/shell/platform/embedder/embedder_surface_gl.h" +#include "flutter/shell/gpu/gpu_studio_gl_skia.h" namespace flutter { @@ -98,6 +99,20 @@ SurfaceFrame::FramebufferInfo EmbedderStudioGL::GLContextFramebufferInfo() return info; } +// |EmbedderStudio| +std::unique_ptr EmbedderStudioGL::CreateGPUStudio() { + if (!IsValid()) { + return nullptr; + } + auto studio = + std::make_unique(main_context_, this); + if (!studio->IsValid()) { + return nullptr; + } + + return studio; +} + // |EmbedderStudio| std::unique_ptr EmbedderStudioGL::CreateSurface() { if (!main_context_) { diff --git a/shell/platform/embedder/embedder_studio_gl.h b/shell/platform/embedder/embedder_studio_gl.h index 65ebda6855bcc..4813cb48b0e3f 100644 --- a/shell/platform/embedder/embedder_studio_gl.h +++ b/shell/platform/embedder/embedder_studio_gl.h @@ -37,6 +37,9 @@ class EmbedderStudioGL final : public EmbedderStudio, // |EmbedderStudio| bool IsValid() const override; + // |EmbedderStudio| + std::unique_ptr CreateGPUStudio() override; + // |EmbedderStudio| std::unique_ptr CreateSurface() override; diff --git a/shell/platform/embedder/embedder_studio_metal.h b/shell/platform/embedder/embedder_studio_metal.h index db1d0bbf1a4be..eefc8e2745a12 100644 --- a/shell/platform/embedder/embedder_studio_metal.h +++ b/shell/platform/embedder/embedder_studio_metal.h @@ -35,6 +35,9 @@ class EmbedderStudioMetal final : public EmbedderStudio, // |EmbedderStudio| bool IsValid() const override; + // |EmbedderStudio| + std::unique_ptr CreateGPUStudio() override; + // |EmbedderStudio| std::unique_ptr CreateSurface() override; diff --git a/shell/platform/embedder/embedder_studio_metal.mm b/shell/platform/embedder/embedder_studio_metal.mm index 87ef747734042..a6ab39298a3d0 100644 --- a/shell/platform/embedder/embedder_studio_metal.mm +++ b/shell/platform/embedder/embedder_studio_metal.mm @@ -9,6 +9,7 @@ #include "flutter/fml/logging.h" #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h" +#include "flutter/shell/gpu/gpu_studio_metal_skia.h" #include "flutter/shell/platform/embedder/embedder_surface_metal.h" #include "third_party/skia/include/gpu/GrDirectContext.h" @@ -38,6 +39,24 @@ return valid_; } +std::unique_ptr EmbedderStudioMetal::CreateGPUStudio() API_AVAILABLE(ios(13.0)) { + if (@available(iOS 13.0, *)) { + } else { + return nullptr; + } + if (!IsValid()) { + return nullptr; + } + + auto studio = std::make_unique(this, main_context_); + + if (!studio->IsValid()) { + return nullptr; + } + + return studio; +} + std::unique_ptr EmbedderStudioMetal::CreateSurface() { if (!IsValid()) { return nullptr; diff --git a/shell/platform/embedder/embedder_studio_software.cc b/shell/platform/embedder/embedder_studio_software.cc index eceeda79fee89..c9baf961acf85 100644 --- a/shell/platform/embedder/embedder_studio_software.cc +++ b/shell/platform/embedder/embedder_studio_software.cc @@ -10,6 +10,7 @@ #include "flutter/shell/platform/embedder/embedder_studio_software.h" #include "flutter/shell/platform/embedder/embedder_surface_software.h" +#include "flutter/shell/gpu/gpu_studio_software.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkSurface.h" @@ -35,6 +36,20 @@ bool EmbedderStudioSoftware::IsValid() const { return valid_; } +// |EmbedderStudio| +std::unique_ptr EmbedderStudioSoftware::CreateGPUStudio() { + if (!IsValid()) { + return nullptr; + } + auto studio = std::make_unique(this); + + if (!studio->IsValid()) { + return nullptr; + } + + return studio; +} + // |EmbedderStudio| std::unique_ptr EmbedderStudioSoftware::CreateSurface() { if (!IsValid()) { diff --git a/shell/platform/embedder/embedder_studio_software.h b/shell/platform/embedder/embedder_studio_software.h index ce9ba6f9f8182..0ab0e2977fd5e 100644 --- a/shell/platform/embedder/embedder_studio_software.h +++ b/shell/platform/embedder/embedder_studio_software.h @@ -31,6 +31,9 @@ class EmbedderStudioSoftware final : public EmbedderStudio, // |EmbedderStudio| bool IsValid() const override; + // |EmbedderStudio| + std::unique_ptr CreateGPUStudio() override; + // |EmbedderStudio| std::unique_ptr CreateSurface() override; diff --git a/shell/platform/embedder/embedder_studio_vulkan.cc b/shell/platform/embedder/embedder_studio_vulkan.cc index ba61e2217a209..4c7e98dcb9573 100644 --- a/shell/platform/embedder/embedder_studio_vulkan.cc +++ b/shell/platform/embedder/embedder_studio_vulkan.cc @@ -14,6 +14,7 @@ #include "flutter/vulkan/vulkan_skia_proc_table.h" #include "include/gpu/GrDirectContext.h" #include "include/gpu/vk/GrVkBackendContext.h" +#include "flutter/shell/gpu/gpu_studio_vulkan.h" #include "include/gpu/vk/GrVkExtensions.h" namespace flutter { @@ -108,6 +109,20 @@ bool EmbedderStudioVulkan::IsValid() const { return valid_; } +// |EmbedderStudio| +std::unique_ptr EmbedderStudioVulkan::CreateGPUStudio() { + if (!IsValid()) { + return nullptr; + } + auto studio = std::make_unique(this, main_context_); + + if (!studio->IsValid()) { + return nullptr; + } + + return studio; +} + // |EmbedderStudio| std::unique_ptr EmbedderStudioVulkan::CreateSurface() { const bool render_to_surface = !external_view_embedder_; diff --git a/shell/platform/embedder/embedder_studio_vulkan.h b/shell/platform/embedder/embedder_studio_vulkan.h index e161819591105..bfd5af3ed5122 100644 --- a/shell/platform/embedder/embedder_studio_vulkan.h +++ b/shell/platform/embedder/embedder_studio_vulkan.h @@ -55,6 +55,9 @@ class EmbedderStudioVulkan final : public EmbedderStudio, // |EmbedderStudio| bool IsValid() const override; + // |EmbedderStudio| + std::unique_ptr CreateGPUStudio() override; + // |EmbedderStudio| std::unique_ptr CreateSurface() override; diff --git a/shell/platform/embedder/platform_view_embedder_unittests.cc b/shell/platform/embedder/platform_view_embedder_unittests.cc index 04b4fb804b871..f0a07cc8aa004 100644 --- a/shell/platform/embedder/platform_view_embedder_unittests.cc +++ b/shell/platform/embedder/platform_view_embedder_unittests.cc @@ -62,6 +62,7 @@ class MockResponse : public PlatformMessageResponse { class MockStudio : public EmbedderStudio { public: MOCK_CONST_METHOD0(IsValid, bool()); + MOCK_METHOD0(CreateGPUStudio, std::unique_ptr()); MOCK_METHOD0(CreateSurface, std::unique_ptr()); MOCK_CONST_METHOD0(CreateResourceContext, sk_sp()); }; From b9f524cee802a9308145a46b86e7198403d42160 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 12:51:45 -0700 Subject: [PATCH 018/142] Format --- shell/gpu/gpu_studio_gl_impeller.h | 4 ++-- shell/gpu/gpu_studio_gl_skia.cc | 5 ++--- shell/gpu/gpu_studio_gl_skia.h | 5 ++--- shell/gpu/gpu_studio_metal_impeller.h | 2 +- shell/gpu/gpu_studio_metal_impeller.mm | 2 +- shell/gpu/gpu_studio_metal_skia.h | 4 ++-- shell/gpu/gpu_studio_metal_skia.mm | 6 ++---- shell/gpu/gpu_studio_software.h | 2 +- shell/gpu/gpu_studio_vulkan.cc | 6 ++---- shell/gpu/gpu_studio_vulkan.h | 4 ++-- shell/gpu/gpu_studio_vulkan_impeller.h | 2 +- shell/platform/embedder/embedder_studio_gl.cc | 5 ++--- shell/platform/embedder/embedder_studio_metal.mm | 2 +- shell/platform/embedder/embedder_studio_software.cc | 2 +- shell/platform/embedder/embedder_studio_vulkan.cc | 2 +- 15 files changed, 23 insertions(+), 30 deletions(-) diff --git a/shell/gpu/gpu_studio_gl_impeller.h b/shell/gpu/gpu_studio_gl_impeller.h index 9c54d7eb18283..cad5ff185c1a0 100644 --- a/shell/gpu/gpu_studio_gl_impeller.h +++ b/shell/gpu/gpu_studio_gl_impeller.h @@ -6,11 +6,11 @@ #define SHELL_GPU_GPU_STUDIO_GL_IMPELLER_H_ #include "flutter/common/graphics/gl_context_switch.h" +#include "flutter/flow/studio.h" #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/impeller/aiks/aiks_context.h" -#include "flutter/flow/studio.h" #include "flutter/impeller/renderer/context.h" #include "flutter/shell/gpu/gpu_surface_gl_delegate.h" @@ -19,7 +19,7 @@ namespace flutter { class GPUStudioGLImpeller final : public Studio { public: explicit GPUStudioGLImpeller(GPUSurfaceGLDelegate* delegate, - std::shared_ptr context); + std::shared_ptr context); // |Studio| ~GPUStudioGLImpeller() override; diff --git a/shell/gpu/gpu_studio_gl_skia.cc b/shell/gpu/gpu_studio_gl_skia.cc index b4dce0fbc51d6..00c36c7b6e29c 100644 --- a/shell/gpu/gpu_studio_gl_skia.cc +++ b/shell/gpu/gpu_studio_gl_skia.cc @@ -28,9 +28,8 @@ namespace flutter { GPUStudioGLSkia::GPUStudioGLSkia(const sk_sp& gr_context, - GPUSurfaceGLDelegate* delegate) - : delegate_(delegate), - context_(gr_context) { + GPUSurfaceGLDelegate* delegate) + : delegate_(delegate), context_(gr_context) { auto context_switch = delegate_->GLContextMakeCurrent(); if (!context_switch->GetResult()) { FML_LOG(ERROR) diff --git a/shell/gpu/gpu_studio_gl_skia.h b/shell/gpu/gpu_studio_gl_skia.h index 9dbedb0b6d58e..25ee264d1cfbf 100644 --- a/shell/gpu/gpu_studio_gl_skia.h +++ b/shell/gpu/gpu_studio_gl_skia.h @@ -10,8 +10,8 @@ #include "flutter/common/graphics/gl_context_switch.h" #include "flutter/flow/embedded_views.h" -#include "flutter/flow/surface.h" #include "flutter/flow/studio.h" +#include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/shell/gpu/gpu_surface_gl_delegate.h" @@ -23,7 +23,7 @@ namespace flutter { class GPUStudioGLSkia : public Studio { public: GPUStudioGLSkia(const sk_sp& gr_context, - GPUSurfaceGLDelegate* delegate); + GPUSurfaceGLDelegate* delegate); // |Studio| ~GPUStudioGLSkia() override; @@ -44,7 +44,6 @@ class GPUStudioGLSkia : public Studio { bool AllowsDrawingWhenGpuDisabled() const override; private: - GPUSurfaceGLDelegate* delegate_; sk_sp context_; bool valid_ = false; diff --git a/shell/gpu/gpu_studio_metal_impeller.h b/shell/gpu/gpu_studio_metal_impeller.h index d9b534c487540..8ae9386530e90 100644 --- a/shell/gpu/gpu_studio_metal_impeller.h +++ b/shell/gpu/gpu_studio_metal_impeller.h @@ -20,7 +20,7 @@ namespace flutter { class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalImpeller : public Studio { public: GPUStudioMetalImpeller(GPUSurfaceMetalDelegate* delegate, - const std::shared_ptr& context); + const std::shared_ptr& context); // |Studio| ~GPUStudioMetalImpeller(); diff --git a/shell/gpu/gpu_studio_metal_impeller.mm b/shell/gpu/gpu_studio_metal_impeller.mm index b62425a694d49..dbbe46c73738d 100644 --- a/shell/gpu/gpu_studio_metal_impeller.mm +++ b/shell/gpu/gpu_studio_metal_impeller.mm @@ -29,7 +29,7 @@ } GPUStudioMetalImpeller::GPUStudioMetalImpeller(GPUSurfaceMetalDelegate* delegate, - const std::shared_ptr& context) + const std::shared_ptr& context) : delegate_(delegate), impeller_renderer_(CreateImpellerRenderer(context)), aiks_context_( diff --git a/shell/gpu/gpu_studio_metal_skia.h b/shell/gpu/gpu_studio_metal_skia.h index 71d0c69351df0..842a926e1d5e8 100644 --- a/shell/gpu/gpu_studio_metal_skia.h +++ b/shell/gpu/gpu_studio_metal_skia.h @@ -6,8 +6,8 @@ #define FLUTTER_SHELL_GPU_GPU_STUDIO_METAL_H_ #include "flutter/common/graphics/msaa_sample_count.h" -#include "flutter/flow/surface.h" #include "flutter/flow/studio.h" +#include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #include "third_party/skia/include/gpu/GrDirectContext.h" @@ -17,7 +17,7 @@ namespace flutter { class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalSkia : public Studio { public: GPUStudioMetalSkia(GPUSurfaceMetalDelegate* delegate, - sk_sp context); + sk_sp context); // |Studio| ~GPUStudioMetalSkia(); diff --git a/shell/gpu/gpu_studio_metal_skia.mm b/shell/gpu/gpu_studio_metal_skia.mm index 6bc24ab95d5ef..91dc90e496fb8 100644 --- a/shell/gpu/gpu_studio_metal_skia.mm +++ b/shell/gpu/gpu_studio_metal_skia.mm @@ -29,10 +29,8 @@ namespace flutter { GPUStudioMetalSkia::GPUStudioMetalSkia(GPUSurfaceMetalDelegate* delegate, - sk_sp context) - : delegate_(delegate), - context_(std::move(context)) { -} + sk_sp context) + : delegate_(delegate), context_(std::move(context)) {} GPUStudioMetalSkia::~GPUStudioMetalSkia() = default; diff --git a/shell/gpu/gpu_studio_software.h b/shell/gpu/gpu_studio_software.h index 4eca32b8442f6..f953b66c2fa9b 100644 --- a/shell/gpu/gpu_studio_software.h +++ b/shell/gpu/gpu_studio_software.h @@ -5,11 +5,11 @@ #ifndef FLUTTER_SHELL_GPU_GPU_STUDIO_SOFTWARE_H_ #define FLUTTER_SHELL_GPU_GPU_STUDIO_SOFTWARE_H_ +#include "flutter/flow/studio.h" #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/shell/gpu/gpu_surface_software_delegate.h" -#include "flutter/flow/studio.h" namespace flutter { diff --git a/shell/gpu/gpu_studio_vulkan.cc b/shell/gpu/gpu_studio_vulkan.cc index 245a6370f039f..3ba20181ebcce 100644 --- a/shell/gpu/gpu_studio_vulkan.cc +++ b/shell/gpu/gpu_studio_vulkan.cc @@ -14,10 +14,8 @@ namespace flutter { GPUStudioVulkan::GPUStudioVulkan(GPUSurfaceVulkanDelegate* delegate, - const sk_sp& skia_context) - : delegate_(delegate), - skia_context_(skia_context), - weak_factory_(this) {} + const sk_sp& skia_context) + : delegate_(delegate), skia_context_(skia_context), weak_factory_(this) {} GPUStudioVulkan::~GPUStudioVulkan() = default; diff --git a/shell/gpu/gpu_studio_vulkan.h b/shell/gpu/gpu_studio_vulkan.h index ced9ae426bec5..4aef17f558836 100644 --- a/shell/gpu/gpu_studio_vulkan.h +++ b/shell/gpu/gpu_studio_vulkan.h @@ -7,13 +7,13 @@ #include +#include "flutter/flow/studio.h" #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" #include "flutter/vulkan/vulkan_backbuffer.h" #include "flutter/vulkan/vulkan_native_surface.h" -#include "flutter/flow/studio.h" #include "flutter/vulkan/vulkan_window.h" #include "third_party/skia/include/core/SkRefCnt.h" @@ -31,7 +31,7 @@ class GPUStudioVulkan : public Studio { /// GrDirectContext. /// GPUStudioVulkan(GPUSurfaceVulkanDelegate* delegate, - const sk_sp& context); + const sk_sp& context); ~GPUStudioVulkan() override; diff --git a/shell/gpu/gpu_studio_vulkan_impeller.h b/shell/gpu/gpu_studio_vulkan_impeller.h index e25346a9e44de..4c516ad22b799 100644 --- a/shell/gpu/gpu_studio_vulkan_impeller.h +++ b/shell/gpu/gpu_studio_vulkan_impeller.h @@ -5,8 +5,8 @@ #pragma once #include "flutter/common/graphics/gl_context_switch.h" -#include "flutter/flow/surface.h" #include "flutter/flow/studio.h" +#include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/fml/memory/weak_ptr.h" #include "flutter/impeller/aiks/aiks_context.h" diff --git a/shell/platform/embedder/embedder_studio_gl.cc b/shell/platform/embedder/embedder_studio_gl.cc index ba0dc47c2ea60..29693949ad619 100644 --- a/shell/platform/embedder/embedder_studio_gl.cc +++ b/shell/platform/embedder/embedder_studio_gl.cc @@ -7,8 +7,8 @@ #include #include "flutter/shell/common/shell_io_manager.h" -#include "flutter/shell/platform/embedder/embedder_surface_gl.h" #include "flutter/shell/gpu/gpu_studio_gl_skia.h" +#include "flutter/shell/platform/embedder/embedder_surface_gl.h" namespace flutter { @@ -104,8 +104,7 @@ std::unique_ptr EmbedderStudioGL::CreateGPUStudio() { if (!IsValid()) { return nullptr; } - auto studio = - std::make_unique(main_context_, this); + auto studio = std::make_unique(main_context_, this); if (!studio->IsValid()) { return nullptr; } diff --git a/shell/platform/embedder/embedder_studio_metal.mm b/shell/platform/embedder/embedder_studio_metal.mm index a6ab39298a3d0..0425abdcbe0f0 100644 --- a/shell/platform/embedder/embedder_studio_metal.mm +++ b/shell/platform/embedder/embedder_studio_metal.mm @@ -7,9 +7,9 @@ #include #include "flutter/fml/logging.h" +#include "flutter/shell/gpu/gpu_studio_metal_skia.h" #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #import "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h" -#include "flutter/shell/gpu/gpu_studio_metal_skia.h" #include "flutter/shell/platform/embedder/embedder_surface_metal.h" #include "third_party/skia/include/gpu/GrDirectContext.h" diff --git a/shell/platform/embedder/embedder_studio_software.cc b/shell/platform/embedder/embedder_studio_software.cc index c9baf961acf85..84a565a43c34d 100644 --- a/shell/platform/embedder/embedder_studio_software.cc +++ b/shell/platform/embedder/embedder_studio_software.cc @@ -8,9 +8,9 @@ #include "flutter/fml/trace_event.h" +#include "flutter/shell/gpu/gpu_studio_software.h" #include "flutter/shell/platform/embedder/embedder_studio_software.h" #include "flutter/shell/platform/embedder/embedder_surface_software.h" -#include "flutter/shell/gpu/gpu_studio_software.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkImageInfo.h" #include "third_party/skia/include/core/SkSurface.h" diff --git a/shell/platform/embedder/embedder_studio_vulkan.cc b/shell/platform/embedder/embedder_studio_vulkan.cc index 4c7e98dcb9573..a741df7cdab1f 100644 --- a/shell/platform/embedder/embedder_studio_vulkan.cc +++ b/shell/platform/embedder/embedder_studio_vulkan.cc @@ -8,13 +8,13 @@ #include "flutter/flutter_vma/flutter_skia_vma.h" #include "flutter/shell/common/shell_io_manager.h" +#include "flutter/shell/gpu/gpu_studio_vulkan.h" #include "flutter/shell/gpu/gpu_surface_vulkan.h" #include "flutter/shell/gpu/gpu_surface_vulkan_delegate.h" #include "flutter/shell/platform/embedder/embedder_surface_vulkan.h" #include "flutter/vulkan/vulkan_skia_proc_table.h" #include "include/gpu/GrDirectContext.h" #include "include/gpu/vk/GrVkBackendContext.h" -#include "flutter/shell/gpu/gpu_studio_vulkan.h" #include "include/gpu/vk/GrVkExtensions.h" namespace flutter { From b1ced68d85157b5bb1f94880594c3acd310d7122 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 13:20:37 -0700 Subject: [PATCH 019/142] Add CreateGPUStudio to AndroidSurfaces --- .../android/android_surface_gl_impeller.cc | 14 ++++++++++ .../android/android_surface_gl_impeller.h | 3 +++ .../android/android_surface_gl_skia.cc | 26 ++++++++++++++++--- .../android/android_surface_gl_skia.h | 6 +++++ .../android/android_surface_software.cc | 17 ++++++++++++ .../android/android_surface_software.h | 3 +++ .../android_surface_vulkan_impeller.cc | 17 ++++++++++++ .../android/android_surface_vulkan_impeller.h | 3 +++ .../android/surface/android_surface.h | 4 +++ .../android/surface/android_surface_mock.h | 5 ++++ 10 files changed, 94 insertions(+), 4 deletions(-) diff --git a/shell/platform/android/android_surface_gl_impeller.cc b/shell/platform/android/android_surface_gl_impeller.cc index 3200822776a90..7e862f4390b32 100644 --- a/shell/platform/android/android_surface_gl_impeller.cc +++ b/shell/platform/android/android_surface_gl_impeller.cc @@ -9,6 +9,7 @@ #include "flutter/impeller/renderer/backend/gles/proc_table_gles.h" #include "flutter/impeller/toolkit/egl/context.h" #include "flutter/impeller/toolkit/egl/surface.h" +#include "flutter/shell/gpu/gpu_studio_gl_impeller.h" #include "flutter/shell/gpu/gpu_surface_gl_impeller.h" #include "impeller/entity/gles/entity_shaders_gles.h" #include "impeller/scene/shaders/gles/scene_shaders_gles.h" @@ -186,6 +187,19 @@ bool AndroidSurfaceGLImpeller::IsValid() const { return is_valid_; } +// |AndroidSurface| +std::unique_ptr AndroidSurfaceGLImpeller::CreateGPUStudio( + GrDirectContext* gr_context) override { + auto studio = + std::make_unique(this, // delegate + impeller_context_ // context + ); + if (!studio->IsValid()) { + return nullptr; + } + return studio; +} + // |AndroidSurface| std::unique_ptr AndroidSurfaceGLImpeller::CreateGPUSurface( GrDirectContext* gr_context) { diff --git a/shell/platform/android/android_surface_gl_impeller.h b/shell/platform/android/android_surface_gl_impeller.h index b8ca423072f60..d455242ff46c7 100644 --- a/shell/platform/android/android_surface_gl_impeller.h +++ b/shell/platform/android/android_surface_gl_impeller.h @@ -27,6 +27,9 @@ class AndroidSurfaceGLImpeller final : public GPUSurfaceGLDelegate, // |AndroidSurface| bool IsValid() const override; + // |AndroidSurface| + std::unique_ptr CreateGPUStudio(GrDirectContext* gr_context) override; + // |AndroidSurface| std::unique_ptr CreateGPUSurface( GrDirectContext* gr_context) override; diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index 343d691e2ae75..2f285e9747ab3 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -9,6 +9,8 @@ #include "flutter/fml/logging.h" #include "flutter/fml/memory/ref_ptr.h" +#include "flutter/shell/gpu/gpu_studio_gl_skia.h" +#include "flutter/shell/gpu/gpu_surface_gl_skia.h" #include "flutter/shell/platform/android/android_egl_surface.h" #include "flutter/shell/platform/android/android_shell_holder.h" @@ -48,11 +50,10 @@ bool AndroidSurfaceGLSkia::IsValid() const { return offscreen_surface_ && GLContextPtr()->IsValid(); } -std::unique_ptr AndroidSurfaceGLSkia::CreateGPUSurface( +static GrDirectContext* AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( GrDirectContext* gr_context) { if (gr_context) { - return std::make_unique(sk_ref_sp(gr_context), this, - true); + return gr_context; } else { sk_sp main_skia_context = GLContextPtr()->GetMainSkiaContext(); @@ -60,8 +61,25 @@ std::unique_ptr AndroidSurfaceGLSkia::CreateGPUSurface( main_skia_context = GPUSurfaceGLSkia::MakeGLContext(this); GLContextPtr()->SetMainSkiaContext(main_skia_context); } - return std::make_unique(main_skia_context, this, true); + FML_DCHECK(GLContextPtr()->GetMainSkiaContext() == main_skia_context); + return main_skia_context; + } +} + +std::unique_ptr AndroidSurfaceGLSkia::CreateGPUStudio( + GrDirectContext* gr_context) override { + auto studio = std::make_unique( + sk_ref_sp(UseExistingMainContextOrCreate(gr_context)), + this) if (!studio->IsValid()) { + return nullptr; } + return studio; +} + +std::unique_ptr AndroidSurfaceGLSkia::CreateGPUSurface( + GrDirectContext* gr_context) { + return std::make_unique( + UseExistingMainContextOrCreate(gr_context), this, true); } bool AndroidSurfaceGLSkia::OnScreenSurfaceResize(const SkISize& size) { diff --git a/shell/platform/android/android_surface_gl_skia.h b/shell/platform/android/android_surface_gl_skia.h index 274c28f2c6760..1b30c82ea406d 100644 --- a/shell/platform/android/android_surface_gl_skia.h +++ b/shell/platform/android/android_surface_gl_skia.h @@ -30,6 +30,9 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, // |AndroidSurface| bool IsValid() const override; + // |AndroidSurface| + std::unique_ptr CreateGPUStudio() override; + // |AndroidSurface| std::unique_ptr CreateGPUSurface( GrDirectContext* gr_context) override; @@ -86,6 +89,9 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, std::unique_ptr onscreen_surface_; std::unique_ptr offscreen_surface_; + static sk_sp UseExistingMainContextOrCreate( + GrDirectContext* gr_context); + //---------------------------------------------------------------------------- /// @brief Takes the super class AndroidSurface's AndroidContext and /// return a raw pointer to an AndroidContextGL. diff --git a/shell/platform/android/android_surface_software.cc b/shell/platform/android/android_surface_software.cc index fdfc8d9d509ac..ae9f3afe9e55e 100644 --- a/shell/platform/android/android_surface_software.cc +++ b/shell/platform/android/android_surface_software.cc @@ -11,6 +11,8 @@ #include "flutter/fml/platform/android/jni_weak_ref.h" #include "flutter/fml/platform/android/scoped_java_ref.h" #include "flutter/fml/trace_event.h" +#include "flutter/shell/gpu/gpu_studio_gl_software.h" +#include "flutter/shell/gpu/gpu_surface_gl_software.h" #include "flutter/shell/platform/android/android_shell_holder.h" #include "flutter/shell/platform/android/jni/platform_view_android_jni.h" @@ -63,6 +65,21 @@ bool AndroidSurfaceSoftware::ResourceContextClearCurrent() { return false; } +std::unique_ptr AndroidSurfaceSoftware::CreateGPUStudio( + GrDirectContext* gr_context) override { + if (!IsValid()) { + return nullptr; + } + + auto studio = std::make_unique(this); + + if (!studio->IsValid()) { + return nullptr; + } + + return studio; +} + std::unique_ptr AndroidSurfaceSoftware::CreateGPUSurface( // The software AndroidSurface neither uses any passed in Skia context // nor does it interact with the AndroidContext's raster Skia context. diff --git a/shell/platform/android/android_surface_software.h b/shell/platform/android/android_surface_software.h index 38e4c498f3843..6817285a03b71 100644 --- a/shell/platform/android/android_surface_software.h +++ b/shell/platform/android/android_surface_software.h @@ -34,6 +34,9 @@ class AndroidSurfaceSoftware final : public AndroidSurface, // |AndroidSurface| bool ResourceContextClearCurrent() override; + // |AndroidSurface| + std::unique_ptr CreateGPUStudio(GrDirectContext* gr_context) override; + // |AndroidSurface| std::unique_ptr CreateGPUSurface( GrDirectContext* gr_context) override; diff --git a/shell/platform/android/android_surface_vulkan_impeller.cc b/shell/platform/android/android_surface_vulkan_impeller.cc index ca2b4f448ddc5..1c40705f01e03 100644 --- a/shell/platform/android/android_surface_vulkan_impeller.cc +++ b/shell/platform/android/android_surface_vulkan_impeller.cc @@ -11,6 +11,7 @@ #include "flutter/fml/logging.h" #include "flutter/fml/memory/ref_ptr.h" #include "flutter/impeller/renderer/backend/vulkan/context_vk.h" +#include "flutter/shell/gpu/gpu_studio_vulkan_impeller.h" #include "flutter/shell/gpu/gpu_surface_vulkan_impeller.h" #include "flutter/vulkan/vulkan_native_surface_android.h" #include "impeller/entity/vk/entity_shaders_vk.h" @@ -66,6 +67,22 @@ void AndroidSurfaceVulkanImpeller::TeardownOnScreenContext() { // Nothing to do. } +std::unique_ptr AndroidSurfaceVulkanImpeller::CreateGPUStudio( + GrDirectContext* gr_context) override { + if (!IsValid()) { + return nullptr; + } + + std::unique_ptr studio = + std::make_unique(impeller_context_); + + if (!studio->IsValid()) { + return nullptr; + } + + return studio; +} + std::unique_ptr AndroidSurfaceVulkanImpeller::CreateGPUSurface( GrDirectContext* gr_context) { if (!IsValid()) { diff --git a/shell/platform/android/android_surface_vulkan_impeller.h b/shell/platform/android/android_surface_vulkan_impeller.h index c96cbd21a8fe1..315da31f20c36 100644 --- a/shell/platform/android/android_surface_vulkan_impeller.h +++ b/shell/platform/android/android_surface_vulkan_impeller.h @@ -24,6 +24,9 @@ class AndroidSurfaceVulkanImpeller : public AndroidSurface { // |AndroidSurface| bool IsValid() const override; + // |AndroidSurface| + std::unique_ptr CreateGPUStudio(GrDirectContext* gr_context) override; + // |AndroidSurface| std::unique_ptr CreateGPUSurface( GrDirectContext* gr_context) override; diff --git a/shell/platform/android/surface/android_surface.h b/shell/platform/android/surface/android_surface.h index 485f619e1a81b..bc5414a1bd78e 100644 --- a/shell/platform/android/surface/android_surface.h +++ b/shell/platform/android/surface/android_surface.h @@ -7,6 +7,7 @@ #include #include "flutter/flow/embedded_views.h" +#include "flutter/flow/studio.h" #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/shell/platform/android/context/android_context.h" @@ -30,6 +31,9 @@ class AndroidSurface { virtual void TeardownOnScreenContext() = 0; + virtual std::unique_ptr CreateGPUStudio( + GrDirectContext* gr_context = nullptr) = 0; + virtual std::unique_ptr CreateGPUSurface( GrDirectContext* gr_context = nullptr) = 0; diff --git a/shell/platform/android/surface/android_surface_mock.h b/shell/platform/android/surface/android_surface_mock.h index 3f326a21920b7..fb2aae33f30d6 100644 --- a/shell/platform/android/surface/android_surface_mock.h +++ b/shell/platform/android/surface/android_surface_mock.h @@ -25,6 +25,11 @@ class AndroidSurfaceMock final : public GPUSurfaceGLDelegate, MOCK_METHOD(void, TeardownOnScreenContext, (), (override)); + MOCK_METHOD(std::unique_ptr, + CreateGPUStudio, + (GrDirectContext * gr_context), + (override)); + MOCK_METHOD(std::unique_ptr, CreateGPUSurface, (GrDirectContext * gr_context), From 6c7dfc90c6e13a51f3832333b4cc3e0d1e6c91cf Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 13:36:42 -0700 Subject: [PATCH 020/142] Add IOSSurface::CreateGPUStudio --- shell/platform/darwin/ios/ios_surface.h | 4 ++++ .../darwin/ios/ios_surface_metal_impeller.h | 3 +++ .../darwin/ios/ios_surface_metal_impeller.mm | 10 ++++++++++ shell/platform/darwin/ios/ios_surface_metal_skia.h | 3 +++ .../platform/darwin/ios/ios_surface_metal_skia.mm | 8 ++++++++ shell/platform/darwin/ios/ios_surface_software.h | 3 +++ shell/platform/darwin/ios/ios_surface_software.mm | 14 ++++++++++++++ 7 files changed, 45 insertions(+) diff --git a/shell/platform/darwin/ios/ios_surface.h b/shell/platform/darwin/ios/ios_surface.h index 78394f25781c6..90ec430c6569e 100644 --- a/shell/platform/darwin/ios/ios_surface.h +++ b/shell/platform/darwin/ios/ios_surface.h @@ -11,6 +11,7 @@ #include "flutter/flow/embedded_views.h" #include "flutter/flow/surface.h" +#include "flutter/flow/studio.h" #include "flutter/fml/macros.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" @@ -35,6 +36,9 @@ class IOSSurface { virtual void UpdateStorageSizeIfNecessary() = 0; + virtual std::unique_ptr CreateGPUStudio( + GrDirectContext* gr_context = nullptr) = 0; + // Creates a GPU surface. If no GrDirectContext is supplied and the rendering mode // supports one, a new one will be created; otherwise, the software backend // will be used. diff --git a/shell/platform/darwin/ios/ios_surface_metal_impeller.h b/shell/platform/darwin/ios/ios_surface_metal_impeller.h index 6c3615318a9ca..9f29a9cc68dc3 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_impeller.h +++ b/shell/platform/darwin/ios/ios_surface_metal_impeller.h @@ -38,6 +38,9 @@ class SK_API_AVAILABLE_CA_METAL_LAYER IOSSurfaceMetalImpeller final // |IOSSurface| void UpdateStorageSizeIfNecessary() override; + // |IOSSurface| + std::unique_ptr CreateGPUStudio(GrDirectContext* gr_context) override; + // |IOSSurface| std::unique_ptr CreateGPUSurface(GrDirectContext* gr_context) override; diff --git a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm index c1696ff309d70..8871c5551de08 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm @@ -103,6 +103,16 @@ PixelFormat GetColorAttachmentPixelFormat() const override { // Nothing to do. } +// |IOSSurface| +std::unique_ptr IOSSurfaceMetalImpeller::CreateGPUStudio(GrDirectContext*) override { + auto context = std::make_shared( + impeller_context_, + InferOffscreenLayerPixelFormat(FromMTLPixelFormat(layer_.get().pixelFormat))); + return std::make_unique(this, // + context // + ); +} + // |IOSSurface| std::unique_ptr IOSSurfaceMetalImpeller::CreateGPUSurface(GrDirectContext*) { auto context = std::make_shared( diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.h b/shell/platform/darwin/ios/ios_surface_metal_skia.h index efd174b07e09d..80c1f0f5cfbd3 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.h +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.h @@ -35,6 +35,9 @@ class SK_API_AVAILABLE_CA_METAL_LAYER IOSSurfaceMetalSkia final : public IOSSurf // |IOSSurface| void UpdateStorageSizeIfNecessary() override; + // |IOSSurface| + std::unique_ptr CreateGPUStudio(GrDirectContext* gr_context = nullptr) override; + // |IOSSurface| std::unique_ptr CreateGPUSurface(GrDirectContext* gr_context) override; diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.mm b/shell/platform/darwin/ios/ios_surface_metal_skia.mm index 13ac639a2fe0c..ab320edfa6de0 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.mm @@ -39,6 +39,14 @@ // Nothing to do. } +// |IOSSurface| +std::unique_ptr IOSSurfaceMetalSkia::CreateGPUStudio(GrDirectContext* gr_context) override { + FML_DCHECK(context); + return std::make_unique(this, // delegate + sk_ref_sp(context), // context + ); +} + // |IOSSurface| std::unique_ptr IOSSurfaceMetalSkia::CreateGPUSurface(GrDirectContext* context) { FML_DCHECK(context); diff --git a/shell/platform/darwin/ios/ios_surface_software.h b/shell/platform/darwin/ios/ios_surface_software.h index e1ed6b69518c0..e0529df886bf1 100644 --- a/shell/platform/darwin/ios/ios_surface_software.h +++ b/shell/platform/darwin/ios/ios_surface_software.h @@ -31,6 +31,9 @@ class IOSSurfaceSoftware final : public IOSSurface, public GPUSurfaceSoftwareDel // |IOSSurface| void UpdateStorageSizeIfNecessary() override; + // |IOSSurface| + std::unique_ptr CreateGPUStudio(GrDirectContext* gr_context = nullptr) override; + // |IOSSurface| std::unique_ptr CreateGPUSurface(GrDirectContext* gr_context = nullptr) override; diff --git a/shell/platform/darwin/ios/ios_surface_software.mm b/shell/platform/darwin/ios/ios_surface_software.mm index 2e87510cc0885..abc197e1ef98f 100644 --- a/shell/platform/darwin/ios/ios_surface_software.mm +++ b/shell/platform/darwin/ios/ios_surface_software.mm @@ -34,6 +34,20 @@ // Android oddities. } +std::unique_ptr IOSSurfaceSoftware::CreateGPUStudio(GrDirectContext* gr_context) override { + if (!IsValid()) { + return nullptr; + } + + auto studio = std::make_unique(this); + + if (!studio->IsValid()) { + return nullptr; + } + + return studio; +} + std::unique_ptr IOSSurfaceSoftware::CreateGPUSurface(GrDirectContext* gr_context) { if (!IsValid()) { return nullptr; From fa138f14580f423518ab12ed71134c894273c37a Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 13:37:19 -0700 Subject: [PATCH 021/142] Format --- shell/platform/darwin/ios/ios_surface.h | 5 ++--- shell/platform/darwin/ios/ios_surface_metal_skia.mm | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/shell/platform/darwin/ios/ios_surface.h b/shell/platform/darwin/ios/ios_surface.h index 90ec430c6569e..c93eb886f5a25 100644 --- a/shell/platform/darwin/ios/ios_surface.h +++ b/shell/platform/darwin/ios/ios_surface.h @@ -10,8 +10,8 @@ #include #include "flutter/flow/embedded_views.h" -#include "flutter/flow/surface.h" #include "flutter/flow/studio.h" +#include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" @@ -36,8 +36,7 @@ class IOSSurface { virtual void UpdateStorageSizeIfNecessary() = 0; - virtual std::unique_ptr CreateGPUStudio( - GrDirectContext* gr_context = nullptr) = 0; + virtual std::unique_ptr CreateGPUStudio(GrDirectContext* gr_context = nullptr) = 0; // Creates a GPU surface. If no GrDirectContext is supplied and the rendering mode // supports one, a new one will be created; otherwise, the software backend diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.mm b/shell/platform/darwin/ios/ios_surface_metal_skia.mm index ab320edfa6de0..47daaf1ee29a6 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.mm @@ -42,8 +42,8 @@ // |IOSSurface| std::unique_ptr IOSSurfaceMetalSkia::CreateGPUStudio(GrDirectContext* gr_context) override { FML_DCHECK(context); - return std::make_unique(this, // delegate - sk_ref_sp(context), // context + return std::make_unique(this, // delegate + sk_ref_sp(context), // context ); } From 116d9b32b10f63bcdb8203d03871f83eb6856ea9 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 13:42:03 -0700 Subject: [PATCH 022/142] Compile --- shell/gpu/gpu_studio_vulkan.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/gpu/gpu_studio_vulkan.cc b/shell/gpu/gpu_studio_vulkan.cc index 3ba20181ebcce..7f150e6cb9287 100644 --- a/shell/gpu/gpu_studio_vulkan.cc +++ b/shell/gpu/gpu_studio_vulkan.cc @@ -15,7 +15,7 @@ namespace flutter { GPUStudioVulkan::GPUStudioVulkan(GPUSurfaceVulkanDelegate* delegate, const sk_sp& skia_context) - : delegate_(delegate), skia_context_(skia_context), weak_factory_(this) {} + : delegate_(delegate), skia_context_(skia_context) {} GPUStudioVulkan::~GPUStudioVulkan() = default; From 1454b830ee5d2a22d3391cd6fcbc408b5e228119 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 14:35:48 -0700 Subject: [PATCH 023/142] Try to fix compile --- shell/platform/android/android_surface_gl_impeller.cc | 2 +- shell/platform/android/android_surface_gl_skia.cc | 7 ++++--- shell/platform/android/android_surface_gl_skia.h | 4 ++-- shell/platform/android/android_surface_software.cc | 6 +++--- shell/platform/android/android_surface_vulkan_impeller.cc | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) diff --git a/shell/platform/android/android_surface_gl_impeller.cc b/shell/platform/android/android_surface_gl_impeller.cc index 7e862f4390b32..8cf716c594af9 100644 --- a/shell/platform/android/android_surface_gl_impeller.cc +++ b/shell/platform/android/android_surface_gl_impeller.cc @@ -189,7 +189,7 @@ bool AndroidSurfaceGLImpeller::IsValid() const { // |AndroidSurface| std::unique_ptr AndroidSurfaceGLImpeller::CreateGPUStudio( - GrDirectContext* gr_context) override { + GrDirectContext* gr_context) { auto studio = std::make_unique(this, // delegate impeller_context_ // context diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index 2f285e9747ab3..39c3f5c343818 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -50,7 +50,7 @@ bool AndroidSurfaceGLSkia::IsValid() const { return offscreen_surface_ && GLContextPtr()->IsValid(); } -static GrDirectContext* AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( +GrDirectContext* AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( GrDirectContext* gr_context) { if (gr_context) { return gr_context; @@ -67,10 +67,11 @@ static GrDirectContext* AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( } std::unique_ptr AndroidSurfaceGLSkia::CreateGPUStudio( - GrDirectContext* gr_context) override { + GrDirectContext* gr_context) { auto studio = std::make_unique( sk_ref_sp(UseExistingMainContextOrCreate(gr_context)), - this) if (!studio->IsValid()) { + this); + if (!studio->IsValid()) { return nullptr; } return studio; diff --git a/shell/platform/android/android_surface_gl_skia.h b/shell/platform/android/android_surface_gl_skia.h index 1b30c82ea406d..78b82577b2582 100644 --- a/shell/platform/android/android_surface_gl_skia.h +++ b/shell/platform/android/android_surface_gl_skia.h @@ -31,7 +31,7 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, bool IsValid() const override; // |AndroidSurface| - std::unique_ptr CreateGPUStudio() override; + std::unique_ptr CreateGPUStudio(GrDirectContext* gr_context) override; // |AndroidSurface| std::unique_ptr CreateGPUSurface( @@ -89,7 +89,7 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, std::unique_ptr onscreen_surface_; std::unique_ptr offscreen_surface_; - static sk_sp UseExistingMainContextOrCreate( + GrDirectContext* UseExistingMainContextOrCreate( GrDirectContext* gr_context); //---------------------------------------------------------------------------- diff --git a/shell/platform/android/android_surface_software.cc b/shell/platform/android/android_surface_software.cc index ae9f3afe9e55e..7c48418178bb0 100644 --- a/shell/platform/android/android_surface_software.cc +++ b/shell/platform/android/android_surface_software.cc @@ -11,8 +11,8 @@ #include "flutter/fml/platform/android/jni_weak_ref.h" #include "flutter/fml/platform/android/scoped_java_ref.h" #include "flutter/fml/trace_event.h" -#include "flutter/shell/gpu/gpu_studio_gl_software.h" -#include "flutter/shell/gpu/gpu_surface_gl_software.h" +#include "flutter/shell/gpu/gpu_studio_software.h" +#include "flutter/shell/gpu/gpu_surface_software.h" #include "flutter/shell/platform/android/android_shell_holder.h" #include "flutter/shell/platform/android/jni/platform_view_android_jni.h" @@ -66,7 +66,7 @@ bool AndroidSurfaceSoftware::ResourceContextClearCurrent() { } std::unique_ptr AndroidSurfaceSoftware::CreateGPUStudio( - GrDirectContext* gr_context) override { + GrDirectContext* gr_context) { if (!IsValid()) { return nullptr; } diff --git a/shell/platform/android/android_surface_vulkan_impeller.cc b/shell/platform/android/android_surface_vulkan_impeller.cc index 1c40705f01e03..a1802664d61d2 100644 --- a/shell/platform/android/android_surface_vulkan_impeller.cc +++ b/shell/platform/android/android_surface_vulkan_impeller.cc @@ -68,7 +68,7 @@ void AndroidSurfaceVulkanImpeller::TeardownOnScreenContext() { } std::unique_ptr AndroidSurfaceVulkanImpeller::CreateGPUStudio( - GrDirectContext* gr_context) override { + GrDirectContext* gr_context) { if (!IsValid()) { return nullptr; } From 6c8b153990049f59606a97f9b9eecc0a15804e74 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 14:36:40 -0700 Subject: [PATCH 024/142] fuchsia studio --- shell/platform/fuchsia/flutter/BUILD.gn | 2 ++ shell/platform/fuchsia/flutter/engine.cc | 4 +++ shell/platform/fuchsia/flutter/engine.h | 5 +++- shell/platform/fuchsia/flutter/studio.cc | 31 +++++++++++++++++++++ shell/platform/fuchsia/flutter/studio.h | 34 ++++++++++++++++++++++++ 5 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 shell/platform/fuchsia/flutter/studio.cc create mode 100644 shell/platform/fuchsia/flutter/studio.h diff --git a/shell/platform/fuchsia/flutter/BUILD.gn b/shell/platform/fuchsia/flutter/BUILD.gn index cc1407fa98a0f..86def4be58711 100644 --- a/shell/platform/fuchsia/flutter/BUILD.gn +++ b/shell/platform/fuchsia/flutter/BUILD.gn @@ -99,6 +99,8 @@ template("runner_sources") { "software_surface.h", "software_surface_producer.cc", "software_surface_producer.h", + "studio.cc", + "studio.h", "surface.cc", "surface.h", "surface_producer.h", diff --git a/shell/platform/fuchsia/flutter/engine.cc b/shell/platform/fuchsia/flutter/engine.cc index d623804c1712b..8146468c7b737 100644 --- a/shell/platform/fuchsia/flutter/engine.cc +++ b/shell/platform/fuchsia/flutter/engine.cc @@ -833,6 +833,10 @@ void Engine::DestroyFlatlandView(int64_t view_id, }); } +std::unique_ptr Engine::CreateStudio() { + return std::make_unique(surface_producer_->gr_context()); +} + std::unique_ptr Engine::CreateSurface() { return std::make_unique(thread_label_, GetExternalViewEmbedder(), surface_producer_->gr_context()); diff --git a/shell/platform/fuchsia/flutter/engine.h b/shell/platform/fuchsia/flutter/engine.h index e11c41e878c14..eac798a1a1ee9 100644 --- a/shell/platform/fuchsia/flutter/engine.h +++ b/shell/platform/fuchsia/flutter/engine.h @@ -19,7 +19,6 @@ #include #include "flutter/flow/embedded_views.h" -#include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/shell/common/shell.h" #include "flutter/shell/common/thread_host.h" @@ -31,7 +30,9 @@ #include "gfx_external_view_embedder.h" #include "gfx_session_connection.h" #include "isolate_configurator.h" +#include "studio.h" #include "surface_producer.h" +#include "surface.h" namespace flutter_runner { @@ -144,6 +145,8 @@ class Engine final : public fuchsia::memorypressure::Watcher { std::shared_ptr GetExternalViewEmbedder(); + std::unique_ptr CreateStudio(); + std::unique_ptr CreateSurface(); Delegate& delegate_; diff --git a/shell/platform/fuchsia/flutter/studio.cc b/shell/platform/fuchsia/flutter/studio.cc new file mode 100644 index 0000000000000..c1a6f5240daae --- /dev/null +++ b/shell/platform/fuchsia/flutter/studio.cc @@ -0,0 +1,31 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "studio.h" + +#include +#include +#include +#include + +#include "flutter/fml/unique_fd.h" + +namespace flutter_runner { + +Studio::Studio(GrDirectContext* gr_context) + : gr_context_(gr_context) {} + +Studio::~Studio() = default; + +// |flutter::Studio| +bool Studio::IsValid() { + return true; +} + +// |flutter::Studio| +GrDirectContext* Studio::GetContext() { + return gr_context_; +} + +} // namespace flutter_runner diff --git a/shell/platform/fuchsia/flutter/studio.h b/shell/platform/fuchsia/flutter/studio.h new file mode 100644 index 0000000000000..1560238e74ee3 --- /dev/null +++ b/shell/platform/fuchsia/flutter/studio.h @@ -0,0 +1,34 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#pragma once + +#include "flutter/flow/studio.h" +#include "flutter/fml/macros.h" +#include "flutter/fml/memory/weak_ptr.h" + +namespace flutter_runner { + +// The interface between the Flutter rasterizer and the underlying platform. May +// be constructed on any thread but will be used by the engine only on the +// raster thread. +class Studio final : public flutter::Studio { + public: + Studio(GrDirectContext* gr_context); + + ~Studio() override; + + private: + GrDirectContext* gr_context_; + + // |flutter::Studio| + bool IsValid() override; + + // |flutter::Studio| + GrDirectContext* GetContext() override; + + FML_DISALLOW_COPY_AND_ASSIGN(Studio); +}; + +} // namespace flutter_runner From 52ee277ad3ceac59c9e1e991ccb1b4b27741b0eb Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 14:37:40 -0700 Subject: [PATCH 025/142] Format --- shell/platform/android/android_surface_gl_skia.cc | 5 ++--- shell/platform/android/android_surface_gl_skia.h | 3 +-- shell/platform/fuchsia/flutter/engine.h | 2 +- shell/platform/fuchsia/flutter/studio.cc | 3 +-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index 39c3f5c343818..644c17a8b0f0d 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -69,9 +69,8 @@ GrDirectContext* AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( std::unique_ptr AndroidSurfaceGLSkia::CreateGPUStudio( GrDirectContext* gr_context) { auto studio = std::make_unique( - sk_ref_sp(UseExistingMainContextOrCreate(gr_context)), - this); - if (!studio->IsValid()) { + sk_ref_sp(UseExistingMainContextOrCreate(gr_context)), this); + if (!studio->IsValid()) { return nullptr; } return studio; diff --git a/shell/platform/android/android_surface_gl_skia.h b/shell/platform/android/android_surface_gl_skia.h index 78b82577b2582..b7517a2c0745f 100644 --- a/shell/platform/android/android_surface_gl_skia.h +++ b/shell/platform/android/android_surface_gl_skia.h @@ -89,8 +89,7 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, std::unique_ptr onscreen_surface_; std::unique_ptr offscreen_surface_; - GrDirectContext* UseExistingMainContextOrCreate( - GrDirectContext* gr_context); + GrDirectContext* UseExistingMainContextOrCreate(GrDirectContext* gr_context); //---------------------------------------------------------------------------- /// @brief Takes the super class AndroidSurface's AndroidContext and diff --git a/shell/platform/fuchsia/flutter/engine.h b/shell/platform/fuchsia/flutter/engine.h index eac798a1a1ee9..06097a9692f85 100644 --- a/shell/platform/fuchsia/flutter/engine.h +++ b/shell/platform/fuchsia/flutter/engine.h @@ -31,8 +31,8 @@ #include "gfx_session_connection.h" #include "isolate_configurator.h" #include "studio.h" -#include "surface_producer.h" #include "surface.h" +#include "surface_producer.h" namespace flutter_runner { diff --git a/shell/platform/fuchsia/flutter/studio.cc b/shell/platform/fuchsia/flutter/studio.cc index c1a6f5240daae..2b40a531586fa 100644 --- a/shell/platform/fuchsia/flutter/studio.cc +++ b/shell/platform/fuchsia/flutter/studio.cc @@ -13,8 +13,7 @@ namespace flutter_runner { -Studio::Studio(GrDirectContext* gr_context) - : gr_context_(gr_context) {} +Studio::Studio(GrDirectContext* gr_context) : gr_context_(gr_context) {} Studio::~Studio() = default; From 6e298c4843e954675f81feda975ebecc5aa3c6a6 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 14:49:37 -0700 Subject: [PATCH 026/142] Compile --- shell/platform/android/android_surface_gl_skia.cc | 6 +++--- shell/platform/android/android_surface_gl_skia.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index 644c17a8b0f0d..5b094bef6f342 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -50,10 +50,10 @@ bool AndroidSurfaceGLSkia::IsValid() const { return offscreen_surface_ && GLContextPtr()->IsValid(); } -GrDirectContext* AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( +sk_sp AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( GrDirectContext* gr_context) { if (gr_context) { - return gr_context; + return sk_ref_sp(gr_context); } else { sk_sp main_skia_context = GLContextPtr()->GetMainSkiaContext(); @@ -69,7 +69,7 @@ GrDirectContext* AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( std::unique_ptr AndroidSurfaceGLSkia::CreateGPUStudio( GrDirectContext* gr_context) { auto studio = std::make_unique( - sk_ref_sp(UseExistingMainContextOrCreate(gr_context)), this); + UseExistingMainContextOrCreate(gr_context), this); if (!studio->IsValid()) { return nullptr; } diff --git a/shell/platform/android/android_surface_gl_skia.h b/shell/platform/android/android_surface_gl_skia.h index b7517a2c0745f..43b731a9829d6 100644 --- a/shell/platform/android/android_surface_gl_skia.h +++ b/shell/platform/android/android_surface_gl_skia.h @@ -89,7 +89,8 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, std::unique_ptr onscreen_surface_; std::unique_ptr offscreen_surface_; - GrDirectContext* UseExistingMainContextOrCreate(GrDirectContext* gr_context); + sk_sp UseExistingMainContextOrCreate( + GrDirectContext* gr_context); //---------------------------------------------------------------------------- /// @brief Takes the super class AndroidSurface's AndroidContext and From aeac80f7bc85748051fa076a168c3de16023f04d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 14:55:28 -0700 Subject: [PATCH 027/142] Compile --- ci/licenses_golden/licenses_flutter | 4 ++++ shell/gpu/gpu_studio_vulkan.cc | 5 ++--- shell/gpu/gpu_studio_vulkan.h | 4 +--- shell/platform/darwin/ios/ios_surface_metal_impeller.mm | 3 ++- shell/platform/darwin/ios/ios_surface_metal_skia.mm | 3 ++- shell/platform/darwin/ios/ios_surface_software.mm | 4 +++- shell/platform/embedder/embedder_studio_vulkan.cc | 2 +- 7 files changed, 15 insertions(+), 10 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index 8460892f4dcfd..67ae72eb5cb98 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -2824,6 +2824,8 @@ ORIGIN: ../../../flutter/shell/platform/fuchsia/flutter/software_surface.cc + .. ORIGIN: ../../../flutter/shell/platform/fuchsia/flutter/software_surface.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/fuchsia/flutter/software_surface_producer.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/fuchsia/flutter/software_surface_producer.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/fuchsia/flutter/studio.cc + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/fuchsia/flutter/studio.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/fuchsia/flutter/surface.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/fuchsia/flutter/surface.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/fuchsia/flutter/surface_producer.h + ../../../flutter/LICENSE @@ -5403,6 +5405,8 @@ FILE: ../../../flutter/shell/platform/fuchsia/flutter/software_surface.cc FILE: ../../../flutter/shell/platform/fuchsia/flutter/software_surface.h FILE: ../../../flutter/shell/platform/fuchsia/flutter/software_surface_producer.cc FILE: ../../../flutter/shell/platform/fuchsia/flutter/software_surface_producer.h +FILE: ../../../flutter/shell/platform/fuchsia/flutter/studio.cc +FILE: ../../../flutter/shell/platform/fuchsia/flutter/studio.h FILE: ../../../flutter/shell/platform/fuchsia/flutter/surface.cc FILE: ../../../flutter/shell/platform/fuchsia/flutter/surface.h FILE: ../../../flutter/shell/platform/fuchsia/flutter/surface_producer.h diff --git a/shell/gpu/gpu_studio_vulkan.cc b/shell/gpu/gpu_studio_vulkan.cc index 7f150e6cb9287..90453b9f4bd22 100644 --- a/shell/gpu/gpu_studio_vulkan.cc +++ b/shell/gpu/gpu_studio_vulkan.cc @@ -13,9 +13,8 @@ namespace flutter { -GPUStudioVulkan::GPUStudioVulkan(GPUSurfaceVulkanDelegate* delegate, - const sk_sp& skia_context) - : delegate_(delegate), skia_context_(skia_context) {} +GPUStudioVulkan::GPUStudioVulkan(const sk_sp& skia_context) + : skia_context_(skia_context) {} GPUStudioVulkan::~GPUStudioVulkan() = default; diff --git a/shell/gpu/gpu_studio_vulkan.h b/shell/gpu/gpu_studio_vulkan.h index 4aef17f558836..294a2572ac247 100644 --- a/shell/gpu/gpu_studio_vulkan.h +++ b/shell/gpu/gpu_studio_vulkan.h @@ -30,8 +30,7 @@ class GPUStudioVulkan : public Studio { /// @brief Create a GPUStudioVulkan while letting it reuse an existing /// GrDirectContext. /// - GPUStudioVulkan(GPUSurfaceVulkanDelegate* delegate, - const sk_sp& context); + GPUStudioVulkan(const sk_sp& context); ~GPUStudioVulkan() override; @@ -44,7 +43,6 @@ class GPUStudioVulkan : public Studio { static SkColorType ColorTypeFromFormat(const VkFormat format); private: - GPUSurfaceVulkanDelegate* delegate_; sk_sp skia_context_; FML_DISALLOW_COPY_AND_ASSIGN(GPUStudioVulkan); diff --git a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm index 8871c5551de08..d2c48a87f2aba 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm @@ -6,6 +6,7 @@ #include "flutter/impeller/renderer/backend/metal/formats_mtl.h" #include "flutter/impeller/renderer/context.h" +#include "flutter/shell/gpu/gpu_studio_metal_impeller.h" #include "flutter/shell/gpu/gpu_surface_metal_impeller.h" namespace { @@ -104,7 +105,7 @@ PixelFormat GetColorAttachmentPixelFormat() const override { } // |IOSSurface| -std::unique_ptr IOSSurfaceMetalImpeller::CreateGPUStudio(GrDirectContext*) override { +std::unique_ptr IOSSurfaceMetalImpeller::CreateGPUStudio(GrDirectContext*) { auto context = std::make_shared( impeller_context_, InferOffscreenLayerPixelFormat(FromMTLPixelFormat(layer_.get().pixelFormat))); diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.mm b/shell/platform/darwin/ios/ios_surface_metal_skia.mm index 47daaf1ee29a6..c561d67a6fc38 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.mm @@ -6,6 +6,7 @@ #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #include "flutter/shell/gpu/gpu_surface_metal_skia.h" +#include "flutter/shell/gpu/gpu_studio_metal_skia.h" #include "flutter/shell/platform/darwin/ios/ios_context_metal_skia.h" namespace flutter { @@ -40,7 +41,7 @@ } // |IOSSurface| -std::unique_ptr IOSSurfaceMetalSkia::CreateGPUStudio(GrDirectContext* gr_context) override { +std::unique_ptr IOSSurfaceMetalSkia::CreateGPUStudio(GrDirectContext* gr_context) { FML_DCHECK(context); return std::make_unique(this, // delegate sk_ref_sp(context), // context diff --git a/shell/platform/darwin/ios/ios_surface_software.mm b/shell/platform/darwin/ios/ios_surface_software.mm index abc197e1ef98f..481f3f331d4e6 100644 --- a/shell/platform/darwin/ios/ios_surface_software.mm +++ b/shell/platform/darwin/ios/ios_surface_software.mm @@ -11,6 +11,8 @@ #include "flutter/fml/logging.h" #include "flutter/fml/platform/darwin/cf_utils.h" #include "flutter/fml/trace_event.h" +#include "flutter/shell/gpu/gpu_surface_software.h" +#include "flutter/shell/gpu/gpu_studio_software.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/utils/mac/SkCGUtils.h" @@ -34,7 +36,7 @@ // Android oddities. } -std::unique_ptr IOSSurfaceSoftware::CreateGPUStudio(GrDirectContext* gr_context) override { +std::unique_ptr IOSSurfaceSoftware::CreateGPUStudio(GrDirectContext* gr_context) { if (!IsValid()) { return nullptr; } diff --git a/shell/platform/embedder/embedder_studio_vulkan.cc b/shell/platform/embedder/embedder_studio_vulkan.cc index a741df7cdab1f..1a03b103a7220 100644 --- a/shell/platform/embedder/embedder_studio_vulkan.cc +++ b/shell/platform/embedder/embedder_studio_vulkan.cc @@ -114,7 +114,7 @@ std::unique_ptr EmbedderStudioVulkan::CreateGPUStudio() { if (!IsValid()) { return nullptr; } - auto studio = std::make_unique(this, main_context_); + auto studio = std::make_unique(main_context_); if (!studio->IsValid()) { return nullptr; From c985269f67236df83f02f8c2eed362092551384d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 14:55:38 -0700 Subject: [PATCH 028/142] Format --- shell/platform/darwin/ios/ios_surface_metal_skia.mm | 2 +- shell/platform/darwin/ios/ios_surface_software.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.mm b/shell/platform/darwin/ios/ios_surface_metal_skia.mm index c561d67a6fc38..16762b4db6b29 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.mm @@ -4,9 +4,9 @@ #import "flutter/shell/platform/darwin/ios/ios_surface_metal_skia.h" +#include "flutter/shell/gpu/gpu_studio_metal_skia.h" #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" #include "flutter/shell/gpu/gpu_surface_metal_skia.h" -#include "flutter/shell/gpu/gpu_studio_metal_skia.h" #include "flutter/shell/platform/darwin/ios/ios_context_metal_skia.h" namespace flutter { diff --git a/shell/platform/darwin/ios/ios_surface_software.mm b/shell/platform/darwin/ios/ios_surface_software.mm index 481f3f331d4e6..a61221248ee76 100644 --- a/shell/platform/darwin/ios/ios_surface_software.mm +++ b/shell/platform/darwin/ios/ios_surface_software.mm @@ -11,8 +11,8 @@ #include "flutter/fml/logging.h" #include "flutter/fml/platform/darwin/cf_utils.h" #include "flutter/fml/trace_event.h" -#include "flutter/shell/gpu/gpu_surface_software.h" #include "flutter/shell/gpu/gpu_studio_software.h" +#include "flutter/shell/gpu/gpu_surface_software.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/utils/mac/SkCGUtils.h" From c2e9f57e6da974880e77ad721ea67491e43be4c6 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 15:16:25 -0700 Subject: [PATCH 029/142] Compile --- shell/gpu/gpu_studio_gl_impeller.cc | 2 +- shell/gpu/gpu_studio_gl_impeller.h | 2 +- shell/platform/darwin/ios/ios_surface_metal_skia.mm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/shell/gpu/gpu_studio_gl_impeller.cc b/shell/gpu/gpu_studio_gl_impeller.cc index 1ffb0e38ed2fb..70dfad1e438f0 100644 --- a/shell/gpu/gpu_studio_gl_impeller.cc +++ b/shell/gpu/gpu_studio_gl_impeller.cc @@ -13,7 +13,7 @@ namespace flutter { GPUStudioGLImpeller::GPUStudioGLImpeller( GPUSurfaceGLDelegate* delegate, - std::shared_ptr context) { + const std::shared_ptr& context) { if (delegate == nullptr) { return; } diff --git a/shell/gpu/gpu_studio_gl_impeller.h b/shell/gpu/gpu_studio_gl_impeller.h index cad5ff185c1a0..9f26e8d022e83 100644 --- a/shell/gpu/gpu_studio_gl_impeller.h +++ b/shell/gpu/gpu_studio_gl_impeller.h @@ -19,7 +19,7 @@ namespace flutter { class GPUStudioGLImpeller final : public Studio { public: explicit GPUStudioGLImpeller(GPUSurfaceGLDelegate* delegate, - std::shared_ptr context); + const std::shared_ptr& context); // |Studio| ~GPUStudioGLImpeller() override; diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.mm b/shell/platform/darwin/ios/ios_surface_metal_skia.mm index 16762b4db6b29..ff2b858e5b91f 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.mm @@ -41,7 +41,7 @@ } // |IOSSurface| -std::unique_ptr IOSSurfaceMetalSkia::CreateGPUStudio(GrDirectContext* gr_context) { +std::unique_ptr IOSSurfaceMetalSkia::CreateGPUStudio(GrDirectContext* context) { FML_DCHECK(context); return std::make_unique(this, // delegate sk_ref_sp(context), // context From dceb2d201732fb0d8f3ba59913dd2f1c359fab8c Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 15:16:46 -0700 Subject: [PATCH 030/142] Format --- shell/gpu/gpu_studio_gl_impeller.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/shell/gpu/gpu_studio_gl_impeller.h b/shell/gpu/gpu_studio_gl_impeller.h index 9f26e8d022e83..9cddf0a29de3c 100644 --- a/shell/gpu/gpu_studio_gl_impeller.h +++ b/shell/gpu/gpu_studio_gl_impeller.h @@ -18,8 +18,9 @@ namespace flutter { class GPUStudioGLImpeller final : public Studio { public: - explicit GPUStudioGLImpeller(GPUSurfaceGLDelegate* delegate, - const std::shared_ptr& context); + explicit GPUStudioGLImpeller( + GPUSurfaceGLDelegate* delegate, + const std::shared_ptr& context); // |Studio| ~GPUStudioGLImpeller() override; From 9f256fac5a061df4aedb51dd338ce734e8b501b5 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 15:30:17 -0700 Subject: [PATCH 031/142] Compile --- shell/platform/darwin/ios/ios_surface_metal_skia.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.mm b/shell/platform/darwin/ios/ios_surface_metal_skia.mm index ff2b858e5b91f..7a64898ff865a 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.mm @@ -43,8 +43,8 @@ // |IOSSurface| std::unique_ptr IOSSurfaceMetalSkia::CreateGPUStudio(GrDirectContext* context) { FML_DCHECK(context); - return std::make_unique(this, // delegate - sk_ref_sp(context), // context + return std::make_unique(this, // delegate + sk_ref_sp(context) // context ); } From 05063a5b505432c147dc77914cf66ea66409d35e Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 16:24:00 -0700 Subject: [PATCH 032/142] Wire up platformview and rasterizer --- shell/common/platform_view.cc | 33 +++++++--- shell/common/platform_view.h | 8 ++- shell/common/rasterizer.cc | 66 ++++++++++--------- shell/common/rasterizer.h | 4 +- shell/common/shell.cc | 16 +++-- .../platform/android/platform_view_android.cc | 9 +++ .../platform/android/platform_view_android.h | 3 + shell/platform/darwin/ios/platform_view_ios.h | 3 + .../platform/darwin/ios/platform_view_ios.mm | 12 ++++ .../embedder/platform_view_embedder.cc | 5 ++ .../embedder/platform_view_embedder.h | 3 + .../platform/fuchsia/flutter/platform_view.cc | 7 ++ .../platform/fuchsia/flutter/platform_view.h | 8 +++ 13 files changed, 127 insertions(+), 50 deletions(-) diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 4e6df69e823d2..b9c73f5323d2b 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -65,27 +65,36 @@ void PlatformView::NotifyDestroyed() { constexpr int64_t kFlutterDefaultViewId = 0; -std::unique_ptr PlatformView::CreateSurface() { +std::pair, std::unique_ptr> +PlatformView::CreateStudioAndSurface() { + std::unique_ptr studio; std::unique_ptr surface; // Threading: We want to use the platform view on the non-platform thread. // Using the weak pointer is illegal. But, we are going to introduce a latch - // so that the platform view is not collected till the surface is obtained. + // so that the platform view is not collected till the studio and the surface + // are obtained. auto* platform_view = this; fml::ManualResetWaitableEvent latch; fml::TaskRunner::RunNowOrPostTask( - task_runners_.GetRasterTaskRunner(), [platform_view, &surface, &latch]() { + task_runners_.GetRasterTaskRunner(), + [platform_view, &studio, &surface, &latch]() { + studio = platform_view->CreateRenderingStudio(); surface = platform_view->CreateRenderingSurface(kFlutterDefaultViewId); - if (surface && !surface->IsValid()) { + if (!studio || !studio->IsValid() || !surface || !surface->IsValid()) { surface.reset(); + studio.reset(); } latch.Signal(); }); latch.Wait(); - if (!surface) { + std::pair, std::unique_ptr> result; + if (!studio || !surface) { FML_LOG(ERROR) << "Failed to create platform view rendering surface"; - return nullptr; + return result; } - return surface; + result.first = std::move(studio); + result.second = std::move(surface); + return result; } void PlatformView::ScheduleFrame() { @@ -140,11 +149,19 @@ void PlatformView::MarkTextureFrameAvailable(int64_t texture_id) { delegate_.OnPlatformViewMarkTextureFrameAvailable(texture_id); } +std::unique_ptr PlatformView::CreateRenderingStudio() { + // We have a default implementation because tests create a platform view but + // never a rendering studio. + FML_DCHECK(false) << "This platform does not provide a rendering studio but " + "it was notified of rendering studio creation."; + return nullptr; +} + std::unique_ptr PlatformView::CreateRenderingSurface(int64_t view_id) { // We have a default implementation because tests create a platform view but // never a rendering surface. FML_DCHECK(false) << "This platform does not provide a rendering surface but " - "it was notified of surface rendering surface creation."; + "it was notified of rendering surface creation."; return nullptr; } diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index cd8c15a838162..77088d57eceb6 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -11,6 +11,7 @@ #include "flutter/common/graphics/texture.h" #include "flutter/common/task_runners.h" #include "flutter/flow/embedded_views.h" +#include "flutter/flow/studio.h" #include "flutter/flow/surface.h" #include "flutter/fml/macros.h" #include "flutter/fml/mapping.h" @@ -493,7 +494,8 @@ class PlatformView { /// virtual void NotifyDestroyed(); - std::unique_ptr CreateSurface(); + std::pair, std::unique_ptr> + CreateStudioAndSurface(); //---------------------------------------------------------------------------- /// @brief Used by embedders to schedule a frame. In response to this @@ -829,7 +831,9 @@ class PlatformView { const Settings& GetSettings() const; protected: - // This is the only method called on the raster task runner. + virtual std::unique_ptr CreateRenderingStudio(); + + // This is called on the raster task runner. virtual std::unique_ptr CreateRenderingSurface(int64_t view_id); PlatformView::Delegate& delegate_; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index d4a43e66b32da..f29f02f25eed5 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -51,7 +51,9 @@ fml::TaskRunnerAffineWeakPtr Rasterizer::GetSnapshotDelegate() return weak_factory_.GetWeakPtr(); } -void Rasterizer::Setup(std::unique_ptr surface) { +void Rasterizer::Setup(std::unique_ptr studio, + std::unique_ptr surface) { + studio_ = std::move(studio); surface_ = std::move(surface); if (max_cache_bytes_.has_value()) { @@ -59,7 +61,7 @@ void Rasterizer::Setup(std::unique_ptr surface) { user_override_resource_cache_bytes_); } - auto context_switch = surface_->MakeRenderContextCurrent(); + auto context_switch = studio_->MakeRenderContextCurrent(); if (context_switch->GetResult()) { compositor_context_->OnGrContextCreated(); } @@ -77,8 +79,8 @@ void Rasterizer::Setup(std::unique_ptr surface) { if (raster_thread_merger_) { raster_thread_merger_->SetMergeUnmergeCallback([=]() { // Clear the GL context after the thread configuration has changed. - if (surface_) { - surface_->ClearRenderContext(); + if (studio_) { + studio_->ClearRenderContext(); } }); } @@ -91,16 +93,17 @@ void Rasterizer::TeardownExternalViewEmbedder() { } void Rasterizer::Teardown() { - if (surface_) { - auto context_switch = surface_->MakeRenderContextCurrent(); + if (studio_) { + auto context_switch = studio_->MakeRenderContextCurrent(); if (context_switch->GetResult()) { compositor_context_->OnGrContextDestroyed(); - if (auto* context = surface_->GetContext()) { + if (auto* context = studio_->GetContext()) { context->purgeUnlockedResources(/*scratchResourcesOnly=*/false); } } - surface_.reset(); + studio_.reset(); } + surface_.reset(); last_layer_tree_.reset(); @@ -125,18 +128,18 @@ void Rasterizer::DisableThreadMergerIfNeeded() { } void Rasterizer::NotifyLowMemoryWarning() const { - if (!surface_) { + if (!studio_) { FML_DLOG(INFO) << "Rasterizer::NotifyLowMemoryWarning called with no surface."; return; } - auto context = surface_->GetContext(); + auto context = studio_->GetContext(); if (!context) { FML_DLOG(INFO) << "Rasterizer::NotifyLowMemoryWarning called with no GrContext."; return; } - auto context_switch = surface_->MakeRenderContextCurrent(); + auto context_switch = studio_->MakeRenderContextCurrent(); if (!context_switch->GetResult()) { return; } @@ -148,7 +151,7 @@ std::shared_ptr Rasterizer::GetTextureRegistry() { } GrDirectContext* Rasterizer::GetGrContext() { - return surface_ ? surface_->GetContext() : nullptr; + return studio_ ? studio_->GetContext() : nullptr; } flutter::LayerTree* Rasterizer::GetLastLayerTree() { @@ -157,7 +160,7 @@ flutter::LayerTree* Rasterizer::GetLastLayerTree() { void Rasterizer::DrawLastLayerTree( std::unique_ptr frame_timings_recorder) { - if (!last_layer_tree_ || !surface_) { + if (!last_layer_tree_ || !studio_) { return; } RasterStatus raster_status = @@ -298,9 +301,9 @@ std::unique_ptr Rasterizer::MakeSkiaGpuImage( result = MakeBitmapImage(display_list, image_info); }) .SetIfFalse([&result, &image_info, &display_list, - surface = surface_.get(), + studio = studio_.get(), gpu_image_behavior = gpu_image_behavior_] { - if (!surface || + if (!studio || gpu_image_behavior == MakeGpuImageBehavior::kBitmap) { // TODO(dnfield): This isn't safe if display_list contains any GPU // resources like an SkImage_gpu. @@ -308,13 +311,13 @@ std::unique_ptr Rasterizer::MakeSkiaGpuImage( return; } - auto context_switch = surface->MakeRenderContextCurrent(); + auto context_switch = studio->MakeRenderContextCurrent(); if (!context_switch->GetResult()) { result = MakeBitmapImage(display_list, image_info); return; } - auto* context = surface->GetContext(); + auto* context = studio->GetContext(); if (!context) { result = MakeBitmapImage(display_list, image_info); return; @@ -505,7 +508,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( FML_DCHECK(!external_view_embedder_->GetUsedThisFrame()); external_view_embedder_->SetUsedThisFrame(true); external_view_embedder_->BeginFrame( - layer_tree.frame_size(), surface_->GetContext(), + layer_tree.frame_size(), studio_->GetContext(), layer_tree.device_pixel_ratio(), raster_thread_merger_); embedder_root_canvas = external_view_embedder_->GetRootCanvas(); } @@ -533,7 +536,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( embedder_root_canvas ? embedder_root_canvas : frame->Canvas(); auto compositor_frame = compositor_context_->AcquireFrame( - surface_->GetContext(), // skia GrContext + studio_->GetContext(), // skia GrContext root_surface_canvas, // root surface canvas external_view_embedder_.get(), // external view embedder root_surface_transformation, // root surface transformation @@ -542,7 +545,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( .supports_readback, // surface supports pixel reads raster_thread_merger_, // thread merger frame->GetDisplayListBuilder().get(), // display list builder - surface_->GetAiksContext() // aiks context + studio_->GetAiksContext() // aiks context ); if (compositor_frame) { compositor_context_->raster_cache().BeginFrame(); @@ -571,7 +574,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( } bool ignore_raster_cache = true; - if (surface_->EnableRasterCache() && + if (studio_->EnableRasterCache() && !layer_tree.is_leaf_layer_tracing_enabled()) { ignore_raster_cache = false; } @@ -605,7 +608,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( if (external_view_embedder_ && (!raster_thread_merger_ || raster_thread_merger_->IsMerged())) { FML_DCHECK(!frame->IsSubmitted()); - external_view_embedder_->SubmitFrame(surface_->GetContext(), + external_view_embedder_->SubmitFrame(studio_->GetContext(), std::move(frame)); } else { frame->Submit(); @@ -621,8 +624,8 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( &compositor_context_->raster_cache()); FireNextFrameCallbackIfPresent(); - if (surface_->GetContext()) { - surface_->GetContext()->performDeferredCleanup(kSkiaCleanupExpiration); + if (studio_->GetContext()) { + studio_->GetContext()->performDeferredCleanup(kSkiaCleanupExpiration); } return raster_status; @@ -689,7 +692,7 @@ sk_sp Rasterizer::ScreenshotLayerTreeAsImage( // render context is GL. frame->Raster() pops the gl context in platforms // that gl context switching are used. (For example, older iOS that uses GL) // We reset the GL context using the context switch. - auto context_switch = surface_->MakeRenderContextCurrent(); + auto context_switch = studio_->MakeRenderContextCurrent(); if (!context_switch->GetResult()) { FML_LOG(ERROR) << "Screenshot: unable to make image screenshot"; return nullptr; @@ -725,8 +728,7 @@ Rasterizer::Screenshot Rasterizer::ScreenshotLastLayerTree( sk_sp data = nullptr; std::string format; - GrDirectContext* surface_context = - surface_ ? surface_->GetContext() : nullptr; + GrDirectContext* surface_context = studio_ ? studio_->GetContext() : nullptr; switch (type) { case ScreenshotType::SkiaPicture: @@ -804,13 +806,13 @@ void Rasterizer::SetResourceCacheMaxBytes(size_t max_bytes, bool from_user) { } max_cache_bytes_ = max_bytes; - if (!surface_) { + if (!studio_) { return; } - GrDirectContext* context = surface_->GetContext(); + GrDirectContext* context = studio_->GetContext(); if (context) { - auto context_switch = surface_->MakeRenderContextCurrent(); + auto context_switch = studio_->MakeRenderContextCurrent(); if (!context_switch->GetResult()) { return; } @@ -820,10 +822,10 @@ void Rasterizer::SetResourceCacheMaxBytes(size_t max_bytes, bool from_user) { } std::optional Rasterizer::GetResourceCacheMaxBytes() const { - if (!surface_) { + if (!studio_) { return std::nullopt; } - GrDirectContext* context = surface_->GetContext(); + GrDirectContext* context = studio_->GetContext(); if (context) { return context->getResourceCacheLimit(); } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index c529ea987dcd5..7092c8523dd9b 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -15,6 +15,7 @@ #include "flutter/flow/embedded_views.h" #include "flutter/flow/frame_timings.h" #include "flutter/flow/layers/layer_tree.h" +#include "flutter/flow/studio.h" #include "flutter/flow/surface.h" #include "flutter/fml/closure.h" #include "flutter/fml/memory/weak_ptr.h" @@ -152,7 +153,7 @@ class Rasterizer final : public SnapshotDelegate, /// /// @param[in] surface The on-screen render surface. /// - void Setup(std::unique_ptr surface); + void Setup(std::unique_ptr studio, std::unique_ptr surface); //---------------------------------------------------------------------------- /// @brief Releases the previously set up on-screen render surface and @@ -541,6 +542,7 @@ class Rasterizer final : public SnapshotDelegate, Delegate& delegate_; MakeGpuImageBehavior gpu_image_behavior_; + std::unique_ptr studio_; std::unique_ptr surface_; std::unique_ptr snapshot_surface_producer_; std::unique_ptr compositor_context_; diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 01c8d123d6c9f..f92c8c2091f34 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -750,8 +750,10 @@ void Shell::OnPlatformViewCreated() { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); - std::unique_ptr surface = platform_view_->CreateSurface(); - if (surface == nullptr) { + auto studio_and_surface = platform_view_->CreateStudioAndSurface(); + std::unique_ptr studio = std::move(studio_and_surface.first); + std::unique_ptr surface = std::move(studio_and_surface.second); + if (studio == nullptr || surface == nullptr) { // TODO(dkwingsmt): This case is observed in windows unit tests. Anyway, // we're probably not creating the surface in this callback eventually. return; @@ -782,15 +784,15 @@ void Shell::OnPlatformViewCreated() { !task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread(); fml::AutoResetWaitableEvent latch; - auto raster_task = - fml::MakeCopyable([&waiting_for_first_frame = waiting_for_first_frame_, - rasterizer = rasterizer_->GetWeakPtr(), // - surface = std::move(surface)]() mutable { + auto raster_task = fml::MakeCopyable( + [&waiting_for_first_frame = waiting_for_first_frame_, + rasterizer = rasterizer_->GetWeakPtr(), // + studio = std::move(studio), surface = std::move(surface)]() mutable { if (rasterizer) { // Enables the thread merger which may be used by the external view // embedder. rasterizer->EnableThreadMergerIfNeeded(); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); } waiting_for_first_frame.store(true); diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index 4ba82e801df6d..f0f7a745bb2bf 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -280,6 +280,15 @@ std::unique_ptr PlatformViewAndroid::CreateVSyncWaiter() { return std::make_unique(task_runners_); } +// |PlatformView| +std::unique_ptr PlatformViewAndroid::CreateRenderingStudio() { + if (!android_surface_) { + return nullptr; + } + return android_surface_->CreateGPUStudio( + android_context_->GetMainSkiaContext().get()); +} + // |PlatformView| std::unique_ptr PlatformViewAndroid::CreateRenderingSurface( int64_t view_id) { diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index 1bcd8a6482631..20962ab5fa897 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -142,6 +142,9 @@ class PlatformViewAndroid final : public PlatformView { // |PlatformView| std::unique_ptr CreateVSyncWaiter() override; + // |PlatformView| + std::unique_ptr CreateRenderingStudio() override; + // |PlatformView| std::unique_ptr CreateRenderingSurface(int64_t view_id) override; diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index ba036bd6aa341..c9c0d4f3cfa2b 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -148,6 +148,9 @@ class PlatformViewIOS final : public PlatformView { // |PlatformView| void HandlePlatformMessage(std::unique_ptr message) override; + // |PlatformView| + std::unique_ptr CreateRenderingStudio() override; + // |PlatformView| std::unique_ptr CreateRenderingSurface(int64_t view_id) override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index 851e5ecdbad00..7b13a27c5b04d 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -137,6 +137,18 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} texture_id, fml::scoped_nsobject>{[texture retain]})); } +// |PlatformView| +std::unique_ptr PlatformViewIOS::CreateRenderingStudio() { + FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); + std::lock_guard guard(ios_surface_mutex_); + if (!ios_surface_) { + FML_DLOG(INFO) << "Could not CreateRenderingSurface, this PlatformViewIOS " + "has no ViewController."; + return nullptr; + } + return ios_surface_->CreateGPUStudio(ios_context_->GetMainContext().get()); +} + // |PlatformView| std::unique_ptr PlatformViewIOS::CreateRenderingSurface(int64_t view_id) { FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); diff --git a/shell/platform/embedder/platform_view_embedder.cc b/shell/platform/embedder/platform_view_embedder.cc index 09ae49db8210b..5714af00d8430 100644 --- a/shell/platform/embedder/platform_view_embedder.cc +++ b/shell/platform/embedder/platform_view_embedder.cc @@ -87,6 +87,11 @@ void PlatformViewEmbedder::HandlePlatformMessage( std::move(message)); } +// |PlatformView| +std::unique_ptr PlatformViewEmbedder::CreateRenderingStudio() { + return embedder_studio_->CreateGPUStudio(); +} + // |PlatformView| std::unique_ptr PlatformViewEmbedder::CreateRenderingSurface( int64_t view_id) { diff --git a/shell/platform/embedder/platform_view_embedder.h b/shell/platform/embedder/platform_view_embedder.h index 3e30a33101b5b..b0e723dece794 100644 --- a/shell/platform/embedder/platform_view_embedder.h +++ b/shell/platform/embedder/platform_view_embedder.h @@ -83,6 +83,9 @@ class PlatformViewEmbedder final : public PlatformView { std::shared_ptr platform_message_handler_; PlatformDispatchTable platform_dispatch_table_; + // |PlatformView| + std::unique_ptr CreateRenderingStudio() override; + // |PlatformView| std::unique_ptr CreateRenderingSurface(int64_t view_id) override; diff --git a/shell/platform/fuchsia/flutter/platform_view.cc b/shell/platform/fuchsia/flutter/platform_view.cc index e0238148c3029..51447ff5daaca 100644 --- a/shell/platform/fuchsia/flutter/platform_view.cc +++ b/shell/platform/fuchsia/flutter/platform_view.cc @@ -50,6 +50,7 @@ PlatformView::PlatformView( fuchsia::ui::pointerinjector::RegistryHandle pointerinjector_registry, OnEnableWireframe wireframe_enabled_callback, OnUpdateView on_update_view_callback, + OnCreateStudio on_create_studio_callback, OnCreateSurface on_create_surface_callback, OnSemanticsNodeUpdate on_semantics_node_update_callback, OnRequestAnnounce on_request_announce_callback, @@ -67,6 +68,7 @@ PlatformView::PlatformView( std::move(mouse_source))), wireframe_enabled_callback_(std::move(wireframe_enabled_callback)), on_update_view_callback_(std::move(on_update_view_callback)), + on_create_studio_callback_(std::move(on_create_studio_callback)), on_create_surface_callback_(std::move(on_create_surface_callback)), on_semantics_node_update_callback_( std::move(on_semantics_node_update_callback)), @@ -314,6 +316,11 @@ std::unique_ptr PlatformView::CreateVSyncWaiter() { task_runners_); } +// |flutter::PlatformView| +std::unique_ptr PlatformView::CreateRenderingStudio() { + return on_create_studio_callback_ ? on_create_studio_callback_() : nullptr; +} + // |flutter::PlatformView| std::unique_ptr PlatformView::CreateRenderingSurface( int64_t view_id) { diff --git a/shell/platform/fuchsia/flutter/platform_view.h b/shell/platform/fuchsia/flutter/platform_view.h index 5ae674f8d8fee..f9357dfd971bb 100644 --- a/shell/platform/fuchsia/flutter/platform_view.h +++ b/shell/platform/fuchsia/flutter/platform_view.h @@ -34,6 +34,8 @@ #include "focus_delegate.h" #include "pointer_delegate.h" #include "pointer_injector_delegate.h" +#include "studio.h" +#include "surface.h" #include "text_delegate.h" namespace flutter_runner { @@ -41,6 +43,7 @@ namespace flutter_runner { using OnEnableWireframe = fit::function; using ViewCallback = std::function; using OnUpdateView = fit::function; +using OnCreateStudio = fit::function()>; using OnCreateSurface = fit::function()>; using OnSemanticsNodeUpdate = fit::function; @@ -78,6 +81,7 @@ class PlatformView : public flutter::PlatformView { fuchsia::ui::pointerinjector::RegistryHandle pointerinjector_registry, OnEnableWireframe wireframe_enabled_callback, OnUpdateView on_update_view_callback, + OnCreateStudio on_create_studio_callback, OnCreateSurface on_create_surface_callback, OnSemanticsNodeUpdate on_semantics_node_update_callback, OnRequestAnnounce on_request_announce_callback, @@ -105,6 +109,9 @@ class PlatformView : public flutter::PlatformView { // |flutter::PlatformView| std::unique_ptr CreateVSyncWaiter() override; + // |flutter::PlatformView| + std::unique_ptr CreateRenderingStudio() override; + // |flutter::PlatformView| std::unique_ptr CreateRenderingSurface( int64_t view_id) override; @@ -179,6 +186,7 @@ class PlatformView : public flutter::PlatformView { OnEnableWireframe wireframe_enabled_callback_; OnUpdateView on_update_view_callback_; + OnCreateStudio on_create_studio_callback_; OnCreateSurface on_create_surface_callback_; OnSemanticsNodeUpdate on_semantics_node_update_callback_; OnRequestAnnounce on_request_announce_callback_; From 37e119c4ab904f978e218cb914916e3ffb4ad8b5 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 16:39:36 -0700 Subject: [PATCH 033/142] Fix compile --- shell/common/rasterizer_unittests.cc | 57 +++++++++++++------ .../fuchsia/flutter/flatland_platform_view.cc | 2 + .../fuchsia/flutter/gfx_platform_view.cc | 2 + .../fuchsia/flutter/gfx_platform_view.h | 1 + 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index a9ebaff8f2f0c..a80c83264714b 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -40,6 +40,15 @@ class MockDelegate : public Rasterizer::Delegate { MOCK_CONST_METHOD0(GetSettings, const Settings&()); }; +class MockStudio : public Studio { + public: + MOCK_METHOD0(IsValid, bool()); + MOCK_METHOD0(GetContext, GrDirectContext*()); + // MOCK_METHOD0(MakeRenderContextCurrent, std::unique_ptr()); + // MOCK_METHOD0(ClearRenderContext, bool()); + // MOCK_CONST_METHOD0(AllowsDrawingWhenGpuDisabled, bool()); +}; + class MockSurface : public Surface { public: MOCK_METHOD0(IsValid, bool()); @@ -116,10 +125,11 @@ TEST(RasterizerTest, drawEmptyPipeline) { ON_CALL(delegate, GetSettings()).WillByDefault(ReturnRef(settings)); ON_CALL(delegate, GetTaskRunners()).WillByDefault(ReturnRef(task_runners)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -147,6 +157,7 @@ TEST(RasterizerTest, .WillRepeatedly(ReturnRef(task_runners)); EXPECT_CALL(delegate, OnFrameRasterized(_)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); std::shared_ptr> external_view_embedder = @@ -180,7 +191,7 @@ TEST(RasterizerTest, nullptr))) .Times(1); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -217,6 +228,7 @@ TEST( .WillRepeatedly(ReturnRef(task_runners)); EXPECT_CALL(delegate, OnFrameRasterized(_)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); std::shared_ptr> external_view_embedder = std::make_shared>(); @@ -245,7 +257,7 @@ TEST( /*raster_thread_merger=*/_)) .Times(1); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -286,6 +298,7 @@ TEST( EXPECT_CALL(delegate, OnFrameRasterized(_)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); std::shared_ptr> external_view_embedder = @@ -317,7 +330,7 @@ TEST( /*raster_thread_merger=*/_)) .Times(1); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), @@ -353,6 +366,7 @@ TEST(RasterizerTest, EXPECT_CALL(delegate, OnFrameRasterized(_)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); std::shared_ptr> external_view_embedder = @@ -391,7 +405,7 @@ TEST(RasterizerTest, /*raster_thread_merger=*/_)) .Times(2); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), @@ -474,6 +488,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { .WillRepeatedly(ReturnRef(task_runners)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); @@ -481,7 +496,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { std::shared_ptr> external_view_embedder = std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, @@ -531,6 +546,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { .WillRepeatedly(ReturnRef(task_runners)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); @@ -538,7 +554,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { std::shared_ptr> external_view_embedder = std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); EXPECT_CALL( *external_view_embedder, @@ -577,6 +593,7 @@ TEST(RasterizerTest, EXPECT_CALL(delegate, OnFrameRasterized(_)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); auto is_gpu_disabled_sync_switch = std::make_shared(false); @@ -596,7 +613,7 @@ TEST(RasterizerTest, EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -633,6 +650,7 @@ TEST( .WillRepeatedly(ReturnRef(task_runners)); EXPECT_CALL(delegate, OnFrameRasterized(_)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); auto is_gpu_disabled_sync_switch = std::make_shared(true); @@ -653,7 +671,7 @@ TEST( EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -691,6 +709,7 @@ TEST( .WillRepeatedly(ReturnRef(task_runners)); EXPECT_CALL(delegate, OnFrameRasterized(_)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); auto is_gpu_disabled_sync_switch = std::make_shared(false); @@ -710,7 +729,7 @@ TEST( EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -748,6 +767,7 @@ TEST( .WillRepeatedly(ReturnRef(task_runners)); EXPECT_CALL(delegate, OnFrameRasterized(_)).Times(0); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); auto is_gpu_disabled_sync_switch = std::make_shared(true); @@ -766,7 +786,7 @@ TEST( EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -811,6 +831,7 @@ TEST( }); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); auto is_gpu_disabled_sync_switch = std::make_shared(false); @@ -821,7 +842,7 @@ TEST( EXPECT_CALL(*surface, AcquireFrame(SkISize())); EXPECT_CALL(*surface, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -864,6 +885,7 @@ TEST(RasterizerTest, }); latch.Wait(); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()) .WillRepeatedly(Return(true)); @@ -900,7 +922,7 @@ TEST(RasterizerTest, }); thread_host.raster_thread->GetTaskRunner()->PostTask([&] { - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = @@ -944,6 +966,7 @@ TEST(RasterizerTest, TeardownFreesResourceCache) { .WillRepeatedly(ReturnRef(task_runners)); auto rasterizer = std::make_unique(delegate); + auto studio = std::make_unique>(); auto surface = std::make_unique>(); auto context = GrDirectContext::MakeMock(nullptr); context->setResourceCacheLimit(0); @@ -954,7 +977,7 @@ TEST(RasterizerTest, TeardownFreesResourceCache) { }); EXPECT_CALL(*surface, GetContext()).WillRepeatedly(Return(context.get())); - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); EXPECT_EQ(context->getResourceCacheLimit(), 0ul); rasterizer->SetResourceCacheMaxBytes(10000000, false); @@ -1045,6 +1068,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { int frames_submitted = 0; fml::CountDownLatch submit_latch(2); + auto studio = std::make_unique>(); auto surface = std::make_unique(); ON_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(true)); ON_CALL(*surface, AcquireFrame(SkISize())) @@ -1071,7 +1095,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { [] { return std::make_unique(true); })); thread_host.raster_thread->GetTaskRunner()->PostTask([&] { - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = @@ -1128,6 +1152,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { const auto first_timestamp = fml::TimePoint::Now() - millis_16; fml::CountDownLatch submit_latch(1); + auto studio = std::make_unique>(); auto surface = std::make_unique(); ON_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(true)); ON_CALL(*surface, AcquireFrame(SkISize())) @@ -1152,7 +1177,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { [] { return std::make_unique(true); })); thread_host.raster_thread->GetTaskRunner()->PostTask([&] { - rasterizer->Setup(std::move(surface)); + rasterizer->Setup(std::move(studio), std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); diff --git a/shell/platform/fuchsia/flutter/flatland_platform_view.cc b/shell/platform/fuchsia/flutter/flatland_platform_view.cc index 0922661723f71..0555c597438e2 100644 --- a/shell/platform/fuchsia/flutter/flatland_platform_view.cc +++ b/shell/platform/fuchsia/flutter/flatland_platform_view.cc @@ -26,6 +26,7 @@ FlatlandPlatformView::FlatlandPlatformView( OnCreateFlatlandView on_create_view_callback, OnUpdateView on_update_view_callback, OnDestroyFlatlandView on_destroy_view_callback, + OnCreateStudio on_create_studio_callback, OnCreateSurface on_create_surface_callback, OnSemanticsNodeUpdate on_semantics_node_update_callback, OnRequestAnnounce on_request_announce_callback, @@ -47,6 +48,7 @@ FlatlandPlatformView::FlatlandPlatformView( std::move(pointerinjector_registry), std::move(wireframe_enabled_callback), std::move(on_update_view_callback), + std::move(on_create_studio_callback), std::move(on_create_surface_callback), std::move(on_semantics_node_update_callback), std::move(on_request_announce_callback), diff --git a/shell/platform/fuchsia/flutter/gfx_platform_view.cc b/shell/platform/fuchsia/flutter/gfx_platform_view.cc index ed9eeece151a0..1dcb2c2e8c534 100644 --- a/shell/platform/fuchsia/flutter/gfx_platform_view.cc +++ b/shell/platform/fuchsia/flutter/gfx_platform_view.cc @@ -27,6 +27,7 @@ GfxPlatformView::GfxPlatformView( OnCreateGfxView on_create_view_callback, OnUpdateView on_update_view_callback, OnDestroyGfxView on_destroy_view_callback, + OnCreateStudio on_create_studio_callback, OnCreateSurface on_create_surface_callback, OnSemanticsNodeUpdate on_semantics_node_update_callback, OnRequestAnnounce on_request_announce_callback, @@ -48,6 +49,7 @@ GfxPlatformView::GfxPlatformView( std::move(pointerinjector_registry), std::move(wireframe_enabled_callback), std::move(on_update_view_callback), + std::move(on_create_studio_callback), std::move(on_create_surface_callback), std::move(on_semantics_node_update_callback), std::move(on_request_announce_callback), diff --git a/shell/platform/fuchsia/flutter/gfx_platform_view.h b/shell/platform/fuchsia/flutter/gfx_platform_view.h index 1004a85808c56..577620021311f 100644 --- a/shell/platform/fuchsia/flutter/gfx_platform_view.h +++ b/shell/platform/fuchsia/flutter/gfx_platform_view.h @@ -44,6 +44,7 @@ class GfxPlatformView final : public flutter_runner::PlatformView, OnCreateGfxView on_create_view_callback, OnUpdateView on_update_view_callback, OnDestroyGfxView on_destroy_view_callback, + OnCreateStudio on_create_studio_callback, OnCreateSurface on_create_surface_callback, OnSemanticsNodeUpdate on_semantics_node_update_callback, OnRequestAnnounce on_request_announce_callback, From a099aab69ee9e38eeb00e7c77d8a57ebba4539a4 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 22:56:49 -0700 Subject: [PATCH 034/142] Mock more --- shell/common/rasterizer_unittests.cc | 52 +++---- shell/common/shell_test_platform_view_gl.cc | 14 +- shell/common/shell_test_platform_view_gl.h | 5 + shell/common/shell_test_platform_view_metal.h | 3 + .../common/shell_test_platform_view_metal.mm | 6 + .../common/shell_test_platform_view_vulkan.cc | 134 +++++++++--------- .../common/shell_test_platform_view_vulkan.h | 14 +- shell/common/shell_unittests.cc | 59 ++++++-- .../embedder/platform_view_embedder.h | 13 -- 9 files changed, 180 insertions(+), 120 deletions(-) diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index a80c83264714b..ae82d13127ce9 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -44,9 +44,9 @@ class MockStudio : public Studio { public: MOCK_METHOD0(IsValid, bool()); MOCK_METHOD0(GetContext, GrDirectContext*()); - // MOCK_METHOD0(MakeRenderContextCurrent, std::unique_ptr()); - // MOCK_METHOD0(ClearRenderContext, bool()); - // MOCK_CONST_METHOD0(AllowsDrawingWhenGpuDisabled, bool()); + MOCK_METHOD0(MakeRenderContextCurrent, std::unique_ptr()); + MOCK_METHOD0(ClearRenderContext, bool()); + MOCK_CONST_METHOD0(AllowsDrawingWhenGpuDisabled, bool()); }; class MockSurface : public Surface { @@ -127,7 +127,7 @@ TEST(RasterizerTest, drawEmptyPipeline) { auto rasterizer = std::make_unique(delegate); auto studio = std::make_unique>(); auto surface = std::make_unique>(); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), std::move(surface)); fml::AutoResetWaitableEvent latch; @@ -171,10 +171,10 @@ TEST(RasterizerTest, /*surface=*/nullptr, framebuffer_info, /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); + EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); EXPECT_CALL(*surface, AcquireFrame(SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); EXPECT_CALL(*external_view_embedder, @@ -241,10 +241,10 @@ TEST( /*surface=*/nullptr, framebuffer_info, /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); + EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); EXPECT_CALL(*surface, AcquireFrame(SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); EXPECT_CALL(*external_view_embedder, @@ -312,10 +312,10 @@ TEST( /*surface=*/nullptr, framebuffer_info, /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); + EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); EXPECT_CALL(*surface, AcquireFrame(SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging) .WillRepeatedly(Return(true)); @@ -384,13 +384,13 @@ TEST(RasterizerTest, /*surface=*/nullptr, framebuffer_info, /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()) + EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()) .WillRepeatedly(Return(true)); // Prepare two frames for Draw() and DrawLastLayerTree(). EXPECT_CALL(*surface, AcquireFrame(SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame1)))) .WillOnce(Return(ByMove(std::move(surface_frame2)))); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging) .WillRepeatedly(Return(true)); @@ -490,7 +490,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { auto rasterizer = std::make_unique(delegate); auto studio = std::make_unique>(); auto surface = std::make_unique>(); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); std::shared_ptr> external_view_embedder = @@ -548,7 +548,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { auto rasterizer = std::make_unique(delegate); auto studio = std::make_unique>(); auto surface = std::make_unique>(); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); std::shared_ptr> external_view_embedder = @@ -604,13 +604,13 @@ TEST(RasterizerTest, /*surface=*/nullptr, /*framebuffer_info=*/framebuffer_info, /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); + EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); ON_CALL(delegate, GetIsGpuDisabledSyncSwitch()) .WillByDefault(Return(is_gpu_disabled_sync_switch)); EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()).Times(0); EXPECT_CALL(*surface, AcquireFrame(SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), std::move(surface)); @@ -662,13 +662,13 @@ TEST( /*surface=*/nullptr, /*framebuffer_info=*/framebuffer_info, /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); + EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); ON_CALL(delegate, GetIsGpuDisabledSyncSwitch()) .WillByDefault(Return(is_gpu_disabled_sync_switch)); EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()).Times(0); EXPECT_CALL(*surface, AcquireFrame(SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), std::move(surface)); @@ -721,12 +721,12 @@ TEST( /*surface=*/nullptr, /*framebuffer_info=*/framebuffer_info, /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(false)); + EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(false)); EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()) .WillOnce(Return(is_gpu_disabled_sync_switch)); EXPECT_CALL(*surface, AcquireFrame(SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), std::move(surface)); @@ -779,11 +779,11 @@ TEST( /*surface=*/nullptr, /*framebuffer_info=*/framebuffer_info, /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(false)); + EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(false)); EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()) .WillOnce(Return(is_gpu_disabled_sync_switch)); EXPECT_CALL(*surface, AcquireFrame(SkISize())).Times(0); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), std::move(surface)); @@ -840,7 +840,7 @@ TEST( ON_CALL(*surface, AcquireFrame(SkISize())) .WillByDefault(::testing::Invoke([] { return nullptr; })); EXPECT_CALL(*surface, AcquireFrame(SkISize())); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), std::move(surface)); fml::AutoResetWaitableEvent latch; @@ -887,7 +887,7 @@ TEST(RasterizerTest, auto studio = std::make_unique>(); auto surface = std::make_unique>(); - EXPECT_CALL(*surface, AllowsDrawingWhenGpuDisabled()) + EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()) .WillRepeatedly(Return(true)); ON_CALL(*surface, AcquireFrame(SkISize())) .WillByDefault(::testing::Invoke([] { @@ -971,11 +971,11 @@ TEST(RasterizerTest, TeardownFreesResourceCache) { auto context = GrDirectContext::MakeMock(nullptr); context->setResourceCacheLimit(0); - EXPECT_CALL(*surface, MakeRenderContextCurrent()) + EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillRepeatedly([]() -> std::unique_ptr { return std::make_unique(true); }); - EXPECT_CALL(*surface, GetContext()).WillRepeatedly(Return(context.get())); + EXPECT_CALL(*studio, GetContext()).WillRepeatedly(Return(context.get())); rasterizer->Setup(std::move(studio), std::move(surface)); EXPECT_EQ(context->getResourceCacheLimit(), 0ul); diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index 170b285604c5b..1ed6e9e47ffba 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -36,11 +36,23 @@ void ShellTestPlatformViewGL::SimulateVSync() { vsync_clock_->SimulateVSync(); } +// |PlatformView| +std::unique_ptr ShellTestPlatformViewGL::CreateRenderingStudio() { + if (main_context_ == nullptr) { + main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); + } + return std::make_unique( + main_context_, this); +} + // |PlatformView| std::unique_ptr ShellTestPlatformViewGL::CreateRenderingSurface( int64_t view_id) { + if (main_context_ == nullptr) { + main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); + } return std::make_unique( - GPUSurfaceGLSkia::MakeGLContext(this), this, true); + main_context_, this, true); } // |PlatformView| diff --git a/shell/common/shell_test_platform_view_gl.h b/shell/common/shell_test_platform_view_gl.h index e403e380a5d24..eb2c1b4ef55ec 100644 --- a/shell/common/shell_test_platform_view_gl.h +++ b/shell/common/shell_test_platform_view_gl.h @@ -39,9 +39,14 @@ class ShellTestPlatformViewGL : public ShellTestPlatformView, std::shared_ptr shell_test_external_view_embedder_; + sk_sp main_context_; + // |PlatformView| std::unique_ptr CreateRenderingSurface(int64_t view_id) override; + // |PlatformView| + std::unique_ptr CreateRenderingStudio() override; + // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; diff --git a/shell/common/shell_test_platform_view_metal.h b/shell/common/shell_test_platform_view_metal.h index 84f8e07f92240..2372663f2d009 100644 --- a/shell/common/shell_test_platform_view_metal.h +++ b/shell/common/shell_test_platform_view_metal.h @@ -46,6 +46,9 @@ class ShellTestPlatformViewMetal final : public ShellTestPlatformView, // |PlatformView| PointerDataDispatcherMaker GetDispatcherMaker() override; + // |PlatformView| + std::unique_ptr CreateRenderingStudio() override; + // |PlatformView| std::unique_ptr CreateRenderingSurface(int64_t view_id) override; diff --git a/shell/common/shell_test_platform_view_metal.mm b/shell/common/shell_test_platform_view_metal.mm index 77c54ce4e4c2f..51c74c65a950f 100644 --- a/shell/common/shell_test_platform_view_metal.mm +++ b/shell/common/shell_test_platform_view_metal.mm @@ -10,6 +10,7 @@ #include "flutter/fml/platform/darwin/scoped_nsobject.h" #include "flutter/shell/gpu/gpu_surface_metal_skia.h" +#include "flutter/shell/gpu/gpu_studio_metal_skia.h" #include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h" namespace flutter { @@ -91,6 +92,11 @@ GPUMTLTextureInfo offscreen_texture_info() const { }; } +// |PlatformView| +std::unique_ptr ShellTestPlatformViewMetal::CreateRenderingStudio() { + return std::make_unique(this, [metal_context_->context() mainContext]); +} + // |PlatformView| std::unique_ptr ShellTestPlatformViewMetal::CreateRenderingSurface(int64_t view_id) { return std::make_unique(this, [metal_context_->context() mainContext], diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index ce40fcb496c1f..94b05920547bb 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -39,7 +39,12 @@ ShellTestPlatformViewVulkan::ShellTestPlatformViewVulkan( vsync_clock_(std::move(vsync_clock)), proc_table_(fml::MakeRefCounted(VULKAN_SO_PATH)), shell_test_external_view_embedder_( - std::move(shell_test_external_view_embedder)) {} + std::move(shell_test_external_view_embedder)) { + // Create the Skia GrContext. + if (!CreateSkiaGrContext()) { + FML_DLOG(ERROR) << "Could not create Skia context."; + } +} ShellTestPlatformViewVulkan::~ShellTestPlatformViewVulkan() = default; @@ -51,11 +56,17 @@ void ShellTestPlatformViewVulkan::SimulateVSync() { vsync_clock_->SimulateVSync(); } +// |PlatformView| +std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingStudio() { + return std::make_unique(context_, this); +} + // |PlatformView| std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface( int64_t view_id) { return std::make_unique(proc_table_, - shell_test_external_view_embedder_); + shell_test_external_view_embedder_, + context_); } // |PlatformView| @@ -71,66 +82,7 @@ PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() { }; } -// TODO(gw280): This code was forked from vulkan_window.cc specifically for -// shell_test. -// We need to merge this functionality back into //vulkan. -// https://github.com/flutter/flutter/issues/51132 -ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( - fml::RefPtr vk, - std::shared_ptr - shell_test_external_view_embedder) - : valid_(false), - vk_(std::move(vk)), - shell_test_external_view_embedder_( - std::move(shell_test_external_view_embedder)) { - if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { - FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; - return; - } - - // Create the application instance. - std::vector extensions = { - VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, - }; - - application_ = std::make_unique( - *vk_, "FlutterTest", std::move(extensions), VK_MAKE_VERSION(1, 0, 0), - VK_MAKE_VERSION(1, 1, 0), true); - - if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) { - // Make certain the application instance was created and it set up the - // instance proc table entries. - FML_DLOG(ERROR) << "Instance proc addresses have not been set up."; - return; - } - - // Create the device. - - logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); - - if (logical_device_ == nullptr || !logical_device_->IsValid() || - !vk_->AreDeviceProcsSetup()) { - // Make certain the device was created and it set up the device proc table - // entries. - FML_DLOG(ERROR) << "Device proc addresses have not been set up."; - return; - } - - memory_allocator_ = FlutterSkiaVulkanMemoryAllocator::Make( - application_->GetAPIVersion(), application_->GetInstance(), - logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(), - vk_, true); - - // Create the Skia GrContext. - if (!CreateSkiaGrContext()) { - FML_DLOG(ERROR) << "Could not create Skia context."; - return; - } - - valid_ = true; -} - -bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaGrContext() { +bool ShellTestPlatformViewVulkan::CreateSkiaGrContext() { GrVkBackendContext backend_context; if (!CreateSkiaBackendContext(&backend_context)) { @@ -156,9 +108,9 @@ bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaGrContext() { return true; } -bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaBackendContext( +bool ShellTestPlatformViewVulkan::CreateSkiaBackendContext( GrVkBackendContext* context) { - auto getProc = CreateSkiaGetProc(vk_); + auto getProc = CreateSkiaGetProc(proc_table_); if (getProc == nullptr) { FML_DLOG(ERROR) << "GetProcAddress is null"; @@ -186,6 +138,60 @@ bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaBackendContext( return true; } +// TODO(gw280): This code was forked from vulkan_window.cc specifically for +// shell_test. +// We need to merge this functionality back into //vulkan. +// https://github.com/flutter/flutter/issues/51132 +ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( + fml::RefPtr vk, + std::shared_ptr + shell_test_external_view_embedder) + : valid_(false), + vk_(std::move(vk)), + shell_test_external_view_embedder_( + std::move(shell_test_external_view_embedder)), + context_(context) { + if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { + FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; + return; + } + + // Create the application instance. + std::vector extensions = { + VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, + }; + + application_ = std::make_unique( + *vk_, "FlutterTest", std::move(extensions), VK_MAKE_VERSION(1, 0, 0), + VK_MAKE_VERSION(1, 1, 0), true); + + if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) { + // Make certain the application instance was created and it set up the + // instance proc table entries. + FML_DLOG(ERROR) << "Instance proc addresses have not been set up."; + return; + } + + // Create the device. + + logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); + + if (logical_device_ == nullptr || !logical_device_->IsValid() || + !vk_->AreDeviceProcsSetup()) { + // Make certain the device was created and it set up the device proc table + // entries. + FML_DLOG(ERROR) << "Device proc addresses have not been set up."; + return; + } + + memory_allocator_ = FlutterSkiaVulkanMemoryAllocator::Make( + application_->GetAPIVersion(), application_->GetInstance(), + logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(), + vk_, true); + + valid_ = true; +} + ShellTestPlatformViewVulkan::OffScreenSurface::~OffScreenSurface() {} bool ShellTestPlatformViewVulkan::OffScreenSurface::IsValid() { diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 323112ceba3ad..bd5b2db9a476d 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -33,7 +33,8 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { public: OffScreenSurface(fml::RefPtr vk, std::shared_ptr - shell_test_external_view_embedder); + shell_test_external_view_embedder, + sk_sp context); ~OffScreenSurface() override; @@ -58,9 +59,6 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { sk_sp memory_allocator_; sk_sp context_; - bool CreateSkiaGrContext(); - bool CreateSkiaBackendContext(GrVkBackendContext* context); - FML_DISALLOW_COPY_AND_ASSIGN(OffScreenSurface); }; @@ -73,6 +71,11 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { std::shared_ptr shell_test_external_view_embedder_; + sk_sp context_; + + // |PlatformView| + std::unique_ptr CreateRenderingStudio() override; + // |PlatformView| std::unique_ptr CreateRenderingSurface(int64_t view_id) override; @@ -85,6 +88,9 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { // |PlatformView| PointerDataDispatcherMaker GetDispatcherMaker() override; + bool CreateSkiaGrContext(); + bool CreateSkiaBackendContext(GrVkBackendContext* context); + FML_DISALLOW_COPY_AND_ASSIGN(ShellTestPlatformViewVulkan); }; diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 3978336f07be9..4ec827a985711 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -117,15 +117,10 @@ class MockPlatformViewDelegate : public PlatformView::Delegate { AssetResolver::AssetResolverType type)); }; -class MockSurface : public Surface { +class MockStudio : public Studio { public: MOCK_METHOD0(IsValid, bool()); - MOCK_METHOD1(AcquireFrame, - std::unique_ptr(const SkISize& size)); - - MOCK_CONST_METHOD0(GetRootTransformation, SkMatrix()); - MOCK_METHOD0(GetContext, GrDirectContext*()); MOCK_METHOD0(MakeRenderContextCurrent, std::unique_ptr()); @@ -133,11 +128,24 @@ class MockSurface : public Surface { MOCK_METHOD0(ClearRenderContext, bool()); }; +class MockSurface : public Surface { + public: + MOCK_METHOD0(IsValid, bool()); + + MOCK_METHOD0(GetContext, GrDirectContext*()); + + MOCK_METHOD1(AcquireFrame, + std::unique_ptr(const SkISize& size)); + + MOCK_CONST_METHOD0(GetRootTransformation, SkMatrix()); +}; + class MockPlatformView : public PlatformView { public: MockPlatformView(MockPlatformViewDelegate& delegate, const TaskRunners& task_runners) : PlatformView(delegate, task_runners) {} + MOCK_METHOD0(CreateRenderingStudio, std::unique_ptr()); MOCK_METHOD1(CreateRenderingSurface, std::unique_ptr(int64_t)); MOCK_CONST_METHOD0(GetPlatformMessageHandler, std::shared_ptr()); @@ -147,6 +155,7 @@ class TestPlatformView : public PlatformView { public: TestPlatformView(Shell& shell, const TaskRunners& task_runners) : PlatformView(shell, task_runners) {} + MOCK_METHOD0(CreateRenderingStudio, std::unique_ptr()); MOCK_METHOD1(CreateRenderingSurface, std::unique_ptr(int64_t)); }; @@ -1597,16 +1606,24 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { [task_runners, main_context](flutter::Shell& shell) { auto result = std::make_unique(shell, task_runners); ON_CALL(*result, CreateRenderingSurface(0ll)) + .WillByDefault(::testing::Invoke( + [main_context] { + auto surface = std::make_unique(); + ON_CALL(*surface, GetContext()) + .WillByDefault(Return(main_context.get())); + return surface; + })); + ON_CALL(*result, CreateRenderingStudio()) .WillByDefault(::testing::Invoke([main_context] { - auto surface = std::make_unique(); - ON_CALL(*surface, GetContext()) + auto studio = std::make_unique(); + ON_CALL(*studio, GetContext()) .WillByDefault(Return(main_context.get())); - ON_CALL(*surface, IsValid()).WillByDefault(Return(true)); - ON_CALL(*surface, MakeRenderContextCurrent()) + ON_CALL(*studio, IsValid()).WillByDefault(Return(true)); + ON_CALL(*studio, MakeRenderContextCurrent()) .WillByDefault(::testing::Invoke([] { return std::make_unique(true); })); - return surface; + return studio; })); return result; }; @@ -3118,6 +3135,9 @@ TEST_F(ShellTest, Spawn) { ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke( [] { return std::make_unique(); })); + ON_CALL(*result, CreateRenderingStudio()) + .WillByDefault(::testing::Invoke( + [] { return std::make_unique(); })); return result; }, [](Shell& shell) { return std::make_unique(shell); }); @@ -3230,6 +3250,9 @@ TEST_F(ShellTest, SpawnWithDartEntrypointArgs) { ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke( [] { return std::make_unique(); })); + ON_CALL(*result, CreateRenderingStudio()) + .WillByDefault(::testing::Invoke( + [] { return std::make_unique(); })); return result; }, [](Shell& shell) { return std::make_unique(shell); }); @@ -3293,6 +3316,9 @@ TEST_F(ShellTest, IOManagerIsSharedBetweenParentAndSpawnedShell) { ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke( [] { return std::make_unique(); })); + ON_CALL(*result, CreateRenderingStudio()) + .WillByDefault(::testing::Invoke( + [] { return std::make_unique(); })); return result; }, [](Shell& shell) { return std::make_unique(shell); }); @@ -3347,6 +3373,9 @@ TEST_F(ShellTest, IOManagerInSpawnedShellIsNotNullAfterParentShellDestroyed) { ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke( [] { return std::make_unique(); })); + ON_CALL(*result, CreateRenderingStudio()) + .WillByDefault(::testing::Invoke( + [] { return std::make_unique(); })); return result; }, [](Shell& shell) { return std::make_unique(shell); }); @@ -3395,6 +3424,9 @@ TEST_F(ShellTest, ImageGeneratorRegistryNotNullAfterParentShellDestroyed) { ON_CALL(*result, CreateRenderingSurface(0ll)) .WillByDefault(::testing::Invoke( [] { return std::make_unique(); })); + ON_CALL(*result, CreateRenderingStudio()) + .WillByDefault(::testing::Invoke( + [] { return std::make_unique(); })); return result; }, [](Shell& shell) { return std::make_unique(shell); }); @@ -3891,8 +3923,11 @@ TEST_F(ShellTest, SpawnWorksWithOnError) { std::make_unique<::testing::NiceMock>( platform_view_delegate, shell.GetTaskRunners()); ON_CALL(*result, CreateRenderingSurface(0ll)) + .WillByDefault(::testing::Invoke( + [] { return std::make_unique(); })); + ON_CALL(*result, CreateRenderingStudio()) .WillByDefault(::testing::Invoke([] { - return std::make_unique<::testing::NiceMock>(); + return std::make_unique<::testing::NiceMock>(); })); return result; }, diff --git a/shell/platform/embedder/platform_view_embedder.h b/shell/platform/embedder/platform_view_embedder.h index b0e723dece794..9766f6bf8a8a6 100644 --- a/shell/platform/embedder/platform_view_embedder.h +++ b/shell/platform/embedder/platform_view_embedder.h @@ -14,21 +14,8 @@ #include "flutter/shell/platform/embedder/embedder.h" #include "flutter/shell/platform/embedder/embedder_studio.h" #include "flutter/shell/platform/embedder/embedder_surface.h" -// #include "flutter/shell/platform/embedder/embedder_surface_software.h" #include "flutter/shell/platform/embedder/vsync_waiter_embedder.h" -// #ifdef SHELL_ENABLE_GL -// #include "flutter/shell/platform/embedder/embedder_surface_gl.h" -// #endif - -// #ifdef SHELL_ENABLE_METAL -// #include "flutter/shell/platform/embedder/embedder_surface_metal.h" -// #endif - -// #ifdef SHELL_ENABLE_VULKAN -// #include "flutter/shell/platform/embedder/embedder_surface_vulkan.h" -// #endif - namespace flutter { class PlatformViewEmbedder final : public PlatformView { From 0a1aa0a900d84d22311880ad47c4cfd948ba5c80 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 22:57:02 -0700 Subject: [PATCH 035/142] Format --- shell/common/shell_test_platform_view_gl.cc | 6 ++---- shell/common/shell_test_platform_view_metal.mm | 2 +- shell/common/shell_test_platform_view_vulkan.cc | 5 ++--- shell/common/shell_unittests.cc | 13 ++++++------- 4 files changed, 11 insertions(+), 15 deletions(-) diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index 1ed6e9e47ffba..d4c182f406c2f 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -41,8 +41,7 @@ std::unique_ptr ShellTestPlatformViewGL::CreateRenderingStudio() { if (main_context_ == nullptr) { main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); } - return std::make_unique( - main_context_, this); + return std::make_unique(main_context_, this); } // |PlatformView| @@ -51,8 +50,7 @@ std::unique_ptr ShellTestPlatformViewGL::CreateRenderingSurface( if (main_context_ == nullptr) { main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); } - return std::make_unique( - main_context_, this, true); + return std::make_unique(main_context_, this, true); } // |PlatformView| diff --git a/shell/common/shell_test_platform_view_metal.mm b/shell/common/shell_test_platform_view_metal.mm index 51c74c65a950f..12a4a073170fd 100644 --- a/shell/common/shell_test_platform_view_metal.mm +++ b/shell/common/shell_test_platform_view_metal.mm @@ -9,8 +9,8 @@ #include #include "flutter/fml/platform/darwin/scoped_nsobject.h" -#include "flutter/shell/gpu/gpu_surface_metal_skia.h" #include "flutter/shell/gpu/gpu_studio_metal_skia.h" +#include "flutter/shell/gpu/gpu_surface_metal_skia.h" #include "flutter/shell/platform/darwin/graphics/FlutterDarwinContextMetalSkia.h" namespace flutter { diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 94b05920547bb..dbb1ecd79ca3b 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -64,9 +64,8 @@ std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingStudio() { // |PlatformView| std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface( int64_t view_id) { - return std::make_unique(proc_table_, - shell_test_external_view_embedder_, - context_); + return std::make_unique( + proc_table_, shell_test_external_view_embedder_, context_); } // |PlatformView| diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 4ec827a985711..ecfcd34b55388 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -1606,13 +1606,12 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { [task_runners, main_context](flutter::Shell& shell) { auto result = std::make_unique(shell, task_runners); ON_CALL(*result, CreateRenderingSurface(0ll)) - .WillByDefault(::testing::Invoke( - [main_context] { - auto surface = std::make_unique(); - ON_CALL(*surface, GetContext()) - .WillByDefault(Return(main_context.get())); - return surface; - })); + .WillByDefault(::testing::Invoke([main_context] { + auto surface = std::make_unique(); + ON_CALL(*surface, GetContext()) + .WillByDefault(Return(main_context.get())); + return surface; + })); ON_CALL(*result, CreateRenderingStudio()) .WillByDefault(::testing::Invoke([main_context] { auto studio = std::make_unique(); From 801b4f4269740bd4d6ae5800f72c5085a077052e Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 20 Mar 2023 23:41:56 -0700 Subject: [PATCH 036/142] Fix shell unittest --- shell/common/shell_unittests.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index ecfcd34b55388..99f5824b944fa 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -1606,10 +1606,9 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { [task_runners, main_context](flutter::Shell& shell) { auto result = std::make_unique(shell, task_runners); ON_CALL(*result, CreateRenderingSurface(0ll)) - .WillByDefault(::testing::Invoke([main_context] { + .WillByDefault(::testing::Invoke([] { auto surface = std::make_unique(); - ON_CALL(*surface, GetContext()) - .WillByDefault(Return(main_context.get())); + ON_CALL(*surface, IsValid()).WillByDefault(Return(true)); return surface; })); ON_CALL(*result, CreateRenderingStudio()) From aab8ece144c94644ee2cf14a71144d62fb6dad69 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 21 Mar 2023 01:11:53 -0700 Subject: [PATCH 037/142] SkSLPrecompiler --- shell/common/shell_test_platform_view_metal.h | 1 + .../common/shell_test_platform_view_metal.mm | 6 +++-- shell/gpu/gpu_studio_metal_skia.h | 6 +++-- shell/gpu/gpu_studio_metal_skia.mm | 21 +++++---------- shell/gpu/gpu_surface_metal_delegate.cc | 15 +++++++++++ shell/gpu/gpu_surface_metal_delegate.h | 11 ++++++++ shell/gpu/gpu_surface_metal_skia.h | 4 ++- shell/gpu/gpu_surface_metal_skia.mm | 26 +++++++------------ .../darwin/ios/ios_surface_metal_skia.h | 1 + .../darwin/ios/ios_surface_metal_skia.mm | 15 ++++++----- .../platform/embedder/embedder_studio_metal.h | 1 + .../embedder/embedder_studio_metal.mm | 6 +++-- .../embedder/embedder_surface_metal.h | 3 +++ .../embedder/embedder_surface_metal.mm | 13 ++++++---- 14 files changed, 78 insertions(+), 51 deletions(-) diff --git a/shell/common/shell_test_platform_view_metal.h b/shell/common/shell_test_platform_view_metal.h index 2372663f2d009..bffea1e20eeff 100644 --- a/shell/common/shell_test_platform_view_metal.h +++ b/shell/common/shell_test_platform_view_metal.h @@ -29,6 +29,7 @@ class ShellTestPlatformViewMetal final : public ShellTestPlatformView, private: const std::unique_ptr metal_context_; + std::shared_ptr sksl_precompiler_; const CreateVsyncWaiter create_vsync_waiter_; const std::shared_ptr vsync_clock_; const std::shared_ptr diff --git a/shell/common/shell_test_platform_view_metal.mm b/shell/common/shell_test_platform_view_metal.mm index 12a4a073170fd..f9c8deb131c99 100644 --- a/shell/common/shell_test_platform_view_metal.mm +++ b/shell/common/shell_test_platform_view_metal.mm @@ -67,6 +67,7 @@ GPUMTLTextureInfo offscreen_texture_info() const { vsync_clock_(std::move(vsync_clock)), shell_test_external_view_embedder_(std::move(shell_test_external_view_embedder)) { FML_CHECK([metal_context_->context() mainContext] != nil); + sksl_precompiler_ = std::make_shared(); } ShellTestPlatformViewMetal::~ShellTestPlatformViewMetal() = default; @@ -94,13 +95,14 @@ GPUMTLTextureInfo offscreen_texture_info() const { // |PlatformView| std::unique_ptr ShellTestPlatformViewMetal::CreateRenderingStudio() { - return std::make_unique(this, [metal_context_->context() mainContext]); + return std::make_unique(this, [metal_context_->context() mainContext], + sksl_precompiler_); } // |PlatformView| std::unique_ptr ShellTestPlatformViewMetal::CreateRenderingSurface(int64_t view_id) { return std::make_unique(this, [metal_context_->context() mainContext], - MsaaSampleCount::kNone); + MsaaSampleCount::kNone, sksl_precompiler_); } // |GPUSurfaceMetalDelegate| diff --git a/shell/gpu/gpu_studio_metal_skia.h b/shell/gpu/gpu_studio_metal_skia.h index 842a926e1d5e8..08d83ace65439 100644 --- a/shell/gpu/gpu_studio_metal_skia.h +++ b/shell/gpu/gpu_studio_metal_skia.h @@ -17,7 +17,9 @@ namespace flutter { class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalSkia : public Studio { public: GPUStudioMetalSkia(GPUSurfaceMetalDelegate* delegate, - sk_sp context); + sk_sp context, + std::shared_ptr + sksl_precompiler); // |Studio| ~GPUStudioMetalSkia(); @@ -28,7 +30,7 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUStudioMetalSkia : public Studio { private: const GPUSurfaceMetalDelegate* delegate_; sk_sp context_; - GrDirectContext* precompiled_sksl_context_ = nullptr; + std::shared_ptr sksl_precompiler_; // |Studio| GrDirectContext* GetContext() override; diff --git a/shell/gpu/gpu_studio_metal_skia.mm b/shell/gpu/gpu_studio_metal_skia.mm index 91dc90e496fb8..58d9866d5997f 100644 --- a/shell/gpu/gpu_studio_metal_skia.mm +++ b/shell/gpu/gpu_studio_metal_skia.mm @@ -9,7 +9,6 @@ #include -#include "flutter/common/graphics/persistent_cache.h" #include "flutter/fml/make_copyable.h" #include "flutter/fml/platform/darwin/cf_utils.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" @@ -28,9 +27,11 @@ namespace flutter { -GPUStudioMetalSkia::GPUStudioMetalSkia(GPUSurfaceMetalDelegate* delegate, - sk_sp context) - : delegate_(delegate), context_(std::move(context)) {} +GPUStudioMetalSkia::GPUStudioMetalSkia( + GPUSurfaceMetalDelegate* delegate, + sk_sp context, + std::shared_ptr sksl_precompiler) + : delegate_(delegate), context_(std::move(context)), sksl_precompiler_(sksl_precompiler) {} GPUStudioMetalSkia::~GPUStudioMetalSkia() = default; @@ -39,16 +40,6 @@ return context_ != nullptr; } -void GPUStudioMetalSkia::PrecompileKnownSkSLsIfNecessary() { - auto* current_context = GetContext(); - if (current_context == precompiled_sksl_context_) { - // Known SkSLs have already been prepared in this context. - return; - } - precompiled_sksl_context_ = current_context; - flutter::PersistentCache::GetCacheForProcess()->PrecompileKnownSkSLs(precompiled_sksl_context_); -} - // |Studio| GrDirectContext* GPUStudioMetalSkia::GetContext() { return context_.get(); @@ -58,7 +49,7 @@ std::unique_ptr GPUStudioMetalSkia::MakeRenderContextCurrent() { // A context may either be necessary to render to the surface or to snapshot an offscreen // surface. Either way, SkSL precompilation must be attempted. - PrecompileKnownSkSLsIfNecessary(); + sksl_precompiler_->PrecompileKnownSkSLsIfNecessary(GetContext()); // This backend has no such concept. return std::make_unique(true); diff --git a/shell/gpu/gpu_surface_metal_delegate.cc b/shell/gpu/gpu_surface_metal_delegate.cc index 7a22d8de88a89..8b1fd17a3cab3 100644 --- a/shell/gpu/gpu_surface_metal_delegate.cc +++ b/shell/gpu/gpu_surface_metal_delegate.cc @@ -4,6 +4,8 @@ #include "flutter/shell/gpu/gpu_surface_metal_delegate.h" +#include "flutter/common/graphics/persistent_cache.h" + namespace flutter { GPUSurfaceMetalDelegate::GPUSurfaceMetalDelegate( @@ -20,4 +22,17 @@ bool GPUSurfaceMetalDelegate::AllowsDrawingWhenGpuDisabled() const { return true; } +GPUSurfaceMetalDelegate::SkSLPrecompiler::SkSLPrecompiler() {} + +void GPUSurfaceMetalDelegate::SkSLPrecompiler::PrecompileKnownSkSLsIfNecessary( + GrDirectContext* current_context) { + if (current_context == precompiled_sksl_context_) { + // Known SkSLs have already been prepared in this context. + return; + } + precompiled_sksl_context_ = current_context; + flutter::PersistentCache::GetCacheForProcess()->PrecompileKnownSkSLs( + precompiled_sksl_context_); +} + } // namespace flutter diff --git a/shell/gpu/gpu_surface_metal_delegate.h b/shell/gpu/gpu_surface_metal_delegate.h index 6d5e0852d8c85..0136dc71d785b 100644 --- a/shell/gpu/gpu_surface_metal_delegate.h +++ b/shell/gpu/gpu_surface_metal_delegate.h @@ -50,6 +50,17 @@ enum class MTLRenderTargetType { kMTLTexture, kCAMetalLayer }; /// class GPUSurfaceMetalDelegate { public: + class SkSLPrecompiler { + public: + SkSLPrecompiler(); + void PrecompileKnownSkSLsIfNecessary(GrDirectContext* current_context); + + private: + GrDirectContext* precompiled_sksl_context_; + + FML_DISALLOW_COPY_AND_ASSIGN(SkSLPrecompiler); + }; + //------------------------------------------------------------------------------ /// @brief Construct a new GPUSurfaceMetalDelegate object with the specified /// render_target type. diff --git a/shell/gpu/gpu_surface_metal_skia.h b/shell/gpu/gpu_surface_metal_skia.h index bd7d6a35135f3..c04f3213d51d2 100644 --- a/shell/gpu/gpu_surface_metal_skia.h +++ b/shell/gpu/gpu_surface_metal_skia.h @@ -18,6 +18,8 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalSkia : public Surface { GPUSurfaceMetalSkia(GPUSurfaceMetalDelegate* delegate, sk_sp context, MsaaSampleCount msaa_samples, + std::shared_ptr + sksl_precompiler, bool render_to_surface = true); // |Surface| @@ -30,8 +32,8 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalSkia : public Surface { const GPUSurfaceMetalDelegate* delegate_; const MTLRenderTargetType render_target_type_; sk_sp context_; - GrDirectContext* precompiled_sksl_context_ = nullptr; MsaaSampleCount msaa_samples_ = MsaaSampleCount::kNone; + std::shared_ptr sksl_precompiler_; // TODO(38466): Refactor GPU surface APIs take into account the fact that an // external view embedder may want to render to the root surface. This is a // hack to make avoid allocating resources for the root surface when an diff --git a/shell/gpu/gpu_surface_metal_skia.mm b/shell/gpu/gpu_surface_metal_skia.mm index 4f625a9e724a8..7356684d4f4c6 100644 --- a/shell/gpu/gpu_surface_metal_skia.mm +++ b/shell/gpu/gpu_surface_metal_skia.mm @@ -9,7 +9,6 @@ #include -#include "flutter/common/graphics/persistent_cache.h" #include "flutter/fml/make_copyable.h" #include "flutter/fml/platform/darwin/cf_utils.h" #include "flutter/fml/platform/darwin/scoped_nsobject.h" @@ -50,14 +49,17 @@ } } // namespace -GPUSurfaceMetalSkia::GPUSurfaceMetalSkia(GPUSurfaceMetalDelegate* delegate, - sk_sp context, - MsaaSampleCount msaa_samples, - bool render_to_surface) +GPUSurfaceMetalSkia::GPUSurfaceMetalSkia( + GPUSurfaceMetalDelegate* delegate, + sk_sp context, + MsaaSampleCount msaa_samples, + std::shared_ptr sksl_precompiler, + bool render_to_surface) : delegate_(delegate), render_target_type_(delegate->GetRenderTargetType()), context_(std::move(context)), msaa_samples_(msaa_samples), + sksl_precompiler_(sksl_precompiler), render_to_surface_(render_to_surface) { // If this preference is explicitly set, we allow for disabling partial repaint. NSNumber* disablePartialRepaint = @@ -74,16 +76,6 @@ return context_ != nullptr; } -void GPUSurfaceMetalSkia::PrecompileKnownSkSLsIfNecessary() { - auto* current_context = GetContext(); - if (current_context == precompiled_sksl_context_) { - // Known SkSLs have already been prepared in this context. - return; - } - precompiled_sksl_context_ = current_context; - flutter::PersistentCache::GetCacheForProcess()->PrecompileKnownSkSLs(precompiled_sksl_context_); -} - // |Surface| std::unique_ptr GPUSurfaceMetalSkia::AcquireFrame(const SkISize& frame_size) { if (!IsValid()) { @@ -102,7 +94,7 @@ [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { return true; }, frame_size); } - PrecompileKnownSkSLsIfNecessary(); + sksl_precompiler_->PrecompileKnownSkSLsIfNecessary(GetContext()); switch (render_target_type_) { case MTLRenderTargetType::kCAMetalLayer: @@ -256,7 +248,7 @@ std::unique_ptr GPUSurfaceMetalSkia::MakeRenderContextCurrent() { // A context may either be necessary to render to the surface or to snapshot an offscreen // surface. Either way, SkSL precompilation must be attempted. - PrecompileKnownSkSLsIfNecessary(); + sksl_precompiler_->PrecompileKnownSkSLsIfNecessary(GetContext()); // This backend has no such concept. return std::make_unique(true); diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.h b/shell/platform/darwin/ios/ios_surface_metal_skia.h index 80c1f0f5cfbd3..43f6dd1268ae9 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.h +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.h @@ -28,6 +28,7 @@ class SK_API_AVAILABLE_CA_METAL_LAYER IOSSurfaceMetalSkia final : public IOSSurf id device_; id command_queue_; bool is_valid_ = false; + std::shared_ptr sksl_precompiler_; // |IOSSurface| bool IsValid() const override; diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.mm b/shell/platform/darwin/ios/ios_surface_metal_skia.mm index 7a64898ff865a..15b465528d221 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.mm @@ -25,6 +25,7 @@ auto darwin_context = metal_context->GetDarwinContext().get(); command_queue_ = darwin_context.commandQueue; device_ = darwin_context.device; + sksl_precompiler_ = std::make_shared(); } // |IOSSurface| @@ -43,18 +44,18 @@ // |IOSSurface| std::unique_ptr IOSSurfaceMetalSkia::CreateGPUStudio(GrDirectContext* context) { FML_DCHECK(context); - return std::make_unique(this, // delegate - sk_ref_sp(context) // context - ); + return std::make_unique(this, // delegate + sk_ref_sp(context), // context + sksl_precompiler_); } // |IOSSurface| std::unique_ptr IOSSurfaceMetalSkia::CreateGPUSurface(GrDirectContext* context) { FML_DCHECK(context); - return std::make_unique(this, // delegate - sk_ref_sp(context), // context - GetContext()->GetMsaaSampleCount() // sample count - ); + return std::make_unique(this, // delegate + sk_ref_sp(context), // context + GetContext()->GetMsaaSampleCount(), // sample count + sksl_precompiler_); } // |GPUSurfaceMetalDelegate| diff --git a/shell/platform/embedder/embedder_studio_metal.h b/shell/platform/embedder/embedder_studio_metal.h index eefc8e2745a12..6c7d9e6e838fe 100644 --- a/shell/platform/embedder/embedder_studio_metal.h +++ b/shell/platform/embedder/embedder_studio_metal.h @@ -64,6 +64,7 @@ class EmbedderStudioMetal final : public EmbedderStudio, sk_sp surface_; sk_sp main_context_; sk_sp resource_context_; + std::shared_ptr sksl_precompiler_; FML_DISALLOW_COPY_AND_ASSIGN(EmbedderStudioMetal); }; diff --git a/shell/platform/embedder/embedder_studio_metal.mm b/shell/platform/embedder/embedder_studio_metal.mm index 0425abdcbe0f0..6a7f3fb267815 100644 --- a/shell/platform/embedder/embedder_studio_metal.mm +++ b/shell/platform/embedder/embedder_studio_metal.mm @@ -30,6 +30,7 @@ resource_context_ = [FlutterDarwinContextMetalSkia createGrContext:(id)device commandQueue:(id)command_queue]; + sksl_precompiler_ = std::make_shared(); valid_ = main_context_ && resource_context_; } @@ -48,7 +49,7 @@ return nullptr; } - auto studio = std::make_unique(this, main_context_); + auto studio = std::make_unique(this, main_context_, sksl_precompiler_); if (!studio->IsValid()) { return nullptr; @@ -63,7 +64,8 @@ } const bool render_to_surface = !external_view_embedder_; return std::make_unique(main_context_, - this, // GPU surface GL delegate + this, // GPU surface GL delegate + sksl_precompiler_, render_to_surface // render to surface ); } diff --git a/shell/platform/embedder/embedder_surface_metal.h b/shell/platform/embedder/embedder_surface_metal.h index 54ad165e5e3c4..63bc238dbefd6 100644 --- a/shell/platform/embedder/embedder_surface_metal.h +++ b/shell/platform/embedder/embedder_surface_metal.h @@ -20,6 +20,8 @@ class EmbedderSurfaceMetal final : public EmbedderSurface { public: EmbedderSurfaceMetal(sk_sp main_context, EmbedderStudioMetal* studio, + std::shared_ptr + sksl_precompiler, bool render_to_surface); ~EmbedderSurfaceMetal() override; @@ -30,6 +32,7 @@ class EmbedderSurfaceMetal final : public EmbedderSurface { private: sk_sp main_context_; EmbedderStudioMetal* studio_; + std::shared_ptr sksl_precompiler_; bool render_to_surface_; // |EmbedderSurface| diff --git a/shell/platform/embedder/embedder_surface_metal.mm b/shell/platform/embedder/embedder_surface_metal.mm index 8560c2e5d6174..1f237eb5d3213 100644 --- a/shell/platform/embedder/embedder_surface_metal.mm +++ b/shell/platform/embedder/embedder_surface_metal.mm @@ -15,11 +15,14 @@ FLUTTER_ASSERT_NOT_ARC namespace flutter { -EmbedderSurfaceMetal::EmbedderSurfaceMetal(sk_sp main_context, - EmbedderStudioMetal* studio, - bool render_to_surface) +EmbedderSurfaceMetal::EmbedderSurfaceMetal( + sk_sp main_context, + EmbedderStudioMetal* studio, + std::shared_ptr sksl_precompiler, + bool render_to_surface) : main_context_(std::move(main_context)), studio_(studio), + sksl_precompiler_(sksl_precompiler), render_to_surface_(render_to_surface) {} EmbedderSurfaceMetal::~EmbedderSurfaceMetal() = default; @@ -37,8 +40,8 @@ return nullptr; } - auto surface = std::make_unique(studio_, main_context_, - MsaaSampleCount::kNone, render_to_surface_); + auto surface = std::make_unique( + studio_, main_context_, MsaaSampleCount::kNone, sksl_precompiler_, render_to_surface_); if (!surface->IsValid()) { return nullptr; From 172e4dd49d1e77075abfcd203c85c8300e9063d3 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 21 Mar 2023 12:29:28 -0700 Subject: [PATCH 038/142] Fix all tests --- shell/common/rasterizer.cc | 2 +- shell/common/rasterizer_unittests.cc | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index f29f02f25eed5..bb1734506957e 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -477,7 +477,7 @@ RasterStatus Rasterizer::DrawToSurface( FML_DCHECK(surface_); RasterStatus raster_status; - if (surface_->AllowsDrawingWhenGpuDisabled()) { + if (studio_->AllowsDrawingWhenGpuDisabled()) { raster_status = DrawToSurfaceUnsafe(frame_timings_recorder, layer_tree); } else { delegate_.GetIsGpuDisabledSyncSwitch()->Execute( diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index ae82d13127ce9..8569c83e44cec 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -899,7 +899,7 @@ TEST(RasterizerTest, [](const SurfaceFrame& frame, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); })); - ON_CALL(*surface, MakeRenderContextCurrent()) + ON_CALL(*studio, MakeRenderContextCurrent()) .WillByDefault(::testing::Invoke( [] { return std::make_unique(true); })); @@ -1070,7 +1070,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { fml::CountDownLatch submit_latch(2); auto studio = std::make_unique>(); auto surface = std::make_unique(); - ON_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(true)); + ON_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(true)); ON_CALL(*surface, AcquireFrame(SkISize())) .WillByDefault(::testing::Invoke([&] { SurfaceFrame::FramebufferInfo framebuffer_info; @@ -1090,7 +1090,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { /*frame_size=*/SkISize::Make(800, 600)); })); - ON_CALL(*surface, MakeRenderContextCurrent()) + ON_CALL(*studio, MakeRenderContextCurrent()) .WillByDefault(::testing::Invoke( [] { return std::make_unique(true); })); @@ -1154,7 +1154,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { fml::CountDownLatch submit_latch(1); auto studio = std::make_unique>(); auto surface = std::make_unique(); - ON_CALL(*surface, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(true)); + ON_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(true)); ON_CALL(*surface, AcquireFrame(SkISize())) .WillByDefault(::testing::Invoke([&] { SurfaceFrame::FramebufferInfo framebuffer_info; @@ -1172,7 +1172,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { /*frame_size=*/SkISize::Make(800, 600)); })); - ON_CALL(*surface, MakeRenderContextCurrent()) + ON_CALL(*studio, MakeRenderContextCurrent()) .WillByDefault(::testing::Invoke( [] { return std::make_unique(true); })); From 9489c4e744beaf76ebfe1cbbd7ef7e33b9278d9f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 21 Mar 2023 13:35:38 -0700 Subject: [PATCH 039/142] Fix compile --- shell/common/shell_test_platform_view_gl.cc | 1 + .../common/shell_test_platform_view_vulkan.cc | 38 ++++++++++--------- .../common/shell_test_platform_view_vulkan.h | 15 ++++++-- shell/platform/fuchsia/flutter/engine.cc | 6 +++ 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index d4c182f406c2f..02a205b455cf3 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -6,6 +6,7 @@ #include +#include "flutter/shell/gpu/gpu_studio_gl_skia.h" #include "flutter/shell/gpu/gpu_surface_gl_skia.h" namespace flutter { diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index dbb1ecd79ca3b..64c51a93675fa 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -6,9 +6,10 @@ #include -#include "flutter/common/graphics/persistent_cache.h" +// #include "flutter/common/graphics/persistent_cache.h" #include "flutter/flutter_vma/flutter_skia_vma.h" #include "flutter/shell/common/context_options.h" +#include "flutter/shell/gpu/gpu_studio_vulkan.h" #include "flutter/vulkan/vulkan_skia_proc_table.h" #include "flutter/vulkan/vulkan_utilities.h" @@ -40,6 +41,17 @@ ShellTestPlatformViewVulkan::ShellTestPlatformViewVulkan( proc_table_(fml::MakeRefCounted(VULKAN_SO_PATH)), shell_test_external_view_embedder_( std::move(shell_test_external_view_embedder)) { + // Create the application instance. + std::vector extensions = { + VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, + }; + + application_ = std::make_unique( + *proc_table_, "FlutterTest", std::move(extensions), + VK_MAKE_VERSION(1, 0, 0), VK_MAKE_VERSION(1, 1, 0), true); + + // Create the device. + logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); // Create the Skia GrContext. if (!CreateSkiaGrContext()) { FML_DLOG(ERROR) << "Could not create Skia context."; @@ -65,7 +77,8 @@ std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingStudio() { std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface( int64_t view_id) { return std::make_unique( - proc_table_, shell_test_external_view_embedder_, context_); + proc_table_, shell_test_external_view_embedder_, context_, application_, + logical_device_); } // |PlatformView| @@ -144,26 +157,21 @@ bool ShellTestPlatformViewVulkan::CreateSkiaBackendContext( ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( fml::RefPtr vk, std::shared_ptr - shell_test_external_view_embedder) + shell_test_external_view_embedder, + sk_sp context, + const std::make_unique& application, + const std::unique_ptr& logical_device) : valid_(false), vk_(std::move(vk)), shell_test_external_view_embedder_( std::move(shell_test_external_view_embedder)), - context_(context) { + context_(context), +{ if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; return; } - // Create the application instance. - std::vector extensions = { - VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, - }; - - application_ = std::make_unique( - *vk_, "FlutterTest", std::move(extensions), VK_MAKE_VERSION(1, 0, 0), - VK_MAKE_VERSION(1, 1, 0), true); - if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) { // Make certain the application instance was created and it set up the // instance proc table entries. @@ -171,10 +179,6 @@ ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( return; } - // Create the device. - - logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); - if (logical_device_ == nullptr || !logical_device_->IsValid() || !vk_->AreDeviceProcsSetup()) { // Make certain the device was created and it set up the device proc table diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index bd5b2db9a476d..41a8ae95f279c 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -31,10 +31,13 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { private: class OffScreenSurface : public flutter::Surface { public: - OffScreenSurface(fml::RefPtr vk, - std::shared_ptr - shell_test_external_view_embedder, - sk_sp context); + OffScreenSurface( + fml::RefPtr vk, + std::shared_ptr + shell_test_external_view_embedder, + sk_sp context, + const std::make_unique& application, + const std::unique_ptr& logical_device); ~OffScreenSurface() override; @@ -73,6 +76,10 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { sk_sp context_; + std::make_unique application_; + + std::unique_ptr logical_device_; + // |PlatformView| std::unique_ptr CreateRenderingStudio() override; diff --git a/shell/platform/fuchsia/flutter/engine.cc b/shell/platform/fuchsia/flutter/engine.cc index 8146468c7b737..93695ccd6eef8 100644 --- a/shell/platform/fuchsia/flutter/engine.cc +++ b/shell/platform/fuchsia/flutter/engine.cc @@ -366,6 +366,9 @@ void Engine::Initialize( std::bind(&Engine::DestroyFlatlandView, this, std::placeholders::_1, std::placeholders::_2); + OnCreateSurface on_create_studio_callback = + std::bind(&Engine::CreateStudio, this); + OnCreateSurface on_create_surface_callback = std::bind(&Engine::CreateSurface, this); @@ -425,6 +428,7 @@ void Engine::Initialize( std::move(on_destroy_gfx_view_callback), on_destroy_flatland_view_callback = std::move(on_destroy_flatland_view_callback), + on_create_studio_callback = std::move(on_create_studio_callback), on_create_surface_callback = std::move(on_create_surface_callback), on_semantics_node_update_callback = std::move(on_semantics_node_update_callback), @@ -496,6 +500,7 @@ void Engine::Initialize( std::move(on_create_flatland_view_callback), std::move(on_update_view_callback), std::move(on_destroy_flatland_view_callback), + std::move(on_create_studio_callback), std::move(on_create_surface_callback), std::move(on_semantics_node_update_callback), std::move(on_request_announce_callback), @@ -516,6 +521,7 @@ void Engine::Initialize( std::move(on_create_gfx_view_callback), std::move(on_update_view_callback), std::move(on_destroy_gfx_view_callback), + std::move(on_create_studio_callback), std::move(on_create_surface_callback), std::move(on_semantics_node_update_callback), std::move(on_request_announce_callback), From 1eb7657a0004c8d1827d3a173f558d53200351ef Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 21 Mar 2023 21:38:31 +0000 Subject: [PATCH 040/142] Fix ShellTestPlatformViewVulkan compile --- .../common/shell_test_platform_view_vulkan.cc | 69 +++++++++---------- .../common/shell_test_platform_view_vulkan.h | 14 ++-- 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 64c51a93675fa..618e60ca910b6 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -41,6 +41,12 @@ ShellTestPlatformViewVulkan::ShellTestPlatformViewVulkan( proc_table_(fml::MakeRefCounted(VULKAN_SO_PATH)), shell_test_external_view_embedder_( std::move(shell_test_external_view_embedder)) { + + if (!proc_table_ || !proc_table_->HasAcquiredMandatoryProcAddresses()) { + FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; + return; + } + // Create the application instance. std::vector extensions = { VK_KHR_EXTERNAL_SEMAPHORE_CAPABILITIES_EXTENSION_NAME, @@ -50,8 +56,29 @@ ShellTestPlatformViewVulkan::ShellTestPlatformViewVulkan( *proc_table_, "FlutterTest", std::move(extensions), VK_MAKE_VERSION(1, 0, 0), VK_MAKE_VERSION(1, 1, 0), true); + if (!application_->IsValid() || !proc_table_->AreInstanceProcsSetup()) { + // Make certain the application instance was created and it set up the + // instance proc table entries. + FML_DLOG(ERROR) << "Instance proc addresses have not been set up."; + return; + } + // Create the device. logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); + + if (logical_device_ == nullptr || !logical_device_->IsValid() || + !proc_table_->AreDeviceProcsSetup()) { + // Make certain the device was created and it set up the device proc table + // entries. + FML_DLOG(ERROR) << "Device proc addresses have not been set up."; + return; + } + + memory_allocator_ = FlutterSkiaVulkanMemoryAllocator::Make( + application_->GetAPIVersion(), application_->GetInstance(), + logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(), + proc_table_, true); + // Create the Skia GrContext. if (!CreateSkiaGrContext()) { FML_DLOG(ERROR) << "Could not create Skia context."; @@ -70,15 +97,14 @@ void ShellTestPlatformViewVulkan::SimulateVSync() { // |PlatformView| std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingStudio() { - return std::make_unique(context_, this); + return std::make_unique(context_); } // |PlatformView| std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface( int64_t view_id) { return std::make_unique( - proc_table_, shell_test_external_view_embedder_, context_, application_, - logical_device_); + proc_table_, shell_test_external_view_embedder_, context_, memory_allocator_); } // |PlatformView| @@ -159,46 +185,17 @@ ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( std::shared_ptr shell_test_external_view_embedder, sk_sp context, - const std::make_unique& application, - const std::unique_ptr& logical_device) - : valid_(false), - vk_(std::move(vk)), + sk_sp memory_allocator) + : vk_(std::move(vk)), shell_test_external_view_embedder_( std::move(shell_test_external_view_embedder)), context_(context), -{ - if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { - FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; - return; - } - - if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) { - // Make certain the application instance was created and it set up the - // instance proc table entries. - FML_DLOG(ERROR) << "Instance proc addresses have not been set up."; - return; - } - - if (logical_device_ == nullptr || !logical_device_->IsValid() || - !vk_->AreDeviceProcsSetup()) { - // Make certain the device was created and it set up the device proc table - // entries. - FML_DLOG(ERROR) << "Device proc addresses have not been set up."; - return; - } - - memory_allocator_ = FlutterSkiaVulkanMemoryAllocator::Make( - application_->GetAPIVersion(), application_->GetInstance(), - logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(), - vk_, true); - - valid_ = true; -} + memory_allocator_(memory_allocator) {} ShellTestPlatformViewVulkan::OffScreenSurface::~OffScreenSurface() {} bool ShellTestPlatformViewVulkan::OffScreenSurface::IsValid() { - return valid_; + return true; } std::unique_ptr diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 41a8ae95f279c..bbb7e6929aeb7 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -36,8 +36,7 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { std::shared_ptr shell_test_external_view_embedder, sk_sp context, - const std::make_unique& application, - const std::unique_ptr& logical_device); + sk_sp memory_allocator); ~OffScreenSurface() override; @@ -53,14 +52,11 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { GrDirectContext* GetContext() override; private: - bool valid_; fml::RefPtr vk_; std::shared_ptr shell_test_external_view_embedder_; - std::unique_ptr application_; - std::unique_ptr logical_device_; - sk_sp memory_allocator_; sk_sp context_; + sk_sp memory_allocator_; FML_DISALLOW_COPY_AND_ASSIGN(OffScreenSurface); }; @@ -76,9 +72,11 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { sk_sp context_; - std::make_unique application_; + std::unique_ptr application_; + + std::unique_ptr logical_device_; - std::unique_ptr logical_device_; + sk_sp memory_allocator_; // |PlatformView| std::unique_ptr CreateRenderingStudio() override; From 06ce3f475a1f29cd1b3c8c06b689f5882253dc64 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 21 Mar 2023 21:39:27 +0000 Subject: [PATCH 041/142] Format --- shell/common/shell_test_platform_view_vulkan.cc | 6 +++--- shell/common/shell_test_platform_view_vulkan.h | 11 +++++------ 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 618e60ca910b6..1c3cc22cc684e 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -41,7 +41,6 @@ ShellTestPlatformViewVulkan::ShellTestPlatformViewVulkan( proc_table_(fml::MakeRefCounted(VULKAN_SO_PATH)), shell_test_external_view_embedder_( std::move(shell_test_external_view_embedder)) { - if (!proc_table_ || !proc_table_->HasAcquiredMandatoryProcAddresses()) { FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; return; @@ -103,8 +102,9 @@ std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingStudio() { // |PlatformView| std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface( int64_t view_id) { - return std::make_unique( - proc_table_, shell_test_external_view_embedder_, context_, memory_allocator_); + return std::make_unique(proc_table_, + shell_test_external_view_embedder_, + context_, memory_allocator_); } // |PlatformView| diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index bbb7e6929aeb7..6d6f1dc540971 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -31,12 +31,11 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { private: class OffScreenSurface : public flutter::Surface { public: - OffScreenSurface( - fml::RefPtr vk, - std::shared_ptr - shell_test_external_view_embedder, - sk_sp context, - sk_sp memory_allocator); + OffScreenSurface(fml::RefPtr vk, + std::shared_ptr + shell_test_external_view_embedder, + sk_sp context, + sk_sp memory_allocator); ~OffScreenSurface() override; From cd14ba1a0744c9e28ae5cf449ae6853904d0fefb Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 21 Mar 2023 14:50:18 -0700 Subject: [PATCH 042/142] Fix a few tests --- shell/gpu/gpu_studio_metal_skia.mm | 2 +- shell/gpu/gpu_surface_metal_skia.mm | 2 +- .../embedder/embedder_surface_metal.mm | 2 +- shell/testing/tester_main.cc | 18 ++++++++++++++++-- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/shell/gpu/gpu_studio_metal_skia.mm b/shell/gpu/gpu_studio_metal_skia.mm index 58d9866d5997f..dc691fd8f62eb 100644 --- a/shell/gpu/gpu_studio_metal_skia.mm +++ b/shell/gpu/gpu_studio_metal_skia.mm @@ -31,7 +31,7 @@ GPUSurfaceMetalDelegate* delegate, sk_sp context, std::shared_ptr sksl_precompiler) - : delegate_(delegate), context_(std::move(context)), sksl_precompiler_(sksl_precompiler) {} + : delegate_(delegate), context_(std::move(context)), sksl_precompiler_(std::move(sksl_precompiler)) {} GPUStudioMetalSkia::~GPUStudioMetalSkia() = default; diff --git a/shell/gpu/gpu_surface_metal_skia.mm b/shell/gpu/gpu_surface_metal_skia.mm index 7356684d4f4c6..31a60f565b11b 100644 --- a/shell/gpu/gpu_surface_metal_skia.mm +++ b/shell/gpu/gpu_surface_metal_skia.mm @@ -59,7 +59,7 @@ render_target_type_(delegate->GetRenderTargetType()), context_(std::move(context)), msaa_samples_(msaa_samples), - sksl_precompiler_(sksl_precompiler), + sksl_precompiler_(std::move(sksl_precompiler)), render_to_surface_(render_to_surface) { // If this preference is explicitly set, we allow for disabling partial repaint. NSNumber* disablePartialRepaint = diff --git a/shell/platform/embedder/embedder_surface_metal.mm b/shell/platform/embedder/embedder_surface_metal.mm index 1f237eb5d3213..32b9a34409c4d 100644 --- a/shell/platform/embedder/embedder_surface_metal.mm +++ b/shell/platform/embedder/embedder_surface_metal.mm @@ -22,7 +22,7 @@ bool render_to_surface) : main_context_(std::move(main_context)), studio_(studio), - sksl_precompiler_(sksl_precompiler), + sksl_precompiler_(std::move(sksl_precompiler)), render_to_surface_(render_to_surface) {} EmbedderSurfaceMetal::~EmbedderSurfaceMetal() = default; diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index c2e470e66ad64..3e9f3d68beed2 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -24,6 +24,7 @@ #include "flutter/shell/common/switches.h" #include "flutter/shell/common/thread_host.h" #include "flutter/shell/gpu/gpu_surface_software.h" +#include "flutter/shell/gpu/gpu_studio_software.h" #include "third_party/dart/runtime/include/bin/dart_io_api.h" #include "third_party/dart/runtime/include/dart_api.h" @@ -67,13 +68,19 @@ class TesterExternalViewEmbedder : public ExternalViewEmbedder { DisplayListBuilder builder_; }; +class TesterGPUStudioSoftware : public GPUStudioSoftware { + public: + TesterGPUStudioSoftware(GPUSurfaceSoftwareDelegate* delegate) + : GPUStudioSoftware(delegate) {} + + bool EnableRasterCache() const override { return false; } +}; + class TesterGPUSurfaceSoftware : public GPUSurfaceSoftware { public: TesterGPUSurfaceSoftware(GPUSurfaceSoftwareDelegate* delegate, bool render_to_surface) : GPUSurfaceSoftware(delegate, render_to_surface) {} - - bool EnableRasterCache() const override { return false; } }; class TesterPlatformView : public PlatformView, @@ -82,6 +89,13 @@ class TesterPlatformView : public PlatformView, TesterPlatformView(Delegate& delegate, const TaskRunners& task_runners) : PlatformView(delegate, task_runners) {} + // |PlatformView| + std::unique_ptr CreateRenderingStudio() override { + auto studio = std::make_unique(this); + FML_DCHECK(studio->IsValid()); + return studio; + } + // |PlatformView| std::unique_ptr CreateRenderingSurface(int64_t view_id) override { auto surface = std::make_unique( From 283a451e1b737de943ea8a599967e99d58cbc746 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 21 Mar 2023 14:54:30 -0700 Subject: [PATCH 043/142] Format --- shell/gpu/gpu_studio_metal_skia.mm | 4 +++- shell/testing/tester_main.cc | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/shell/gpu/gpu_studio_metal_skia.mm b/shell/gpu/gpu_studio_metal_skia.mm index dc691fd8f62eb..61eaa1ebcbce9 100644 --- a/shell/gpu/gpu_studio_metal_skia.mm +++ b/shell/gpu/gpu_studio_metal_skia.mm @@ -31,7 +31,9 @@ GPUSurfaceMetalDelegate* delegate, sk_sp context, std::shared_ptr sksl_precompiler) - : delegate_(delegate), context_(std::move(context)), sksl_precompiler_(std::move(sksl_precompiler)) {} + : delegate_(delegate), + context_(std::move(context)), + sksl_precompiler_(std::move(sksl_precompiler)) {} GPUStudioMetalSkia::~GPUStudioMetalSkia() = default; diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index 3e9f3d68beed2..fff20be376814 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -23,8 +23,8 @@ #include "flutter/shell/common/shell.h" #include "flutter/shell/common/switches.h" #include "flutter/shell/common/thread_host.h" -#include "flutter/shell/gpu/gpu_surface_software.h" #include "flutter/shell/gpu/gpu_studio_software.h" +#include "flutter/shell/gpu/gpu_surface_software.h" #include "third_party/dart/runtime/include/bin/dart_io_api.h" #include "third_party/dart/runtime/include/dart_api.h" From 8e6ef11206b0288c0c70e24d16b51de9de24b5f8 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 21 Mar 2023 15:01:21 -0700 Subject: [PATCH 044/142] Fix fuchsia test --- shell/platform/fuchsia/flutter/engine.cc | 2 +- .../fuchsia/flutter/flatland_platform_view.h | 1 + .../fuchsia/flutter/platform_view_unittest.cc | 12 ++++++++++++ .../flutter/tests/flatland_platform_view_unittest.cc | 12 ++++++++++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/shell/platform/fuchsia/flutter/engine.cc b/shell/platform/fuchsia/flutter/engine.cc index 93695ccd6eef8..b32bedc40897a 100644 --- a/shell/platform/fuchsia/flutter/engine.cc +++ b/shell/platform/fuchsia/flutter/engine.cc @@ -366,7 +366,7 @@ void Engine::Initialize( std::bind(&Engine::DestroyFlatlandView, this, std::placeholders::_1, std::placeholders::_2); - OnCreateSurface on_create_studio_callback = + OnCreateStudio on_create_studio_callback = std::bind(&Engine::CreateStudio, this); OnCreateSurface on_create_surface_callback = diff --git a/shell/platform/fuchsia/flutter/flatland_platform_view.h b/shell/platform/fuchsia/flutter/flatland_platform_view.h index afe0819842cd9..2315c2674e028 100644 --- a/shell/platform/fuchsia/flutter/flatland_platform_view.h +++ b/shell/platform/fuchsia/flutter/flatland_platform_view.h @@ -40,6 +40,7 @@ class FlatlandPlatformView final : public flutter_runner::PlatformView { OnCreateFlatlandView on_create_view_callback, OnUpdateView on_update_view_callback, OnDestroyFlatlandView on_destroy_view_callback, + OnCreateStudio on_create_studio_callback, OnCreateSurface on_create_surface_callback, OnSemanticsNodeUpdate on_semantics_node_update_callback, OnRequestAnnounce on_request_announce_callback, diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index 64902116300ac..be9bac1005a73 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -31,6 +31,7 @@ #include "gtest/gtest.h" #include "platform/assert.h" +#include "studio.h" #include "surface.h" #include "task_runner_adapter.h" #include "tests/fakes/focuser.h" @@ -296,6 +297,11 @@ class PlatformViewBuilder { return *this; } + PlatformViewBuilder& SetCreateStudioCallback(OnCreateStudio callback) { + on_create_studio_callback_ = std::move(callback); + return *this; + } + PlatformViewBuilder& SetCreateSurfaceCallback(OnCreateSurface callback) { on_create_surface_callback_ = std::move(callback); return *this; @@ -322,6 +328,7 @@ class PlatformViewBuilder { std::move(on_create_view_callback_), std::move(on_update_view_callback_), std::move(on_destroy_view_callback_), + std::move(on_create_studio_callback_), std::move(on_create_surface_callback_), std::move(on_semantics_node_update_callback_), std::move(on_request_announce_callback_), @@ -351,6 +358,7 @@ class PlatformViewBuilder { OnCreateGfxView on_create_view_callback_; OnUpdateView on_update_view_callback_; OnDestroyGfxView on_destroy_view_callback_; + OnCreateStudio on_create_studio_callback_; OnCreateSurface on_create_surface_callback_; OnSemanticsNodeUpdate on_semantics_node_update_callback_; OnRequestAnnounce on_request_announce_callback_; @@ -492,6 +500,9 @@ TEST_F(PlatformViewTests, CreateSurfaceTest) { flutter::MakeDefaultContextOptions(flutter::ContextType::kRender)); std::shared_ptr external_view_embedder = std::make_shared(); + auto CreateStudioCallback = [gr_context]() { + return std::make_unique(gr_context.get()); + }; auto CreateSurfaceCallback = [&external_view_embedder, gr_context]() { return std::make_unique( "PlatformViewTest", external_view_embedder, gr_context.get()); @@ -499,6 +510,7 @@ TEST_F(PlatformViewTests, CreateSurfaceTest) { flutter_runner::GfxPlatformView platform_view = PlatformViewBuilder(delegate, std::move(task_runners)) + .SetCreateStudioCallback(CreateStudioCallback) .SetCreateSurfaceCallback(CreateSurfaceCallback) .SetExternalViewEmbedder(external_view_embedder) .Build(); diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index 262ab27af1700..cc4ba273a6136 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -33,6 +33,7 @@ #include "fakes/platform_message.h" #include "fakes/touch_source.h" #include "fakes/view_ref_focused.h" +#include "flutter/shell/platform/fuchsia/flutter/studio.h" #include "flutter/shell/platform/fuchsia/flutter/surface.h" #include "flutter/shell/platform/fuchsia/flutter/task_runner_adapter.h" #include "platform/assert.h" @@ -402,6 +403,11 @@ class PlatformViewBuilder { return *this; } + PlatformViewBuilder& SetCreateStudioCallback(OnCreateStudio callback) { + on_create_studio_callback_ = std::move(callback); + return *this; + } + PlatformViewBuilder& SetCreateSurfaceCallback(OnCreateSurface callback) { on_create_surface_callback_ = std::move(callback); return *this; @@ -427,6 +433,7 @@ class PlatformViewBuilder { std::move(on_create_view_callback_), std::move(on_update_view_callback_), std::move(on_destroy_view_callback_), + std::move(on_create_studio_callback_), std::move(on_create_surface_callback_), std::move(on_semantics_node_update_callback_), std::move(on_request_announce_callback_), @@ -456,6 +463,7 @@ class PlatformViewBuilder { OnCreateFlatlandView on_create_view_callback_; OnDestroyFlatlandView on_destroy_view_callback_; OnUpdateView on_update_view_callback_; + OnCreateStudio on_create_studio_callback_; OnCreateSurface on_create_surface_callback_; OnSemanticsNodeUpdate on_semantics_node_update_callback_; OnRequestAnnounce on_request_announce_callback_; @@ -611,12 +619,16 @@ TEST_F(FlatlandPlatformViewTests, CreateSurfaceTest) { flutter::MakeDefaultContextOptions(flutter::ContextType::kRender)); std::shared_ptr external_view_embedder = std::make_shared(); + auto CreateStudioCallback = [gr_context]() { + return std::make_unique(gr_context.get()); + }; auto CreateSurfaceCallback = [&external_view_embedder, gr_context]() { return std::make_unique( "PlatformViewTest", external_view_embedder, gr_context.get()); }; auto platform_view = PlatformViewBuilder(delegate, std::move(task_runners)) + .SetCreateStudioCallback(CreateStudioCallback) .SetCreateSurfaceCallback(CreateSurfaceCallback) .SetExternalViewEmbedder(external_view_embedder) .Build(); From 6c444b7d75ce319f40b07a2be3113929a5fe4d60 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 22 Mar 2023 05:06:09 +0000 Subject: [PATCH 045/142] Fix ocmpile and lint --- .../fuchsia/flutter/tests/flatland_platform_view_unittest.cc | 2 +- shell/testing/tester_main.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index cc4ba273a6136..9b4a8524ae038 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -620,7 +620,7 @@ TEST_F(FlatlandPlatformViewTests, CreateSurfaceTest) { std::shared_ptr external_view_embedder = std::make_shared(); auto CreateStudioCallback = [gr_context]() { - return std::make_unique(gr_context.get()); + return std::make_unique(gr_context.get()); }; auto CreateSurfaceCallback = [&external_view_embedder, gr_context]() { return std::make_unique( diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index fff20be376814..d0a3711505b44 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -70,7 +70,7 @@ class TesterExternalViewEmbedder : public ExternalViewEmbedder { class TesterGPUStudioSoftware : public GPUStudioSoftware { public: - TesterGPUStudioSoftware(GPUSurfaceSoftwareDelegate* delegate) + explicit TesterGPUStudioSoftware(GPUSurfaceSoftwareDelegate* delegate) : GPUStudioSoftware(delegate) {} bool EnableRasterCache() const override { return false; } From 842a1bb45ee951fb13c31e17a445851d4fe3ae3d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 22 Mar 2023 18:06:36 +0000 Subject: [PATCH 046/142] Fix lint --- shell/common/shell_test_platform_view_vulkan.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 1c3cc22cc684e..04f55c245e9b9 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -189,8 +189,8 @@ ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( : vk_(std::move(vk)), shell_test_external_view_embedder_( std::move(shell_test_external_view_embedder)), - context_(context), - memory_allocator_(memory_allocator) {} + context_(std::move(context)), + memory_allocator_(std::move(memory_allocator)) {} ShellTestPlatformViewVulkan::OffScreenSurface::~OffScreenSurface() {} From 99116ef60f326ee43710d839024cfe0f2260963d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 22 Mar 2023 19:42:54 +0000 Subject: [PATCH 047/142] Fix GL bug --- shell/platform/embedder/embedder_studio_gl.cc | 14 +++++++++----- shell/platform/embedder/embedder_studio_gl.h | 2 ++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/shell/platform/embedder/embedder_studio_gl.cc b/shell/platform/embedder/embedder_studio_gl.cc index 29693949ad619..c749c31515e92 100644 --- a/shell/platform/embedder/embedder_studio_gl.cc +++ b/shell/platform/embedder/embedder_studio_gl.cc @@ -104,7 +104,7 @@ std::unique_ptr EmbedderStudioGL::CreateGPUStudio() { if (!IsValid()) { return nullptr; } - auto studio = std::make_unique(main_context_, this); + auto studio = std::make_unique(MainContext(), this); if (!studio->IsValid()) { return nullptr; } @@ -114,12 +114,9 @@ std::unique_ptr EmbedderStudioGL::CreateGPUStudio() { // |EmbedderStudio| std::unique_ptr EmbedderStudioGL::CreateSurface() { - if (!main_context_) { - main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); - } const bool render_to_surface = !external_view_embedder_; return std::make_unique( - main_context_, + MainContext(), this, // GPU surface GL delegate render_to_surface // render to surface ); @@ -148,4 +145,11 @@ sk_sp EmbedderStudioGL::CreateResourceContext() const { return nullptr; } +sk_sp EmbedderStudioGL::MainContext() { + if (!main_context_) { + main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); + } + return main_context_; +} + } // namespace flutter diff --git a/shell/platform/embedder/embedder_studio_gl.h b/shell/platform/embedder/embedder_studio_gl.h index 4813cb48b0e3f..74b0620b80776 100644 --- a/shell/platform/embedder/embedder_studio_gl.h +++ b/shell/platform/embedder/embedder_studio_gl.h @@ -78,6 +78,8 @@ class EmbedderStudioGL final : public EmbedderStudio, std::shared_ptr external_view_embedder_; + sk_sp MainContext(); + FML_DISALLOW_COPY_AND_ASSIGN(EmbedderStudioGL); }; From de857a7a69b2e3cbebc56594b848a3479f6c970d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 22 Mar 2023 19:43:17 +0000 Subject: [PATCH 048/142] Fix order --- shell/common/shell_test_platform_view_gl.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/common/shell_test_platform_view_gl.h b/shell/common/shell_test_platform_view_gl.h index eb2c1b4ef55ec..635bba96efa03 100644 --- a/shell/common/shell_test_platform_view_gl.h +++ b/shell/common/shell_test_platform_view_gl.h @@ -42,10 +42,10 @@ class ShellTestPlatformViewGL : public ShellTestPlatformView, sk_sp main_context_; // |PlatformView| - std::unique_ptr CreateRenderingSurface(int64_t view_id) override; + std::unique_ptr CreateRenderingStudio() override; // |PlatformView| - std::unique_ptr CreateRenderingStudio() override; + std::unique_ptr CreateRenderingSurface(int64_t view_id) override; // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; From 4fa18ccae71b7d42502487ea2eb5440b956d3e82 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 22 Mar 2023 21:57:30 +0000 Subject: [PATCH 049/142] Try to revert ShellTestPlatformViewVulkan --- .../common/shell_test_platform_view_vulkan.cc | 120 +++++++++--------- .../common/shell_test_platform_view_vulkan.h | 26 ++-- 2 files changed, 65 insertions(+), 81 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 04f55c245e9b9..ce40fcb496c1f 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -6,10 +6,9 @@ #include -// #include "flutter/common/graphics/persistent_cache.h" +#include "flutter/common/graphics/persistent_cache.h" #include "flutter/flutter_vma/flutter_skia_vma.h" #include "flutter/shell/common/context_options.h" -#include "flutter/shell/gpu/gpu_studio_vulkan.h" #include "flutter/vulkan/vulkan_skia_proc_table.h" #include "flutter/vulkan/vulkan_utilities.h" @@ -39,9 +38,52 @@ ShellTestPlatformViewVulkan::ShellTestPlatformViewVulkan( create_vsync_waiter_(std::move(create_vsync_waiter)), vsync_clock_(std::move(vsync_clock)), proc_table_(fml::MakeRefCounted(VULKAN_SO_PATH)), + shell_test_external_view_embedder_( + std::move(shell_test_external_view_embedder)) {} + +ShellTestPlatformViewVulkan::~ShellTestPlatformViewVulkan() = default; + +std::unique_ptr ShellTestPlatformViewVulkan::CreateVSyncWaiter() { + return create_vsync_waiter_(); +} + +void ShellTestPlatformViewVulkan::SimulateVSync() { + vsync_clock_->SimulateVSync(); +} + +// |PlatformView| +std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface( + int64_t view_id) { + return std::make_unique(proc_table_, + shell_test_external_view_embedder_); +} + +// |PlatformView| +std::shared_ptr +ShellTestPlatformViewVulkan::CreateExternalViewEmbedder() { + return shell_test_external_view_embedder_; +} + +// |PlatformView| +PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() { + return [](DefaultPointerDataDispatcher::Delegate& delegate) { + return std::make_unique(delegate); + }; +} + +// TODO(gw280): This code was forked from vulkan_window.cc specifically for +// shell_test. +// We need to merge this functionality back into //vulkan. +// https://github.com/flutter/flutter/issues/51132 +ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( + fml::RefPtr vk, + std::shared_ptr + shell_test_external_view_embedder) + : valid_(false), + vk_(std::move(vk)), shell_test_external_view_embedder_( std::move(shell_test_external_view_embedder)) { - if (!proc_table_ || !proc_table_->HasAcquiredMandatoryProcAddresses()) { + if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; return; } @@ -52,10 +94,10 @@ ShellTestPlatformViewVulkan::ShellTestPlatformViewVulkan( }; application_ = std::make_unique( - *proc_table_, "FlutterTest", std::move(extensions), - VK_MAKE_VERSION(1, 0, 0), VK_MAKE_VERSION(1, 1, 0), true); + *vk_, "FlutterTest", std::move(extensions), VK_MAKE_VERSION(1, 0, 0), + VK_MAKE_VERSION(1, 1, 0), true); - if (!application_->IsValid() || !proc_table_->AreInstanceProcsSetup()) { + if (!application_->IsValid() || !vk_->AreInstanceProcsSetup()) { // Make certain the application instance was created and it set up the // instance proc table entries. FML_DLOG(ERROR) << "Instance proc addresses have not been set up."; @@ -63,10 +105,11 @@ ShellTestPlatformViewVulkan::ShellTestPlatformViewVulkan( } // Create the device. + logical_device_ = application_->AcquireFirstCompatibleLogicalDevice(); if (logical_device_ == nullptr || !logical_device_->IsValid() || - !proc_table_->AreDeviceProcsSetup()) { + !vk_->AreDeviceProcsSetup()) { // Make certain the device was created and it set up the device proc table // entries. FML_DLOG(ERROR) << "Device proc addresses have not been set up."; @@ -76,51 +119,18 @@ ShellTestPlatformViewVulkan::ShellTestPlatformViewVulkan( memory_allocator_ = FlutterSkiaVulkanMemoryAllocator::Make( application_->GetAPIVersion(), application_->GetInstance(), logical_device_->GetPhysicalDeviceHandle(), logical_device_->GetHandle(), - proc_table_, true); + vk_, true); // Create the Skia GrContext. if (!CreateSkiaGrContext()) { FML_DLOG(ERROR) << "Could not create Skia context."; + return; } -} - -ShellTestPlatformViewVulkan::~ShellTestPlatformViewVulkan() = default; -std::unique_ptr ShellTestPlatformViewVulkan::CreateVSyncWaiter() { - return create_vsync_waiter_(); + valid_ = true; } -void ShellTestPlatformViewVulkan::SimulateVSync() { - vsync_clock_->SimulateVSync(); -} - -// |PlatformView| -std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingStudio() { - return std::make_unique(context_); -} - -// |PlatformView| -std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface( - int64_t view_id) { - return std::make_unique(proc_table_, - shell_test_external_view_embedder_, - context_, memory_allocator_); -} - -// |PlatformView| -std::shared_ptr -ShellTestPlatformViewVulkan::CreateExternalViewEmbedder() { - return shell_test_external_view_embedder_; -} - -// |PlatformView| -PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() { - return [](DefaultPointerDataDispatcher::Delegate& delegate) { - return std::make_unique(delegate); - }; -} - -bool ShellTestPlatformViewVulkan::CreateSkiaGrContext() { +bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaGrContext() { GrVkBackendContext backend_context; if (!CreateSkiaBackendContext(&backend_context)) { @@ -146,9 +156,9 @@ bool ShellTestPlatformViewVulkan::CreateSkiaGrContext() { return true; } -bool ShellTestPlatformViewVulkan::CreateSkiaBackendContext( +bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaBackendContext( GrVkBackendContext* context) { - auto getProc = CreateSkiaGetProc(proc_table_); + auto getProc = CreateSkiaGetProc(vk_); if (getProc == nullptr) { FML_DLOG(ERROR) << "GetProcAddress is null"; @@ -176,26 +186,10 @@ bool ShellTestPlatformViewVulkan::CreateSkiaBackendContext( return true; } -// TODO(gw280): This code was forked from vulkan_window.cc specifically for -// shell_test. -// We need to merge this functionality back into //vulkan. -// https://github.com/flutter/flutter/issues/51132 -ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( - fml::RefPtr vk, - std::shared_ptr - shell_test_external_view_embedder, - sk_sp context, - sk_sp memory_allocator) - : vk_(std::move(vk)), - shell_test_external_view_embedder_( - std::move(shell_test_external_view_embedder)), - context_(std::move(context)), - memory_allocator_(std::move(memory_allocator)) {} - ShellTestPlatformViewVulkan::OffScreenSurface::~OffScreenSurface() {} bool ShellTestPlatformViewVulkan::OffScreenSurface::IsValid() { - return true; + return valid_; } std::unique_ptr diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 6d6f1dc540971..323112ceba3ad 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -33,9 +33,7 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { public: OffScreenSurface(fml::RefPtr vk, std::shared_ptr - shell_test_external_view_embedder, - sk_sp context, - sk_sp memory_allocator); + shell_test_external_view_embedder); ~OffScreenSurface() override; @@ -51,11 +49,17 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { GrDirectContext* GetContext() override; private: + bool valid_; fml::RefPtr vk_; std::shared_ptr shell_test_external_view_embedder_; - sk_sp context_; + std::unique_ptr application_; + std::unique_ptr logical_device_; sk_sp memory_allocator_; + sk_sp context_; + + bool CreateSkiaGrContext(); + bool CreateSkiaBackendContext(GrVkBackendContext* context); FML_DISALLOW_COPY_AND_ASSIGN(OffScreenSurface); }; @@ -69,17 +73,6 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { std::shared_ptr shell_test_external_view_embedder_; - sk_sp context_; - - std::unique_ptr application_; - - std::unique_ptr logical_device_; - - sk_sp memory_allocator_; - - // |PlatformView| - std::unique_ptr CreateRenderingStudio() override; - // |PlatformView| std::unique_ptr CreateRenderingSurface(int64_t view_id) override; @@ -92,9 +85,6 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { // |PlatformView| PointerDataDispatcherMaker GetDispatcherMaker() override; - bool CreateSkiaGrContext(); - bool CreateSkiaBackendContext(GrVkBackendContext* context); - FML_DISALLOW_COPY_AND_ASSIGN(ShellTestPlatformViewVulkan); }; From 8048a3a1515f25d6c1d50598e0e82e2d1bfe5c27 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 23 Mar 2023 07:33:23 +0000 Subject: [PATCH 050/142] OffScreenContext --- .../common/shell_test_platform_view_vulkan.cc | 50 +++++++++------ .../common/shell_test_platform_view_vulkan.h | 64 ++++++++++++++++--- 2 files changed, 86 insertions(+), 28 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index ce40fcb496c1f..3c7662fda42ca 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -9,6 +9,7 @@ #include "flutter/common/graphics/persistent_cache.h" #include "flutter/flutter_vma/flutter_skia_vma.h" #include "flutter/shell/common/context_options.h" +#include "flutter/shell/gpu/gpu_studio_vulkan.h" #include "flutter/vulkan/vulkan_skia_proc_table.h" #include "flutter/vulkan/vulkan_utilities.h" @@ -51,10 +52,21 @@ void ShellTestPlatformViewVulkan::SimulateVSync() { vsync_clock_->SimulateVSync(); } +// |PlatformView| +std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingStudio() { + if (!offscreen_context_) { + offscreen_context_ = std::unique_ptr(); + } + return std::make_unique(offscreen_context_); +} + // |PlatformView| std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface( int64_t view_id) { - return std::make_unique(proc_table_, + if (!offscreen_context_) { + offscreen_context_ = std::unique_ptr(); + } + return std::make_unique(offscreen_context_, shell_test_external_view_embedder_); } @@ -75,14 +87,9 @@ PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() { // shell_test. // We need to merge this functionality back into //vulkan. // https://github.com/flutter/flutter/issues/51132 -ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( - fml::RefPtr vk, - std::shared_ptr - shell_test_external_view_embedder) - : valid_(false), - vk_(std::move(vk)), - shell_test_external_view_embedder_( - std::move(shell_test_external_view_embedder)) { +ShellTestPlatformViewVulkan::OffScreenContext::OffScreenContext( + fml::RefPtr vk) + : vk_(std::move(vk)) { if (!vk_ || !vk_->HasAcquiredMandatoryProcAddresses()) { FML_DLOG(ERROR) << "Proc table has not acquired mandatory proc addresses."; return; @@ -124,13 +131,12 @@ ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( // Create the Skia GrContext. if (!CreateSkiaGrContext()) { FML_DLOG(ERROR) << "Could not create Skia context."; - return; } - - valid_ = true; } -bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaGrContext() { +ShellTestPlatformViewVulkan::OffScreenContext::~OffScreenContext() {} + +bool ShellTestPlatformViewVulkan::OffScreenContext::CreateSkiaGrContext() { GrVkBackendContext backend_context; if (!CreateSkiaBackendContext(&backend_context)) { @@ -156,7 +162,7 @@ bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaGrContext() { return true; } -bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaBackendContext( +bool ShellTestPlatformViewVulkan::OffScreenContext::CreateSkiaBackendContext( GrVkBackendContext* context) { auto getProc = CreateSkiaGetProc(vk_); @@ -186,10 +192,18 @@ bool ShellTestPlatformViewVulkan::OffScreenSurface::CreateSkiaBackendContext( return true; } +ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( + const std::shared_ptr& offscreen_context, + std::shared_ptr + shell_test_external_view_embedder) + : shell_test_external_view_embedder_( + std::move(shell_test_external_view_embedder)), + offscreen_context_(offscreen_context) {} + ShellTestPlatformViewVulkan::OffScreenSurface::~OffScreenSurface() {} bool ShellTestPlatformViewVulkan::OffScreenSurface::IsValid() { - return valid_; + return GetContext(); } std::unique_ptr @@ -197,8 +211,8 @@ ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame( const SkISize& size) { auto image_info = SkImageInfo::Make(size, SkColorType::kRGBA_8888_SkColorType, SkAlphaType::kOpaque_SkAlphaType); - auto surface = SkSurface::MakeRenderTarget( - context_.get(), skgpu::Budgeted::kNo, image_info, 0, nullptr); + auto surface = SkSurface::MakeRenderTarget(GetContext(), skgpu::Budgeted::kNo, + image_info, 0, nullptr); SurfaceFrame::SubmitCallback callback = [](const SurfaceFrame&, DlCanvas* canvas) -> bool { canvas->Flush(); @@ -214,7 +228,7 @@ ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame( } GrDirectContext* ShellTestPlatformViewVulkan::OffScreenSurface::GetContext() { - return context_.get(); + return offscreen_context_->GetContext().get(); } SkMatrix ShellTestPlatformViewVulkan::OffScreenSurface::GetRootTransformation() diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 323112ceba3ad..ff144b3202fba 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -29,9 +29,55 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { void SimulateVSync() override; private: + class OffScreenContext { + public: + OffScreenContext(fml::RefPtr vk); + + ~OffScreenContext(); + + sk_sp GetContext() { return context_; } + + private: + fml::RefPtr vk_; + std::unique_ptr application_; + std::unique_ptr logical_device_; + sk_sp memory_allocator_; + sk_sp context_; + + bool CreateSkiaGrContext(); + bool CreateSkiaBackendContext(GrVkBackendContext* context); + + FML_DISALLOW_COPY_AND_ASSIGN(OffScreenContext); + }; + + class OffScreenStudio : public flutter::Studio { + public: + //------------------------------------------------------------------------------ + /// @brief Create a GPUStudioVulkan while letting it reuse an existing + /// GrDirectContext. + /// + OffScreenStudio(const std::shared_ptr& offscreen_context) + : offscreen_context_(offscreen_context) {} + + ~OffScreenStudio() override = default; + + // |Studio| + bool IsValid() override { return GetContext(); } + + // |Studio| + GrDirectContext* GetContext() override { + return offscreen_context_->GetContext().get(); + } + + private: + std::shared_ptr offscreen_context_; + + FML_DISALLOW_COPY_AND_ASSIGN(OffScreenStudio); + }; + class OffScreenSurface : public flutter::Surface { public: - OffScreenSurface(fml::RefPtr vk, + OffScreenSurface(const std::shared_ptr& offscreen_context, std::shared_ptr shell_test_external_view_embedder); @@ -43,23 +89,16 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { // |Surface| std::unique_ptr AcquireFrame(const SkISize& size) override; + // |Surface| SkMatrix GetRootTransformation() const override; // |Surface| GrDirectContext* GetContext() override; private: - bool valid_; - fml::RefPtr vk_; std::shared_ptr shell_test_external_view_embedder_; - std::unique_ptr application_; - std::unique_ptr logical_device_; - sk_sp memory_allocator_; - sk_sp context_; - - bool CreateSkiaGrContext(); - bool CreateSkiaBackendContext(GrVkBackendContext* context); + std::shared_ptr offscreen_context_; FML_DISALLOW_COPY_AND_ASSIGN(OffScreenSurface); }; @@ -73,6 +112,11 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { std::shared_ptr shell_test_external_view_embedder_; + std::shared_ptr offscreen_context_; + + // |PlatformView| + std::unique_ptr CreateRenderingStudio() override; + // |PlatformView| std::unique_ptr CreateRenderingSurface(int64_t view_id) override; From 2c9c7e826e2a1d9c9468b02a981515900e98b637 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 23 Mar 2023 07:48:20 +0000 Subject: [PATCH 051/142] Fix vulkan bug --- shell/common/shell_test_platform_view_vulkan.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 3c7662fda42ca..72d8016b33afe 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -55,7 +55,7 @@ void ShellTestPlatformViewVulkan::SimulateVSync() { // |PlatformView| std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingStudio() { if (!offscreen_context_) { - offscreen_context_ = std::unique_ptr(); + offscreen_context_ = std::make_shared(proc_table_); } return std::make_unique(offscreen_context_); } @@ -64,7 +64,7 @@ std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingStudio() { std::unique_ptr ShellTestPlatformViewVulkan::CreateRenderingSurface( int64_t view_id) { if (!offscreen_context_) { - offscreen_context_ = std::unique_ptr(); + offscreen_context_ = std::make_shared(proc_table_); } return std::make_unique(offscreen_context_, shell_test_external_view_embedder_); From adf3515e45d375621553234d2273ee825af3e45d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 23 Mar 2023 20:57:03 +0000 Subject: [PATCH 052/142] Remove unnecessary methods of Surface. --- flow/surface.cc | 20 -------------- flow/surface.h | 10 ------- shell/common/rasterizer.h | 4 +-- shell/common/snapshot_controller.h | 3 ++- shell/common/snapshot_controller_impeller.cc | 6 ++--- shell/common/snapshot_controller_skia.cc | 26 +++++++------------ shell/gpu/gpu_surface_gl_impeller.cc | 25 ------------------ shell/gpu/gpu_surface_gl_impeller.h | 15 ----------- shell/gpu/gpu_surface_gl_skia.cc | 15 ----------- shell/gpu/gpu_surface_gl_skia.h | 9 ------- shell/gpu/gpu_surface_vulkan_impeller.cc | 17 ------------ shell/gpu/gpu_surface_vulkan_impeller.h | 9 ------- .../external_view_embedder_unittests.cc | 5 ---- 13 files changed, 15 insertions(+), 149 deletions(-) diff --git a/flow/surface.cc b/flow/surface.cc index fbd3d427c2de2..4461ce3888860 100644 --- a/flow/surface.cc +++ b/flow/surface.cc @@ -10,26 +10,6 @@ Surface::Surface() = default; Surface::~Surface() = default; -std::unique_ptr Surface::MakeRenderContextCurrent() { - return std::make_unique(true); -} - -bool Surface::ClearRenderContext() { - return false; -} - -bool Surface::AllowsDrawingWhenGpuDisabled() const { - return true; -} - -bool Surface::EnableRasterCache() const { - return true; -} - -impeller::AiksContext* Surface::GetAiksContext() const { - return nullptr; -} - Surface::SurfaceData Surface::GetSurfaceData() const { return {}; } diff --git a/flow/surface.h b/flow/surface.h index 5cc5d6def08a1..e594d08a01232 100644 --- a/flow/surface.h +++ b/flow/surface.h @@ -41,16 +41,6 @@ class Surface { virtual GrDirectContext* GetContext() = 0; - virtual std::unique_ptr MakeRenderContextCurrent(); - - virtual bool ClearRenderContext(); - - virtual bool AllowsDrawingWhenGpuDisabled() const; - - virtual bool EnableRasterCache() const; - - virtual impeller::AiksContext* GetAiksContext() const; - /// Capture the `SurfaceData` currently present in the surface. /// /// Not guaranteed to work on all setups and not intended to be used in diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index bc12025d05820..58d38e55174b5 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -503,9 +503,7 @@ class Rasterizer final : public SnapshotDelegate, fml::Milliseconds GetFrameBudget() const override; // |SnapshotController::Delegate| - const std::unique_ptr& GetSurface() const override { - return surface_; - } + Studio* GetStudio() const override { return studio_.get(); } // |SnapshotController::Delegate| const std::unique_ptr& GetSnapshotSurfaceProducer() diff --git a/shell/common/snapshot_controller.h b/shell/common/snapshot_controller.h index 11651325edd43..3d44f3bf5bbf5 100644 --- a/shell/common/snapshot_controller.h +++ b/shell/common/snapshot_controller.h @@ -7,6 +7,7 @@ #include "flutter/common/settings.h" #include "flutter/display_list/image/dl_image.h" +#include "flutter/flow/studio.h" #include "flutter/flow/surface.h" #include "flutter/fml/synchronization/sync_switch.h" #include "flutter/lib/ui/snapshot_delegate.h" @@ -19,7 +20,7 @@ class SnapshotController { class Delegate { public: virtual ~Delegate() = default; - virtual const std::unique_ptr& GetSurface() const = 0; + virtual Studio* GetStudio() const = 0; virtual const std::unique_ptr& GetSnapshotSurfaceProducer() const = 0; virtual std::shared_ptr GetIsGpuDisabledSyncSwitch() diff --git a/shell/common/snapshot_controller_impeller.cc b/shell/common/snapshot_controller_impeller.cc index 5e7317805812d..f909b8acd3c1b 100644 --- a/shell/common/snapshot_controller_impeller.cc +++ b/shell/common/snapshot_controller_impeller.cc @@ -36,10 +36,10 @@ sk_sp SnapshotControllerImpeller::DoMakeRasterSnapshot( impeller::DisplayListDispatcher dispatcher; display_list->Dispatch(dispatcher); impeller::Picture picture = dispatcher.EndRecordingAsPicture(); - if (GetDelegate().GetSurface() && - GetDelegate().GetSurface()->GetAiksContext()) { + if (GetDelegate().GetStudio() && + GetDelegate().GetStudio()->GetAiksContext()) { impeller::AiksContext* context = - GetDelegate().GetSurface()->GetAiksContext(); + GetDelegate().GetStudio()->GetAiksContext(); auto max_size = context->GetContext() ->GetResourceAllocator() diff --git a/shell/common/snapshot_controller_skia.cc b/shell/common/snapshot_controller_skia.cc index 720854885eff0..fc63f76f84702 100644 --- a/shell/common/snapshot_controller_skia.cc +++ b/shell/common/snapshot_controller_skia.cc @@ -53,20 +53,13 @@ sk_sp SnapshotControllerSkia::DoMakeRasterSnapshot( SkImageInfo image_info = SkImageInfo::MakeN32Premul( size.width(), size.height(), SkColorSpace::MakeSRGB()); - std::unique_ptr pbuffer_surface; - Surface* snapshot_surface = nullptr; + Studio* snapshot_studio = nullptr; auto& delegate = GetDelegate(); - if (delegate.GetSurface() && delegate.GetSurface()->GetContext()) { - snapshot_surface = delegate.GetSurface().get(); - } else if (delegate.GetSnapshotSurfaceProducer()) { - pbuffer_surface = - delegate.GetSnapshotSurfaceProducer()->CreateSnapshotSurface(); - if (pbuffer_surface && pbuffer_surface->GetContext()) { - snapshot_surface = pbuffer_surface.get(); - } + if (delegate.GetStudio() && delegate.GetStudio()->GetContext()) { + snapshot_studio = delegate.GetStudio(); } - if (!snapshot_surface) { + if (!snapshot_studio) { // Raster surface is fine if there is no on screen surface. This might // happen in case of software rendering. sk_sp sk_surface = SkSurface::MakeRaster(image_info); @@ -79,14 +72,13 @@ sk_sp SnapshotControllerSkia::DoMakeRasterSnapshot( result = DrawSnapshot(surface, draw_callback); }) .SetIfFalse([&] { - FML_DCHECK(snapshot_surface); - auto context_switch = - snapshot_surface->MakeRenderContextCurrent(); + FML_DCHECK(snapshot_studio); + auto context_switch = snapshot_studio->MakeRenderContextCurrent(); if (!context_switch->GetResult()) { return; } - GrRecordingContext* context = snapshot_surface->GetContext(); + GrRecordingContext* context = snapshot_studio->GetContext(); auto max_size = context->maxRenderTargetSize(); double scale_factor = std::min( 1.0, static_cast(max_size) / @@ -136,8 +128,8 @@ sk_sp SnapshotControllerSkia::ConvertToRasterImage( // If the rasterizer does not have a surface with a GrContext, then it will // be unable to render a cross-context SkImage. The caller will need to // create the raster image on the IO thread. - if (GetDelegate().GetSurface() == nullptr || - GetDelegate().GetSurface()->GetContext() == nullptr) { + if (GetDelegate().GetStudio() == nullptr || + GetDelegate().GetStudio()->GetContext() == nullptr) { return nullptr; } diff --git a/shell/gpu/gpu_surface_gl_impeller.cc b/shell/gpu/gpu_surface_gl_impeller.cc index 2a7386613c781..c7e6a5e039c84 100644 --- a/shell/gpu/gpu_surface_gl_impeller.cc +++ b/shell/gpu/gpu_surface_gl_impeller.cc @@ -139,29 +139,4 @@ GrDirectContext* GPUSurfaceGLImpeller::GetContext() { return nullptr; } -// |Surface| -std::unique_ptr -GPUSurfaceGLImpeller::MakeRenderContextCurrent() { - return delegate_->GLContextMakeCurrent(); -} - -// |Surface| -bool GPUSurfaceGLImpeller::ClearRenderContext() { - return delegate_->GLContextClearCurrent(); -} - -bool GPUSurfaceGLImpeller::AllowsDrawingWhenGpuDisabled() const { - return delegate_->AllowsDrawingWhenGpuDisabled(); -} - -// |Surface| -bool GPUSurfaceGLImpeller::EnableRasterCache() const { - return false; -} - -// |Surface| -impeller::AiksContext* GPUSurfaceGLImpeller::GetAiksContext() const { - return aiks_context_.get(); -} - } // namespace flutter diff --git a/shell/gpu/gpu_surface_gl_impeller.h b/shell/gpu/gpu_surface_gl_impeller.h index 367bad23835ac..abfc5dfb32231 100644 --- a/shell/gpu/gpu_surface_gl_impeller.h +++ b/shell/gpu/gpu_surface_gl_impeller.h @@ -43,21 +43,6 @@ class GPUSurfaceGLImpeller final : public Surface { // |Surface| GrDirectContext* GetContext() override; - // |Surface| - std::unique_ptr MakeRenderContextCurrent() override; - - // |Surface| - bool ClearRenderContext() override; - - // |Surface| - bool AllowsDrawingWhenGpuDisabled() const override; - - // |Surface| - bool EnableRasterCache() const override; - - // |Surface| - impeller::AiksContext* GetAiksContext() const override; - FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceGLImpeller); }; diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index e5662366b1ea6..e4b81f6605641 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -321,19 +321,4 @@ GrDirectContext* GPUSurfaceGLSkia::GetContext() { return context_.get(); } -// |Surface| -std::unique_ptr GPUSurfaceGLSkia::MakeRenderContextCurrent() { - return delegate_->GLContextMakeCurrent(); -} - -// |Surface| -bool GPUSurfaceGLSkia::ClearRenderContext() { - return delegate_->GLContextClearCurrent(); -} - -// |Surface| -bool GPUSurfaceGLSkia::AllowsDrawingWhenGpuDisabled() const { - return delegate_->AllowsDrawingWhenGpuDisabled(); -} - } // namespace flutter diff --git a/shell/gpu/gpu_surface_gl_skia.h b/shell/gpu/gpu_surface_gl_skia.h index 1cbb4c50ecd29..f242f76f02662 100644 --- a/shell/gpu/gpu_surface_gl_skia.h +++ b/shell/gpu/gpu_surface_gl_skia.h @@ -43,15 +43,6 @@ class GPUSurfaceGLSkia : public Surface { // |Surface| GrDirectContext* GetContext() override; - // |Surface| - std::unique_ptr MakeRenderContextCurrent() override; - - // |Surface| - bool ClearRenderContext() override; - - // |Surface| - bool AllowsDrawingWhenGpuDisabled() const override; - private: bool CreateOrUpdateSurfaces(const SkISize& size); diff --git a/shell/gpu/gpu_surface_vulkan_impeller.cc b/shell/gpu/gpu_surface_vulkan_impeller.cc index 0e3854900a54f..a2dc1607b77da 100644 --- a/shell/gpu/gpu_surface_vulkan_impeller.cc +++ b/shell/gpu/gpu_surface_vulkan_impeller.cc @@ -109,21 +109,4 @@ GrDirectContext* GPUSurfaceVulkanImpeller::GetContext() { return nullptr; } -// |Surface| -std::unique_ptr -GPUSurfaceVulkanImpeller::MakeRenderContextCurrent() { - // This backend has no such concept. - return std::make_unique(true); -} - -// |Surface| -bool GPUSurfaceVulkanImpeller::EnableRasterCache() const { - return false; -} - -// |Surface| -impeller::AiksContext* GPUSurfaceVulkanImpeller::GetAiksContext() const { - return aiks_context_.get(); -} - } // namespace flutter diff --git a/shell/gpu/gpu_surface_vulkan_impeller.h b/shell/gpu/gpu_surface_vulkan_impeller.h index cf72b2e0e18c9..1514c1368c9fb 100644 --- a/shell/gpu/gpu_surface_vulkan_impeller.h +++ b/shell/gpu/gpu_surface_vulkan_impeller.h @@ -40,15 +40,6 @@ class GPUSurfaceVulkanImpeller final : public Surface { // |Surface| GrDirectContext* GetContext() override; - // |Surface| - std::unique_ptr MakeRenderContextCurrent() override; - - // |Surface| - bool EnableRasterCache() const override; - - // |Surface| - impeller::AiksContext* GetAiksContext() const override; - FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceVulkanImpeller); }; 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 b9c527b16c710..af933e4251f2d 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 @@ -57,11 +57,6 @@ class SurfaceMock : public Surface { MOCK_METHOD(SkMatrix, GetRootTransformation, (), (const, override)); MOCK_METHOD(GrDirectContext*, GetContext, (), (override)); - - MOCK_METHOD(std::unique_ptr, - MakeRenderContextCurrent, - (), - (override)); }; fml::RefPtr GetThreadMergerFromPlatformThread( From 457894735fd6b3b9c784a23607e6c1b6b311a916 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 23 Mar 2023 22:54:26 +0000 Subject: [PATCH 053/142] Compile --- shell/gpu/gpu_surface_metal_impeller.h | 12 ------------ shell/gpu/gpu_surface_metal_impeller.mm | 20 -------------------- shell/gpu/gpu_surface_metal_skia.h | 5 ----- shell/gpu/gpu_surface_metal_skia.mm | 14 -------------- 4 files changed, 51 deletions(-) diff --git a/shell/gpu/gpu_surface_metal_impeller.h b/shell/gpu/gpu_surface_metal_impeller.h index 6254d851a5062..41340873638bb 100644 --- a/shell/gpu/gpu_surface_metal_impeller.h +++ b/shell/gpu/gpu_surface_metal_impeller.h @@ -44,18 +44,6 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalImpeller : public Surface { // |Surface| GrDirectContext* GetContext() override; - // |Surface| - std::unique_ptr MakeRenderContextCurrent() override; - - // |Surface| - bool AllowsDrawingWhenGpuDisabled() const override; - - // |Surface| - bool EnableRasterCache() const override; - - // |Surface| - impeller::AiksContext* GetAiksContext() const override; - FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceMetalImpeller); }; diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index bad9f26ca780d..8e3056e390514 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -113,26 +113,6 @@ return nullptr; } -// |Surface| -std::unique_ptr GPUSurfaceMetalImpeller::MakeRenderContextCurrent() { - // This backend has no such concept. - return std::make_unique(true); -} - -bool GPUSurfaceMetalImpeller::AllowsDrawingWhenGpuDisabled() const { - return delegate_->AllowsDrawingWhenGpuDisabled(); -} - -// |Surface| -bool GPUSurfaceMetalImpeller::EnableRasterCache() const { - return false; -} - -// |Surface| -impeller::AiksContext* GPUSurfaceMetalImpeller::GetAiksContext() const { - return aiks_context_.get(); -} - Surface::SurfaceData GPUSurfaceMetalImpeller::GetSurfaceData() const { if (!(last_drawable_ && [last_drawable_ conformsToProtocol:@protocol(CAMetalDrawable)])) { return {}; diff --git a/shell/gpu/gpu_surface_metal_skia.h b/shell/gpu/gpu_surface_metal_skia.h index c04f3213d51d2..da6cdc0efa24d 100644 --- a/shell/gpu/gpu_surface_metal_skia.h +++ b/shell/gpu/gpu_surface_metal_skia.h @@ -55,11 +55,6 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalSkia : public Surface { GrDirectContext* GetContext() override; // |Surface| - std::unique_ptr MakeRenderContextCurrent() override; - - // |Surface| - bool AllowsDrawingWhenGpuDisabled() const override; - std::unique_ptr AcquireFrameFromCAMetalLayer( const SkISize& frame_info); diff --git a/shell/gpu/gpu_surface_metal_skia.mm b/shell/gpu/gpu_surface_metal_skia.mm index 31a60f565b11b..ca8507c5546e8 100644 --- a/shell/gpu/gpu_surface_metal_skia.mm +++ b/shell/gpu/gpu_surface_metal_skia.mm @@ -244,18 +244,4 @@ return context_.get(); } -// |Surface| -std::unique_ptr GPUSurfaceMetalSkia::MakeRenderContextCurrent() { - // A context may either be necessary to render to the surface or to snapshot an offscreen - // surface. Either way, SkSL precompilation must be attempted. - sksl_precompiler_->PrecompileKnownSkSLsIfNecessary(GetContext()); - - // This backend has no such concept. - return std::make_unique(true); -} - -bool GPUSurfaceMetalSkia::AllowsDrawingWhenGpuDisabled() const { - return delegate_->AllowsDrawingWhenGpuDisabled(); -} - } // namespace flutter From c94c37198432466126a0eb7decd0f685114c59ab Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 24 Mar 2023 01:25:33 +0000 Subject: [PATCH 054/142] Try to fix Android snapshot --- shell/common/snapshot_controller_skia.cc | 6 ++++++ shell/common/snapshot_surface_producer.h | 4 ++-- shell/platform/android/android_context_gl_unittests.cc | 4 ++-- shell/platform/android/android_surface_gl_impeller.cc | 2 +- shell/platform/android/android_surface_gl_impeller.h | 2 +- shell/platform/android/android_surface_gl_skia.cc | 4 ++-- shell/platform/android/android_surface_gl_skia.h | 2 +- shell/platform/android/surface/android_surface.cc | 2 +- shell/platform/android/surface/android_surface.h | 2 +- shell/platform/android/surface/snapshot_surface_producer.cc | 5 ++--- shell/platform/android/surface/snapshot_surface_producer.h | 3 +-- 11 files changed, 20 insertions(+), 16 deletions(-) diff --git a/shell/common/snapshot_controller_skia.cc b/shell/common/snapshot_controller_skia.cc index fc63f76f84702..e5edaf65324c8 100644 --- a/shell/common/snapshot_controller_skia.cc +++ b/shell/common/snapshot_controller_skia.cc @@ -57,6 +57,12 @@ sk_sp SnapshotControllerSkia::DoMakeRasterSnapshot( auto& delegate = GetDelegate(); if (delegate.GetStudio() && delegate.GetStudio()->GetContext()) { snapshot_studio = delegate.GetStudio(); + } else if (delegate.GetSnapshotSurfaceProducer()) { + std::unique_ptr pbuffer_studio = + delegate.GetSnapshotSurfaceProducer()->CreateSnapshotStudio(); + if (pbuffer_studio && pbuffer_studio->GetContext()) { + snapshot_studio = pbuffer_studio.get(); + } } if (!snapshot_studio) { diff --git a/shell/common/snapshot_surface_producer.h b/shell/common/snapshot_surface_producer.h index ae505109beda8..9a00259b6e89e 100644 --- a/shell/common/snapshot_surface_producer.h +++ b/shell/common/snapshot_surface_producer.h @@ -7,7 +7,7 @@ #include -#include "flutter/flow/surface.h" +#include "flutter/flow/studio.h" namespace flutter { @@ -15,7 +15,7 @@ class SnapshotSurfaceProducer { public: virtual ~SnapshotSurfaceProducer() = default; - virtual std::unique_ptr CreateSnapshotSurface() = 0; + virtual std::unique_ptr CreateSnapshotStudio() = 0; }; } // namespace flutter diff --git a/shell/platform/android/android_context_gl_unittests.cc b/shell/platform/android/android_context_gl_unittests.cc index bf1c7a78407ec..faa9ed4820605 100644 --- a/shell/platform/android/android_context_gl_unittests.cc +++ b/shell/platform/android/android_context_gl_unittests.cc @@ -136,7 +136,7 @@ TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNotNull) { android_surface->SetNativeWindow(window); auto onscreen_surface = android_surface->GetOnscreenSurface(); EXPECT_NE(onscreen_surface, nullptr); - android_surface->CreateSnapshotSurface(); + android_surface->CreateSnapshotStudio(); EXPECT_EQ(onscreen_surface, android_surface->GetOnscreenSurface()); } @@ -160,7 +160,7 @@ TEST(AndroidSurfaceGL, CreateSnapshopSurfaceWhenOnscreenSurfaceIsNull) { auto android_surface = std::make_unique(android_context, jni); EXPECT_EQ(android_surface->GetOnscreenSurface(), nullptr); - android_surface->CreateSnapshotSurface(); + android_surface->CreateSnapshotStudio(); EXPECT_NE(android_surface->GetOnscreenSurface(), nullptr); } diff --git a/shell/platform/android/android_surface_gl_impeller.cc b/shell/platform/android/android_surface_gl_impeller.cc index 8cf716c594af9..5c6e74113deb9 100644 --- a/shell/platform/android/android_surface_gl_impeller.cc +++ b/shell/platform/android/android_surface_gl_impeller.cc @@ -252,7 +252,7 @@ bool AndroidSurfaceGLImpeller::SetNativeWindow( } // |AndroidSurface| -std::unique_ptr AndroidSurfaceGLImpeller::CreateSnapshotSurface() { +std::unique_ptr AndroidSurfaceGLImpeller::CreateSnapshotStudio() { FML_UNREACHABLE(); } diff --git a/shell/platform/android/android_surface_gl_impeller.h b/shell/platform/android/android_surface_gl_impeller.h index d455242ff46c7..8164bf7416bda 100644 --- a/shell/platform/android/android_surface_gl_impeller.h +++ b/shell/platform/android/android_surface_gl_impeller.h @@ -50,7 +50,7 @@ class AndroidSurfaceGLImpeller final : public GPUSurfaceGLDelegate, bool SetNativeWindow(fml::RefPtr window) override; // |AndroidSurface| - std::unique_ptr CreateSnapshotSurface() override; + std::unique_ptr CreateSnapshotStudio() override; // |AndroidSurface| std::shared_ptr GetImpellerContext() override; diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index 5b094bef6f342..3fc3e60c1d6ea 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -227,7 +227,7 @@ AndroidContextGLSkia* AndroidSurfaceGLSkia::GLContextPtr() const { return reinterpret_cast(android_context_.get()); } -std::unique_ptr AndroidSurfaceGLSkia::CreateSnapshotSurface() { +std::unique_ptr AndroidSurfaceGLSkia::CreateSnapshotStudio() { if (!onscreen_surface_ || !onscreen_surface_->IsValid()) { onscreen_surface_ = GLContextPtr()->CreatePbufferSurface(); } @@ -238,7 +238,7 @@ std::unique_ptr AndroidSurfaceGLSkia::CreateSnapshotSurface() { GLContextPtr()->SetMainSkiaContext(main_skia_context); } - return std::make_unique(main_skia_context, this, true); + return std::make_unique(main_skia_context, this); } } // namespace flutter diff --git a/shell/platform/android/android_surface_gl_skia.h b/shell/platform/android/android_surface_gl_skia.h index 43b731a9829d6..d7e8a843cbf46 100644 --- a/shell/platform/android/android_surface_gl_skia.h +++ b/shell/platform/android/android_surface_gl_skia.h @@ -53,7 +53,7 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, bool SetNativeWindow(fml::RefPtr window) override; // |AndroidSurface| - virtual std::unique_ptr CreateSnapshotSurface() override; + virtual std::unique_ptr CreateSnapshotStudio() override; // |GPUSurfaceGLDelegate| std::unique_ptr GLContextMakeCurrent() override; diff --git a/shell/platform/android/surface/android_surface.cc b/shell/platform/android/surface/android_surface.cc index ab96387edbd77..6d158abf885f2 100644 --- a/shell/platform/android/surface/android_surface.cc +++ b/shell/platform/android/surface/android_surface.cc @@ -15,7 +15,7 @@ AndroidSurface::AndroidSurface( AndroidSurface::~AndroidSurface() = default; -std::unique_ptr AndroidSurface::CreateSnapshotSurface() { +std::unique_ptr AndroidSurface::CreateSnapshotStudio() { return nullptr; } diff --git a/shell/platform/android/surface/android_surface.h b/shell/platform/android/surface/android_surface.h index bc5414a1bd78e..8f69472c3fbde 100644 --- a/shell/platform/android/surface/android_surface.h +++ b/shell/platform/android/surface/android_surface.h @@ -45,7 +45,7 @@ class AndroidSurface { virtual bool SetNativeWindow(fml::RefPtr window) = 0; - virtual std::unique_ptr CreateSnapshotSurface(); + virtual std::unique_ptr CreateSnapshotStudio(); virtual std::shared_ptr GetImpellerContext(); diff --git a/shell/platform/android/surface/snapshot_surface_producer.cc b/shell/platform/android/surface/snapshot_surface_producer.cc index 3ca4c37f3ce6a..500db668e3570 100644 --- a/shell/platform/android/surface/snapshot_surface_producer.cc +++ b/shell/platform/android/surface/snapshot_surface_producer.cc @@ -10,9 +10,8 @@ AndroidSnapshotSurfaceProducer::AndroidSnapshotSurfaceProducer( AndroidSurface& android_surface) : android_surface_(android_surface) {} -std::unique_ptr -AndroidSnapshotSurfaceProducer::CreateSnapshotSurface() { - return android_surface_.CreateSnapshotSurface(); +std::unique_ptr AndroidSnapshotSurfaceProducer::CreateSnapshotStudio() { + return android_surface_.CreateSnapshotStudio(); } } // namespace flutter diff --git a/shell/platform/android/surface/snapshot_surface_producer.h b/shell/platform/android/surface/snapshot_surface_producer.h index 5ec8c68b2f457..4c7a9acee49d9 100644 --- a/shell/platform/android/surface/snapshot_surface_producer.h +++ b/shell/platform/android/surface/snapshot_surface_producer.h @@ -5,7 +5,6 @@ #ifndef SHELL_PLATFORM_ANDROID_SURFACE_SNAPSHOT_SURFACE_PRODUCER_H_ #define SHELL_PLATFORM_ANDROID_SURFACE_SNAPSHOT_SURFACE_PRODUCER_H_ -#include "flutter/flow/surface.h" #include "flutter/shell/common/snapshot_surface_producer.h" #include "flutter/shell/platform/android/surface/android_surface.h" @@ -16,7 +15,7 @@ class AndroidSnapshotSurfaceProducer : public SnapshotSurfaceProducer { explicit AndroidSnapshotSurfaceProducer(AndroidSurface& android_surface); // |SnapshotSurfaceProducer| - std::unique_ptr CreateSnapshotSurface() override; + std::unique_ptr CreateSnapshotStudio() override; private: AndroidSurface& android_surface_; From d00abbf189a43b231d32ae008c16c609e8fca3ab Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 24 Mar 2023 01:30:38 +0000 Subject: [PATCH 055/142] Fix compile --- shell/platform/android/android_surface_gl_impeller.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/android/android_surface_gl_impeller.cc b/shell/platform/android/android_surface_gl_impeller.cc index 5c6e74113deb9..0bd9d88bc1533 100644 --- a/shell/platform/android/android_surface_gl_impeller.cc +++ b/shell/platform/android/android_surface_gl_impeller.cc @@ -252,7 +252,7 @@ bool AndroidSurfaceGLImpeller::SetNativeWindow( } // |AndroidSurface| -std::unique_ptr AndroidSurfaceGLImpeller::CreateSnapshotStudio() { +std::unique_ptr AndroidSurfaceGLImpeller::CreateSnapshotStudio() { FML_UNREACHABLE(); } From 841ba568f7c5f111ae0c10283323fbfe23faea9e Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 24 Mar 2023 18:50:31 +0000 Subject: [PATCH 056/142] Try fix android snapshotting --- shell/common/snapshot_controller_skia.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/common/snapshot_controller_skia.cc b/shell/common/snapshot_controller_skia.cc index e5edaf65324c8..5af46b0dfddb7 100644 --- a/shell/common/snapshot_controller_skia.cc +++ b/shell/common/snapshot_controller_skia.cc @@ -53,12 +53,13 @@ sk_sp SnapshotControllerSkia::DoMakeRasterSnapshot( SkImageInfo image_info = SkImageInfo::MakeN32Premul( size.width(), size.height(), SkColorSpace::MakeSRGB()); + std::unique_ptr pbuffer_studio; Studio* snapshot_studio = nullptr; auto& delegate = GetDelegate(); if (delegate.GetStudio() && delegate.GetStudio()->GetContext()) { snapshot_studio = delegate.GetStudio(); } else if (delegate.GetSnapshotSurfaceProducer()) { - std::unique_ptr pbuffer_studio = + pbuffer_studio = delegate.GetSnapshotSurfaceProducer()->CreateSnapshotStudio(); if (pbuffer_studio && pbuffer_studio->GetContext()) { snapshot_studio = pbuffer_studio.get(); From e59b8b8fff161a5eb87870daf771c1bca88e0909 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 24 Mar 2023 20:23:15 +0000 Subject: [PATCH 057/142] Split Setup and RegisterSurface --- shell/common/rasterizer.cc | 11 ++++-- shell/common/rasterizer.h | 4 ++- shell/common/rasterizer_unittests.cc | 51 +++++++++++++++++++--------- shell/common/shell.cc | 4 ++- 4 files changed, 49 insertions(+), 21 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index ac79241ddb77f..dce2fe23e1728 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -51,10 +51,8 @@ fml::TaskRunnerAffineWeakPtr Rasterizer::GetSnapshotDelegate() return weak_factory_.GetWeakPtr(); } -void Rasterizer::Setup(std::unique_ptr studio, - std::unique_ptr surface) { +void Rasterizer::Setup(std::unique_ptr studio) { studio_ = std::move(studio); - surface_ = std::move(surface); if (max_cache_bytes_.has_value()) { SetResourceCacheMaxBytes(max_cache_bytes_.value(), @@ -146,6 +144,13 @@ void Rasterizer::NotifyLowMemoryWarning() const { context->performDeferredCleanup(std::chrono::milliseconds(0)); } +void Rasterizer::RegisterSurface(int64_t view_id, + std::unique_ptr surface) { + // TODO(dkwingsmt) + FML_DCHECK(view_id == 0ll); + surface_ = std::move(surface); +} + std::shared_ptr Rasterizer::GetTextureRegistry() { return compositor_context_->texture_registry(); } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 58d38e55174b5..ab6c4841326bd 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -153,7 +153,9 @@ class Rasterizer final : public SnapshotDelegate, /// /// @param[in] surface The on-screen render surface. /// - void Setup(std::unique_ptr studio, std::unique_ptr surface); + void Setup(std::unique_ptr studio); + + void RegisterSurface(int64_t view_id, std::unique_ptr surface); //---------------------------------------------------------------------------- /// @brief Releases the previously set up on-screen render surface and diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 8569c83e44cec..38764cc0467da 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -27,6 +27,9 @@ using testing::ReturnRef; namespace flutter { namespace { + +constexpr int64_t kDefaultViewId = 0; + class MockDelegate : public Rasterizer::Delegate { public: MOCK_METHOD1(OnFrameRasterized, void(const FrameTiming& frame_timing)); @@ -129,7 +132,8 @@ TEST(RasterizerTest, drawEmptyPipeline) { auto surface = std::make_unique>(); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -191,7 +195,8 @@ TEST(RasterizerTest, nullptr))) .Times(1); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -257,7 +262,8 @@ TEST( /*raster_thread_merger=*/_)) .Times(1); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -330,7 +336,8 @@ TEST( /*raster_thread_merger=*/_)) .Times(1); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), @@ -405,7 +412,8 @@ TEST(RasterizerTest, /*raster_thread_merger=*/_)) .Times(2); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), @@ -496,7 +504,8 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { std::shared_ptr> external_view_embedder = std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, @@ -554,7 +563,8 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { std::shared_ptr> external_view_embedder = std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); EXPECT_CALL( *external_view_embedder, @@ -613,7 +623,8 @@ TEST(RasterizerTest, EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -671,7 +682,8 @@ TEST( EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -729,7 +741,8 @@ TEST( EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -786,7 +799,8 @@ TEST( EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -842,7 +856,8 @@ TEST( EXPECT_CALL(*surface, AcquireFrame(SkISize())); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -922,7 +937,8 @@ TEST(RasterizerTest, }); thread_host.raster_thread->GetTaskRunner()->PostTask([&] { - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = @@ -977,7 +993,8 @@ TEST(RasterizerTest, TeardownFreesResourceCache) { }); EXPECT_CALL(*studio, GetContext()).WillRepeatedly(Return(context.get())); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); EXPECT_EQ(context->getResourceCacheLimit(), 0ul); rasterizer->SetResourceCacheMaxBytes(10000000, false); @@ -1095,7 +1112,8 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { [] { return std::make_unique(true); })); thread_host.raster_thread->GetTaskRunner()->PostTask([&] { - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = @@ -1177,7 +1195,8 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { [] { return std::make_unique(true); })); thread_host.raster_thread->GetTaskRunner()->PostTask([&] { - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index f92c8c2091f34..164c9b99e8187 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -792,7 +792,9 @@ void Shell::OnPlatformViewCreated() { // Enables the thread merger which may be used by the external view // embedder. rasterizer->EnableThreadMergerIfNeeded(); - rasterizer->Setup(std::move(studio), std::move(surface)); + rasterizer->Setup(std::move(studio)); + // TODO(dkwingsmt): Change 0ll + rasterizer->RegisterSurface(0ll, std::move(surface)); } waiting_for_first_frame.store(true); From a671009572550ee509ecf50efe3376b321b42457 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 24 Mar 2023 21:41:34 +0000 Subject: [PATCH 058/142] Replace GetLastLayerTree with Has*, add enable_leaf_layer_tracing to DrawLastLayerTree --- shell/common/rasterizer.cc | 15 +++++++++++---- shell/common/rasterizer.h | 5 +++-- shell/common/shell.cc | 7 +++---- shell/common/shell_unittests.cc | 2 +- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index dce2fe23e1728..5bb7f8f0cb501 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -159,15 +159,19 @@ GrDirectContext* Rasterizer::GetGrContext() { return studio_ ? studio_->GetContext() : nullptr; } -flutter::LayerTree* Rasterizer::GetLastLayerTree() { - return last_layer_tree_.get(); +bool Rasterizer::HasLastLayerTree() const { + return !!last_layer_tree_; } void Rasterizer::DrawLastLayerTree( - std::unique_ptr frame_timings_recorder) { + std::unique_ptr frame_timings_recorder, + bool enable_leaf_layer_tracing) { if (!last_layer_tree_ || !studio_) { return; } + if (enable_leaf_layer_tracing) { + last_layer_tree_->enable_leaf_layer_tracing(true); + } RasterStatus raster_status = DrawToSurface(*frame_timings_recorder, *last_layer_tree_); @@ -178,6 +182,9 @@ void Rasterizer::DrawLastLayerTree( external_view_embedder_->EndFrame(should_resubmit_frame, raster_thread_merger_); } + if (enable_leaf_layer_tracing) { + last_layer_tree_->enable_leaf_layer_tracing(false); + } } RasterStatus Rasterizer::Draw( @@ -724,7 +731,7 @@ sk_sp Rasterizer::ScreenshotLayerTreeAsImage( Rasterizer::Screenshot Rasterizer::ScreenshotLastLayerTree( Rasterizer::ScreenshotType type, bool base64_encode) { - auto* layer_tree = GetLastLayerTree(); + auto* layer_tree = last_layer_tree_.get(); if (layer_tree == nullptr) { FML_LOG(ERROR) << "Last layer tree was null when screenshotting."; return {}; diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index ab6c4841326bd..7d401e259275b 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -203,7 +203,7 @@ class Rasterizer final : public SnapshotDelegate, /// @return A pointer to the last layer or `nullptr` if this rasterizer /// has never rendered a frame. /// - flutter::LayerTree* GetLastLayerTree(); + bool HasLastLayerTree() const; //---------------------------------------------------------------------------- /// @brief Draws a last layer tree to the render surface. This may seem @@ -219,7 +219,8 @@ class Rasterizer final : public SnapshotDelegate, /// to generate the layer tree describing the same contents. /// void DrawLastLayerTree( - std::unique_ptr frame_timings_recorder); + std::unique_ptr frame_timings_recorder, + bool enable_leaf_layer_tracing = false); // |SnapshotDelegate| GrDirectContext* GetGrContext() override; diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 164c9b99e8187..359d94a3d4723 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1896,7 +1896,7 @@ bool Shell::OnServiceProtocolRenderFrameWithRasterStats( rapidjson::Document* response) { FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); - if (auto last_layer_tree = rasterizer_->GetLastLayerTree()) { + if (rasterizer_->HasLastLayerTree()) { auto& allocator = response->GetAllocator(); response->SetObject(); response->AddMember("type", "RenderFrameWithRasterStats", allocator); @@ -1910,9 +1910,8 @@ bool Shell::OnServiceProtocolRenderFrameWithRasterStats( frame_timings_recorder->RecordBuildStart(now); frame_timings_recorder->RecordBuildEnd(now); - last_layer_tree->enable_leaf_layer_tracing(true); - rasterizer_->DrawLastLayerTree(std::move(frame_timings_recorder)); - last_layer_tree->enable_leaf_layer_tracing(false); + rasterizer_->DrawLastLayerTree(std::move(frame_timings_recorder), + /* enable_leaf_layer_tracing=*/true); rapidjson::Value snapshots; snapshots.SetArray(); diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 99f5824b944fa..d36677bdf5a18 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -274,7 +274,7 @@ static bool RasterizerHasLayerTree(Shell* shell) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetRasterTaskRunner(), [shell, &latch, &has_layer_tree]() { - has_layer_tree = shell->GetRasterizer()->GetLastLayerTree() != nullptr; + has_layer_tree = shell->GetRasterizer()->HasLastLayerTree(); latch.Signal(); }); latch.Wait(); From bd58880c9cef4080aa93a5dede6f4aca9262ae95 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 24 Mar 2023 22:12:08 +0000 Subject: [PATCH 059/142] Better flow DrawLastLayerTree --- shell/common/rasterizer.cc | 12 +++++++----- shell/common/rasterizer.h | 12 ++++++------ 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 5bb7f8f0cb501..6750456eb1312 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -169,11 +169,16 @@ void Rasterizer::DrawLastLayerTree( if (!last_layer_tree_ || !studio_) { return; } + // TODO(dkwingsmt): Apply to all last trees + flutter::LayerTree& layer_tree = *last_layer_tree_; if (enable_leaf_layer_tracing) { - last_layer_tree_->enable_leaf_layer_tracing(true); + layer_tree.enable_leaf_layer_tracing(true); } RasterStatus raster_status = - DrawToSurface(*frame_timings_recorder, *last_layer_tree_); + DrawToSurface(*frame_timings_recorder, layer_tree); + if (enable_leaf_layer_tracing) { + layer_tree.enable_leaf_layer_tracing(false); + } // EndFrame should perform cleanups for the external_view_embedder. if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) { @@ -182,9 +187,6 @@ void Rasterizer::DrawLastLayerTree( external_view_embedder_->EndFrame(should_resubmit_frame, raster_thread_merger_); } - if (enable_leaf_layer_tracing) { - last_layer_tree_->enable_leaf_layer_tracing(false); - } } RasterStatus Rasterizer::Draw( diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 7d401e259275b..92f8f999c65ce 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -206,12 +206,12 @@ class Rasterizer final : public SnapshotDelegate, bool HasLastLayerTree() const; //---------------------------------------------------------------------------- - /// @brief Draws a last layer tree to the render surface. This may seem - /// entirely redundant at first glance. After all, on surface loss - /// and re-acquisition, the framework generates a new layer tree. - /// Otherwise, why render the same contents to the screen again? - /// This is used as an optimization in cases where there are - /// external textures (video or camera streams for example) in + /// @brief Draws to all render surfaces their last layer trees. This may + /// seem entirely redundant at first glance. After all, on surface + /// loss and re-acquisition, the framework generates a new layer + /// tree. Otherwise, why render the same contents to the screen + /// again? This is used as an optimization in cases where there + /// are external textures (video or camera streams for example) in /// referenced in the layer tree. These textures may be updated at /// a cadence different from that of the Flutter application. /// Flutter can re-render the layer tree with just the updated From dc6be1f31d4a8553660d913c6da77983041e7847 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 24 Mar 2023 22:36:25 +0000 Subject: [PATCH 060/142] Remove resubmitted; replace with DoDrawResult --- shell/common/rasterizer.cc | 52 ++++++++++++++++++++++++-------------- shell/common/rasterizer.h | 17 ++++++++----- 2 files changed, 44 insertions(+), 25 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 6750456eb1312..c34c0e40cc12c 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -202,16 +202,17 @@ RasterStatus Rasterizer::Draw( .GetRasterTaskRunner() ->RunsTasksOnCurrentThread()); - RasterStatus raster_status = RasterStatus::kFailed; + DoDrawResult draw_result; LayerTreePipeline::Consumer consumer = - [&](std::unique_ptr item) { + [this, &draw_result, + &discard_callback](std::unique_ptr item) { std::shared_ptr layer_tree = std::move(item->layer_tree); std::unique_ptr frame_timings_recorder = std::move(item->frame_timings_recorder); if (discard_callback(*layer_tree.get())) { - raster_status = RasterStatus::kDiscarded; + draw_result.raster_status = RasterStatus::kDiscarded; } else { - raster_status = + draw_result = DoDraw(std::move(frame_timings_recorder), std::move(layer_tree)); } }; @@ -223,17 +224,18 @@ RasterStatus Rasterizer::Draw( // if the raster status is to resubmit the frame, we push the frame to the // front of the queue and also change the consume status to more available. - bool should_resubmit_frame = ShouldResubmitFrame(raster_status); + bool should_resubmit_frame = ShouldResubmitFrame(draw_result.raster_status); if (should_resubmit_frame) { auto resubmitted_layer_tree_item = std::make_unique( - std::move(resubmitted_layer_tree_), std::move(resubmitted_recorder_)); + std::move(draw_result.resubmitted_layer_tree), + std::move(draw_result.resubmitted_recorder)); auto front_continuation = pipeline->ProduceIfEmpty(); - PipelineProduceResult result = + PipelineProduceResult pipeline_result = front_continuation.Complete(std::move(resubmitted_layer_tree_item)); - if (result.success) { + if (pipeline_result.success) { consume_result = PipelineConsumeResult::MoreAvailable; } - } else if (raster_status == RasterStatus::kEnqueuePipeline) { + } else if (draw_result.raster_status == RasterStatus::kEnqueuePipeline) { consume_result = PipelineConsumeResult::MoreAvailable; } @@ -262,7 +264,7 @@ RasterStatus Rasterizer::Draw( break; } - return raster_status; + return draw_result.raster_status; } bool Rasterizer::ShouldResubmitFrame(const RasterStatus& raster_status) { @@ -383,7 +385,7 @@ fml::Milliseconds Rasterizer::GetFrameBudget() const { return delegate_.GetFrameBudget(); }; -RasterStatus Rasterizer::DoDraw( +Rasterizer::DoDrawResult Rasterizer::DoDraw( std::unique_ptr frame_timings_recorder, std::shared_ptr layer_tree) { TRACE_EVENT_WITH_FRAME_NUMBER(frame_timings_recorder, "flutter", @@ -393,7 +395,9 @@ RasterStatus Rasterizer::DoDraw( ->RunsTasksOnCurrentThread()); if (!layer_tree || !surface_) { - return RasterStatus::kFailed; + return DoDrawResult{ + .raster_status = RasterStatus::kFailed, + }; } PersistentCache* persistent_cache = PersistentCache::GetCacheForProcess(); @@ -404,12 +408,16 @@ RasterStatus Rasterizer::DoDraw( if (raster_status == RasterStatus::kSuccess) { last_layer_tree_ = std::move(layer_tree); } else if (ShouldResubmitFrame(raster_status)) { - resubmitted_layer_tree_ = std::move(layer_tree); - resubmitted_recorder_ = frame_timings_recorder->CloneUntil( - FrameTimingsRecorder::State::kBuildEnd); - return raster_status; + return DoDrawResult{ + .raster_status = raster_status, + .resubmitted_layer_tree = std::move(layer_tree), + .resubmitted_recorder = frame_timings_recorder->CloneUntil( + FrameTimingsRecorder::State::kBuildEnd), + }; } else if (raster_status == RasterStatus::kDiscarded) { - return raster_status; + return DoDrawResult{ + .raster_status = raster_status, + }; } if (persistent_cache->IsDumpingSkp() && @@ -477,11 +485,15 @@ RasterStatus Rasterizer::DoDraw( if (raster_thread_merger_) { if (raster_thread_merger_->DecrementLease() == fml::RasterThreadStatus::kUnmergedNow) { - return RasterStatus::kEnqueuePipeline; + return DoDrawResult{ + .raster_status = RasterStatus::kEnqueuePipeline, + }; } } - return raster_status; + return DoDrawResult{ + .raster_status = raster_status, + }; } RasterStatus Rasterizer::DrawToSurface( @@ -733,6 +745,8 @@ sk_sp Rasterizer::ScreenshotLayerTreeAsImage( Rasterizer::Screenshot Rasterizer::ScreenshotLastLayerTree( Rasterizer::ScreenshotType type, bool base64_encode) { + // TODO(dkwingsmt): Probably screenshot all layer trees instead of just + // the first one and put them together. auto* layer_tree = last_layer_tree_.get(); if (layer_tree == nullptr) { FML_LOG(ERROR) << "Last layer tree was null when screenshotting."; diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 92f8f999c65ce..83bd020883339 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -487,6 +487,16 @@ class Rasterizer final : public SnapshotDelegate, void DisableThreadMergerIfNeeded(); private: + struct DoDrawResult { + RasterStatus raster_status = RasterStatus::kFailed; + // Set when we need attempt to rasterize the layer tree again. This + // layer_tree has not successfully rasterized. This can happen due to the + // change in the thread configuration. This will be inserted to the front of + // the pipeline. + std::shared_ptr resubmitted_layer_tree; + std::unique_ptr resubmitted_recorder; + }; + // |SnapshotDelegate| std::unique_ptr MakeSkiaGpuImage( sk_sp display_list, @@ -526,7 +536,7 @@ class Rasterizer final : public SnapshotDelegate, GrDirectContext* surface_context, bool compressed); - RasterStatus DoDraw( + DoDrawResult DoDraw( std::unique_ptr frame_timings_recorder, std::shared_ptr layer_tree); @@ -549,11 +559,6 @@ class Rasterizer final : public SnapshotDelegate, std::unique_ptr compositor_context_; // This is the last successfully rasterized layer tree. std::shared_ptr last_layer_tree_; - // Set when we need attempt to rasterize the layer tree again. This layer_tree - // has not successfully rasterized. This can happen due to the change in the - // thread configuration. This will be inserted to the front of the pipeline. - std::shared_ptr resubmitted_layer_tree_; - std::unique_ptr resubmitted_recorder_; fml::closure next_frame_callback_; bool user_override_resource_cache_bytes_; std::optional max_cache_bytes_; From 0bd3a34ad2ddd1cc3134b24fe1ca0c7b12dec264 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sat, 25 Mar 2023 21:08:56 +0000 Subject: [PATCH 061/142] Rasterizer has multiple surfaces --- shell/common/rasterizer.cc | 136 ++++++++++++++++++++++++------------- shell/common/rasterizer.h | 71 +++++++++++++------ shell/common/shell.cc | 27 ++++---- 3 files changed, 154 insertions(+), 80 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index c34c0e40cc12c..f27ab9492b07b 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -101,9 +101,7 @@ void Rasterizer::Teardown() { } studio_.reset(); } - surface_.reset(); - - last_layer_tree_.reset(); + surfaces_.clear(); if (raster_thread_merger_.get() != nullptr && raster_thread_merger_.get()->IsMerged()) { @@ -146,9 +144,16 @@ void Rasterizer::NotifyLowMemoryWarning() const { void Rasterizer::RegisterSurface(int64_t view_id, std::unique_ptr surface) { - // TODO(dkwingsmt) - FML_DCHECK(view_id == 0ll); - surface_ = std::move(surface); + bool insertion_happened = + surfaces_ + .try_emplace(view_id, + std::make_unique(std::move(surface))) + .second; + if (!insertion_happened) { + FML_DLOG(INFO) + << "Rasterizer::RegisterSurface called with an existing view ID " + << view_id << "."; + } } std::shared_ptr Rasterizer::GetTextureRegistry() { @@ -160,33 +165,50 @@ GrDirectContext* Rasterizer::GetGrContext() { } bool Rasterizer::HasLastLayerTree() const { - return !!last_layer_tree_; + // TODO(dkwingsmt): This method is only available in unittests now + for (auto& record_pair : surfaces_) { + auto& layer_tree = record_pair.second->last_tree; + if (layer_tree) { + return true; + } + } + return false; } -void Rasterizer::DrawLastLayerTree( +int Rasterizer::DrawLastLayerTree( std::unique_ptr frame_timings_recorder, bool enable_leaf_layer_tracing) { - if (!last_layer_tree_ || !studio_) { - return; - } - // TODO(dkwingsmt): Apply to all last trees - flutter::LayerTree& layer_tree = *last_layer_tree_; - if (enable_leaf_layer_tracing) { - layer_tree.enable_leaf_layer_tracing(true); - } - RasterStatus raster_status = - DrawToSurface(*frame_timings_recorder, layer_tree); - if (enable_leaf_layer_tracing) { - layer_tree.enable_leaf_layer_tracing(false); + if (!studio_) { + return 0; + } + int success_count = 0; + bool should_resubmit_frame = false; + for (auto& record_pair : surfaces_) { + Surface* surface = record_pair.second->surface.get(); + flutter::LayerTree* layer_tree = record_pair.second->last_tree.get(); + if (!surface || !layer_tree) { + continue; + } + if (enable_leaf_layer_tracing) { + layer_tree->enable_leaf_layer_tracing(true); + } + RasterStatus raster_status = DrawToSurface( + *frame_timings_recorder, layer_tree, record_pair.second.get()); + if (enable_leaf_layer_tracing) { + layer_tree->enable_leaf_layer_tracing(false); + } + should_resubmit_frame = + should_resubmit_frame || ShouldResubmitFrame(raster_status); + success_count += 1; } // EndFrame should perform cleanups for the external_view_embedder. if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) { - bool should_resubmit_frame = ShouldResubmitFrame(raster_status); external_view_embedder_->SetUsedThisFrame(false); external_view_embedder_->EndFrame(should_resubmit_frame, raster_thread_merger_); } + return success_count; } RasterStatus Rasterizer::Draw( @@ -212,8 +234,10 @@ RasterStatus Rasterizer::Draw( if (discard_callback(*layer_tree.get())) { draw_result.raster_status = RasterStatus::kDiscarded; } else { - draw_result = - DoDraw(std::move(frame_timings_recorder), std::move(layer_tree)); + // TODO(dkwingsmt) + int64_t view_id = 0ll; + draw_result = DoDraw(view_id, std::move(frame_timings_recorder), + std::move(layer_tree)); } }; @@ -386,6 +410,7 @@ fml::Milliseconds Rasterizer::GetFrameBudget() const { }; Rasterizer::DoDrawResult Rasterizer::DoDraw( + int64_t view_id, std::unique_ptr frame_timings_recorder, std::shared_ptr layer_tree) { TRACE_EVENT_WITH_FRAME_NUMBER(frame_timings_recorder, "flutter", @@ -393,8 +418,9 @@ Rasterizer::DoDrawResult Rasterizer::DoDraw( FML_DCHECK(delegate_.GetTaskRunners() .GetRasterTaskRunner() ->RunsTasksOnCurrentThread()); + SurfaceRecord* surface_record = GetSurface(view_id); - if (!layer_tree || !surface_) { + if (!layer_tree || !surface_record) { return DoDrawResult{ .raster_status = RasterStatus::kFailed, }; @@ -404,9 +430,9 @@ Rasterizer::DoDrawResult Rasterizer::DoDraw( persistent_cache->ResetStoredNewShaders(); RasterStatus raster_status = - DrawToSurface(*frame_timings_recorder, *layer_tree); + DrawToSurface(*frame_timings_recorder, layer_tree.get(), surface_record); if (raster_status == RasterStatus::kSuccess) { - last_layer_tree_ = std::move(layer_tree); + surface_record->last_tree = std::move(layer_tree); } else if (ShouldResubmitFrame(raster_status)) { return DoDrawResult{ .raster_status = raster_status, @@ -422,8 +448,8 @@ Rasterizer::DoDrawResult Rasterizer::DoDraw( if (persistent_cache->IsDumpingSkp() && persistent_cache->StoredNewShaders()) { - auto screenshot = - ScreenshotLastLayerTree(ScreenshotType::SkiaPicture, false); + auto screenshot = ScreenshotLayerTree(ScreenshotType::SkiaPicture, false, + *surface_record); persistent_cache->DumpSkp(*screenshot.data); } @@ -498,20 +524,22 @@ Rasterizer::DoDrawResult Rasterizer::DoDraw( RasterStatus Rasterizer::DrawToSurface( FrameTimingsRecorder& frame_timings_recorder, - flutter::LayerTree& layer_tree) { + flutter::LayerTree* layer_tree, + SurfaceRecord* surface_record) { TRACE_EVENT0("flutter", "Rasterizer::DrawToSurface"); - FML_DCHECK(surface_); + FML_DCHECK(surface_record); RasterStatus raster_status; if (studio_->AllowsDrawingWhenGpuDisabled()) { - raster_status = DrawToSurfaceUnsafe(frame_timings_recorder, layer_tree); + raster_status = + DrawToSurfaceUnsafe(frame_timings_recorder, layer_tree, surface_record); } else { delegate_.GetIsGpuDisabledSyncSwitch()->Execute( fml::SyncSwitch::Handlers() .SetIfTrue([&] { raster_status = RasterStatus::kDiscarded; }) .SetIfFalse([&] { - raster_status = - DrawToSurfaceUnsafe(frame_timings_recorder, layer_tree); + raster_status = DrawToSurfaceUnsafe(frame_timings_recorder, + layer_tree, surface_record); })); } @@ -523,8 +551,11 @@ RasterStatus Rasterizer::DrawToSurface( /// \see Rasterizer::DrawToSurface RasterStatus Rasterizer::DrawToSurfaceUnsafe( FrameTimingsRecorder& frame_timings_recorder, - flutter::LayerTree& layer_tree) { - FML_DCHECK(surface_); + flutter::LayerTree* layer_tree, + SurfaceRecord* surface_record) { + Surface* surface = surface_record->surface.get(); + flutter::LayerTree* last_layer_tree = surface_record->last_tree.get(); + FML_DCHECK(surface); compositor_context_->ui_time().SetLapTime( frame_timings_recorder.GetBuildDuration()); @@ -534,8 +565,8 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( FML_DCHECK(!external_view_embedder_->GetUsedThisFrame()); external_view_embedder_->SetUsedThisFrame(true); external_view_embedder_->BeginFrame( - layer_tree.frame_size(), studio_->GetContext(), - layer_tree.device_pixel_ratio(), raster_thread_merger_); + layer_tree->frame_size(), studio_->GetContext(), + layer_tree->device_pixel_ratio(), raster_thread_merger_); embedder_root_canvas = external_view_embedder_->GetRootCanvas(); } @@ -545,7 +576,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( // // Deleting a surface also clears the GL context. Therefore, acquire the // frame after calling `BeginFrame` as this operation resets the GL context. - auto frame = surface_->AcquireFrame(layer_tree.frame_size()); + auto frame = surface->AcquireFrame(layer_tree->frame_size()); if (frame == nullptr) { frame_timings_recorder.RecordRasterEnd( &compositor_context_->raster_cache()); @@ -556,7 +587,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( // root surface transformation is set by the embedder instead of // having to apply it here. SkMatrix root_surface_transformation = - embedder_root_canvas ? SkMatrix{} : surface_->GetRootTransformation(); + embedder_root_canvas ? SkMatrix{} : surface->GetRootTransformation(); auto root_surface_canvas = embedder_root_canvas ? embedder_root_canvas : frame->Canvas(); @@ -580,7 +611,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( // when leaf layer tracing is enabled we wish to repaint the whole frame // for accurate performance metrics. if (frame->framebuffer_info().supports_partial_repaint && - !layer_tree.is_leaf_layer_tracing_enabled()) { + !layer_tree->is_leaf_layer_tracing_enabled()) { // Disable partial repaint if external_view_embedder_ SubmitFrame is // involved - ExternalViewEmbedder unconditionally clears the entire // surface and also partial repaint with platform view present is @@ -591,7 +622,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( damage = std::make_unique(); if (frame->framebuffer_info().existing_damage && !force_full_repaint) { - damage->SetPreviousLayerTree(last_layer_tree_.get()); + damage->SetPreviousLayerTree(last_layer_tree); damage->AddAdditionalDamage(*frame->framebuffer_info().existing_damage); damage->SetClipAlignment( frame->framebuffer_info().horizontal_clip_alignment, @@ -601,12 +632,12 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( bool ignore_raster_cache = true; if (studio_->EnableRasterCache() && - !layer_tree.is_leaf_layer_tracing_enabled()) { + !layer_tree->is_leaf_layer_tracing_enabled()) { ignore_raster_cache = false; } RasterStatus raster_status = - compositor_frame->Raster(layer_tree, // layer tree + compositor_frame->Raster(*layer_tree, // layer tree ignore_raster_cache, // ignore raster cache damage.get() // frame damage ); @@ -745,13 +776,22 @@ sk_sp Rasterizer::ScreenshotLayerTreeAsImage( Rasterizer::Screenshot Rasterizer::ScreenshotLastLayerTree( Rasterizer::ScreenshotType type, bool base64_encode) { - // TODO(dkwingsmt): Probably screenshot all layer trees instead of just - // the first one and put them together. - auto* layer_tree = last_layer_tree_.get(); - if (layer_tree == nullptr) { + // TODO(dkwingsmt): Probably screenshot all layer trees and put them together + // instead of just the first one. + SurfaceRecord* surface_record = GetFirstSurface(); + if (surface_record == nullptr || surface_record->last_tree == nullptr) { FML_LOG(ERROR) << "Last layer tree was null when screenshotting."; return {}; } + return ScreenshotLayerTree(type, base64_encode, *surface_record); +} + +Rasterizer::Screenshot Rasterizer::ScreenshotLayerTree( + ScreenshotType type, + bool base64_encode, + SurfaceRecord& surface_record) { + auto& surface = surface_record.surface; + auto* layer_tree = surface_record.last_tree.get(); sk_sp data = nullptr; std::string format; @@ -774,7 +814,7 @@ Rasterizer::Screenshot Rasterizer::ScreenshotLastLayerTree( surface_context, true); break; case ScreenshotType::SurfaceData: { - Surface::SurfaceData surface_data = surface_->GetSurfaceData(); + Surface::SurfaceData surface_data = surface->GetSurfaceData(); format = surface_data.pixel_format; data = surface_data.data; break; diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 83bd020883339..14fae960d48b6 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -7,6 +7,7 @@ #include #include +#include #include "flutter/common/settings.h" #include "flutter/common/task_runners.h" @@ -139,24 +140,22 @@ class Rasterizer final : public SnapshotDelegate, ~Rasterizer(); //---------------------------------------------------------------------------- - /// @brief Rasterizers may be created well before an on-screen surface is + /// @brief Rasterizers may be created well before an on-screen studio is /// available for rendering. Shells usually create a rasterizer in - /// their constructors. Once an on-screen surface is available + /// their constructors. Once an on-screen studio is available /// however, one may be provided to the rasterizer using this - /// call. No rendering may occur before this call. The surface is + /// call. No rendering may occur before this call. The studio is /// held till the balancing call to `Rasterizer::Teardown` is - /// made. Calling a setup before tearing down the previous surface + /// made. Calling a setup before tearing down the studio /// (if this is not the first time the surface has been set up) is /// user error. /// /// @see `Rasterizer::Teardown` /// - /// @param[in] surface The on-screen render surface. + /// @param[in] studio The on-screen render studio. /// void Setup(std::unique_ptr studio); - void RegisterSurface(int64_t view_id, std::unique_ptr surface); - //---------------------------------------------------------------------------- /// @brief Releases the previously set up on-screen render surface and /// collects associated resources. No more rendering may occur @@ -190,13 +189,9 @@ class Rasterizer final : public SnapshotDelegate, fml::TaskRunnerAffineWeakPtr GetSnapshotDelegate() const; + void RegisterSurface(int64_t view_id, std::unique_ptr surface); + //---------------------------------------------------------------------------- - /// @brief Sometimes, it may be necessary to render the same frame again - /// without having to wait for the framework to build a whole new - /// layer tree describing the same contents. One such case is when - /// external textures (video or camera streams for example) are - /// updated in an otherwise static layer tree. To support this use - /// case, the rasterizer holds onto the last rendered layer tree. /// /// @bug https://github.com/flutter/flutter/issues/33939 /// @@ -218,7 +213,8 @@ class Rasterizer final : public SnapshotDelegate, /// textures instead of waiting for the framework to do the work /// to generate the layer tree describing the same contents. /// - void DrawLastLayerTree( + /// @return The number of surfaces that are drawn this way. + int DrawLastLayerTree( std::unique_ptr frame_timings_recorder, bool enable_leaf_layer_tracing = false); @@ -497,6 +493,35 @@ class Rasterizer final : public SnapshotDelegate, std::unique_ptr resubmitted_recorder; }; + struct SurfaceRecord { + explicit SurfaceRecord(std::unique_ptr surface) + : surface(std::move(surface)) {} + + std::unique_ptr surface; + // This is the information for the last successfully drawing. + // + // Sometimes, it may be necessary to render the same frame again without + // having to wait for the framework to build a whole new layer tree + // describing the same contents. One such case is when external textures + // (video or camera streams for example) are updated in an otherwise static + // layer tree. To support this use case, the rasterizer holds onto the last + // rendered layer tree. + std::shared_ptr last_tree; + }; + + SurfaceRecord* GetSurface(int64_t view_id) { + auto found_surface = surfaces_.find(view_id); + if (found_surface == surfaces_.end()) { + return nullptr; + } + return found_surface->second.get(); + } + + SurfaceRecord* GetFirstSurface() { + // TODO(dkwingsmt) + return GetSurface(0ll); + } + // |SnapshotDelegate| std::unique_ptr MakeSkiaGpuImage( sk_sp display_list, @@ -537,14 +562,21 @@ class Rasterizer final : public SnapshotDelegate, bool compressed); DoDrawResult DoDraw( + int64_t view_id, std::unique_ptr frame_timings_recorder, std::shared_ptr layer_tree); RasterStatus DrawToSurface(FrameTimingsRecorder& frame_timings_recorder, - flutter::LayerTree& layer_tree); + flutter::LayerTree* layer_tree, + SurfaceRecord* surface_record); RasterStatus DrawToSurfaceUnsafe(FrameTimingsRecorder& frame_timings_recorder, - flutter::LayerTree& layer_tree); + flutter::LayerTree* layer_tree, + SurfaceRecord* surface_record); + + Screenshot ScreenshotLayerTree(ScreenshotType type, + bool base64_encode, + SurfaceRecord& surface_record); void FireNextFrameCallbackIfPresent(); @@ -554,11 +586,12 @@ class Rasterizer final : public SnapshotDelegate, Delegate& delegate_; MakeGpuImageBehavior gpu_image_behavior_; std::unique_ptr studio_; - std::unique_ptr surface_; + std::unordered_map> surfaces_; std::unique_ptr snapshot_surface_producer_; std::unique_ptr compositor_context_; - // This is the last successfully rasterized layer tree. - std::shared_ptr last_layer_tree_; + // Set when we need attempt to rasterize the layer tree again. This layer_tree + // has not successfully rasterized. This can happen due to the change in the + // thread configuration. This will be inserted to the front of the pipeline. fml::closure next_frame_callback_; bool user_override_resource_cache_bytes_; std::optional max_cache_bytes_; diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 359d94a3d4723..b3d22259f9587 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -1896,23 +1896,24 @@ bool Shell::OnServiceProtocolRenderFrameWithRasterStats( rapidjson::Document* response) { FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); - if (rasterizer_->HasLastLayerTree()) { + // When rendering the last layer tree, we do not need to build a frame, + // invariants in FrameTimingRecorder enforce that raster timings can not be + // set before build-end. + auto frame_timings_recorder = std::make_unique(); + const auto now = fml::TimePoint::Now(); + frame_timings_recorder->RecordVsync(now, now); + frame_timings_recorder->RecordBuildStart(now); + frame_timings_recorder->RecordBuildEnd(now); + + int success_count = + rasterizer_->DrawLastLayerTree(std::move(frame_timings_recorder), + /* enable_leaf_layer_tracing=*/true); + + if (success_count > 0) { auto& allocator = response->GetAllocator(); response->SetObject(); response->AddMember("type", "RenderFrameWithRasterStats", allocator); - // When rendering the last layer tree, we do not need to build a frame, - // invariants in FrameTimingRecorder enforce that raster timings can not be - // set before build-end. - auto frame_timings_recorder = std::make_unique(); - const auto now = fml::TimePoint::Now(); - frame_timings_recorder->RecordVsync(now, now); - frame_timings_recorder->RecordBuildStart(now); - frame_timings_recorder->RecordBuildEnd(now); - - rasterizer_->DrawLastLayerTree(std::move(frame_timings_recorder), - /* enable_leaf_layer_tracing=*/true); - rapidjson::Value snapshots; snapshots.SetArray(); From 644d50acb723a0d22f61f350e1b65ac58b9ea8f6 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sat, 25 Mar 2023 21:52:18 +0000 Subject: [PATCH 062/142] surfaces_ contains objects instead of unique_ptrs --- shell/common/rasterizer.cc | 15 ++++++--------- shell/common/rasterizer.h | 4 ++-- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index f27ab9492b07b..b49fec6ee44e7 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -145,10 +145,7 @@ void Rasterizer::NotifyLowMemoryWarning() const { void Rasterizer::RegisterSurface(int64_t view_id, std::unique_ptr surface) { bool insertion_happened = - surfaces_ - .try_emplace(view_id, - std::make_unique(std::move(surface))) - .second; + surfaces_.try_emplace(view_id, std::move(surface)).second; if (!insertion_happened) { FML_DLOG(INFO) << "Rasterizer::RegisterSurface called with an existing view ID " @@ -167,7 +164,7 @@ GrDirectContext* Rasterizer::GetGrContext() { bool Rasterizer::HasLastLayerTree() const { // TODO(dkwingsmt): This method is only available in unittests now for (auto& record_pair : surfaces_) { - auto& layer_tree = record_pair.second->last_tree; + auto& layer_tree = record_pair.second.last_tree; if (layer_tree) { return true; } @@ -184,16 +181,16 @@ int Rasterizer::DrawLastLayerTree( int success_count = 0; bool should_resubmit_frame = false; for (auto& record_pair : surfaces_) { - Surface* surface = record_pair.second->surface.get(); - flutter::LayerTree* layer_tree = record_pair.second->last_tree.get(); + Surface* surface = record_pair.second.surface.get(); + flutter::LayerTree* layer_tree = record_pair.second.last_tree.get(); if (!surface || !layer_tree) { continue; } if (enable_leaf_layer_tracing) { layer_tree->enable_leaf_layer_tracing(true); } - RasterStatus raster_status = DrawToSurface( - *frame_timings_recorder, layer_tree, record_pair.second.get()); + RasterStatus raster_status = + DrawToSurface(*frame_timings_recorder, layer_tree, &record_pair.second); if (enable_leaf_layer_tracing) { layer_tree->enable_leaf_layer_tracing(false); } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 14fae960d48b6..8f2a7dae5a7b2 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -514,7 +514,7 @@ class Rasterizer final : public SnapshotDelegate, if (found_surface == surfaces_.end()) { return nullptr; } - return found_surface->second.get(); + return &found_surface->second; } SurfaceRecord* GetFirstSurface() { @@ -586,7 +586,7 @@ class Rasterizer final : public SnapshotDelegate, Delegate& delegate_; MakeGpuImageBehavior gpu_image_behavior_; std::unique_ptr studio_; - std::unordered_map> surfaces_; + std::unordered_map surfaces_; std::unique_ptr snapshot_surface_producer_; std::unique_ptr compositor_context_; // Set when we need attempt to rasterize the layer tree again. This layer_tree From 253f3c98b2fb4cd1d5fc81bd631dacb4b730991e Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 27 Mar 2023 18:49:19 +0000 Subject: [PATCH 063/142] Split out CreateSurface --- shell/common/platform_view.cc | 42 ++++++++++++++++++++++++----------- shell/common/platform_view.h | 4 ++-- shell/common/shell.cc | 5 ++--- 3 files changed, 33 insertions(+), 18 deletions(-) diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index b9c73f5323d2b..fac06cee3b7b1 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -65,10 +65,8 @@ void PlatformView::NotifyDestroyed() { constexpr int64_t kFlutterDefaultViewId = 0; -std::pair, std::unique_ptr> -PlatformView::CreateStudioAndSurface() { +std::unique_ptr PlatformView::CreateStudio() { std::unique_ptr studio; - std::unique_ptr surface; // Threading: We want to use the platform view on the non-platform thread. // Using the weak pointer is illegal. But, we are going to introduce a latch // so that the platform view is not collected till the studio and the surface @@ -76,25 +74,43 @@ PlatformView::CreateStudioAndSurface() { auto* platform_view = this; fml::ManualResetWaitableEvent latch; fml::TaskRunner::RunNowOrPostTask( - task_runners_.GetRasterTaskRunner(), - [platform_view, &studio, &surface, &latch]() { + task_runners_.GetRasterTaskRunner(), [platform_view, &studio, &latch]() { studio = platform_view->CreateRenderingStudio(); + if (!studio || !studio->IsValid()) { + studio.reset(); + } + latch.Signal(); + }); + latch.Wait(); + if (!studio) { + FML_LOG(ERROR) << "Failed to create platform view rendering studio"; + return nullptr; + } + return studio; +} + +std::unique_ptr PlatformView::CreateSurface() { + std::unique_ptr surface; + // Threading: We want to use the platform view on the non-platform thread. + // Using the weak pointer is illegal. But, we are going to introduce a latch + // so that the platform view is not collected till the studio and the surface + // are obtained. + auto* platform_view = this; + fml::ManualResetWaitableEvent latch; + fml::TaskRunner::RunNowOrPostTask( + task_runners_.GetRasterTaskRunner(), [platform_view, &surface, &latch]() { surface = platform_view->CreateRenderingSurface(kFlutterDefaultViewId); - if (!studio || !studio->IsValid() || !surface || !surface->IsValid()) { + if (!surface || !surface->IsValid()) { surface.reset(); - studio.reset(); } latch.Signal(); }); latch.Wait(); - std::pair, std::unique_ptr> result; - if (!studio || !surface) { + if (!surface) { FML_LOG(ERROR) << "Failed to create platform view rendering surface"; - return result; + return nullptr; } - result.first = std::move(studio); - result.second = std::move(surface); - return result; + return surface; } void PlatformView::ScheduleFrame() { diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 77088d57eceb6..985a25bcfe014 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -494,8 +494,8 @@ class PlatformView { /// virtual void NotifyDestroyed(); - std::pair, std::unique_ptr> - CreateStudioAndSurface(); + std::unique_ptr CreateStudio(); + std::unique_ptr CreateSurface(); //---------------------------------------------------------------------------- /// @brief Used by embedders to schedule a frame. In response to this diff --git a/shell/common/shell.cc b/shell/common/shell.cc index b3d22259f9587..3bf10ce28d615 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -750,9 +750,8 @@ void Shell::OnPlatformViewCreated() { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); - auto studio_and_surface = platform_view_->CreateStudioAndSurface(); - std::unique_ptr studio = std::move(studio_and_surface.first); - std::unique_ptr surface = std::move(studio_and_surface.second); + std::unique_ptr studio = platform_view_->CreateStudio(); + std::unique_ptr surface = platform_view_->CreateSurface(); if (studio == nullptr || surface == nullptr) { // TODO(dkwingsmt): This case is observed in windows unit tests. Anyway, // we're probably not creating the surface in this callback eventually. From 9dc2cebb92f0bd5008b96c4cb9418db4bffec28a Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 27 Mar 2023 22:12:46 +0000 Subject: [PATCH 064/142] Embedder.AddRenderSurface --- shell/common/rasterizer.cc | 8 +++---- shell/common/rasterizer.h | 2 +- shell/common/rasterizer_unittests.cc | 32 ++++++++++++++-------------- shell/common/shell.cc | 26 ++++++++++++++++++++-- shell/common/shell.h | 2 ++ shell/platform/embedder/embedder.cc | 16 ++++++++++++++ shell/platform/embedder/embedder.h | 13 +++++++++++ 7 files changed, 75 insertions(+), 24 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index b49fec6ee44e7..4de7e9038613d 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -142,14 +142,12 @@ void Rasterizer::NotifyLowMemoryWarning() const { context->performDeferredCleanup(std::chrono::milliseconds(0)); } -void Rasterizer::RegisterSurface(int64_t view_id, - std::unique_ptr surface) { +void Rasterizer::AddSurface(int64_t view_id, std::unique_ptr surface) { bool insertion_happened = surfaces_.try_emplace(view_id, std::move(surface)).second; if (!insertion_happened) { - FML_DLOG(INFO) - << "Rasterizer::RegisterSurface called with an existing view ID " - << view_id << "."; + FML_DLOG(INFO) << "Rasterizer::AddSurface called with an existing view ID " + << view_id << "."; } } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 8f2a7dae5a7b2..6ff0d74dff670 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -189,7 +189,7 @@ class Rasterizer final : public SnapshotDelegate, fml::TaskRunnerAffineWeakPtr GetSnapshotDelegate() const; - void RegisterSurface(int64_t view_id, std::unique_ptr surface); + void AddSurface(int64_t view_id, std::unique_ptr surface); //---------------------------------------------------------------------------- /// diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 38764cc0467da..b923611896ee0 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -133,7 +133,7 @@ TEST(RasterizerTest, drawEmptyPipeline) { EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -196,7 +196,7 @@ TEST(RasterizerTest, .Times(1); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -263,7 +263,7 @@ TEST( .Times(1); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -337,7 +337,7 @@ TEST( .Times(1); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), @@ -413,7 +413,7 @@ TEST(RasterizerTest, .Times(2); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), @@ -505,7 +505,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, @@ -564,7 +564,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); EXPECT_CALL( *external_view_embedder, @@ -624,7 +624,7 @@ TEST(RasterizerTest, .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -683,7 +683,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -742,7 +742,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -800,7 +800,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -857,7 +857,7 @@ TEST( EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -938,7 +938,7 @@ TEST(RasterizerTest, thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = @@ -994,7 +994,7 @@ TEST(RasterizerTest, TeardownFreesResourceCache) { EXPECT_CALL(*studio, GetContext()).WillRepeatedly(Return(context.get())); rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); EXPECT_EQ(context->getResourceCacheLimit(), 0ul); rasterizer->SetResourceCacheMaxBytes(10000000, false); @@ -1113,7 +1113,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = @@ -1196,7 +1196,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(studio)); - rasterizer->RegisterSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 3bf10ce28d615..0f328503ba32a 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -744,6 +744,8 @@ DartVM* Shell::GetDartVM() { return &vm_; } +constexpr int64_t kFlutterDefaultViewId = 0ll; + // |PlatformView::Delegate| void Shell::OnPlatformViewCreated() { TRACE_EVENT0("flutter", "Shell::OnPlatformViewCreated"); @@ -792,8 +794,7 @@ void Shell::OnPlatformViewCreated() { // embedder. rasterizer->EnableThreadMergerIfNeeded(); rasterizer->Setup(std::move(studio)); - // TODO(dkwingsmt): Change 0ll - rasterizer->RegisterSurface(0ll, std::move(surface)); + rasterizer->AddSurface(kFlutterDefaultViewId, std::move(surface)); } waiting_for_first_frame.store(true); @@ -1982,6 +1983,27 @@ bool Shell::OnServiceProtocolReloadAssetFonts( return true; } +void Shell::AddRenderSurface(int64_t view_id) { + TRACE_EVENT0("flutter", "Shell::AddRenderSurface"); + FML_DCHECK(is_setup_); + FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); + + std::unique_ptr surface = platform_view_->CreateSurface(); + fml::AutoResetWaitableEvent latch; + task_runners_.GetRasterTaskRunner()->PostTask( + fml::MakeCopyable([&latch, // + rasterizer = rasterizer_->GetWeakPtr(), // + surface = std::move(surface), // + view_id // + ]() mutable { + if (rasterizer) { + rasterizer->AddSurface(view_id, std::move(surface)); + } + latch.Signal(); + })); + latch.Wait(); +} + Rasterizer::Screenshot Shell::Screenshot( Rasterizer::ScreenshotType screenshot_type, bool base64_encode) { diff --git a/shell/common/shell.h b/shell/common/shell.h index 6a1c9852e233b..9642a7e3b428c 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -297,6 +297,8 @@ class Shell final : public PlatformView::Delegate, /// bool IsSetup() const; + void AddRenderSurface(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Captures a screenshot and optionally Base64 encodes the data /// of the last layer tree rendered by the rasterizer in this diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 051b3f3811ae9..eb7e72d7135db 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -2046,6 +2046,22 @@ FlutterEngineResult FlutterEngineShutdown(FLUTTER_API_SYMBOL(FlutterEngine) return kSuccess; } +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineAddRenderSurface( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterRendererConfig* config, + void* user_data, + int64_t view_id) { + if (engine == nullptr) { + return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid."); + } + flutter::EmbedderEngine* embedder_engine = + reinterpret_cast(engine); + embedder_engine->GetShell().AddRenderSurface(view_id); + + return kSuccess; +} + FlutterEngineResult FlutterEngineSendWindowMetricsEvent( FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterWindowMetricsEvent* flutter_metrics) { diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 5cdba06ef505d..d296fab874add 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -2243,6 +2243,13 @@ FLUTTER_EXPORT FlutterEngineResult FlutterEngineRunInitialized( FLUTTER_API_SYMBOL(FlutterEngine) engine); +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineAddRenderSurface( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterRendererConfig* config, + void* user_data, + int64_t view_id); + FLUTTER_EXPORT FlutterEngineResult FlutterEngineSendWindowMetricsEvent( FLUTTER_API_SYMBOL(FlutterEngine) engine, @@ -2817,6 +2824,11 @@ typedef FlutterEngineResult (*FlutterEngineDeinitializeFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine); typedef FlutterEngineResult (*FlutterEngineRunInitializedFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine); +typedef FlutterEngineResult (*FlutterEngineAddRenderSurfaceFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, + const FlutterRendererConfig* config, + void* user_data, + int64_t view_id); typedef FlutterEngineResult (*FlutterEngineSendWindowMetricsEventFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine, const FlutterWindowMetricsEvent* event); @@ -2926,6 +2938,7 @@ typedef struct { FlutterEngineInitializeFnPtr Initialize; FlutterEngineDeinitializeFnPtr Deinitialize; FlutterEngineRunInitializedFnPtr RunInitialized; + FlutterEngineAddRenderSurfaceFnPtr AddRenderSurface; FlutterEngineSendWindowMetricsEventFnPtr SendWindowMetricsEvent; FlutterEngineSendPointerEventFnPtr SendPointerEvent; FlutterEngineSendKeyEventFnPtr SendKeyEvent; From 13b3a95f46eaea9f812d092703538b4137ebeab5 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 27 Mar 2023 22:23:47 +0000 Subject: [PATCH 065/142] Fix embedder test --- shell/platform/embedder/embedder.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index eb7e72d7135db..18fb98c1c8f75 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -3099,6 +3099,7 @@ FlutterEngineResult FlutterEngineGetProcAddresses( SET_PROC(Initialize, FlutterEngineInitialize); SET_PROC(Deinitialize, FlutterEngineDeinitialize); SET_PROC(RunInitialized, FlutterEngineRunInitialized); + SET_PROC(AddRenderSurface, FlutterEngineAddRenderSurface); SET_PROC(SendWindowMetricsEvent, FlutterEngineSendWindowMetricsEvent); SET_PROC(SendPointerEvent, FlutterEngineSendPointerEvent); SET_PROC(SendKeyEvent, FlutterEngineSendKeyEvent); From 23d99de0d55db8cd61e4fe385af0fbd22b895c21 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 27 Mar 2023 22:32:39 +0000 Subject: [PATCH 066/142] Move MakeGLContext to studio --- shell/common/shell_test_platform_view_gl.cc | 4 +- shell/gpu/gpu_studio_gl_skia.cc | 41 +++++++++++++++---- shell/gpu/gpu_studio_gl_skia.h | 2 + shell/gpu/gpu_surface_gl_skia.cc | 34 --------------- shell/gpu/gpu_surface_gl_skia.h | 2 - .../android/android_surface_gl_skia.cc | 4 +- shell/platform/embedder/embedder_studio_gl.cc | 2 +- 7 files changed, 40 insertions(+), 49 deletions(-) diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index 02a205b455cf3..1e36400d96939 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -40,7 +40,7 @@ void ShellTestPlatformViewGL::SimulateVSync() { // |PlatformView| std::unique_ptr ShellTestPlatformViewGL::CreateRenderingStudio() { if (main_context_ == nullptr) { - main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); + main_context_ = GPUStudioGLSkia::MakeGLContext(this); } return std::make_unique(main_context_, this); } @@ -49,7 +49,7 @@ std::unique_ptr ShellTestPlatformViewGL::CreateRenderingStudio() { std::unique_ptr ShellTestPlatformViewGL::CreateRenderingSurface( int64_t view_id) { if (main_context_ == nullptr) { - main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); + main_context_ = GPUStudioGLSkia::MakeGLContext(this); } return std::make_unique(main_context_, this, true); } diff --git a/shell/gpu/gpu_studio_gl_skia.cc b/shell/gpu/gpu_studio_gl_skia.cc index 00c36c7b6e29c..60ae52e808c91 100644 --- a/shell/gpu/gpu_studio_gl_skia.cc +++ b/shell/gpu/gpu_studio_gl_skia.cc @@ -17,16 +17,41 @@ #include "third_party/skia/include/core/SkColorType.h" #include "third_party/skia/include/gpu/GrContextOptions.h" -// These are common defines present on all OpenGL headers. However, we don't -// want to perform GL header reasolution on each platform we support. So just -// define these upfront. It is unlikely we will need more. But, if we do, we can -// add the same here. -#define GPU_GL_RGBA8 0x8058 -#define GPU_GL_RGBA4 0x8056 -#define GPU_GL_RGB565 0x8D62 - namespace flutter { +// Default maximum number of bytes of GPU memory of budgeted resources in the +// cache. +// The shell will dynamically increase or decrease this cache based on the +// viewport size, unless a user has specifically requested a size on the Skia +// system channel. +static const size_t kGrCacheMaxByteSize = 24 * (1 << 20); + +sk_sp GPUStudioGLSkia::MakeGLContext( + GPUSurfaceGLDelegate* delegate) { + auto context_switch = delegate->GLContextMakeCurrent(); + if (!context_switch->GetResult()) { + FML_LOG(ERROR) + << "Could not make the context current to set up the Gr context."; + return nullptr; + } + + const auto options = + MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kOpenGL); + + auto context = GrDirectContext::MakeGL(delegate->GetGLInterface(), options); + + if (!context) { + FML_LOG(ERROR) << "Failed to set up Skia Gr context."; + return nullptr; + } + + context->setResourceCacheLimit(kGrCacheMaxByteSize); + + PersistentCache::GetCacheForProcess()->PrecompileKnownSkSLs(context.get()); + + return context; +} + GPUStudioGLSkia::GPUStudioGLSkia(const sk_sp& gr_context, GPUSurfaceGLDelegate* delegate) : delegate_(delegate), context_(gr_context) { diff --git a/shell/gpu/gpu_studio_gl_skia.h b/shell/gpu/gpu_studio_gl_skia.h index 25ee264d1cfbf..2744e4e794404 100644 --- a/shell/gpu/gpu_studio_gl_skia.h +++ b/shell/gpu/gpu_studio_gl_skia.h @@ -22,6 +22,8 @@ namespace flutter { class GPUStudioGLSkia : public Studio { public: + static sk_sp MakeGLContext(GPUSurfaceGLDelegate* delegate); + GPUStudioGLSkia(const sk_sp& gr_context, GPUSurfaceGLDelegate* delegate); diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index e4b81f6605641..d828efdced2d0 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -4,7 +4,6 @@ #include "flutter/shell/gpu/gpu_surface_gl_skia.h" -#include "flutter/common/graphics/persistent_cache.h" #include "flutter/fml/base32.h" #include "flutter/fml/logging.h" #include "flutter/fml/size.h" @@ -29,39 +28,6 @@ namespace flutter { -// Default maximum number of bytes of GPU memory of budgeted resources in the -// cache. -// The shell will dynamically increase or decrease this cache based on the -// viewport size, unless a user has specifically requested a size on the Skia -// system channel. -static const size_t kGrCacheMaxByteSize = 24 * (1 << 20); - -sk_sp GPUSurfaceGLSkia::MakeGLContext( - GPUSurfaceGLDelegate* delegate) { - auto context_switch = delegate->GLContextMakeCurrent(); - if (!context_switch->GetResult()) { - FML_LOG(ERROR) - << "Could not make the context current to set up the Gr context."; - return nullptr; - } - - const auto options = - MakeDefaultContextOptions(ContextType::kRender, GrBackendApi::kOpenGL); - - auto context = GrDirectContext::MakeGL(delegate->GetGLInterface(), options); - - if (!context) { - FML_LOG(ERROR) << "Failed to set up Skia Gr context."; - return nullptr; - } - - context->setResourceCacheLimit(kGrCacheMaxByteSize); - - PersistentCache::GetCacheForProcess()->PrecompileKnownSkSLs(context.get()); - - return context; -} - GPUSurfaceGLSkia::GPUSurfaceGLSkia(const sk_sp& gr_context, GPUSurfaceGLDelegate* delegate, bool render_to_surface) diff --git a/shell/gpu/gpu_surface_gl_skia.h b/shell/gpu/gpu_surface_gl_skia.h index f242f76f02662..3d340ce4171c4 100644 --- a/shell/gpu/gpu_surface_gl_skia.h +++ b/shell/gpu/gpu_surface_gl_skia.h @@ -22,8 +22,6 @@ namespace flutter { class GPUSurfaceGLSkia : public Surface { public: - static sk_sp MakeGLContext(GPUSurfaceGLDelegate* delegate); - GPUSurfaceGLSkia(const sk_sp& gr_context, GPUSurfaceGLDelegate* delegate, bool render_to_surface); diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index 3fc3e60c1d6ea..f266c2daa7217 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -58,7 +58,7 @@ sk_sp AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( sk_sp main_skia_context = GLContextPtr()->GetMainSkiaContext(); if (!main_skia_context) { - main_skia_context = GPUSurfaceGLSkia::MakeGLContext(this); + main_skia_context = GPUStudioGLSkia::MakeGLContext(this); GLContextPtr()->SetMainSkiaContext(main_skia_context); } FML_DCHECK(GLContextPtr()->GetMainSkiaContext() == main_skia_context); @@ -234,7 +234,7 @@ std::unique_ptr AndroidSurfaceGLSkia::CreateSnapshotStudio() { sk_sp main_skia_context = GLContextPtr()->GetMainSkiaContext(); if (!main_skia_context) { - main_skia_context = GPUSurfaceGLSkia::MakeGLContext(this); + main_skia_context = GPUStudioGLSkia::MakeGLContext(this); GLContextPtr()->SetMainSkiaContext(main_skia_context); } diff --git a/shell/platform/embedder/embedder_studio_gl.cc b/shell/platform/embedder/embedder_studio_gl.cc index c749c31515e92..36885f9400866 100644 --- a/shell/platform/embedder/embedder_studio_gl.cc +++ b/shell/platform/embedder/embedder_studio_gl.cc @@ -147,7 +147,7 @@ sk_sp EmbedderStudioGL::CreateResourceContext() const { sk_sp EmbedderStudioGL::MainContext() { if (!main_context_) { - main_context_ = GPUSurfaceGLSkia::MakeGLContext(this); + main_context_ = GPUStudioGLSkia::MakeGLContext(this); } return main_context_; } From a9ff44c063cf1cb6e27d44426f8f90afa4639a03 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 27 Mar 2023 23:53:08 +0000 Subject: [PATCH 067/142] Remove config --- shell/platform/embedder/embedder.cc | 1 - shell/platform/embedder/embedder.h | 2 -- 2 files changed, 3 deletions(-) diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 18fb98c1c8f75..17a754fb0f577 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -2049,7 +2049,6 @@ FlutterEngineResult FlutterEngineShutdown(FLUTTER_API_SYMBOL(FlutterEngine) FLUTTER_EXPORT FlutterEngineResult FlutterEngineAddRenderSurface( FLUTTER_API_SYMBOL(FlutterEngine) engine, - const FlutterRendererConfig* config, void* user_data, int64_t view_id) { if (engine == nullptr) { diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index d296fab874add..06f8217a93f14 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -2246,7 +2246,6 @@ FlutterEngineResult FlutterEngineRunInitialized( FLUTTER_EXPORT FlutterEngineResult FlutterEngineAddRenderSurface( FLUTTER_API_SYMBOL(FlutterEngine) engine, - const FlutterRendererConfig* config, void* user_data, int64_t view_id); @@ -2826,7 +2825,6 @@ typedef FlutterEngineResult (*FlutterEngineRunInitializedFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine); typedef FlutterEngineResult (*FlutterEngineAddRenderSurfaceFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine, - const FlutterRendererConfig* config, void* user_data, int64_t view_id); typedef FlutterEngineResult (*FlutterEngineSendWindowMetricsEventFnPtr)( From ceb0e1177a35bf1dee3ede9993732c8d291c7bd8 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 27 Mar 2023 18:07:14 -0700 Subject: [PATCH 068/142] Add view id to many --- lib/ui/dart_ui.cc | 2 +- lib/ui/window.dart | 6 ++--- lib/ui/window/platform_configuration.cc | 5 ++-- lib/ui/window/platform_configuration.h | 4 ++-- runtime/runtime_controller.cc | 4 ++-- runtime/runtime_controller.h | 2 +- runtime/runtime_delegate.h | 3 ++- shell/common/animator.cc | 5 ++-- shell/common/animator.h | 2 +- shell/common/animator_unittests.cc | 6 +++-- shell/common/engine.cc | 5 ++-- shell/common/engine.h | 3 ++- shell/common/engine_unittests.cc | 2 +- shell/common/pipeline.h | 7 ++++-- shell/common/rasterizer.cc | 5 ++-- shell/common/rasterizer.h | 1 + shell/common/rasterizer_unittests.cc | 31 ++++++++++++++----------- shell/common/shell_test.cc | 4 +++- 18 files changed, 57 insertions(+), 40 deletions(-) diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 57242c11ac9aa..e26aeb307fd55 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -98,7 +98,7 @@ typedef CanvasPath Path; V(PlatformConfigurationNativeApi::ImplicitViewEnabled, 0) \ V(PlatformConfigurationNativeApi::DefaultRouteName, 0) \ V(PlatformConfigurationNativeApi::ScheduleFrame, 0) \ - V(PlatformConfigurationNativeApi::Render, 1) \ + V(PlatformConfigurationNativeApi::Render, 2) \ V(PlatformConfigurationNativeApi::UpdateSemantics, 1) \ V(PlatformConfigurationNativeApi::SetNeedsReportTimings, 1) \ V(PlatformConfigurationNativeApi::SetIsolateDebugName, 1) \ diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 19f40c6e1ee6a..44389d09f8f39 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -289,10 +289,10 @@ class FlutterView { /// scheduling of frames. /// * [RendererBinding], the Flutter framework class which manages layout and /// painting. - void render(Scene scene) => _render(scene); + void render(Scene scene) => _render(viewId == 0 ? 0 : viewId.hashCode, scene); - @Native)>(symbol: 'PlatformConfigurationNativeApi::Render') - external static void _render(Scene scene); + @Native)>(symbol: 'PlatformConfigurationNativeApi::Render') + external static void _render(int viewId, Scene scene); /// Change the retained semantics data about this [FlutterView]. /// diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index 4e6e583745d4d..25124cd9d3458 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -280,9 +280,10 @@ void PlatformConfiguration::CompletePlatformMessageResponse( response->Complete(std::make_unique(std::move(data))); } -void PlatformConfigurationNativeApi::Render(Scene* scene) { +void PlatformConfigurationNativeApi::Render(int64_t view_id, Scene* scene) { UIDartState::ThrowIfUIOperationsProhibited(); - UIDartState::Current()->platform_configuration()->client()->Render(scene); + UIDartState::Current()->platform_configuration()->client()->Render(view_id, + scene); } void PlatformConfigurationNativeApi::SetNeedsReportTimings(bool value) { diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 381b8e02e1072..57c939647715f 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -78,7 +78,7 @@ class PlatformConfigurationClient { /// @brief Updates the client's rendering on the GPU with the newly /// provided Scene. /// - virtual void Render(Scene* scene) = 0; + virtual void Render(int64_t view_id, Scene* scene) = 0; //-------------------------------------------------------------------------- /// @brief Receives an updated semantics tree from the Framework. @@ -485,7 +485,7 @@ class PlatformConfigurationNativeApi { static void ScheduleFrame(); - static void Render(Scene* scene); + static void Render(int64_t view_id, Scene* scene); static void UpdateSemantics(SemanticsUpdate* update); diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 996cc381149bf..0b934f635da1f 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -314,8 +314,8 @@ void RuntimeController::ScheduleFrame() { } // |PlatformConfigurationClient| -void RuntimeController::Render(Scene* scene) { - client_.Render(scene->takeLayerTree()); +void RuntimeController::Render(int64_t view_id, Scene* scene) { + client_.Render(view_id, scene->takeLayerTree()); } // |PlatformConfigurationClient| diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index b3fc828f8264c..0312294f01732 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -622,7 +622,7 @@ class RuntimeController : public PlatformConfigurationClient { void ScheduleFrame() override; // |PlatformConfigurationClient| - void Render(Scene* scene) override; + void Render(int64_t view_id, Scene* scene) override; // |PlatformConfigurationClient| void UpdateSemantics(SemanticsUpdate* update) override; diff --git a/runtime/runtime_delegate.h b/runtime/runtime_delegate.h index 0fbb43391e113..c34f99ef6cc16 100644 --- a/runtime/runtime_delegate.h +++ b/runtime/runtime_delegate.h @@ -27,7 +27,8 @@ class RuntimeDelegate { virtual void ScheduleFrame(bool regenerate_layer_tree = true) = 0; - virtual void Render(std::shared_ptr layer_tree) = 0; + virtual void Render(int64_t view_id, + std::shared_ptr layer_tree) = 0; virtual void UpdateSemantics(SemanticsNodeUpdates update, CustomAccessibilityActionUpdates actions) = 0; diff --git a/shell/common/animator.cc b/shell/common/animator.cc index 0b969c2ccbc0b..fa1a36d2aae79 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -128,7 +128,8 @@ void Animator::BeginFrame( } } -void Animator::Render(std::shared_ptr layer_tree) { +void Animator::Render(int64_t view_id, + std::shared_ptr layer_tree) { has_rendered_ = true; last_layer_tree_size_ = layer_tree->frame_size(); @@ -148,7 +149,7 @@ void Animator::Render(std::shared_ptr layer_tree) { frame_timings_recorder_->GetVsyncTargetTime()); auto layer_tree_item = std::make_unique( - std::move(layer_tree), std::move(frame_timings_recorder_)); + view_id, std::move(layer_tree), std::move(frame_timings_recorder_)); // Commit the pending continuation. PipelineProduceResult result = producer_continuation_.Complete(std::move(layer_tree_item)); diff --git a/shell/common/animator.h b/shell/common/animator.h index dfacb4a786bf3..a89a94b8fcc32 100644 --- a/shell/common/animator.h +++ b/shell/common/animator.h @@ -54,7 +54,7 @@ class Animator final { void RequestFrame(bool regenerate_layer_tree = true); - void Render(std::shared_ptr layer_tree); + void Render(int64_t view_id, std::shared_ptr layer_tree); const std::weak_ptr GetVsyncWaiter() const; diff --git a/shell/common/animator_unittests.cc b/shell/common/animator_unittests.cc index 05c728c57ae16..8323cd49033a0 100644 --- a/shell/common/animator_unittests.cc +++ b/shell/common/animator_unittests.cc @@ -23,6 +23,8 @@ namespace flutter { namespace testing { +constexpr int64_t kDefaultViewId = 0; + class FakeAnimatorDelegate : public Animator::Delegate { public: MOCK_METHOD2(OnAnimatorBeginFrame, @@ -157,7 +159,7 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyIdleBeforeRender) { ASSERT_FALSE(delegate.notify_idle_called_); auto layer_tree = std::make_shared(SkISize::Make(600, 800), 1.0); - animator->Render(std::move(layer_tree)); + animator->Render(kDefaultViewId, std::move(layer_tree)); task_runners.GetPlatformTaskRunner()->PostTask(flush_vsync_task); }, // See kNotifyIdleTaskWaitTime in animator.cc. @@ -240,7 +242,7 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyDelegateIfPipelineIsNotEmpty) { PostTaskSync(task_runners.GetUITaskRunner(), [&] { auto layer_tree = std::make_shared(SkISize::Make(600, 800), 1.0); - animator->Render(std::move(layer_tree)); + animator->Render(kDefaultViewId, std::move(layer_tree)); }); } diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 522ee89a52a7b..a141d09cd1fa7 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -450,7 +450,8 @@ void Engine::ScheduleFrame(bool regenerate_layer_tree) { animator_->RequestFrame(regenerate_layer_tree); } -void Engine::Render(std::shared_ptr layer_tree) { +void Engine::Render(int64_t view_id, + std::shared_ptr layer_tree) { if (!layer_tree) { return; } @@ -461,7 +462,7 @@ void Engine::Render(std::shared_ptr layer_tree) { return; } - animator_->Render(std::move(layer_tree)); + animator_->Render(view_id, std::move(layer_tree)); } void Engine::UpdateSemantics(SemanticsNodeUpdates update, diff --git a/shell/common/engine.h b/shell/common/engine.h index c6ff37eae37a5..8c5a07379f86b 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -895,7 +895,8 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { std::string DefaultRouteName() override; // |RuntimeDelegate| - void Render(std::shared_ptr layer_tree) override; + void Render(int64_t view_id, + std::shared_ptr layer_tree) override; // |RuntimeDelegate| void UpdateSemantics(SemanticsNodeUpdates update, diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index 3bfdd000c37eb..85c4656506485 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -51,7 +51,7 @@ class MockRuntimeDelegate : public RuntimeDelegate { MOCK_METHOD0(ImplicitViewEnabled, bool()); MOCK_METHOD0(DefaultRouteName, std::string()); MOCK_METHOD1(ScheduleFrame, void(bool)); - MOCK_METHOD1(Render, void(std::shared_ptr)); + MOCK_METHOD2(Render, void(int64_t, std::shared_ptr)); MOCK_METHOD2(UpdateSemantics, void(SemanticsNodeUpdates, CustomAccessibilityActionUpdates)); MOCK_METHOD1(HandlePlatformMessage, void(std::unique_ptr)); diff --git a/shell/common/pipeline.h b/shell/common/pipeline.h index 1de4498e7f08c..f58d57ab263f8 100644 --- a/shell/common/pipeline.h +++ b/shell/common/pipeline.h @@ -252,10 +252,13 @@ class Pipeline { }; struct LayerTreeItem { - LayerTreeItem(std::shared_ptr layer_tree, + LayerTreeItem(int64_t view_id, + std::shared_ptr layer_tree, std::unique_ptr frame_timings_recorder) - : layer_tree(std::move(layer_tree)), + : view_id(view_id), + layer_tree(std::move(layer_tree)), frame_timings_recorder(std::move(frame_timings_recorder)) {} + int64_t view_id; std::shared_ptr layer_tree; std::unique_ptr frame_timings_recorder; }; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 4de7e9038613d..c222b1837b1a5 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -226,11 +226,10 @@ RasterStatus Rasterizer::Draw( std::shared_ptr layer_tree = std::move(item->layer_tree); std::unique_ptr frame_timings_recorder = std::move(item->frame_timings_recorder); + int64_t view_id = item->view_id; if (discard_callback(*layer_tree.get())) { draw_result.raster_status = RasterStatus::kDiscarded; } else { - // TODO(dkwingsmt) - int64_t view_id = 0ll; draw_result = DoDraw(view_id, std::move(frame_timings_recorder), std::move(layer_tree)); } @@ -246,6 +245,7 @@ RasterStatus Rasterizer::Draw( bool should_resubmit_frame = ShouldResubmitFrame(draw_result.raster_status); if (should_resubmit_frame) { auto resubmitted_layer_tree_item = std::make_unique( + draw_result.resubmitted_view_id, std::move(draw_result.resubmitted_layer_tree), std::move(draw_result.resubmitted_recorder)); auto front_continuation = pipeline->ProduceIfEmpty(); @@ -431,6 +431,7 @@ Rasterizer::DoDrawResult Rasterizer::DoDraw( } else if (ShouldResubmitFrame(raster_status)) { return DoDrawResult{ .raster_status = raster_status, + .resubmitted_view_id = view_id, .resubmitted_layer_tree = std::move(layer_tree), .resubmitted_recorder = frame_timings_recorder->CloneUntil( FrameTimingsRecorder::State::kBuildEnd), diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 6ff0d74dff670..c0047902c5660 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -485,6 +485,7 @@ class Rasterizer final : public SnapshotDelegate, private: struct DoDrawResult { RasterStatus raster_status = RasterStatus::kFailed; + int64_t resubmitted_view_id; // Set when we need attempt to rasterize the layer tree again. This // layer_tree has not successfully rasterized. This can happen due to the // change in the thread configuration. This will be inserted to the front of diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index b923611896ee0..f54e52644fc56 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -203,7 +203,7 @@ TEST(RasterizerTest, auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -270,7 +270,7 @@ TEST( auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -343,7 +343,7 @@ TEST( auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -419,7 +419,7 @@ TEST(RasterizerTest, auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -468,7 +468,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -525,7 +525,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -631,7 +631,7 @@ TEST(RasterizerTest, auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -690,7 +690,7 @@ TEST( auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -749,7 +749,7 @@ TEST( auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -807,7 +807,7 @@ TEST( auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -864,7 +864,7 @@ TEST( auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder()); + kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -945,7 +945,8 @@ TEST(RasterizerTest, std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i])); + kDefaultViewId, std::move(layer_tree), + CreateFinishedBuildRecorder(timestamps[i])); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -1120,7 +1121,8 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i])); + kDefaultViewId, std::move(layer_tree), + CreateFinishedBuildRecorder(timestamps[i])); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); @@ -1201,7 +1203,8 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( - std::move(layer_tree), CreateFinishedBuildRecorder(first_timestamp)); + kDefaultViewId, std::move(layer_tree), + CreateFinishedBuildRecorder(first_timestamp)); PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index a799e6bcb4811..d5fab1f5be7b9 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -20,6 +20,8 @@ namespace flutter { namespace testing { +constexpr int64_t kDefaultViewId = 0; + ShellTest::ShellTest() : thread_host_("io.flutter.test." + GetCurrentTestName() + ".", ThreadHost::Type::Platform | ThreadHost::Type::IO | @@ -208,7 +210,7 @@ void ShellTest::PumpOneFrame(Shell* shell, if (builder) { builder(root_layer); } - runtime_delegate->Render(std::move(layer_tree)); + runtime_delegate->Render(kDefaultViewId, std::move(layer_tree)); latch.Signal(); }); latch.Wait(); From 2c69edaf6979f3896545dfa2f2c81e60c07fab9d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 27 Mar 2023 21:59:55 -0700 Subject: [PATCH 069/142] Fix ios --- shell/common/rasterizer.cc | 3 +-- shell/common/rasterizer.h | 3 ++- shell/platform/darwin/ios/ios_surface_metal_impeller.mm | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index c222b1837b1a5..738f76cdb18fa 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -550,7 +550,6 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( flutter::LayerTree* layer_tree, SurfaceRecord* surface_record) { Surface* surface = surface_record->surface.get(); - flutter::LayerTree* last_layer_tree = surface_record->last_tree.get(); FML_DCHECK(surface); compositor_context_->ui_time().SetLapTime( @@ -618,7 +617,7 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( damage = std::make_unique(); if (frame->framebuffer_info().existing_damage && !force_full_repaint) { - damage->SetPreviousLayerTree(last_layer_tree); + damage->SetPreviousLayerTree(surface_record->last_tree.get()); damage->AddAdditionalDamage(*frame->framebuffer_info().existing_damage); damage->SetClipAlignment( frame->framebuffer_info().horizontal_clip_alignment, diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index c0047902c5660..27be24a0abb14 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -575,7 +575,8 @@ class Rasterizer final : public SnapshotDelegate, flutter::LayerTree* layer_tree, SurfaceRecord* surface_record); - Screenshot ScreenshotLayerTree(ScreenshotType type, + Screenshot ScreenshotLayerTree(view_id, + ScreenshotType type, bool base64_encode, SurfaceRecord& surface_record); diff --git a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm index 67be44b0f3fd6..e48623e943135 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm @@ -47,11 +47,10 @@ // |IOSSurface| std::unique_ptr IOSSurfaceMetalImpeller::CreateGPUStudio(GrDirectContext*) { - auto context = std::make_shared( - impeller_context_, - InferOffscreenLayerPixelFormat(FromMTLPixelFormat(layer_.get().pixelFormat))); - return std::make_unique(this, // - context // + impeller_context_->UpdateOffscreenLayerPixelFormat( + InferOffscreenLayerPixelFormat(impeller::FromMTLPixelFormat(layer_.get().pixelFormat))); + return std::make_unique(this, // + impeller_context_ // ); } From 31c1068315b6b8c1e3133d20877198d6ccc471e5 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 27 Mar 2023 22:07:24 -0700 Subject: [PATCH 070/142] Fix compile --- shell/common/rasterizer.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 27be24a0abb14..c0047902c5660 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -575,8 +575,7 @@ class Rasterizer final : public SnapshotDelegate, flutter::LayerTree* layer_tree, SurfaceRecord* surface_record); - Screenshot ScreenshotLayerTree(view_id, - ScreenshotType type, + Screenshot ScreenshotLayerTree(ScreenshotType type, bool base64_encode, SurfaceRecord& surface_record); From 45109abaeb868b2c7492073d131a7a14b7087aeb Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 29 Mar 2023 15:37:47 -0700 Subject: [PATCH 071/142] Add view_id to acquireFrame --- flow/surface.h | 3 +- shell/common/rasterizer.cc | 8 +++-- shell/common/rasterizer.h | 6 ++-- shell/common/rasterizer_unittests.cc | 31 ++++++++++--------- .../common/shell_test_platform_view_vulkan.cc | 1 + .../common/shell_test_platform_view_vulkan.h | 3 +- shell/common/shell_unittests.cc | 5 +-- shell/gpu/gpu_surface_gl_impeller.cc | 1 + shell/gpu/gpu_surface_gl_impeller.h | 3 +- shell/gpu/gpu_surface_gl_skia.cc | 1 + shell/gpu/gpu_surface_gl_skia.h | 3 +- shell/gpu/gpu_surface_metal_impeller.h | 3 +- shell/gpu/gpu_surface_metal_impeller.mm | 3 +- shell/gpu/gpu_surface_metal_skia.h | 4 ++- shell/gpu/gpu_surface_metal_skia.mm | 6 ++-- shell/gpu/gpu_surface_software.cc | 1 + shell/gpu/gpu_surface_software.h | 3 +- shell/gpu/gpu_surface_vulkan.cc | 1 + shell/gpu/gpu_surface_vulkan.h | 3 +- shell/gpu/gpu_surface_vulkan_impeller.cc | 1 + shell/gpu/gpu_surface_vulkan_impeller.h | 3 +- .../external_view_embedder.cc | 7 ++++- .../external_view_embedder.h | 1 + .../external_view_embedder_unittests.cc | 18 ++++++----- .../framework/Source/FlutterPlatformViews.mm | 5 ++- .../Source/FlutterPlatformViewsTest.mm | 25 ++++++++------- .../Source/FlutterPlatformViews_Internal.h | 2 ++ .../darwin/ios/ios_external_view_embedder.mm | 6 +++- 28 files changed, 102 insertions(+), 55 deletions(-) diff --git a/flow/surface.h b/flow/surface.h index e594d08a01232..947a6b8603a10 100644 --- a/flow/surface.h +++ b/flow/surface.h @@ -35,7 +35,8 @@ class Surface { virtual bool IsValid() = 0; - virtual std::unique_ptr AcquireFrame(const SkISize& size) = 0; + virtual std::unique_ptr AcquireFrame(int64_t view_id, + const SkISize& size) = 0; virtual SkMatrix GetRootTransformation() const = 0; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 738f76cdb18fa..5e6bcc53d7e01 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -144,7 +144,10 @@ void Rasterizer::NotifyLowMemoryWarning() const { void Rasterizer::AddSurface(int64_t view_id, std::unique_ptr surface) { bool insertion_happened = - surfaces_.try_emplace(view_id, std::move(surface)).second; + surfaces_ + .try_emplace(/* map key=*/view_id, /*constructor args:*/ view_id, + std::move(surface)) + .second; if (!insertion_happened) { FML_DLOG(INFO) << "Rasterizer::AddSurface called with an existing view ID " << view_id << "."; @@ -571,7 +574,8 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( // // Deleting a surface also clears the GL context. Therefore, acquire the // frame after calling `BeginFrame` as this operation resets the GL context. - auto frame = surface->AcquireFrame(layer_tree->frame_size()); + auto frame = + surface->AcquireFrame(surface_record->view_id, layer_tree->frame_size()); if (frame == nullptr) { frame_timings_recorder.RecordRasterEnd( &compositor_context_->raster_cache()); diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index c0047902c5660..5c4bb2639a48c 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -495,8 +495,10 @@ class Rasterizer final : public SnapshotDelegate, }; struct SurfaceRecord { - explicit SurfaceRecord(std::unique_ptr surface) - : surface(std::move(surface)) {} + SurfaceRecord(int64_t view_id, std::unique_ptr surface) + : view_id(view_id), surface(std::move(surface)) {} + + int64_t view_id; std::unique_ptr surface; // This is the information for the last successfully drawing. diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index f54e52644fc56..b6efdf9df19f3 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -55,8 +55,9 @@ class MockStudio : public Studio { class MockSurface : public Surface { public: MOCK_METHOD0(IsValid, bool()); - MOCK_METHOD1(AcquireFrame, - std::unique_ptr(const SkISize& size)); + MOCK_METHOD2(AcquireFrame, + std::unique_ptr(int64_t view_id, + const SkISize& size)); MOCK_CONST_METHOD0(GetRootTransformation, SkMatrix()); MOCK_METHOD0(GetContext, GrDirectContext*()); MOCK_METHOD0(GetExternalViewEmbedder, ExternalViewEmbedder*()); @@ -176,7 +177,7 @@ TEST(RasterizerTest, /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); - EXPECT_CALL(*surface, AcquireFrame(SkISize())) + EXPECT_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); @@ -247,7 +248,7 @@ TEST( /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); - EXPECT_CALL(*surface, AcquireFrame(SkISize())) + EXPECT_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); @@ -319,7 +320,7 @@ TEST( /*submit_callback=*/[](const SurfaceFrame&, DlCanvas*) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(true)); - EXPECT_CALL(*surface, AcquireFrame(SkISize())) + EXPECT_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); @@ -394,7 +395,7 @@ TEST(RasterizerTest, EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()) .WillRepeatedly(Return(true)); // Prepare two frames for Draw() and DrawLastLayerTree(). - EXPECT_CALL(*surface, AcquireFrame(SkISize())) + EXPECT_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame1)))) .WillOnce(Return(ByMove(std::move(surface_frame2)))); EXPECT_CALL(*studio, MakeRenderContextCurrent()) @@ -618,7 +619,7 @@ TEST(RasterizerTest, ON_CALL(delegate, GetIsGpuDisabledSyncSwitch()) .WillByDefault(Return(is_gpu_disabled_sync_switch)); EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()).Times(0); - EXPECT_CALL(*surface, AcquireFrame(SkISize())) + EXPECT_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); @@ -677,7 +678,7 @@ TEST( ON_CALL(delegate, GetIsGpuDisabledSyncSwitch()) .WillByDefault(Return(is_gpu_disabled_sync_switch)); EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()).Times(0); - EXPECT_CALL(*surface, AcquireFrame(SkISize())) + EXPECT_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); @@ -736,7 +737,7 @@ TEST( EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(false)); EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()) .WillOnce(Return(is_gpu_disabled_sync_switch)); - EXPECT_CALL(*surface, AcquireFrame(SkISize())) + EXPECT_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillOnce(Return(ByMove(std::move(surface_frame)))); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); @@ -795,7 +796,7 @@ TEST( EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillOnce(Return(false)); EXPECT_CALL(delegate, GetIsGpuDisabledSyncSwitch()) .WillOnce(Return(is_gpu_disabled_sync_switch)); - EXPECT_CALL(*surface, AcquireFrame(SkISize())).Times(0); + EXPECT_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())).Times(0); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); @@ -851,9 +852,9 @@ TEST( std::make_shared(false); ON_CALL(delegate, GetIsGpuDisabledSyncSwitch()) .WillByDefault(Return(is_gpu_disabled_sync_switch)); - ON_CALL(*surface, AcquireFrame(SkISize())) + ON_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillByDefault(::testing::Invoke([] { return nullptr; })); - EXPECT_CALL(*surface, AcquireFrame(SkISize())); + EXPECT_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio)); @@ -904,7 +905,7 @@ TEST(RasterizerTest, auto surface = std::make_unique>(); EXPECT_CALL(*studio, AllowsDrawingWhenGpuDisabled()) .WillRepeatedly(Return(true)); - ON_CALL(*surface, AcquireFrame(SkISize())) + ON_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillByDefault(::testing::Invoke([] { SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; @@ -1089,7 +1090,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { auto studio = std::make_unique>(); auto surface = std::make_unique(); ON_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(true)); - ON_CALL(*surface, AcquireFrame(SkISize())) + ON_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillByDefault(::testing::Invoke([&] { SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; @@ -1175,7 +1176,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { auto studio = std::make_unique>(); auto surface = std::make_unique(); ON_CALL(*studio, AllowsDrawingWhenGpuDisabled()).WillByDefault(Return(true)); - ON_CALL(*surface, AcquireFrame(SkISize())) + ON_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())) .WillByDefault(::testing::Invoke([&] { SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 72d8016b33afe..7c4c0ac62f38f 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -208,6 +208,7 @@ bool ShellTestPlatformViewVulkan::OffScreenSurface::IsValid() { std::unique_ptr ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame( + int64_t view_id, const SkISize& size) { auto image_info = SkImageInfo::Make(size, SkColorType::kRGBA_8888_SkColorType, SkAlphaType::kOpaque_SkAlphaType); diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index ff144b3202fba..54067aa11de76 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -87,7 +87,8 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { bool IsValid() override; // |Surface| - std::unique_ptr AcquireFrame(const SkISize& size) override; + std::unique_ptr AcquireFrame(int64_t view_id, + const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index d36677bdf5a18..2b487ae02b2d9 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -134,8 +134,9 @@ class MockSurface : public Surface { MOCK_METHOD0(GetContext, GrDirectContext*()); - MOCK_METHOD1(AcquireFrame, - std::unique_ptr(const SkISize& size)); + MOCK_METHOD2(AcquireFrame, + std::unique_ptr(int64_t view_id, + const SkISize& size)); MOCK_CONST_METHOD0(GetRootTransformation, SkMatrix()); }; diff --git a/shell/gpu/gpu_surface_gl_impeller.cc b/shell/gpu/gpu_surface_gl_impeller.cc index c7e6a5e039c84..ee6bb0d146e10 100644 --- a/shell/gpu/gpu_surface_gl_impeller.cc +++ b/shell/gpu/gpu_surface_gl_impeller.cc @@ -51,6 +51,7 @@ bool GPUSurfaceGLImpeller::IsValid() { // |Surface| std::unique_ptr GPUSurfaceGLImpeller::AcquireFrame( + int64_t view_id, const SkISize& size) { if (!IsValid()) { FML_LOG(ERROR) << "OpenGL surface was invalid."; diff --git a/shell/gpu/gpu_surface_gl_impeller.h b/shell/gpu/gpu_surface_gl_impeller.h index abfc5dfb32231..aaec9cb13c57d 100644 --- a/shell/gpu/gpu_surface_gl_impeller.h +++ b/shell/gpu/gpu_surface_gl_impeller.h @@ -35,7 +35,8 @@ class GPUSurfaceGLImpeller final : public Surface { fml::WeakPtrFactory weak_factory_; // |Surface| - std::unique_ptr AcquireFrame(const SkISize& size) override; + std::unique_ptr AcquireFrame(int64_t view_id, + const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index d828efdced2d0..55997d03dfe89 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -165,6 +165,7 @@ SkMatrix GPUSurfaceGLSkia::GetRootTransformation() const { // |Surface| std::unique_ptr GPUSurfaceGLSkia::AcquireFrame( + int64_t view_id, const SkISize& size) { if (delegate_ == nullptr) { return nullptr; diff --git a/shell/gpu/gpu_surface_gl_skia.h b/shell/gpu/gpu_surface_gl_skia.h index 3d340ce4171c4..6367c8112584d 100644 --- a/shell/gpu/gpu_surface_gl_skia.h +++ b/shell/gpu/gpu_surface_gl_skia.h @@ -33,7 +33,8 @@ class GPUSurfaceGLSkia : public Surface { bool IsValid() override; // |Surface| - std::unique_ptr AcquireFrame(const SkISize& size) override; + std::unique_ptr AcquireFrame(int64_t view_id, + const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/gpu/gpu_surface_metal_impeller.h b/shell/gpu/gpu_surface_metal_impeller.h index 41340873638bb..d5b18e68ef785 100644 --- a/shell/gpu/gpu_surface_metal_impeller.h +++ b/shell/gpu/gpu_surface_metal_impeller.h @@ -36,7 +36,8 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalImpeller : public Surface { fml::scoped_nsprotocol> last_drawable_; // |Surface| - std::unique_ptr AcquireFrame(const SkISize& size) override; + std::unique_ptr AcquireFrame(int64_t view_id, + const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index 8e3056e390514..3c4206e55c9f4 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -43,7 +43,8 @@ } // |Surface| -std::unique_ptr GPUSurfaceMetalImpeller::AcquireFrame(const SkISize& frame_info) { +std::unique_ptr GPUSurfaceMetalImpeller::AcquireFrame(int64_t view_id, + const SkISize& frame_info) { TRACE_EVENT0("impeller", "GPUSurfaceMetalImpeller::AcquireFrame"); if (!IsValid()) { diff --git a/shell/gpu/gpu_surface_metal_skia.h b/shell/gpu/gpu_surface_metal_skia.h index da6cdc0efa24d..f828a4e9a9938 100644 --- a/shell/gpu/gpu_surface_metal_skia.h +++ b/shell/gpu/gpu_surface_metal_skia.h @@ -46,7 +46,8 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalSkia : public Surface { std::map damage_; // |Surface| - std::unique_ptr AcquireFrame(const SkISize& size) override; + std::unique_ptr AcquireFrame(int64_t view_id, + const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; @@ -59,6 +60,7 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalSkia : public Surface { const SkISize& frame_info); std::unique_ptr AcquireFrameFromMTLTexture( + int64_t view_id, const SkISize& frame_info); void PrecompileKnownSkSLsIfNecessary(); diff --git a/shell/gpu/gpu_surface_metal_skia.mm b/shell/gpu/gpu_surface_metal_skia.mm index ca8507c5546e8..14f23fbe532c5 100644 --- a/shell/gpu/gpu_surface_metal_skia.mm +++ b/shell/gpu/gpu_surface_metal_skia.mm @@ -77,7 +77,8 @@ } // |Surface| -std::unique_ptr GPUSurfaceMetalSkia::AcquireFrame(const SkISize& frame_size) { +std::unique_ptr GPUSurfaceMetalSkia::AcquireFrame(int64_t view_id, + const SkISize& frame_size) { if (!IsValid()) { FML_LOG(ERROR) << "Metal surface was invalid."; return nullptr; @@ -100,7 +101,7 @@ case MTLRenderTargetType::kCAMetalLayer: return AcquireFrameFromCAMetalLayer(frame_size); case MTLRenderTargetType::kMTLTexture: - return AcquireFrameFromMTLTexture(frame_size); + return AcquireFrameFromMTLTexture(view_id, frame_size); default: FML_CHECK(false) << "Unknown MTLRenderTargetType type."; } @@ -190,6 +191,7 @@ } std::unique_ptr GPUSurfaceMetalSkia::AcquireFrameFromMTLTexture( + int64_t view_id, const SkISize& frame_info) { GPUMTLTextureInfo texture = delegate_->GetMTLTexture(frame_info); id mtl_texture = (id)(texture.texture); diff --git a/shell/gpu/gpu_surface_software.cc b/shell/gpu/gpu_surface_software.cc index efb905ba24ecb..d61cf66dc93c3 100644 --- a/shell/gpu/gpu_surface_software.cc +++ b/shell/gpu/gpu_surface_software.cc @@ -27,6 +27,7 @@ bool GPUSurfaceSoftware::IsValid() { // |Surface| std::unique_ptr GPUSurfaceSoftware::AcquireFrame( + int64_t view_id, const SkISize& logical_size) { SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; diff --git a/shell/gpu/gpu_surface_software.h b/shell/gpu/gpu_surface_software.h index 18bc8d5b41446..2c9a2fc73c373 100644 --- a/shell/gpu/gpu_surface_software.h +++ b/shell/gpu/gpu_surface_software.h @@ -23,7 +23,8 @@ class GPUSurfaceSoftware : public Surface { bool IsValid() override; // |Surface| - std::unique_ptr AcquireFrame(const SkISize& size) override; + std::unique_ptr AcquireFrame(int64_t view_id, + const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/gpu/gpu_surface_vulkan.cc b/shell/gpu/gpu_surface_vulkan.cc index ac5298a17b96b..9e373f746ec9a 100644 --- a/shell/gpu/gpu_surface_vulkan.cc +++ b/shell/gpu/gpu_surface_vulkan.cc @@ -29,6 +29,7 @@ bool GPUSurfaceVulkan::IsValid() { } std::unique_ptr GPUSurfaceVulkan::AcquireFrame( + int64_t view_id, const SkISize& frame_size) { if (!IsValid()) { FML_LOG(ERROR) << "Vulkan surface was invalid."; diff --git a/shell/gpu/gpu_surface_vulkan.h b/shell/gpu/gpu_surface_vulkan.h index c198f7c60e8f4..7b32f7da9bc40 100644 --- a/shell/gpu/gpu_surface_vulkan.h +++ b/shell/gpu/gpu_surface_vulkan.h @@ -40,7 +40,8 @@ class GPUSurfaceVulkan : public Surface { bool IsValid() override; // |Surface| - std::unique_ptr AcquireFrame(const SkISize& size) override; + std::unique_ptr AcquireFrame(int64_t view_id, + const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; diff --git a/shell/gpu/gpu_surface_vulkan_impeller.cc b/shell/gpu/gpu_surface_vulkan_impeller.cc index a2dc1607b77da..a18ffdbea59a1 100644 --- a/shell/gpu/gpu_surface_vulkan_impeller.cc +++ b/shell/gpu/gpu_surface_vulkan_impeller.cc @@ -44,6 +44,7 @@ bool GPUSurfaceVulkanImpeller::IsValid() { // |Surface| std::unique_ptr GPUSurfaceVulkanImpeller::AcquireFrame( + int64_t view_id, const SkISize& size) { if (!IsValid()) { FML_LOG(ERROR) << "Vulkan surface was invalid."; diff --git a/shell/gpu/gpu_surface_vulkan_impeller.h b/shell/gpu/gpu_surface_vulkan_impeller.h index 1514c1368c9fb..d3421fa1d834b 100644 --- a/shell/gpu/gpu_surface_vulkan_impeller.h +++ b/shell/gpu/gpu_surface_vulkan_impeller.h @@ -32,7 +32,8 @@ class GPUSurfaceVulkanImpeller final : public Surface { fml::WeakPtrFactory weak_factory_; // |Surface| - std::unique_ptr AcquireFrame(const SkISize& size) override; + std::unique_ptr AcquireFrame(int64_t view_id, + const SkISize& size) override; // |Surface| SkMatrix GetRootTransformation() const override; 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 f1d8af9f6a710..f6f49320e062d 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc @@ -8,6 +8,8 @@ namespace flutter { +constexpr int64_t kFlutterDefaultViewId = 0ll; + AndroidExternalViewEmbedder::AndroidExternalViewEmbedder( const AndroidContext& android_context, std::shared_ptr jni_facade, @@ -171,6 +173,8 @@ void AndroidExternalViewEmbedder::SubmitFrame( } std::unique_ptr frame = CreateSurfaceIfNeeded(context, // + // TODO(dkwingsmt) + kFlutterDefaultViewId, // view_id, // slices_.at(view_id).get(), // overlay->second // @@ -184,6 +188,7 @@ void AndroidExternalViewEmbedder::SubmitFrame( // |ExternalViewEmbedder| std::unique_ptr AndroidExternalViewEmbedder::CreateSurfaceIfNeeded(GrDirectContext* context, + int64_t render_view_id, int64_t view_id, EmbedderViewSlice* slice, const SkRect& rect) { @@ -191,7 +196,7 @@ AndroidExternalViewEmbedder::CreateSurfaceIfNeeded(GrDirectContext* context, context, android_context_, jni_facade_, surface_factory_); std::unique_ptr frame = - layer->surface->AcquireFrame(frame_size_); + layer->surface->AcquireFrame(render_view_id, frame_size_); // Display the overlay surface. If it's already displayed, then it's // just positioned and sized. jni_facade_->FlutterViewDisplayOverlaySurface(layer->id, // 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 03bae5ecb8e1a..8a9ae366d1de2 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.h +++ b/shell/platform/android/external_view_embedder/external_view_embedder.h @@ -138,6 +138,7 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder { // Creates a Surface when needed or recycles an existing one. // Finally, draws the picture on the frame's canvas. std::unique_ptr CreateSurfaceIfNeeded(GrDirectContext* context, + int64_t render_view_id, int64_t view_id, EmbedderViewSlice* slice, const SkRect& rect); 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 af933e4251f2d..aacf5ed7aa4f0 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 @@ -24,6 +24,8 @@ namespace flutter { namespace testing { +constexpr int64_t kDefaultViewId = 0ll; + using ::testing::ByMove; using ::testing::Return; @@ -51,7 +53,7 @@ class SurfaceMock : public Surface { MOCK_METHOD(std::unique_ptr, AcquireFrame, - (const SkISize& size), + (int64_t view_id, const SkISize& size), (override)); MOCK_METHOD(SkMatrix, GetRootTransformation, (), (const, override)); @@ -274,7 +276,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { /*frame_size=*/SkISize::Make(800, 600)); auto surface_mock = std::make_unique(); - EXPECT_CALL(*surface_mock, AcquireFrame(frame_size)) + EXPECT_CALL(*surface_mock, AcquireFrame(kDefaultViewId, frame_size)) .Times(2 /* frames */) .WillOnce(Return(ByMove(std::move(surface_frame_1)))) .WillOnce(Return(ByMove(std::move(surface_frame_2)))); @@ -476,7 +478,7 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) { /*frame_size=*/SkISize::Make(800, 600)); auto surface_mock = std::make_unique(); - EXPECT_CALL(*surface_mock, AcquireFrame(frame_size)) + EXPECT_CALL(*surface_mock, AcquireFrame(kDefaultViewId, frame_size)) .Times(1 /* frames */) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); @@ -575,7 +577,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) { /*frame_size=*/SkISize::Make(800, 600)); auto surface_mock = std::make_unique(); - EXPECT_CALL(*surface_mock, AcquireFrame(frame_size)) + EXPECT_CALL(*surface_mock, AcquireFrame(kDefaultViewId, frame_size)) .Times(1 /* frames */) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); @@ -679,7 +681,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) { /*frame_size=*/SkISize::Make(800, 600)); auto surface_mock = std::make_unique(); - EXPECT_CALL(*surface_mock, AcquireFrame(frame_size)) + EXPECT_CALL(*surface_mock, AcquireFrame(kDefaultViewId, frame_size)) .Times(1 /* frames */) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); @@ -768,7 +770,7 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) { /*frame_size=*/SkISize::Make(800, 600)); auto surface_mock = std::make_unique(); - EXPECT_CALL(*surface_mock, AcquireFrame(frame_size)) + EXPECT_CALL(*surface_mock, AcquireFrame(kDefaultViewId, frame_size)) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); auto android_surface_mock = @@ -857,7 +859,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { /*frame_size=*/SkISize::Make(800, 600)); auto surface_mock = std::make_unique(); - EXPECT_CALL(*surface_mock, AcquireFrame(frame_size)) + EXPECT_CALL(*surface_mock, AcquireFrame(kDefaultViewId, frame_size)) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); auto android_surface_mock = @@ -983,7 +985,7 @@ TEST(AndroidExternalViewEmbedder, Teardown) { /*frame_size=*/SkISize::Make(800, 600)); auto surface_mock = std::make_unique(); - EXPECT_CALL(*surface_mock, AcquireFrame(frame_size)) + EXPECT_CALL(*surface_mock, AcquireFrame(kDefaultViewId, frame_size)) .WillOnce(Return(ByMove(std::move(surface_frame_1)))); auto android_surface_mock = diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 5978c1137a4b0..a50ef22c32ab1 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -653,6 +653,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, bool FlutterPlatformViewsController::SubmitFrame(GrDirectContext* gr_context, const std::shared_ptr& ios_context, + int64_t render_view_id, std::unique_ptr frame) { TRACE_EVENT0("flutter", "FlutterPlatformViewsController::SubmitFrame"); @@ -727,6 +728,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, // Get a new host layer. std::shared_ptr layer = GetLayer(gr_context, // ios_context, // + render_view_id, // slice, // joined_rect, // current_platform_view_id, // @@ -798,6 +800,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, std::shared_ptr FlutterPlatformViewsController::GetLayer( GrDirectContext* gr_context, const std::shared_ptr& ios_context, + int64_t render_view_id, EmbedderViewSlice* slice, SkRect rect, int64_t view_id, @@ -824,7 +827,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, overlay_view.accessibilityIdentifier = [NSString stringWithFormat:@"platform_view[%lld].overlay_view[%lld]", view_id, overlay_id]; - std::unique_ptr frame = layer->surface->AcquireFrame(frame_size_); + std::unique_ptr frame = layer->surface->AcquireFrame(render_view_id, frame_size_); // If frame is null, AcquireFrame already printed out an error message. if (!frame) { return layer; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 56bc9ccf5bd32..e9f99672b1f92 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -15,6 +15,9 @@ #import "flutter/shell/platform/darwin/ios/platform_view_ios.h" FLUTTER_ASSERT_NOT_ARC + +constexpr int64_t kDefaultViewId = 0ll; + @class FlutterPlatformViewsTestMockPlatformView; static FlutterPlatformViewsTestMockPlatformView* gMockPlatformView = nil; const float kFloatCompareEpsilon = 0.001; @@ -2225,8 +2228,8 @@ - (void)testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashin nullptr, framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return false; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertFalse( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertFalse(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, + std::move(mock_surface))); auto embeddedViewParams_2 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); @@ -2236,7 +2239,7 @@ - (void)testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashin nullptr, framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, + XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, std::move(mock_surface_submit_true))); } @@ -2404,8 +2407,8 @@ - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, + std::move(mock_surface))); // platform view is wrapped by touch interceptor, which itself is wrapped by clipping view. UIView* clippingView1 = view1.superview.superview; UIView* clippingView2 = view2.superview.superview; @@ -2431,8 +2434,8 @@ - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder { std::move(mock_sk_surface), framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, + std::move(mock_surface))); XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] > [flutterView.subviews indexOfObject:clippingView2], @"The first clipping view should be added after the second clipping view."); @@ -2500,8 +2503,8 @@ - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, + std::move(mock_surface))); // platform view is wrapped by touch interceptor, which itself is wrapped by clipping view. UIView* clippingView1 = view1.superview.superview; UIView* clippingView2 = view2.superview.superview; @@ -2527,8 +2530,8 @@ - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder { std::move(mock_sk_surface), framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, + std::move(mock_surface))); XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] < [flutterView.subviews indexOfObject:clippingView2], @"The first clipping view should be added before the second clipping view."); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index 8447d19ca2df9..7315f828f3038 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -253,6 +253,7 @@ class FlutterPlatformViewsController { bool SubmitFrame(GrDirectContext* gr_context, const std::shared_ptr& ios_context, + int64_t render_view_id, std::unique_ptr frame); void OnMethodCall(FlutterMethodCall* call, FlutterResult& result); @@ -318,6 +319,7 @@ class FlutterPlatformViewsController { // the picture on the layer's canvas. std::shared_ptr GetLayer(GrDirectContext* gr_context, const std::shared_ptr& ios_context, + int64_t render_view_id, EmbedderViewSlice* slice, SkRect rect, int64_t view_id, diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.mm b/shell/platform/darwin/ios/ios_external_view_embedder.mm index 4e28b6cfcca82..d93d8cb1ee76d 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.mm +++ b/shell/platform/darwin/ios/ios_external_view_embedder.mm @@ -6,6 +6,8 @@ namespace flutter { +constexpr int64_t kFlutterDefaultViewId = 0ll; + IOSExternalViewEmbedder::IOSExternalViewEmbedder( const std::shared_ptr& platform_views_controller, std::shared_ptr context) @@ -70,7 +72,9 @@ std::unique_ptr frame) { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::SubmitFrame"); FML_CHECK(platform_views_controller_); - platform_views_controller_->SubmitFrame(context, ios_context_, std::move(frame)); + // TODO(dkwingsmt) + platform_views_controller_->SubmitFrame(context, ios_context_, kFlutterDefaultViewId, + std::move(frame)); TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::DidSubmitFrame"); } From d5deac8fb03aab88ecd8b3548c68c22fbda4163d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 29 Mar 2023 16:38:48 -0700 Subject: [PATCH 072/142] Remembered texture-view map --- shell/common/shell_test_platform_view_metal.h | 3 ++- .../common/shell_test_platform_view_metal.mm | 3 ++- shell/gpu/gpu_surface_metal_delegate.h | 3 ++- shell/gpu/gpu_surface_metal_skia.mm | 2 +- .../darwin/ios/ios_surface_metal_impeller.h | 2 +- .../darwin/ios/ios_surface_metal_impeller.mm | 3 ++- .../darwin/ios/ios_surface_metal_skia.h | 2 +- .../darwin/ios/ios_surface_metal_skia.mm | 3 ++- .../macos/framework/Source/FlutterRenderer.h | 2 +- .../macos/framework/Source/FlutterRenderer.mm | 27 ++++++++++--------- .../framework/Source/FlutterRendererTest.mm | 12 ++++++--- shell/platform/embedder/embedder.cc | 6 +++-- shell/platform/embedder/embedder.h | 1 + .../platform/embedder/embedder_studio_metal.h | 5 ++-- .../embedder/embedder_studio_metal.mm | 5 ++-- 15 files changed, 47 insertions(+), 32 deletions(-) diff --git a/shell/common/shell_test_platform_view_metal.h b/shell/common/shell_test_platform_view_metal.h index bffea1e20eeff..d29e6c1c04d78 100644 --- a/shell/common/shell_test_platform_view_metal.h +++ b/shell/common/shell_test_platform_view_metal.h @@ -61,7 +61,8 @@ class ShellTestPlatformViewMetal final : public ShellTestPlatformView, bool PresentDrawable(GrMTLHandle drawable) const override; // |GPUSurfaceMetalDelegate| - GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_info) const override; + GPUMTLTextureInfo GetMTLTexture(int64_t view_id, + const SkISize& frame_info) const override; // |GPUSurfaceMetalDelegate| bool PresentTexture(GPUMTLTextureInfo texture) const override; diff --git a/shell/common/shell_test_platform_view_metal.mm b/shell/common/shell_test_platform_view_metal.mm index f9c8deb131c99..8fcb895af71d7 100644 --- a/shell/common/shell_test_platform_view_metal.mm +++ b/shell/common/shell_test_platform_view_metal.mm @@ -120,7 +120,8 @@ GPUMTLTextureInfo offscreen_texture_info() const { } // |GPUSurfaceMetalDelegate| -GPUMTLTextureInfo ShellTestPlatformViewMetal::GetMTLTexture(const SkISize& frame_info) const { +GPUMTLTextureInfo ShellTestPlatformViewMetal::GetMTLTexture(int64_t view_id, + const SkISize& frame_info) const { return metal_context_->offscreen_texture_info(); } diff --git a/shell/gpu/gpu_surface_metal_delegate.h b/shell/gpu/gpu_surface_metal_delegate.h index 0136dc71d785b..aff58f14da308 100644 --- a/shell/gpu/gpu_surface_metal_delegate.h +++ b/shell/gpu/gpu_surface_metal_delegate.h @@ -91,7 +91,8 @@ class GPUSurfaceMetalDelegate { /// @brief Returns the handle to the MTLTexture to render to. This is only /// called when the specified render target type is `kMTLTexture`. /// - virtual GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_info) const = 0; + virtual GPUMTLTextureInfo GetMTLTexture(int64_t view_id, + const SkISize& frame_info) const = 0; //------------------------------------------------------------------------------ /// @brief Presents the texture with `texture_id` to the "screen". diff --git a/shell/gpu/gpu_surface_metal_skia.mm b/shell/gpu/gpu_surface_metal_skia.mm index 14f23fbe532c5..6191e4cf96ff9 100644 --- a/shell/gpu/gpu_surface_metal_skia.mm +++ b/shell/gpu/gpu_surface_metal_skia.mm @@ -193,7 +193,7 @@ std::unique_ptr GPUSurfaceMetalSkia::AcquireFrameFromMTLTexture( int64_t view_id, const SkISize& frame_info) { - GPUMTLTextureInfo texture = delegate_->GetMTLTexture(frame_info); + GPUMTLTextureInfo texture = delegate_->GetMTLTexture(view_id, frame_info); id mtl_texture = (id)(texture.texture); if (!mtl_texture) { diff --git a/shell/platform/darwin/ios/ios_surface_metal_impeller.h b/shell/platform/darwin/ios/ios_surface_metal_impeller.h index 9f29a9cc68dc3..88abe8fd82b24 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_impeller.h +++ b/shell/platform/darwin/ios/ios_surface_metal_impeller.h @@ -51,7 +51,7 @@ class SK_API_AVAILABLE_CA_METAL_LAYER IOSSurfaceMetalImpeller final bool PresentDrawable(GrMTLHandle drawable) const override; // |GPUSurfaceMetalDelegate| - GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_info) const override; + GPUMTLTextureInfo GetMTLTexture(int64_t view_id, const SkISize& frame_info) const override; // |GPUSurfaceMetalDelegate| bool PresentTexture(GPUMTLTextureInfo texture) const override; diff --git a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm index e48623e943135..2b2c1284e1118 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm @@ -86,7 +86,8 @@ } // |GPUSurfaceMetalDelegate| -GPUMTLTextureInfo IOSSurfaceMetalImpeller::GetMTLTexture(const SkISize& frame_info) const { +GPUMTLTextureInfo IOSSurfaceMetalImpeller::GetMTLTexture(int64_t view_id, + const SkISize& frame_info) const { FML_CHECK(false); return GPUMTLTextureInfo{ .texture_id = -1, // diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.h b/shell/platform/darwin/ios/ios_surface_metal_skia.h index 43f6dd1268ae9..926ad1346b117 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.h +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.h @@ -49,7 +49,7 @@ class SK_API_AVAILABLE_CA_METAL_LAYER IOSSurfaceMetalSkia final : public IOSSurf bool PresentDrawable(GrMTLHandle drawable) const override; // |GPUSurfaceMetalDelegate| - GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_info) const override; + GPUMTLTextureInfo GetMTLTexture(int64_t view_id, const SkISize& frame_info) const override; // |GPUSurfaceMetalDelegate| bool PresentTexture(GPUMTLTextureInfo texture) const override; diff --git a/shell/platform/darwin/ios/ios_surface_metal_skia.mm b/shell/platform/darwin/ios/ios_surface_metal_skia.mm index 15b465528d221..bf80c80201295 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_skia.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_skia.mm @@ -98,7 +98,8 @@ } // |GPUSurfaceMetalDelegate| -GPUMTLTextureInfo IOSSurfaceMetalSkia::GetMTLTexture(const SkISize& frame_info) const { +GPUMTLTextureInfo IOSSurfaceMetalSkia::GetMTLTexture(int64_t view_id, + const SkISize& frame_info) const { FML_CHECK(false) << "render to texture not supported on ios"; return {.texture_id = -1, .texture = nullptr}; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h b/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h index 483a858032bc8..73c16855b7100 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h @@ -38,7 +38,7 @@ /** * Called by the engine when the given view's buffers should be swapped. */ -- (BOOL)present:(uint64_t)viewId texture:(nonnull const FlutterMetalTexture*)texture; +- (BOOL)present:(nonnull const FlutterMetalTexture*)texture; /** * Creates a Metal texture for the given view with the given size. diff --git a/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm b/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm index d7d2c2fc7d6ac..8b254f5534947 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm @@ -14,21 +14,13 @@ static FlutterMetalTexture OnGetNextDrawableForDefaultView(FlutterEngine* engine, const FlutterFrameInfo* frameInfo) { - // TODO(dkwingsmt): This callback only supports single-view, therefore it only - // operates on the default view. To support multi-view, we need a new callback - // that also receives a view ID, or pass the ID via FlutterFrameInfo. - uint64_t viewId = kFlutterDefaultViewId; CGSize size = CGSizeMake(frameInfo->size.width, frameInfo->size.height); - return [engine.renderer createTextureForView:viewId size:size]; + return [engine.renderer createTextureForView:frameInfo->view_id size:size]; } static bool OnPresentDrawableOfDefaultView(FlutterEngine* engine, const FlutterMetalTexture* texture) { - // TODO(dkwingsmt): This callback only supports single-view, therefore it only - // operates on the default view. To support multi-view, we need a new callback - // that also receives a view ID. - uint64_t viewId = kFlutterDefaultViewId; - return [engine.renderer present:viewId texture:texture]; + return [engine.renderer present:texture]; } static bool OnAcquireExternalTexture(FlutterEngine* engine, @@ -46,6 +38,8 @@ @implementation FlutterRenderer { FlutterViewEngineProvider* _viewProvider; FlutterDarwinContextMetalSkia* _darwinMetalContext; + + NSMutableDictionary* _texture_to_view; } - (instancetype)initWithFlutterEngine:(nonnull FlutterEngine*)flutterEngine { @@ -66,6 +60,7 @@ - (instancetype)initWithFlutterEngine:(nonnull FlutterEngine*)flutterEngine { _darwinMetalContext = [[FlutterDarwinContextMetalSkia alloc] initWithMTLDevice:_device commandQueue:_commandQueue]; + _texture_to_view = [NSMutableDictionary dictionary]; } return self; } @@ -95,11 +90,17 @@ - (FlutterMetalTexture)createTextureForView:(uint64_t)viewId size:(CGSize)size { // FlutterMetalTexture has texture `null`, therefore is discarded. return FlutterMetalTexture{}; } - return [view.surfaceManager surfaceForSize:size].asFlutterMetalTexture; + FlutterMetalTexture texture = [view.surfaceManager surfaceForSize:size].asFlutterMetalTexture; + _texture_to_view[@(texture.texture_id)] = @(viewId); + return texture; } -- (BOOL)present:(uint64_t)viewId texture:(const FlutterMetalTexture*)texture { - FlutterView* view = [_viewProvider viewForId:viewId]; +- (BOOL)present:(const FlutterMetalTexture*)texture { + NSNumber* viewId = _texture_to_view[@(texture->texture_id)]; + if (viewId == nil) { + return NO; + } + FlutterView* view = [_viewProvider viewForId:[viewId longLongValue]]; if (view == nil) { return NO; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm index 46da658efd8e6..f3c88be8806d7 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm @@ -62,18 +62,22 @@ - (nonnull FlutterView*)createFlutterViewWithMTLDevice:(id)device OCMStub([viewMock surfaceManager]).andReturn(surfaceManagerMock); id surfaceMock = OCMClassMock([FlutterSurface class]); - - FlutterMetalTexture texture = { + FlutterMetalTexture mockReturnTexture{ + .texture_id = 100ll, // Arbitrary .user_data = (__bridge void*)surfaceMock, }; - + OCMStub([surfaceMock asFlutterMetalTexture]).andReturn(mockReturnTexture); + OCMStub([surfaceManagerMock surfaceForSize:CGSize{}]) + .ignoringNonObjectArgs() + .andReturn(surfaceMock); [[surfaceManagerMock expect] present:[OCMArg checkWithBlock:^(id obj) { NSArray* array = (NSArray*)obj; return array.count == 1 ? YES : NO; }] notify:nil]; - [renderer present:kFlutterDefaultViewId texture:&texture]; + FlutterMetalTexture texture = [renderer createTextureForView:0ll size:CGSize{}]; + [renderer present:&texture]; [surfaceManagerMock verify]; } diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 17a754fb0f577..22ee1290dc439 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -477,12 +477,14 @@ InferMetalPlatformViewCreationCallback( return ptr(user_data, &embedder_texture); }; auto metal_get_texture = - [ptr = config->metal.get_next_drawable_callback, - user_data](const SkISize& frame_size) -> flutter::GPUMTLTextureInfo { + [ptr = config->metal.get_next_drawable_callback, user_data]( + int64_t view_id, + const SkISize& frame_size) -> flutter::GPUMTLTextureInfo { FlutterFrameInfo frame_info = {}; frame_info.struct_size = sizeof(FlutterFrameInfo); frame_info.size = {static_cast(frame_size.width()), static_cast(frame_size.height())}; + frame_info.view_id = view_id; flutter::GPUMTLTextureInfo texture_info; FlutterMetalTexture metal_texture = ptr(user_data, &frame_info); diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 06f8217a93f14..95e627a0bcc4d 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -464,6 +464,7 @@ typedef struct { size_t struct_size; /// The size of the surface that will be backed by the fbo. FlutterUIntSize size; + int64_t view_id; } FlutterFrameInfo; /// Callback for when a frame buffer object is requested. diff --git a/shell/platform/embedder/embedder_studio_metal.h b/shell/platform/embedder/embedder_studio_metal.h index 6c7d9e6e838fe..6c126370bed74 100644 --- a/shell/platform/embedder/embedder_studio_metal.h +++ b/shell/platform/embedder/embedder_studio_metal.h @@ -20,7 +20,7 @@ class EmbedderStudioMetal final : public EmbedderStudio, public: struct MetalDispatchTable { std::function present; // required - std::function + std::function get_texture; // required }; @@ -52,7 +52,8 @@ class EmbedderStudioMetal final : public EmbedderStudio, bool PresentDrawable(GrMTLHandle drawable) const override; // |GPUSurfaceMetalDelegate| - GPUMTLTextureInfo GetMTLTexture(const SkISize& frame_size) const override; + GPUMTLTextureInfo GetMTLTexture(int64_t view_id, + const SkISize& frame_size) const override; // |GPUSurfaceMetalDelegate| bool PresentTexture(GPUMTLTextureInfo texture) const override; diff --git a/shell/platform/embedder/embedder_studio_metal.mm b/shell/platform/embedder/embedder_studio_metal.mm index 6a7f3fb267815..4f1cbae62c16a 100644 --- a/shell/platform/embedder/embedder_studio_metal.mm +++ b/shell/platform/embedder/embedder_studio_metal.mm @@ -84,8 +84,9 @@ return false; } -GPUMTLTextureInfo EmbedderStudioMetal::GetMTLTexture(const SkISize& frame_info) const { - return metal_dispatch_table_.get_texture(frame_info); +GPUMTLTextureInfo EmbedderStudioMetal::GetMTLTexture(int64_t view_id, + const SkISize& frame_info) const { + return metal_dispatch_table_.get_texture(view_id, frame_info); } bool EmbedderStudioMetal::PresentTexture(GPUMTLTextureInfo texture) const { From b73e7a8fcccadb8aa6b8d1892e1b3e8d76fe0623 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 29 Mar 2023 16:51:58 -0700 Subject: [PATCH 073/142] Put view ID in MetalTexture for now --- .../darwin/macos/framework/Source/FlutterRenderer.mm | 8 ++------ .../macos/framework/Source/FlutterRendererTest.mm | 11 ++++------- shell/platform/embedder/embedder.h | 1 + 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm b/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm index 8b254f5534947..a9a8ea847d9f2 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterRenderer.mm @@ -91,16 +91,12 @@ - (FlutterMetalTexture)createTextureForView:(uint64_t)viewId size:(CGSize)size { return FlutterMetalTexture{}; } FlutterMetalTexture texture = [view.surfaceManager surfaceForSize:size].asFlutterMetalTexture; - _texture_to_view[@(texture.texture_id)] = @(viewId); + texture.view_id = viewId; return texture; } - (BOOL)present:(const FlutterMetalTexture*)texture { - NSNumber* viewId = _texture_to_view[@(texture->texture_id)]; - if (viewId == nil) { - return NO; - } - FlutterView* view = [_viewProvider viewForId:[viewId longLongValue]]; + FlutterView* view = [_viewProvider viewForId:texture->view_id]; if (view == nil) { return NO; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm index f3c88be8806d7..9a705ea6c188a 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterRendererTest.mm @@ -62,21 +62,18 @@ - (nonnull FlutterView*)createFlutterViewWithMTLDevice:(id)device OCMStub([viewMock surfaceManager]).andReturn(surfaceManagerMock); id surfaceMock = OCMClassMock([FlutterSurface class]); - FlutterMetalTexture mockReturnTexture{ - .texture_id = 100ll, // Arbitrary + + FlutterMetalTexture texture = { .user_data = (__bridge void*)surfaceMock, + .view_id = 0ll, }; - OCMStub([surfaceMock asFlutterMetalTexture]).andReturn(mockReturnTexture); - OCMStub([surfaceManagerMock surfaceForSize:CGSize{}]) - .ignoringNonObjectArgs() - .andReturn(surfaceMock); + [[surfaceManagerMock expect] present:[OCMArg checkWithBlock:^(id obj) { NSArray* array = (NSArray*)obj; return array.count == 1 ? YES : NO; }] notify:nil]; - FlutterMetalTexture texture = [renderer createTextureForView:0ll size:CGSize{}]; [renderer present:&texture]; [surfaceManagerMock verify]; } diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 95e627a0bcc4d..9e165b1de0ac5 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -654,6 +654,7 @@ typedef struct { /// The callback invoked by the engine when it no longer needs this backing /// store. VoidCallback destruction_callback; + int64_t view_id; } FlutterMetalTexture; /// Callback for when a metal texture is requested. From eda122790e2dcd6f75419f5ea9a2578d1a7c4bb0 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 29 Mar 2023 16:53:15 -0700 Subject: [PATCH 074/142] Fix fuchsia compile --- shell/platform/fuchsia/flutter/surface.cc | 1 + shell/platform/fuchsia/flutter/surface.h | 1 + 2 files changed, 2 insertions(+) diff --git a/shell/platform/fuchsia/flutter/surface.cc b/shell/platform/fuchsia/flutter/surface.cc index 49d06f023cbf8..13ff5f7c8a110 100644 --- a/shell/platform/fuchsia/flutter/surface.cc +++ b/shell/platform/fuchsia/flutter/surface.cc @@ -29,6 +29,7 @@ bool Surface::IsValid() { // |flutter::Surface| std::unique_ptr Surface::AcquireFrame( + int64_t view_id, const SkISize& size) { flutter::SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; diff --git a/shell/platform/fuchsia/flutter/surface.h b/shell/platform/fuchsia/flutter/surface.h index 5d9098fbc6e07..b3e6621db5f09 100644 --- a/shell/platform/fuchsia/flutter/surface.h +++ b/shell/platform/fuchsia/flutter/surface.h @@ -31,6 +31,7 @@ class Surface final : public flutter::Surface { // |flutter::Surface| std::unique_ptr AcquireFrame( + int64_t view_id, const SkISize& size) override; // |flutter::Surface| From 30f816bc4e12f46dec3f5bee772eaaf3a05b256f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 3 Apr 2023 01:51:56 -0700 Subject: [PATCH 075/142] CreateSurface add view_id --- shell/common/platform_view.cc | 8 +++----- shell/common/platform_view.h | 2 +- shell/common/shell.cc | 4 ++-- shell/platform/fuchsia/flutter/engine.h | 2 +- 4 files changed, 7 insertions(+), 9 deletions(-) diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index fac06cee3b7b1..5600d41e32705 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -63,8 +63,6 @@ void PlatformView::NotifyDestroyed() { delegate_.OnPlatformViewDestroyed(); } -constexpr int64_t kFlutterDefaultViewId = 0; - std::unique_ptr PlatformView::CreateStudio() { std::unique_ptr studio; // Threading: We want to use the platform view on the non-platform thread. @@ -89,7 +87,7 @@ std::unique_ptr PlatformView::CreateStudio() { return studio; } -std::unique_ptr PlatformView::CreateSurface() { +std::unique_ptr PlatformView::CreateSurface(int64_t view_id) { std::unique_ptr surface; // Threading: We want to use the platform view on the non-platform thread. // Using the weak pointer is illegal. But, we are going to introduce a latch @@ -98,8 +96,8 @@ std::unique_ptr PlatformView::CreateSurface() { auto* platform_view = this; fml::ManualResetWaitableEvent latch; fml::TaskRunner::RunNowOrPostTask( - task_runners_.GetRasterTaskRunner(), [platform_view, &surface, &latch]() { - surface = platform_view->CreateRenderingSurface(kFlutterDefaultViewId); + task_runners_.GetRasterTaskRunner(), [platform_view, &surface, &latch, view_id]() { + surface = platform_view->CreateRenderingSurface(view_id); if (!surface || !surface->IsValid()) { surface.reset(); } diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 985a25bcfe014..7d698ec7b9636 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -495,7 +495,7 @@ class PlatformView { virtual void NotifyDestroyed(); std::unique_ptr CreateStudio(); - std::unique_ptr CreateSurface(); + std::unique_ptr CreateSurface(int64_t view_id); //---------------------------------------------------------------------------- /// @brief Used by embedders to schedule a frame. In response to this diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 0f328503ba32a..3a2b85419ed5f 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -753,7 +753,7 @@ void Shell::OnPlatformViewCreated() { FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); std::unique_ptr studio = platform_view_->CreateStudio(); - std::unique_ptr surface = platform_view_->CreateSurface(); + std::unique_ptr surface = platform_view_->CreateSurface(kFlutterDefaultViewId); if (studio == nullptr || surface == nullptr) { // TODO(dkwingsmt): This case is observed in windows unit tests. Anyway, // we're probably not creating the surface in this callback eventually. @@ -1988,7 +1988,7 @@ void Shell::AddRenderSurface(int64_t view_id) { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); - std::unique_ptr surface = platform_view_->CreateSurface(); + std::unique_ptr surface = platform_view_->CreateSurface(view_id); fml::AutoResetWaitableEvent latch; task_runners_.GetRasterTaskRunner()->PostTask( fml::MakeCopyable([&latch, // diff --git a/shell/platform/fuchsia/flutter/engine.h b/shell/platform/fuchsia/flutter/engine.h index 06097a9692f85..5cc519b6fd729 100644 --- a/shell/platform/fuchsia/flutter/engine.h +++ b/shell/platform/fuchsia/flutter/engine.h @@ -147,7 +147,7 @@ class Engine final : public fuchsia::memorypressure::Watcher { std::unique_ptr CreateStudio(); - std::unique_ptr CreateSurface(); + std::unique_ptr CreateSurface(int64_t view_id); Delegate& delegate_; From 72536530e629d6b5b79e98e8fb8249ecc47c3541 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 5 Apr 2023 23:02:02 -0700 Subject: [PATCH 076/142] Add and remove View --- lib/ui/hooks.dart | 7 +++ lib/ui/platform_dispatcher.dart | 6 +++ lib/ui/window.dart | 4 +- lib/ui/window/platform_configuration.cc | 19 ++++++++ lib/ui/window/platform_configuration.h | 3 ++ runtime/runtime_controller.cc | 9 ++++ runtime/runtime_controller.h | 2 + shell/common/engine.cc | 4 ++ shell/common/engine.h | 2 + shell/common/platform_view.cc | 18 +------- shell/common/rasterizer.cc | 4 ++ shell/common/rasterizer.h | 2 + shell/common/shell.cc | 58 ++++++++++++++++++++----- shell/common/shell.h | 1 + 14 files changed, 111 insertions(+), 28 deletions(-) diff --git a/lib/ui/hooks.dart b/lib/ui/hooks.dart index f92d287cf0f14..6a27e5d5af4c2 100644 --- a/lib/ui/hooks.dart +++ b/lib/ui/hooks.dart @@ -4,6 +4,13 @@ part of dart.ui; +@pragma('vm:entry-point') +void _addView( + Object id, +) { + PlatformDispatcher.instance._addView(id); +} + @pragma('vm:entry-point') void _updateWindowMetrics( Object id, diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index f955bb5f1882d..92afeb08c6dd3 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -215,6 +215,12 @@ class PlatformDispatcher { _onMetricsChangedZone = Zone.current; } + void _addView(Object id) { + assert(!_views.containsKey(id)); + _views[id] = FlutterView._(id, this); + _viewConfigurations[id] = const _ViewConfiguration(); + } + // Called from the engine, via hooks.dart // // Updates the metrics of the window with the given id. diff --git a/lib/ui/window.dart b/lib/ui/window.dart index 44389d09f8f39..726998b0e2193 100644 --- a/lib/ui/window.dart +++ b/lib/ui/window.dart @@ -289,7 +289,9 @@ class FlutterView { /// scheduling of frames. /// * [RendererBinding], the Flutter framework class which manages layout and /// painting. - void render(Scene scene) => _render(viewId == 0 ? 0 : viewId.hashCode, scene); + void render(Scene scene) { + _render(viewId as int, scene); + } @Native)>(symbol: 'PlatformConfigurationNativeApi::Render') external static void _render(int viewId, Scene scene); diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index 25124cd9d3458..08882ea4249ad 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -43,6 +43,8 @@ void PlatformConfiguration::DidCreateIsolate() { on_error_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_onError"))); + add_view_.Set(tonic::DartState::Current(), + Dart_GetField(library, tonic::ToDart("_addView"))); update_locales_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_updateLocales"))); update_user_settings_data_.Set( @@ -78,6 +80,23 @@ void PlatformConfiguration::DidCreateIsolate() { kImplicitViewId, ViewportMetrics{1.0, 0.0, 0.0, -1})); } +constexpr int64_t kFlutterDefaultViewId = 0ll; + +void PlatformConfiguration::AddView(int64_t view_id) { + if (view_id == kFlutterDefaultViewId) { + return; + } + std::shared_ptr dart_state = add_view_.dart_state().lock(); + if (!dart_state) { + return; + } + tonic::DartState::Scope scope(dart_state); + tonic::CheckAndHandleError( + tonic::DartInvoke(add_view_.Get(), { + tonic::ToDart(view_id), + })); +} + void PlatformConfiguration::UpdateLocales( const std::vector& locales) { std::shared_ptr dart_state = diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 57c939647715f..fa5e6174e4036 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -267,6 +267,8 @@ class PlatformConfiguration final { /// void DidCreateIsolate(); + void AddView(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Update the specified locale data in the framework. /// @@ -434,6 +436,7 @@ class PlatformConfiguration final { private: PlatformConfigurationClient* client_; tonic::DartPersistentValue on_error_; + tonic::DartPersistentValue add_view_; tonic::DartPersistentValue update_locales_; tonic::DartPersistentValue update_user_settings_data_; tonic::DartPersistentValue update_initial_lifecycle_state_; diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 0b934f635da1f..98aa7ef0d2472 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -122,6 +122,15 @@ bool RuntimeController::FlushRuntimeStateToIsolate() { SetInitialLifecycleState(platform_data_.lifecycle_state); } +bool RuntimeController::AddView(int64_t view_id) { + if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { + platform_configuration->AddView(view_id); + return true; + } + + return false; +} + bool RuntimeController::SetViewportMetrics(const ViewportMetrics& metrics) { platform_data_.viewport_metrics = metrics; diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index 0312294f01732..c88f97e3a292a 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -163,6 +163,8 @@ class RuntimeController : public PlatformConfigurationClient { /// std::unique_ptr Clone() const; + bool AddView(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Forward the specified viewport metrics to the running isolate. /// If the isolate is not running, these metrics will be saved and diff --git a/shell/common/engine.cc b/shell/common/engine.cc index a141d09cd1fa7..95710dfcaf447 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -286,6 +286,10 @@ tonic::DartErrorHandleType Engine::GetUIIsolateLastError() { return runtime_controller_->GetLastError(); } +void Engine::AddView(int64_t view_id) { + runtime_controller_->AddView(view_id); +} + void Engine::SetViewportMetrics(const ViewportMetrics& metrics) { runtime_controller_->SetViewportMetrics(metrics); ScheduleFrame(); diff --git a/shell/common/engine.h b/shell/common/engine.h index 8c5a07379f86b..34774bf59dfbb 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -673,6 +673,8 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// std::optional GetUIIsolateReturnCode(); + void AddView(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Updates the viewport metrics for the currently running Flutter /// application. The viewport metrics detail the size of the diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 5600d41e32705..87f3af8e6b3df 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -88,22 +88,8 @@ std::unique_ptr PlatformView::CreateStudio() { } std::unique_ptr PlatformView::CreateSurface(int64_t view_id) { - std::unique_ptr surface; - // Threading: We want to use the platform view on the non-platform thread. - // Using the weak pointer is illegal. But, we are going to introduce a latch - // so that the platform view is not collected till the studio and the surface - // are obtained. - auto* platform_view = this; - fml::ManualResetWaitableEvent latch; - fml::TaskRunner::RunNowOrPostTask( - task_runners_.GetRasterTaskRunner(), [platform_view, &surface, &latch, view_id]() { - surface = platform_view->CreateRenderingSurface(view_id); - if (!surface || !surface->IsValid()) { - surface.reset(); - } - latch.Signal(); - }); - latch.Wait(); + FML_DCHECK(task_runners_.GetRasterTaskRunner()->RunsTasksOnCurrentThread()); + auto surface = CreateRenderingSurface(view_id); if (!surface) { FML_LOG(ERROR) << "Failed to create platform view rendering surface"; return nullptr; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 5e6bcc53d7e01..8166a5ac70a71 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -154,6 +154,10 @@ void Rasterizer::AddSurface(int64_t view_id, std::unique_ptr surface) { } } +void Rasterizer::RemoveSurface(int64_t view_id) { + surfaces_.erase(view_id); +} + std::shared_ptr Rasterizer::GetTextureRegistry() { return compositor_context_->texture_registry(); } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 5c4bb2639a48c..87fcbef522151 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -191,6 +191,8 @@ class Rasterizer final : public SnapshotDelegate, void AddSurface(int64_t view_id, std::unique_ptr surface); + void RemoveSurface(int64_t view_id); + //---------------------------------------------------------------------------- /// /// @bug https://github.com/flutter/flutter/issues/33939 diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 3a2b85419ed5f..07d27ed886a99 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -753,8 +753,7 @@ void Shell::OnPlatformViewCreated() { FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); std::unique_ptr studio = platform_view_->CreateStudio(); - std::unique_ptr surface = platform_view_->CreateSurface(kFlutterDefaultViewId); - if (studio == nullptr || surface == nullptr) { + if (studio == nullptr) { // TODO(dkwingsmt): This case is observed in windows unit tests. Anyway, // we're probably not creating the surface in this callback eventually. return; @@ -786,9 +785,13 @@ void Shell::OnPlatformViewCreated() { fml::AutoResetWaitableEvent latch; auto raster_task = fml::MakeCopyable( - [&waiting_for_first_frame = waiting_for_first_frame_, - rasterizer = rasterizer_->GetWeakPtr(), // - studio = std::move(studio), surface = std::move(surface)]() mutable { + [&waiting_for_first_frame = waiting_for_first_frame_, // + rasterizer = rasterizer_->GetWeakPtr(), // + platform_view = platform_view_.get(), // + studio = std::move(studio) // + ]() mutable { + std::unique_ptr surface = + platform_view->CreateSurface(kFlutterDefaultViewId); if (rasterizer) { // Enables the thread merger which may be used by the external view // embedder. @@ -1987,20 +1990,53 @@ void Shell::AddRenderSurface(int64_t view_id) { TRACE_EVENT0("flutter", "Shell::AddRenderSurface"); FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); + if (!engine_) { + return; + } + if (view_id == kFlutterDefaultViewId) { + return; + } - std::unique_ptr surface = platform_view_->CreateSurface(view_id); - fml::AutoResetWaitableEvent latch; + auto ui_task = [engine = engine_->GetWeakPtr(), // + view_id // + ] { engine->AddView(view_id); }; + // TODO(dkwingsmt): platform_view_ is captured illegally here. + // We need some mechanism from it being collected. task_runners_.GetRasterTaskRunner()->PostTask( - fml::MakeCopyable([&latch, // + fml::MakeCopyable([&task_runners = task_runners_, // + ui_task, // + platform_view = platform_view_.get(), // rasterizer = rasterizer_->GetWeakPtr(), // - surface = std::move(surface), // view_id // + ]() mutable { + if (platform_view && rasterizer) { + std::unique_ptr surface = + platform_view->CreateSurface(view_id); + if (surface) { + rasterizer->AddSurface(view_id, std::move(surface)); + } + task_runners.GetUITaskRunner()->PostTask(ui_task); + } + })); +} + +void Shell::RemoveRenderSurface(int64_t view_id) { + TRACE_EVENT0("flutter", "Shell::RemoveRenderSurface"); + FML_DCHECK(is_setup_); + FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); + + fml::AutoResetWaitableEvent latch; + // platform_view_->RemoveSurface(view_id); // TODO + task_runners_.GetRasterTaskRunner()->PostTask( + [&latch, // + rasterizer = rasterizer_->GetWeakPtr(), // + view_id // ]() mutable { if (rasterizer) { - rasterizer->AddSurface(view_id, std::move(surface)); + rasterizer->RemoveSurface(view_id); } latch.Signal(); - })); + }); latch.Wait(); } diff --git a/shell/common/shell.h b/shell/common/shell.h index 9642a7e3b428c..5f7e62272757e 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -298,6 +298,7 @@ class Shell final : public PlatformView::Delegate, bool IsSetup() const; void AddRenderSurface(int64_t view_id); + void RemoveRenderSurface(int64_t view_id); //---------------------------------------------------------------------------- /// @brief Captures a screenshot and optionally Base64 encodes the data From a910a04bf62ded1026edeacbfe34350911e2b226 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 21 Apr 2023 13:23:24 -0700 Subject: [PATCH 077/142] Workable 2 (multiple initial window) --- flow/embedded_views.cc | 3 +- flow/embedded_views.h | 3 +- lib/ui/compositing.dart | 8 +-- lib/ui/compositing/scene.cc | 29 ++++---- lib/ui/compositing/scene.h | 4 +- lib/ui/compositing/scene_builder.cc | 9 +-- lib/ui/compositing/scene_builder.h | 7 +- lib/ui/dart_ui.cc | 2 +- lib/ui/hooks.dart | 12 ++++ lib/ui/platform_dispatcher.dart | 50 +++++++++++-- lib/ui/window/platform_configuration.cc | 60 ++++++++++++---- lib/ui/window/platform_configuration.h | 20 +++++- lib/ui/window/window.cc | 11 +-- lib/ui/window/window.h | 6 +- runtime/runtime_controller.cc | 25 +++++-- runtime/runtime_controller.h | 4 +- shell/common/engine.cc | 9 ++- shell/common/engine.h | 4 +- shell/common/engine_unittests.cc | 5 +- shell/common/platform_view.cc | 5 +- shell/common/platform_view.h | 3 +- shell/common/rasterizer.cc | 4 +- shell/common/rasterizer.h | 14 ++-- shell/common/rasterizer_unittests.cc | 35 ++++----- shell/common/shell.cc | 44 +++++++----- shell/common/shell.h | 5 +- shell/common/shell_test.cc | 4 +- .../shell_test_external_view_embedder.cc | 3 +- .../shell_test_external_view_embedder.h | 3 +- shell/common/shell_unittests.cc | 72 +++++++++++-------- .../external_view_embedder.cc | 3 +- .../external_view_embedder.h | 3 +- .../external_view_embedder_unittests.cc | 27 ++++--- .../darwin/ios/ios_external_view_embedder.h | 3 +- .../framework/Source/FlutterCompositor.mm | 5 +- .../macos/framework/Source/FlutterEngine.mm | 17 ++--- .../framework/Source/FlutterEngineTest.mm | 9 ++- .../Source/FlutterThreadSynchronizer.h | 12 +++- .../Source/FlutterThreadSynchronizer.mm | 48 ++++++++++--- .../macos/framework/Source/FlutterView.h | 4 +- .../macos/framework/Source/FlutterView.mm | 30 +++++--- .../framework/Source/FlutterViewController.mm | 7 +- .../macos/framework/Source/FlutterViewTest.mm | 5 +- shell/platform/embedder/embedder.cc | 9 +-- shell/platform/embedder/embedder.h | 4 ++ shell/platform/embedder/embedder_engine.cc | 3 +- shell/platform/embedder/embedder_engine.h | 3 +- .../embedder_external_view_embedder.cc | 11 +-- .../embedder_external_view_embedder.h | 6 +- shell/platform/embedder/embedder_layers.cc | 6 +- shell/platform/embedder/embedder_layers.h | 6 +- .../platform_view_embedder_unittests.cc | 4 +- .../embedder/tests/embedder_config_builder.cc | 1 + .../tests/embedder_metal_unittests.mm | 16 +++-- .../embedder/tests/embedder_unittests.cc | 55 ++++++++------ .../flatland_external_view_embedder.cc | 3 +- .../flutter/flatland_external_view_embedder.h | 3 +- .../flutter/gfx_external_view_embedder.cc | 3 +- .../flutter/gfx_external_view_embedder.h | 3 +- .../fuchsia/flutter/platform_view_unittest.cc | 3 +- ...atland_external_view_embedder_unittests.cc | 26 ++++--- .../tests/flatland_platform_view_unittest.cc | 3 +- .../gfx_external_view_embedder_unittests.cc | 26 ++++--- shell/platform/linux/fl_engine.cc | 1 + shell/testing/tester_main.cc | 4 +- 65 files changed, 565 insertions(+), 270 deletions(-) diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc index b76c9730af903..b89ed606fcc14 100644 --- a/flow/embedded_views.cc +++ b/flow/embedded_views.cc @@ -43,7 +43,8 @@ bool DisplayListEmbedderViewSlice::recording_ended() { } void ExternalViewEmbedder::SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) { + std::unique_ptr frame, + int64_t window_view_id) { frame->Submit(); }; diff --git a/flow/embedded_views.h b/flow/embedded_views.h index 4162e79a15af6..c9ee05430d0ab 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -415,7 +415,8 @@ class ExternalViewEmbedder { // // It can also allocate frames for overlay surfaces to compose hybrid views. virtual void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame); + std::unique_ptr frame, + int64_t window_view_id); // This method provides the embedder a way to do additional tasks after // |SubmitFrame|. For example, merge task runners if `should_resubmit_frame` diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index f20ecff7349c6..cfb4e1908064b 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -231,12 +231,12 @@ class PhysicalShapeEngineLayer extends _EngineLayerWrapper { class SceneBuilder extends NativeFieldWrapperClass1 { /// Creates an empty [SceneBuilder] object. @pragma('vm:entry-point') - SceneBuilder() { - _constructor(); + SceneBuilder([Object viewId = 0]) { + _constructor(viewId as int); } - @Native(symbol: 'SceneBuilder::Create') - external void _constructor(); + @Native(symbol: 'SceneBuilder::Create') + external void _constructor(int viewId); // Layers used in this scene. // diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index c5070c6376091..91e9c45c9b4f5 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -26,30 +26,35 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, Scene); void Scene::create(Dart_Handle scene_handle, + int64_t view_id, std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { auto scene = fml::MakeRefCounted( - std::move(rootLayer), rasterizerTracingThreshold, + view_id, std::move(rootLayer), rasterizerTracingThreshold, checkerboardRasterCacheImages, checkerboardOffscreenLayers); scene->AssociateWithDartWrapper(scene_handle); } -Scene::Scene(std::shared_ptr rootLayer, +Scene::Scene(int64_t view_id, + std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { - // Currently only supports a single window. - auto viewport_metrics = UIDartState::Current() - ->platform_configuration() - ->get_window(0) - ->viewport_metrics(); - - layer_tree_ = std::make_shared( - SkISize::Make(viewport_metrics.physical_width, - viewport_metrics.physical_height), - static_cast(viewport_metrics.device_pixel_ratio)); + Window* window = + UIDartState::Current()->platform_configuration()->get_window(view_id); + if (window != nullptr) { + auto viewport_metrics = window->viewport_metrics(); + layer_tree_ = std::make_shared( + SkISize::Make(viewport_metrics.physical_width, + viewport_metrics.physical_height), + static_cast(viewport_metrics.device_pixel_ratio)); + } else { + // TODO(dkwingsmt) + layer_tree_ = std::make_shared(SkISize::Make(0, 0), 1); + } + layer_tree_->set_root_layer(std::move(rootLayer)); layer_tree_->set_rasterizer_tracing_threshold(rasterizerTracingThreshold); layer_tree_->set_checkerboard_raster_cache_images( diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index aca797836fcb1..7a143f0a42d37 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -21,6 +21,7 @@ class Scene : public RefCountedDartWrappable { public: ~Scene() override; static void create(Dart_Handle scene_handle, + int64_t view_id, std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, @@ -39,7 +40,8 @@ class Scene : public RefCountedDartWrappable { void dispose(); private: - Scene(std::shared_ptr rootLayer, + Scene(int64_t view_id, + std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index 63ac03c92c872..e65fb5c741e52 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -34,7 +34,7 @@ namespace flutter { IMPLEMENT_WRAPPERTYPEINFO(ui, SceneBuilder); -SceneBuilder::SceneBuilder() { +SceneBuilder::SceneBuilder(int64_t view_id) : view_id_(view_id) { // Add a ContainerLayer as the root layer, so that AddLayer operations are // always valid. PushLayer(std::make_shared()); @@ -303,9 +303,10 @@ void SceneBuilder::setCheckerboardOffscreenLayers(bool checkerboard) { void SceneBuilder::build(Dart_Handle scene_handle) { FML_DCHECK(layer_stack_.size() >= 1); - Scene::create( - scene_handle, std::move(layer_stack_[0]), rasterizer_tracing_threshold_, - checkerboard_raster_cache_images_, checkerboard_offscreen_layers_); + Scene::create(scene_handle, view_id_, std::move(layer_stack_[0]), + rasterizer_tracing_threshold_, + checkerboard_raster_cache_images_, + checkerboard_offscreen_layers_); layer_stack_.clear(); ClearDartWrapper(); // may delete this object. } diff --git a/lib/ui/compositing/scene_builder.h b/lib/ui/compositing/scene_builder.h index f2de29c4802d2..7cb982b94f465 100644 --- a/lib/ui/compositing/scene_builder.h +++ b/lib/ui/compositing/scene_builder.h @@ -28,9 +28,9 @@ class SceneBuilder : public RefCountedDartWrappable { FML_FRIEND_MAKE_REF_COUNTED(SceneBuilder); public: - static void Create(Dart_Handle wrapper) { + static void Create(Dart_Handle wrapper, int64_t view_id) { UIDartState::ThrowIfUIOperationsProhibited(); - auto res = fml::MakeRefCounted(); + auto res = fml::MakeRefCounted(view_id); res->AssociateWithDartWrapper(wrapper); } @@ -135,12 +135,13 @@ class SceneBuilder : public RefCountedDartWrappable { } private: - SceneBuilder(); + SceneBuilder(int64_t view_id); void AddLayer(std::shared_ptr layer); void PushLayer(std::shared_ptr layer); void PopLayer(); + int64_t view_id_; std::vector> layer_stack_; int rasterizer_tracing_threshold_ = 0; bool checkerboard_raster_cache_images_ = false; diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index e26aeb307fd55..f9e4c29a378ec 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -81,7 +81,7 @@ typedef CanvasPath Path; V(PathMeasure::Create, 3) \ V(Path::Create, 1) \ V(PictureRecorder::Create, 1) \ - V(SceneBuilder::Create, 1) \ + V(SceneBuilder::Create, 2) \ V(SemanticsUpdateBuilder::Create, 1) \ /* Other */ \ V(FontCollection::LoadFontFromList, 3) \ diff --git a/lib/ui/hooks.dart b/lib/ui/hooks.dart index 6a27e5d5af4c2..95b9dbb83f7d9 100644 --- a/lib/ui/hooks.dart +++ b/lib/ui/hooks.dart @@ -11,6 +11,18 @@ void _addView( PlatformDispatcher.instance._addView(id); } +@pragma('vm:entry-point') +void _removeView( + Object id, +) { + PlatformDispatcher.instance._removeView(id); +} + +@pragma('vm:entry-point') +void _sendViewConfigurations(List viewIds) { + PlatformDispatcher.instance._onSentViewConfigurations(viewIds); +} + @pragma('vm:entry-point') void _updateWindowMetrics( Object id, diff --git a/lib/ui/platform_dispatcher.dart b/lib/ui/platform_dispatcher.dart index e771c9518c1fa..b6016d91a713f 100644 --- a/lib/ui/platform_dispatcher.dart +++ b/lib/ui/platform_dispatcher.dart @@ -61,6 +61,8 @@ typedef ErrorCallback = bool Function(Object exception, StackTrace stackTrace); // A gesture setting value that indicates it has not been set by the engine. const double _kUnsetGestureSetting = -1.0; +const int _kImplicitViewId = 0; + // A message channel to receive KeyData from the platform. // // See embedder.cc::kFlutterKeyDataChannel for more information. @@ -111,6 +113,12 @@ class PlatformDispatcher { /// these. Use [instance] to access the singleton. PlatformDispatcher._() { _setNeedsReportTimings = _nativeSetNeedsReportTimings; + // TODO(dkwingsmt): Can not call _implicitViewEnabled here because + // the Dart state has not finished initialization. + // if (_implicitViewEnabled()) { + // print('PlatformDispatcher ctor 2'); + // _implicitView = FlutterView._(_kImplicitViewId, this); + // } } /// The [PlatformDispatcher] singleton. @@ -153,6 +161,10 @@ class PlatformDispatcher { /// the application. /// /// If any of their configurations change, [onMetricsChanged] will be called. + /// + /// If implicit view is enabled but the implicit view is currently closed, + /// this list will not include the implicit view, but [implicitView] will + /// still be a non-null value. Iterable get views => _views.values; final Map _views = {}; @@ -179,12 +191,23 @@ class PlatformDispatcher { /// the application is shut down (although the engine may replace or remove /// the underlying backing surface of the view at its discretion). /// + /// If the implicit view is currently closed, [views] will not include this + /// value, but this property is still non-null, and single-view apps that + /// render into this property will still be able to do so, resulting in a + /// no-op. + /// /// See also: /// /// * [View.of], for accessing the current view. /// * [PlatformDispatcher.views] for a list of all [FlutterView]s provided /// by the platform. - FlutterView? get implicitView => _implicitViewEnabled() ? _views[0] : null; + FlutterView? get implicitView { + if (_implicitView == null && _implicitViewEnabled()) { + _implicitView = FlutterView._(_kImplicitViewId, this); + } + return _implicitView; + } + FlutterView? _implicitView; @Native(symbol: 'PlatformConfigurationNativeApi::ImplicitViewEnabled') external static bool _implicitViewEnabled(); @@ -215,12 +238,31 @@ class PlatformDispatcher { _onMetricsChangedZone = Zone.current; } + FlutterView _createView(Object id) { + if (id == _kImplicitViewId) { + assert(_implicitViewEnabled()); + return implicitView!; + } + return FlutterView._(id, this); + } + void _addView(Object id) { assert(!_views.containsKey(id)); - _views[id] = FlutterView._(id, this); + _views[id] = _createView(id); _viewConfigurations[id] = const _ViewConfiguration(); } + void _removeView(Object id) { + assert(!_views.containsKey(id)); + // TODO(dkwingsmt): Reset _implicitView? + _views.remove(id); + _viewConfigurations.remove(id); + } + + void _onSentViewConfigurations(List viewIds) { + viewIds.forEach(_addView); + } + // Called from the engine, via hooks.dart // // Updates the metrics of the window with the given id. @@ -248,9 +290,7 @@ class PlatformDispatcher { ) { final _ViewConfiguration previousConfiguration = _viewConfigurations[id] ?? const _ViewConfiguration(); - if (!_views.containsKey(id)) { - _views[id] = FlutterView._(id, this); - } + _views.putIfAbsent(id, () => _createView(id)); _viewConfigurations[id] = previousConfiguration.copyWith( view: _views[id], devicePixelRatio: devicePixelRatio, diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index 3b97a597a25a5..bd9a7744daaa9 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -22,7 +22,7 @@ namespace flutter { namespace { -constexpr int kImplicitViewId = 0; +constexpr int64_t kFlutterDefaultViewId = 0ll; Dart_Handle ToByteData(const fml::Mapping& buffer) { return tonic::DartByteData::Create(buffer.GetMapping(), buffer.GetSize()); @@ -34,7 +34,11 @@ PlatformConfigurationClient::~PlatformConfigurationClient() {} PlatformConfiguration::PlatformConfiguration( PlatformConfigurationClient* client) - : client_(client) {} + : client_(client) { + if (client_->ImplicitViewEnabled()) { + AddView(kFlutterDefaultViewId); + } +} PlatformConfiguration::~PlatformConfiguration() {} @@ -45,6 +49,8 @@ void PlatformConfiguration::DidCreateIsolate() { Dart_GetField(library, tonic::ToDart("_onError"))); add_view_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_addView"))); + remove_view_.Set(tonic::DartState::Current(), + Dart_GetField(library, tonic::ToDart("_removeView"))); update_locales_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_updateLocales"))); update_user_settings_data_.Set( @@ -72,20 +78,33 @@ void PlatformConfiguration::DidCreateIsolate() { report_timings_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_reportTimings"))); - // TODO(loicsharma): This should only be created if the embedder enables the - // implicit view. - // See: https://github.com/flutter/flutter/issues/120306 - windows_.emplace(kImplicitViewId, - std::make_unique( - kImplicitViewId, ViewportMetrics{1.0, 0.0, 0.0, -1})); + library_.Set(tonic::DartState::Current(), + Dart_LookupLibrary(tonic::ToDart("dart:ui"))); + + SendViewConfigurations(); } -constexpr int64_t kFlutterDefaultViewId = 0ll; +void PlatformConfiguration::SendViewConfigurations() { + std::shared_ptr dart_state = library_.dart_state().lock(); + FML_DCHECK(dart_state); + tonic::DartState::Scope scope(dart_state); -void PlatformConfiguration::AddView(int64_t view_id) { - if (view_id == kFlutterDefaultViewId) { - return; + // TODO(dkwingsmt): send all of ViewportMetrics + std::vector view_ids; + for (const auto& [view_id, window] : windows_) { + view_ids.push_back(view_id); } + + tonic::CheckAndHandleError(tonic::DartInvokeField( + library_.value(), "_sendViewConfigurations", {tonic::ToDart(view_ids)})); +} + +void PlatformConfiguration::AddView(int64_t view_id) { + // TODO(dkwingsmt): How do I access the current dart state after + // DidCreateIsolate? + windows_.emplace( + view_id, std::make_unique(library_, view_id, + ViewportMetrics{1.0, 0.0, 0.0, -1})); std::shared_ptr dart_state = add_view_.dart_state().lock(); if (!dart_state) { return; @@ -93,8 +112,21 @@ void PlatformConfiguration::AddView(int64_t view_id) { tonic::DartState::Scope scope(dart_state); tonic::CheckAndHandleError( tonic::DartInvoke(add_view_.Get(), { - tonic::ToDart(view_id), - })); + tonic::ToDart(view_id), + })); +} + +void PlatformConfiguration::RemoveView(int64_t view_id) { + windows_.erase(view_id); + std::shared_ptr dart_state = remove_view_.dart_state().lock(); + if (!dart_state) { + return; + } + tonic::DartState::Scope scope(dart_state); + tonic::CheckAndHandleError( + tonic::DartInvoke(remove_view_.Get(), { + tonic::ToDart(view_id), + })); } void PlatformConfiguration::UpdateLocales( diff --git a/lib/ui/window/platform_configuration.h b/lib/ui/window/platform_configuration.h index 61245a343ea4c..e9b17c61f7157 100644 --- a/lib/ui/window/platform_configuration.h +++ b/lib/ui/window/platform_configuration.h @@ -269,6 +269,8 @@ class PlatformConfiguration final { void AddView(int64_t view_id); + void RemoveView(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Update the specified locale data in the framework. /// @@ -409,7 +411,14 @@ class PlatformConfiguration final { /// /// @return a pointer to the Window. /// - Window* get_window(int window_id) { return windows_[window_id].get(); } + Window* get_window(int window_id) { + auto found = windows_.find(window_id); + if (found != windows_.end()) { + return found->second.get(); + } else { + return nullptr; + } + } //---------------------------------------------------------------------------- /// @brief Responds to a previous platform message to the engine from the @@ -437,6 +446,7 @@ class PlatformConfiguration final { PlatformConfigurationClient* client_; tonic::DartPersistentValue on_error_; tonic::DartPersistentValue add_view_; + tonic::DartPersistentValue remove_view_; tonic::DartPersistentValue update_locales_; tonic::DartPersistentValue update_user_settings_data_; tonic::DartPersistentValue update_initial_lifecycle_state_; @@ -448,12 +458,20 @@ class PlatformConfiguration final { tonic::DartPersistentValue draw_frame_; tonic::DartPersistentValue report_timings_; + tonic::DartPersistentValue library_; + + // All *actual* views that the app has. + // + // This means that, if implicit view is enabled but the implicit view is + // currently closed, `windows_` will not have an entry for ID 0. std::unordered_map> windows_; // ID starts at 1 because an ID of 0 indicates that no response is expected. int next_response_id_ = 1; std::unordered_map> pending_responses_; + + void SendViewConfigurations(); }; //---------------------------------------------------------------------------- diff --git a/lib/ui/window/window.cc b/lib/ui/window/window.cc index b269e97f7bf87..0dd181d1c5e98 100644 --- a/lib/ui/window/window.cc +++ b/lib/ui/window/window.cc @@ -13,11 +13,12 @@ namespace flutter { -Window::Window(int64_t window_id, ViewportMetrics metrics) - : window_id_(window_id), viewport_metrics_(std::move(metrics)) { - library_.Set(tonic::DartState::Current(), - Dart_LookupLibrary(tonic::ToDart("dart:ui"))); -} +Window::Window(tonic::DartPersistentValue& library, + int64_t window_id, + ViewportMetrics metrics) + : library_(library), + window_id_(window_id), + viewport_metrics_(std::move(metrics)) {} Window::~Window() {} diff --git a/lib/ui/window/window.h b/lib/ui/window/window.h index aad79f9963f72..f4763174c43eb 100644 --- a/lib/ui/window/window.h +++ b/lib/ui/window/window.h @@ -20,7 +20,9 @@ namespace flutter { class Window final { public: - Window(int64_t window_id, ViewportMetrics metrics); + Window(tonic::DartPersistentValue& library, + int64_t window_id, + ViewportMetrics metrics); ~Window(); @@ -34,7 +36,7 @@ class Window final { void UpdateWindowMetrics(const ViewportMetrics& metrics); private: - tonic::DartPersistentValue library_; + tonic::DartPersistentValue& library_; int64_t window_id_; ViewportMetrics viewport_metrics_; }; diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index c4ccd8e153034..aa5575d1ec31a 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -112,8 +112,12 @@ std::unique_ptr RuntimeController::Clone() const { ); } +constexpr int64_t kFlutterDefaultViewId = 0ll; + bool RuntimeController::FlushRuntimeStateToIsolate() { - return SetViewportMetrics(platform_data_.viewport_metrics) && + // TODO(dkwingsmt) + return SetViewportMetrics(kFlutterDefaultViewId, + platform_data_.viewport_metrics) && SetLocales(platform_data_.locale_data) && SetSemanticsEnabled(platform_data_.semantics_enabled) && SetAccessibilityFeatures( @@ -131,13 +135,26 @@ bool RuntimeController::AddView(int64_t view_id) { return false; } -bool RuntimeController::SetViewportMetrics(const ViewportMetrics& metrics) { +bool RuntimeController::RemoveView(int64_t view_id) { + if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { + platform_configuration->RemoveView(view_id); + return true; + } + + return false; +} + +bool RuntimeController::SetViewportMetrics(int64_t view_id, + const ViewportMetrics& metrics) { TRACE_EVENT0("flutter", "SetViewportMetrics"); platform_data_.viewport_metrics = metrics; if (auto* platform_configuration = GetPlatformConfigurationIfAvailable()) { - platform_configuration->get_window(0)->UpdateWindowMetrics(metrics); - return true; + Window* window = platform_configuration->get_window(view_id); + if (window) { + window->UpdateWindowMetrics(metrics); + return true; + } } return false; diff --git a/runtime/runtime_controller.h b/runtime/runtime_controller.h index c88f97e3a292a..d16fe3edaae92 100644 --- a/runtime/runtime_controller.h +++ b/runtime/runtime_controller.h @@ -165,6 +165,8 @@ class RuntimeController : public PlatformConfigurationClient { bool AddView(int64_t view_id); + bool RemoveView(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Forward the specified viewport metrics to the running isolate. /// If the isolate is not running, these metrics will be saved and @@ -174,7 +176,7 @@ class RuntimeController : public PlatformConfigurationClient { /// /// @return If the window metrics were forwarded to the running isolate. /// - bool SetViewportMetrics(const ViewportMetrics& metrics); + bool SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics); //---------------------------------------------------------------------------- /// @brief Forward the specified locale data to the running isolate. If diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 95710dfcaf447..04d730e4afa44 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -290,8 +290,13 @@ void Engine::AddView(int64_t view_id) { runtime_controller_->AddView(view_id); } -void Engine::SetViewportMetrics(const ViewportMetrics& metrics) { - runtime_controller_->SetViewportMetrics(metrics); +void Engine::RemoveView(int64_t view_id) { + runtime_controller_->RemoveView(view_id); +} + +void Engine::SetViewportMetrics(int64_t view_id, + const ViewportMetrics& metrics) { + runtime_controller_->SetViewportMetrics(view_id, metrics); ScheduleFrame(); } diff --git a/shell/common/engine.h b/shell/common/engine.h index 34774bf59dfbb..839fb35ce9df7 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -675,6 +675,8 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { void AddView(int64_t view_id); + void RemoveView(int64_t view_id); + //---------------------------------------------------------------------------- /// @brief Updates the viewport metrics for the currently running Flutter /// application. The viewport metrics detail the size of the @@ -685,7 +687,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { /// /// @param[in] metrics The metrics /// - void SetViewportMetrics(const ViewportMetrics& metrics); + void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics); //---------------------------------------------------------------------------- /// @brief Notifies the engine that the embedder has sent it a message. diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index 85c4656506485..628810704dac9 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -21,6 +21,8 @@ namespace flutter { namespace { +constexpr int64_t kDefaultViewId = 0ll; + class MockDelegate : public Engine::Delegate { public: MOCK_METHOD2(OnEngineUpdateSemantics, @@ -322,7 +324,8 @@ TEST_F(EngineTest, SpawnResetsViewportMetrics) { const double kViewHeight = 1024; old_viewport_metrics.physical_width = kViewWidth; old_viewport_metrics.physical_height = kViewHeight; - mock_runtime_controller->SetViewportMetrics(old_viewport_metrics); + mock_runtime_controller->SetViewportMetrics(kDefaultViewId, + old_viewport_metrics); auto engine = std::make_unique( /*delegate=*/delegate_, /*dispatcher_maker=*/dispatcher_maker_, diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index 87f3af8e6b3df..cff0b1c797643 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -51,8 +51,9 @@ void PlatformView::SetAccessibilityFeatures(int32_t flags) { delegate_.OnPlatformViewSetAccessibilityFeatures(flags); } -void PlatformView::SetViewportMetrics(const ViewportMetrics& metrics) { - delegate_.OnPlatformViewSetViewportMetrics(metrics); +void PlatformView::SetViewportMetrics(int64_t view_id, + const ViewportMetrics& metrics) { + delegate_.OnPlatformViewSetViewportMetrics(view_id, metrics); } void PlatformView::NotifyCreated() { diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 7d698ec7b9636..3c12332c1d276 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -108,6 +108,7 @@ class PlatformView { /// @param[in] metrics The updated viewport metrics. /// virtual void OnPlatformViewSetViewportMetrics( + int64_t view_id, const ViewportMetrics& metrics) = 0; //-------------------------------------------------------------------------- @@ -470,7 +471,7 @@ class PlatformView { /// /// @param[in] metrics The updated viewport metrics. /// - void SetViewportMetrics(const ViewportMetrics& metrics); + void SetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics); //---------------------------------------------------------------------------- /// @brief Used by embedders to notify the shell that a platform view diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 8fcb10f6393b6..78937353df8ce 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -675,8 +675,8 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( if (external_view_embedder_ && (!raster_thread_merger_ || raster_thread_merger_->IsMerged())) { FML_DCHECK(!frame->IsSubmitted()); - external_view_embedder_->SubmitFrame(studio_->GetContext(), - std::move(frame)); + external_view_embedder_->SubmitFrame( + studio_->GetContext(), std::move(frame), surface_record->view_id); } else { frame->Submit(); } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 54384a81ce9bb..1de2050b0ab86 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -242,7 +242,8 @@ class Rasterizer final : public SnapshotDelegate, std::shared_ptr GetTextureRegistry() override; - using LayerTreeDiscardCallback = std::function; + using LayerTreeDiscardCallback = + std::function; //---------------------------------------------------------------------------- /// @brief Takes the next item from the layer tree pipeline and executes @@ -596,10 +597,9 @@ class Rasterizer final : public SnapshotDelegate, GrDirectContext* surface_context, bool compressed); - DoDrawResult DoDraw( - int64_t view_id, - std::unique_ptr frame_timings_recorder, - std::shared_ptr layer_tree); + DoDrawResult DoDraw(int64_t view_id, + FrameTimingsRecorder& frame_timings_recorder, + std::shared_ptr layer_tree); RasterStatus DrawToSurface(FrameTimingsRecorder& frame_timings_recorder, flutter::LayerTree* layer_tree, @@ -615,7 +615,9 @@ class Rasterizer final : public SnapshotDelegate, void FireNextFrameCallbackIfPresent(); - static bool NoDiscard(const flutter::LayerTree& layer_tree) { return false; } + static bool NoDiscard(int64_t view_id, const flutter::LayerTree& layer_tree) { + return false; + } static bool ShouldResubmitFrame(const RasterStatus& raster_status); Delegate& delegate_; diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index b6efdf9df19f3..7c07515366efc 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -82,9 +82,10 @@ class MockExternalViewEmbedder : public ExternalViewEmbedder { PostPrerollResult( fml::RefPtr raster_thread_merger)); MOCK_METHOD1(CompositeEmbeddedView, DlCanvas*(int64_t view_id)); - MOCK_METHOD2(SubmitFrame, + MOCK_METHOD3(SubmitFrame, void(GrDirectContext* context, - std::unique_ptr frame)); + std::unique_ptr frame, + int64_t window_view_id)); MOCK_METHOD2(EndFrame, void(bool should_resubmit_frame, fml::RefPtr raster_thread_merger)); @@ -208,7 +209,7 @@ TEST(RasterizerTest, PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); latch.Signal(); }); @@ -275,7 +276,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); latch.Signal(); }); @@ -348,7 +349,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); } @@ -424,7 +425,7 @@ TEST(RasterizerTest, PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; // The Draw() will respectively call BeginFrame(), SubmitFrame() and // EndFrame() one time. @@ -473,7 +474,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); latch.Signal(); }); @@ -531,7 +532,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); // Always discard the layer tree. - auto discard_callback = [](LayerTree&) { return true; }; + auto discard_callback = [](int64_t, LayerTree&) { return true; }; RasterStatus status = rasterizer->Draw(pipeline, discard_callback); EXPECT_EQ(status, RasterStatus::kDiscarded); latch.Signal(); @@ -577,7 +578,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; RasterStatus status = rasterizer->Draw(pipeline, no_discard); EXPECT_EQ(status, RasterStatus::kFailed); latch.Signal(); @@ -636,7 +637,7 @@ TEST(RasterizerTest, PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); latch.Signal(); }); @@ -695,7 +696,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; RasterStatus status = rasterizer->Draw(pipeline, no_discard); EXPECT_EQ(status, RasterStatus::kSuccess); latch.Signal(); @@ -754,7 +755,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; RasterStatus status = rasterizer->Draw(pipeline, no_discard); EXPECT_EQ(status, RasterStatus::kSuccess); latch.Signal(); @@ -812,7 +813,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; RasterStatus status = rasterizer->Draw(pipeline, no_discard); EXPECT_EQ(status, RasterStatus::kDiscarded); latch.Signal(); @@ -869,7 +870,7 @@ TEST( PipelineProduceResult result = pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; RasterStatus status = rasterizer->Draw(pipeline, no_discard); EXPECT_EQ(status, RasterStatus::kFailed); latch.Signal(); @@ -953,7 +954,7 @@ TEST(RasterizerTest, EXPECT_TRUE(result.success); EXPECT_EQ(result.is_first_item, i == 0); } - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; // Although we only call 'Rasterizer::Draw' once, it will be called twice // finally because there are two items in the pipeline. rasterizer->Draw(pipeline, no_discard); @@ -1129,7 +1130,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { EXPECT_TRUE(result.success); EXPECT_EQ(result.is_first_item, i == 0); } - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; // Although we only call 'Rasterizer::Draw' once, it will be called twice // finally because there are two items in the pipeline. rasterizer->Draw(pipeline, no_discard); @@ -1210,7 +1211,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { pipeline->Produce().Complete(std::move(layer_tree_item)); EXPECT_TRUE(result.success); EXPECT_EQ(result.is_first_item, true); - auto no_discard = [](LayerTree&) { return false; }; + auto no_discard = [](int64_t, LayerTree&) { return false; }; rasterizer->Draw(pipeline, no_discard); }); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index f7738c196f503..c340c7dcdb932 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -940,7 +940,8 @@ void Shell::OnPlatformViewScheduleFrame() { } // |PlatformView::Delegate| -void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) { +void Shell::OnPlatformViewSetViewportMetrics(int64_t view_id, + const ViewportMetrics& metrics) { FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); @@ -964,15 +965,15 @@ void Shell::OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) { }); task_runners_.GetUITaskRunner()->PostTask( - [engine = engine_->GetWeakPtr(), metrics]() { + [engine = engine_->GetWeakPtr(), metrics, view_id]() { if (engine) { - engine->SetViewportMetrics(metrics); + engine->SetViewportMetrics(view_id, metrics); } }); { std::scoped_lock lock(resize_mutex_); - expected_frame_size_ = + expected_frame_sizes_[view_id] = SkISize::Make(metrics.physical_width, metrics.physical_height); device_pixel_ratio_ = metrics.device_pixel_ratio; } @@ -1179,10 +1180,11 @@ void Shell::OnAnimatorUpdateLatestFrameTargetTime( void Shell::OnAnimatorDraw(std::shared_ptr pipeline) { FML_DCHECK(is_setup_); - auto discard_callback = [this](flutter::LayerTree& tree) { + auto discard_callback = [this](int64_t view_id, flutter::LayerTree& tree) { std::scoped_lock lock(resize_mutex_); - return !expected_frame_size_.isEmpty() && - tree.frame_size() != expected_frame_size_; + auto expected_frame_size = ExpectedFrameSize(view_id); + return !expected_frame_size.isEmpty() && + tree.frame_size() != expected_frame_size; }; task_runners_.GetRasterTaskRunner()->PostTask(fml::MakeCopyable( @@ -1933,7 +1935,8 @@ bool Shell::OnServiceProtocolRenderFrameWithRasterStats( response->AddMember("snapshots", snapshots, allocator); - const auto& frame_size = expected_frame_size_; + // TODO(dkwingsmt) + const auto& frame_size = ExpectedFrameSize(kFlutterDefaultViewId); response->AddMember("frame_width", frame_size.width(), allocator); response->AddMember("frame_height", frame_size.height(), allocator); @@ -2000,15 +2003,14 @@ void Shell::AddRenderSurface(int64_t view_id) { return; } - auto ui_task = [engine = engine_->GetWeakPtr(), // - view_id // - ] { engine->AddView(view_id); }; + task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), // + view_id // + ] { engine->AddView(view_id); }); + // TODO(dkwingsmt): platform_view_ is captured illegally here. // We need some mechanism from it being collected. task_runners_.GetRasterTaskRunner()->PostTask( - fml::MakeCopyable([&task_runners = task_runners_, // - ui_task, // - platform_view = platform_view_.get(), // + fml::MakeCopyable([platform_view = platform_view_.get(), // rasterizer = rasterizer_->GetWeakPtr(), // view_id // ]() mutable { @@ -2018,7 +2020,6 @@ void Shell::AddRenderSurface(int64_t view_id) { if (surface) { rasterizer->AddSurface(view_id, std::move(surface)); } - task_runners.GetUITaskRunner()->PostTask(ui_task); } })); } @@ -2029,7 +2030,10 @@ void Shell::RemoveRenderSurface(int64_t view_id) { FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); fml::AutoResetWaitableEvent latch; - // platform_view_->RemoveSurface(view_id); // TODO + // platform_view_->RemoveSurface(view_id); + task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), // + view_id // + ] { engine->RemoveView(view_id); }); task_runners_.GetRasterTaskRunner()->PostTask( [&latch, // rasterizer = rasterizer_->GetWeakPtr(), // @@ -2157,4 +2161,12 @@ const std::weak_ptr Shell::GetVsyncWaiter() const { return engine_->GetVsyncWaiter(); } +SkISize Shell::ExpectedFrameSize(int64_t view_id) { + auto found = expected_frame_sizes_.find(view_id); + if (found == expected_frame_sizes_.end()) { + return SkISize::MakeEmpty(); + } + return found->second; +} + } // namespace flutter diff --git a/shell/common/shell.h b/shell/common/shell.h index 5f7e62272757e..1382b659966ec 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -472,7 +472,7 @@ class Shell final : public PlatformView::Delegate, std::mutex resize_mutex_; // used to discard wrong size layer tree produced during interactive resizing - SkISize expected_frame_size_ = SkISize::MakeEmpty(); + std::unordered_map expected_frame_sizes_; // Used to communicate the right frame bounds via service protocol. double device_pixel_ratio_ = 0.0; @@ -537,6 +537,7 @@ class Shell final : public PlatformView::Delegate, // |PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( + int64_t view_id, const ViewportMetrics& metrics) override; // |PlatformView::Delegate| @@ -733,6 +734,8 @@ class Shell final : public PlatformView::Delegate, // directory. std::unique_ptr RestoreOriginalAssetResolver(); + SkISize ExpectedFrameSize(int64_t view_id); + // For accessing the Shell via the raster thread, necessary for various // rasterizer callbacks. std::unique_ptr> weak_factory_gpu_; diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index d5fab1f5be7b9..bd05c8726e9e0 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -140,7 +140,7 @@ void ShellTest::SetViewportMetrics(Shell* shell, double width, double height) { shell->GetTaskRunners().GetUITaskRunner()->PostTask( [&latch, engine = shell->weak_engine_, viewport_metrics]() { if (engine) { - engine->SetViewportMetrics(viewport_metrics); + engine->SetViewportMetrics(kDefaultViewId, viewport_metrics); const auto frame_begin_time = fml::TimePoint::Now(); const auto frame_end_time = frame_begin_time + fml::TimeDelta::FromSecondsF(1.0 / 60.0); @@ -182,7 +182,7 @@ void ShellTest::PumpOneFrame(Shell* shell, fml::AutoResetWaitableEvent latch; shell->GetTaskRunners().GetUITaskRunner()->PostTask( [&latch, engine = shell->weak_engine_, viewport_metrics]() { - engine->SetViewportMetrics(viewport_metrics); + engine->SetViewportMetrics(kDefaultViewId, viewport_metrics); const auto frame_begin_time = fml::TimePoint::Now(); const auto frame_end_time = frame_begin_time + fml::TimeDelta::FromSecondsF(1.0 / 60.0); diff --git a/shell/common/shell_test_external_view_embedder.cc b/shell/common/shell_test_external_view_embedder.cc index 2536bb62ac6a2..475de0cd501da 100644 --- a/shell/common/shell_test_external_view_embedder.cc +++ b/shell/common/shell_test_external_view_embedder.cc @@ -91,7 +91,8 @@ DlCanvas* ShellTestExternalViewEmbedder::CompositeEmbeddedView( // |ExternalViewEmbedder| void ShellTestExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - std::unique_ptr frame) { + std::unique_ptr frame, + int64_t view_id) { if (!frame) { return; } diff --git a/shell/common/shell_test_external_view_embedder.h b/shell/common/shell_test_external_view_embedder.h index 204472d5bc050..4aacfc6f7c401 100644 --- a/shell/common/shell_test_external_view_embedder.h +++ b/shell/common/shell_test_external_view_embedder.h @@ -75,7 +75,8 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) override; + std::unique_ptr frame, + int64_t view_id) override; // |ExternalViewEmbedder| void EndFrame( diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index c0b57188573b5..83b48e8b4fbd3 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -57,6 +57,8 @@ namespace flutter { namespace testing { +constexpr int64_t kDefaultViewId = 0ll; + using ::testing::_; using ::testing::Return; @@ -71,8 +73,8 @@ class MockPlatformViewDelegate : public PlatformView::Delegate { MOCK_METHOD1(OnPlatformViewSetNextFrameCallback, void(const fml::closure& closure)); - MOCK_METHOD1(OnPlatformViewSetViewportMetrics, - void(const ViewportMetrics& metrics)); + MOCK_METHOD2(OnPlatformViewSetViewportMetrics, + void(int64_t view_id, const ViewportMetrics& metrics)); MOCK_METHOD1(OnPlatformViewDispatchPlatformMessage, void(std::unique_ptr message)); @@ -1600,7 +1602,8 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { RunEngine(shell.get(), std::move(configuration)); PostSync(shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics({1.0, 100, 100, 22}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.0, 100, 100, 22}); }); // first cache bytes @@ -1629,7 +1632,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(), [&second_shell]() { second_shell->GetPlatformView()->SetViewportMetrics( - {1.0, 100, 100, 22}); + kDefaultViewId, {1.0, 100, 100, 22}); }); // first cache bytes + second cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1638,7 +1641,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(), [&second_shell]() { second_shell->GetPlatformView()->SetViewportMetrics( - {1.0, 100, 300, 22}); + kDefaultViewId, {1.0, 100, 300, 22}); }); // first cache bytes + second cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1646,18 +1649,20 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { std::unique_ptr third_shell = shell_spawn_callback(); PlatformViewNotifyCreated(third_shell.get()); - PostSync( - third_shell->GetTaskRunners().GetPlatformTaskRunner(), [&third_shell]() { - third_shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 100, 22}); - }); + PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(), + [&third_shell]() { + third_shell->GetPlatformView()->SetViewportMetrics( + kDefaultViewId, {1.0, 400, 100, 22}); + }); // first cache bytes + second cache bytes + third cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), static_cast(3840000U)); - PostSync( - third_shell->GetTaskRunners().GetPlatformTaskRunner(), [&third_shell]() { - third_shell->GetPlatformView()->SetViewportMetrics({1.0, 800, 100, 22}); - }); + PostSync(third_shell->GetTaskRunners().GetPlatformTaskRunner(), + [&third_shell]() { + third_shell->GetPlatformView()->SetViewportMetrics( + kDefaultViewId, {1.0, 800, 100, 22}); + }); // max bytes threshold EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), static_cast(4000000U)); @@ -1669,7 +1674,7 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { PostSync(second_shell->GetTaskRunners().GetPlatformTaskRunner(), [&second_shell]() { second_shell->GetPlatformView()->SetViewportMetrics( - {1.0, 100, 100, 22}); + kDefaultViewId, {1.0, 100, 100, 22}); }); // first cache bytes + second cache bytes EXPECT_EQ(GetRasterizerResourceCacheBytesSync(*shell), @@ -1713,7 +1718,8 @@ TEST_F(ShellTest, SetResourceCacheSize) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.0, 400, 200, 22}); }); PumpOneFrame(shell.get()); @@ -1733,7 +1739,8 @@ TEST_F(ShellTest, SetResourceCacheSize) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics({1.0, 800, 400, 22}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.0, 800, 400, 22}); }); PumpOneFrame(shell.get()); @@ -1750,7 +1757,8 @@ TEST_F(ShellTest, SetResourceCacheSizeEarly) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.0, 400, 200, 22}); }); PumpOneFrame(shell.get()); @@ -1777,7 +1785,8 @@ TEST_F(ShellTest, SetResourceCacheSizeNotifiesDart) { fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { - shell->GetPlatformView()->SetViewportMetrics({1.0, 400, 200, 22}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.0, 400, 200, 22}); }); PumpOneFrame(shell.get()); @@ -2642,8 +2651,8 @@ TEST_F(ShellTest, DISABLED_DiscardLayerTreeOnResize) { shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &expected_size]() { shell->GetPlatformView()->SetViewportMetrics( - {1.0, static_cast(expected_size.width()), - static_cast(expected_size.height()), 22}); + kDefaultViewId, {1.0, static_cast(expected_size.width()), + static_cast(expected_size.height()), 22}); }); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -2715,8 +2724,8 @@ TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) { shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &origin_size]() { shell->GetPlatformView()->SetViewportMetrics( - {1.0, static_cast(origin_size.width()), - static_cast(origin_size.height()), 22}); + kDefaultViewId, {1.0, static_cast(origin_size.width()), + static_cast(origin_size.height()), 22}); }); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -2734,8 +2743,8 @@ TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) { shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell, &new_size, &resize_latch]() { shell->GetPlatformView()->SetViewportMetrics( - {1.0, static_cast(new_size.width()), - static_cast(new_size.height()), 22}); + kDefaultViewId, {1.0, static_cast(new_size.width()), + static_cast(new_size.height()), 22}); resize_latch.Signal(); }); @@ -2798,13 +2807,17 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) { RunEngine(shell.get(), std::move(configuration)); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics({0.0, 400, 200, 22}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {0.0, 400, 200, 22}); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics({0.8, 0.0, 200, 22}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {0.8, 0.0, 200, 22}); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics({0.8, 400, 0.0, 22}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {0.8, 400, 0.0, 22}); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics({0.8, 400, 200.0, 22}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {0.8, 400, 200.0, 22}); }); }); }); @@ -2816,7 +2829,8 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) { latch.Reset(); task_runner->PostTask([&]() { - shell->GetPlatformView()->SetViewportMetrics({1.2, 600, 300, 22}); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, + {1.2, 600, 300, 22}); }); latch.Wait(); ASSERT_EQ(last_device_pixel_ratio, 1.2); 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 f6f49320e062d..5d2692e3d89aa 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc @@ -66,7 +66,8 @@ SkRect AndroidExternalViewEmbedder::GetViewRect(int64_t view_id) const { // |ExternalViewEmbedder| void AndroidExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - std::unique_ptr frame) { + std::unique_ptr frame, + int64_t window_view_id) { TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFrame"); if (!FrameHasPlatformLayers()) { 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 8a9ae366d1de2..2038b4190478c 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.h +++ b/shell/platform/android/external_view_embedder/external_view_embedder.h @@ -46,7 +46,8 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) override; + std::unique_ptr frame, + int64_t view_id) override; // |ExternalViewEmbedder| PostPrerollResult PostPrerollAction( 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 aacf5ed7aa4f0..fee260dcb7dbc 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 @@ -311,7 +311,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), + kDefaultViewId); // Submits frame if no Android view in the current frame. EXPECT_TRUE(did_submit_frame); // Doesn't resubmit frame. @@ -379,7 +380,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), + kDefaultViewId); // Doesn't submit frame if there aren't Android views in the previous frame. EXPECT_FALSE(did_submit_frame); // Resubmits frame. @@ -444,7 +446,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), + kDefaultViewId); // Submits frame if there are Android views in the previous frame. EXPECT_TRUE(did_submit_frame); // Doesn't resubmit frame. @@ -552,7 +555,8 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), + kDefaultViewId); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -656,7 +660,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), + kDefaultViewId); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -725,7 +730,8 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), + kDefaultViewId); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -827,7 +833,8 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), + kDefaultViewId); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -915,7 +922,8 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), + kDefaultViewId); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -1027,7 +1035,8 @@ TEST(AndroidExternalViewEmbedder, Teardown) { SkSurface::MakeNull(1000, 1000), framebuffer_info, [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), + kDefaultViewId); 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 3893ccec0c1ab..3b94df3888f2e 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.h +++ b/shell/platform/darwin/ios/ios_external_view_embedder.h @@ -51,7 +51,8 @@ class IOSExternalViewEmbedder : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) override; + std::unique_ptr frame, + int64_t window_view_id) override; // |ExternalViewEmbedder| void EndFrame( diff --git a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm index 96acf4bb2a189..8ec78d3b229a9 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm @@ -19,10 +19,7 @@ bool FlutterCompositor::CreateBackingStore(const FlutterBackingStoreConfig* config, FlutterBackingStore* backing_store_out) { - // TODO(dkwingsmt): This class only supports single-view for now. As more - // classes are gradually converted to multi-view, it should get the view ID - // from somewhere. - FlutterView* view = [view_provider_ viewForId:kFlutterDefaultViewId]; + FlutterView* view = [view_provider_ viewForId:config->view_id]; if (!view) { return false; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 913b9a64f3ae5..f4730dbc9db6a 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -660,13 +660,11 @@ - (FlutterCompositor*)createFlutterCompositor { _compositor.present_layers_callback = [](const FlutterLayer** layers, // size_t layers_count, // + int64_t view_id, // void* user_data // ) { - // TODO(dkwingsmt): This callback only supports single-view, therefore it - // only operates on the default view. To support multi-view, we need a new - // callback that also receives a view ID. - return reinterpret_cast(user_data)->Present(kFlutterDefaultViewId, - layers, layers_count); + return reinterpret_cast(user_data)->Present(view_id, layers, + layers_count); }; _compositor.avoid_backing_store_cache = true; @@ -753,12 +751,6 @@ - (nonnull NSString*)executableName { } - (void)updateWindowMetricsForViewController:(FlutterViewController*)viewController { - if (viewController.viewId != kFlutterDefaultViewId) { - // TODO(dkwingsmt): The embedder API only supports single-view for now. As - // embedder APIs are converted to multi-view, this method should support any - // views. - return; - } if (!_engine || !viewController || !viewController.viewLoaded) { return; } @@ -777,7 +769,7 @@ - (void)updateWindowMetricsForViewController:(FlutterViewController*)viewControl .left = static_cast(scaledBounds.origin.x), .top = static_cast(scaledBounds.origin.y), }; - _embedderAPI.SendWindowMetricsEvent(_engine, &windowMetricsEvent); + _embedderAPI.SendWindowMetricsEvent(_engine, viewController.viewId, &windowMetricsEvent); } - (void)sendPointerEvent:(const FlutterPointerEvent&)event { @@ -897,6 +889,7 @@ - (void)shutDownEngine { } NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator]; + [[FlutterView sharedThreadSynchronizer] shutdown]; FlutterViewController* nextViewController; while ((nextViewController = [viewControllerEnumerator nextObject])) { [nextViewController.flutterView shutdown]; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index af2cc140f909f..ccb3d06834cd4 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -24,6 +24,8 @@ // CREATE_NATIVE_ENTRY and MOCK_ENGINE_PROC are leaky by design // NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) +constexpr int64_t kDefaultViewId = 0ll; + @interface FlutterEngine (Test) /** * The FlutterCompositor object currently in use by the FlutterEngine. @@ -626,9 +628,10 @@ - (nonnull NSView*)createWithViewIdentifier:(int64_t)viewId arguments:(nullable [threadSynchronizer shutdown]; std::thread rasterThread([&threadSynchronizer] { - [threadSynchronizer performCommit:CGSizeMake(100, 100) - notify:^{ - }]; + [threadSynchronizer performCommitForView:kDefaultViewId + size:CGSizeMake(100, 100) + notify:^{ + }]; }); rasterThread.join(); diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h index 8eca9611f0f48..5cc399cb33279 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h @@ -15,7 +15,9 @@ * Called from platform thread. Blocks until commit with given size (or empty) * is requested. */ -- (void)beginResize:(CGSize)size notify:(nonnull dispatch_block_t)notify; +- (void)beginResizeForView:(int64_t)viewId + size:(CGSize)size + notify:(nonnull dispatch_block_t)notify; /** * Called from raster thread. Schedules the given block on platform thread @@ -26,7 +28,13 @@ * * The notify block is guaranteed to be called within a core animation transaction. */ -- (void)performCommit:(CGSize)size notify:(nonnull dispatch_block_t)notify; +- (void)performCommitForView:(int64_t)viewId + size:(CGSize)size + notify:(nonnull dispatch_block_t)notify; + +- (void)registerView:(int64_t)viewId; + +- (void)deregisterView:(int64_t)viewId; /** * Called when shutting down. Unblocks everything and prevents any further synchronization. diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm index cb442ea768ffb..bf4506994e3cd 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm @@ -3,6 +3,7 @@ #import #include +#include #include #import "flutter/fml/logging.h" @@ -11,7 +12,7 @@ @interface FlutterThreadSynchronizer () { std::mutex _mutex; BOOL _shuttingDown; - CGSize _contentSize; + std::unordered_map _contentSizes; std::vector _scheduledBlocks; BOOL _beginResizeWaiting; @@ -20,10 +21,21 @@ @interface FlutterThreadSynchronizer () { std::condition_variable _condBlockBeginResize; } +- (BOOL)allViewsHaveFrame; + @end @implementation FlutterThreadSynchronizer +- (BOOL)allViewsHaveFrame { + for (auto const& [viewId, contentSize] : _contentSizes) { + if (CGSizeEqualToSize(contentSize, CGSizeZero)) { + return NO; + } + } + return YES; +} + - (void)drain { FML_DCHECK([NSThread isMainThread]); @@ -41,7 +53,7 @@ - (void)blockUntilFrameAvailable { _beginResizeWaiting = YES; - while (CGSizeEqualToSize(_contentSize, CGSizeZero) && !_shuttingDown) { + while (![self allViewsHaveFrame] && !_shuttingDown) { _condBlockBeginResize.wait(lock); [self drain]; } @@ -49,10 +61,12 @@ - (void)blockUntilFrameAvailable { _beginResizeWaiting = NO; } -- (void)beginResize:(CGSize)size notify:(nonnull dispatch_block_t)notify { +- (void)beginResizeForView:(int64_t)viewId + size:(CGSize)size + notify:(nonnull dispatch_block_t)notify { std::unique_lock lock(_mutex); - if (CGSizeEqualToSize(_contentSize, CGSizeZero) || _shuttingDown) { + if (![self allViewsHaveFrame] || _shuttingDown) { // No blocking until framework produces at least one frame notify(); return; @@ -62,12 +76,18 @@ - (void)beginResize:(CGSize)size notify:(nonnull dispatch_block_t)notify { notify(); - _contentSize = CGSizeMake(-1, -1); + _contentSizes[viewId] = CGSizeMake(-1, -1); _beginResizeWaiting = YES; - while (!CGSizeEqualToSize(_contentSize, size) && // - !CGSizeEqualToSize(_contentSize, CGSizeZero) && !_shuttingDown) { + while (true) { + if (_shuttingDown) { + break; + } + const CGSize& contentSize = _contentSizes[viewId]; + if (CGSizeEqualToSize(contentSize, size) || CGSizeEqualToSize(contentSize, CGSizeZero)) { + break; + } _condBlockBeginResize.wait(lock); [self drain]; } @@ -75,7 +95,9 @@ - (void)beginResize:(CGSize)size notify:(nonnull dispatch_block_t)notify { _beginResizeWaiting = NO; } -- (void)performCommit:(CGSize)size notify:(nonnull dispatch_block_t)notify { +- (void)performCommitForView:(int64_t)viewId + size:(CGSize)size + notify:(nonnull dispatch_block_t)notify { fml::AutoResetWaitableEvent event; { std::unique_lock lock(_mutex); @@ -87,7 +109,7 @@ - (void)performCommit:(CGSize)size notify:(nonnull dispatch_block_t)notify { fml::AutoResetWaitableEvent& e = event; _scheduledBlocks.push_back(^{ notify(); - _contentSize = size; + _contentSizes[viewId] = size; e.Signal(); }); if (_beginResizeWaiting) { @@ -102,6 +124,14 @@ - (void)performCommit:(CGSize)size notify:(nonnull dispatch_block_t)notify { event.Wait(); } +- (void)registerView:(int64_t)viewId { + _contentSizes[viewId] = CGSizeZero; +} + +- (void)deregisterView:(int64_t)viewId { + _contentSizes.erase(viewId); +} + - (void)shutdown { std::unique_lock lock(_mutex); _shuttingDown = YES; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.h b/shell/platform/darwin/macos/framework/Source/FlutterView.h index 73425737fbd3a..721f6f497f917 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.h @@ -31,7 +31,7 @@ - (nullable instancetype)initWithMTLDevice:(nonnull id)device commandQueue:(nonnull id)commandQueue reshapeListener:(nonnull id)reshapeListener - NS_DESIGNATED_INITIALIZER; + viewId:(int64_t)viewId NS_DESIGNATED_INITIALIZER; - (nullable instancetype)initWithFrame:(NSRect)frameRect pixelFormat:(nullable NSOpenGLPixelFormat*)format NS_UNAVAILABLE; @@ -60,6 +60,8 @@ */ - (void)setBackgroundColor:(nonnull NSColor*)color; ++ (nonnull FlutterThreadSynchronizer*)sharedThreadSynchronizer; + @end @interface FlutterView (FlutterViewPrivate) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.mm b/shell/platform/darwin/macos/framework/Source/FlutterView.mm index c3f802d43ed9e..a5be0767e783a 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.mm @@ -10,8 +10,8 @@ #import @interface FlutterView () { + int64_t _viewId; __weak id _reshapeListener; - FlutterThreadSynchronizer* _threadSynchronizer; FlutterSurfaceManager* _surfaceManager; } @@ -21,24 +21,26 @@ @implementation FlutterView - (instancetype)initWithMTLDevice:(id)device commandQueue:(id)commandQueue - reshapeListener:(id)reshapeListener { + reshapeListener:(id)reshapeListener + viewId:(int64_t)viewId { self = [super initWithFrame:NSZeroRect]; if (self) { [self setWantsLayer:YES]; [self setBackgroundColor:[NSColor blackColor]]; [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawDuringViewResize]; + _viewId = viewId; _reshapeListener = reshapeListener; - _threadSynchronizer = [[FlutterThreadSynchronizer alloc] init]; _surfaceManager = [[FlutterSurfaceManager alloc] initWithDevice:device commandQueue:commandQueue layer:self.layer delegate:self]; + [[FlutterView sharedThreadSynchronizer] registerView:viewId]; } return self; } - (void)onPresent:(CGSize)frameSize withBlock:(dispatch_block_t)block { - [_threadSynchronizer performCommit:frameSize notify:block]; + [[FlutterView sharedThreadSynchronizer] performCommitForView:_viewId size:frameSize notify:block]; } - (FlutterSurfaceManager*)surfaceManager { @@ -46,15 +48,16 @@ - (FlutterSurfaceManager*)surfaceManager { } - (FlutterThreadSynchronizer*)threadSynchronizer { - return _threadSynchronizer; + return [FlutterView sharedThreadSynchronizer]; } - (void)reshaped { CGSize scaledSize = [self convertSizeToBacking:self.bounds.size]; - [_threadSynchronizer beginResize:scaledSize - notify:^{ - [_reshapeListener viewDidReshape:self]; - }]; + [[FlutterView sharedThreadSynchronizer] beginResizeForView:_viewId + size:scaledSize + notify:^{ + [_reshapeListener viewDidReshape:self]; + }]; } - (void)setBackgroundColor:(NSColor*)color { @@ -113,7 +116,6 @@ - (BOOL)layer:(CALayer*)layer } - (void)shutdown { - [_threadSynchronizer shutdown]; } #pragma mark - NSAccessibility overrides @@ -137,4 +139,12 @@ - (NSString*)accessibilityLabel { return applicationName; } +static FlutterThreadSynchronizer* _synchronizer; ++ (FlutterThreadSynchronizer*)sharedThreadSynchronizer { + if (_synchronizer == nil) { + _synchronizer = [[FlutterThreadSynchronizer alloc] init]; + } + return _synchronizer; +} + @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index acd07a827c569..d414c376a8dea 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -480,6 +480,10 @@ - (void)viewWillAppear { [self listenForMetaModifiedKeyUpEvents]; } +- (void)viewDidAppear { + [_engine updateWindowMetricsForViewController:self]; +} + - (void)viewWillDisappear { // Per Apple's documentation, it is discouraged to call removeMonitor: in dealloc, and it's // recommended to be called earlier in the lifecycle. @@ -856,7 +860,8 @@ - (nonnull FlutterView*)createFlutterViewWithMTLDevice:(id)device commandQueue:(id)commandQueue { return [[FlutterView alloc] initWithMTLDevice:device commandQueue:commandQueue - reshapeListener:self]; + reshapeListener:self + viewId:_viewId]; } - (void)onKeyboardLayoutChanged { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm index 15ca078042fd8..40faed5b13efd 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm @@ -8,6 +8,8 @@ #import "flutter/testing/testing.h" +constexpr int64_t kDefaultViewId = 0ll; + @interface TestReshapeListener : NSObject @end @@ -25,6 +27,7 @@ - (void)viewDidReshape:(nonnull NSView*)view { TestReshapeListener* listener = [[TestReshapeListener alloc] init]; FlutterView* view = [[FlutterView alloc] initWithMTLDevice:device commandQueue:queue - reshapeListener:listener]; + reshapeListener:listener + viewId:kDefaultViewId]; EXPECT_EQ([view layer:view.layer shouldInheritContentsScale:3.0 fromWindow:view.window], YES); } diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 8fa0ee09e8dcb..0db62b3edc5c9 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -1069,12 +1069,12 @@ InferExternalViewEmbedderFromArgs(const FlutterCompositor* compositor) { }; flutter::EmbedderExternalViewEmbedder::PresentCallback present_callback = - [c_present_callback, - user_data = compositor->user_data](const auto& layers) { + [c_present_callback, user_data = compositor->user_data]( + const auto& layers, int64_t window_view_id) { TRACE_EVENT0("flutter", "FlutterCompositorPresentLayers"); return c_present_callback( const_cast(layers.data()), layers.size(), - user_data); + window_view_id, user_data); }; return {std::make_unique( @@ -2065,6 +2065,7 @@ FlutterEngineResult FlutterEngineAddRenderSurface( FlutterEngineResult FlutterEngineSendWindowMetricsEvent( FLUTTER_API_SYMBOL(FlutterEngine) engine, + int64_t view_id, const FlutterWindowMetricsEvent* flutter_metrics) { if (engine == nullptr || flutter_metrics == nullptr) { return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid."); @@ -2109,7 +2110,7 @@ FlutterEngineResult FlutterEngineSendWindowMetricsEvent( } return reinterpret_cast(engine)->SetViewportMetrics( - metrics) + view_id, metrics) ? kSuccess : LOG_EMBEDDER_ERROR(kInvalidArguments, "Viewport metrics were invalid."); diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index 6b0ff0baf5a12..70b85ccf132cf 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -1549,6 +1549,7 @@ typedef struct { size_t struct_size; /// The size of the render target the engine expects to render into. FlutterSize size; + int64_t view_id; } FlutterBackingStoreConfig; typedef enum { @@ -1591,6 +1592,7 @@ typedef bool (*FlutterBackingStoreCollectCallback)( typedef bool (*FlutterLayersPresentCallback)(const FlutterLayer** layers, size_t layers_count, + int64_t view_id, void* user_data); typedef struct { @@ -2253,6 +2255,7 @@ FlutterEngineResult FlutterEngineAddRenderSurface( FLUTTER_EXPORT FlutterEngineResult FlutterEngineSendWindowMetricsEvent( FLUTTER_API_SYMBOL(FlutterEngine) engine, + int64_t view_id, const FlutterWindowMetricsEvent* event); FLUTTER_EXPORT @@ -2830,6 +2833,7 @@ typedef FlutterEngineResult (*FlutterEngineAddRenderSurfaceFnPtr)( int64_t view_id); typedef FlutterEngineResult (*FlutterEngineSendWindowMetricsEventFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine, + int64_t view_id, const FlutterWindowMetricsEvent* event); typedef FlutterEngineResult (*FlutterEngineSendPointerEventFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine, diff --git a/shell/platform/embedder/embedder_engine.cc b/shell/platform/embedder/embedder_engine.cc index cc4da738f72fc..b34da8a287f4e 100644 --- a/shell/platform/embedder/embedder_engine.cc +++ b/shell/platform/embedder/embedder_engine.cc @@ -100,6 +100,7 @@ bool EmbedderEngine::NotifyDestroyed() { } bool EmbedderEngine::SetViewportMetrics( + int64_t view_id, const flutter::ViewportMetrics& metrics) { if (!IsValid()) { return false; @@ -109,7 +110,7 @@ bool EmbedderEngine::SetViewportMetrics( if (!platform_view) { return false; } - platform_view->SetViewportMetrics(metrics); + platform_view->SetViewportMetrics(view_id, metrics); return true; } diff --git a/shell/platform/embedder/embedder_engine.h b/shell/platform/embedder/embedder_engine.h index 60d33ba76e652..a587eeb3eaa74 100644 --- a/shell/platform/embedder/embedder_engine.h +++ b/shell/platform/embedder/embedder_engine.h @@ -48,7 +48,8 @@ class EmbedderEngine { bool IsValid() const; - bool SetViewportMetrics(const flutter::ViewportMetrics& metrics); + bool SetViewportMetrics(int64_t view_id, + const flutter::ViewportMetrics& metrics); bool DispatchPointerDataPacket( std::unique_ptr packet); diff --git a/shell/platform/embedder/embedder_external_view_embedder.cc b/shell/platform/embedder/embedder_external_view_embedder.cc index 380b404a13046..d9ae64df14887 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.cc +++ b/shell/platform/embedder/embedder_external_view_embedder.cc @@ -111,13 +111,15 @@ DlCanvas* EmbedderExternalViewEmbedder::CompositeEmbeddedView(int64_t view_id) { } static FlutterBackingStoreConfig MakeBackingStoreConfig( - const SkISize& backing_store_size) { + const SkISize& backing_store_size, + int64_t window_view_id) { FlutterBackingStoreConfig config = {}; config.struct_size = sizeof(config); config.size.width = backing_store_size.width(); config.size.height = backing_store_size.height(); + config.view_id = window_view_id; return config; } @@ -125,7 +127,8 @@ static FlutterBackingStoreConfig MakeBackingStoreConfig( // |ExternalViewEmbedder| void EmbedderExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - std::unique_ptr frame) { + std::unique_ptr frame, + int64_t window_view_id) { auto [matched_render_targets, pending_keys] = render_target_cache_.GetExistingTargetsInCache(pending_views_); @@ -164,7 +167,7 @@ void EmbedderExternalViewEmbedder::SubmitFrame( const auto render_surface_size = external_view->GetRenderSurfaceSize(); const auto backing_store_config = - MakeBackingStoreConfig(render_surface_size); + MakeBackingStoreConfig(render_surface_size, window_view_id); // This is where the embedder will create render targets for us. Control // flow to the embedder makes the engine susceptible to having the embedder @@ -243,7 +246,7 @@ void EmbedderExternalViewEmbedder::SubmitFrame( // Flush the layer description down to the embedder for presentation. // // @warning: Embedder may trample on our OpenGL context here. - presented_layers.InvokePresentCallback(present_callback_); + presented_layers.InvokePresentCallback(present_callback_, window_view_id); } // See why this is necessary in the comment where this collection in realized. diff --git a/shell/platform/embedder/embedder_external_view_embedder.h b/shell/platform/embedder/embedder_external_view_embedder.h index 55a08f0627a72..2118db5e25758 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.h +++ b/shell/platform/embedder/embedder_external_view_embedder.h @@ -33,7 +33,8 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { GrDirectContext* context, const FlutterBackingStoreConfig& config)>; using PresentCallback = - std::function& layers)>; + std::function& layers, + int64_t window_view_id)>; using SurfaceTransformationCallback = std::function; //---------------------------------------------------------------------------- @@ -95,7 +96,8 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) override; + std::unique_ptr frame, + int64_t window_view_id) override; // |ExternalViewEmbedder| DlCanvas* GetRootCanvas() override; diff --git a/shell/platform/embedder/embedder_layers.cc b/shell/platform/embedder/embedder_layers.cc index 6465293748f9f..f5a62b26c4bea 100644 --- a/shell/platform/embedder/embedder_layers.cc +++ b/shell/platform/embedder/embedder_layers.cc @@ -199,14 +199,14 @@ void EmbedderLayers::PushPlatformViewLayer( presented_layers_.push_back(layer); } -void EmbedderLayers::InvokePresentCallback( - const PresentCallback& callback) const { +void EmbedderLayers::InvokePresentCallback(const PresentCallback& callback, + int64_t window_view_id) const { std::vector presented_layers_pointers; presented_layers_pointers.reserve(presented_layers_.size()); for (const auto& layer : presented_layers_) { presented_layers_pointers.push_back(&layer); } - callback(presented_layers_pointers); + callback(presented_layers_pointers, window_view_id); } } // namespace flutter diff --git a/shell/platform/embedder/embedder_layers.h b/shell/platform/embedder/embedder_layers.h index c1cb2907588c9..46137f459df99 100644 --- a/shell/platform/embedder/embedder_layers.h +++ b/shell/platform/embedder/embedder_layers.h @@ -30,8 +30,10 @@ class EmbedderLayers { const EmbeddedViewParams& params); using PresentCallback = - std::function& layers)>; - void InvokePresentCallback(const PresentCallback& callback) const; + std::function& layers, + int64_t view_id)>; + void InvokePresentCallback(const PresentCallback& callback, + int64_t window_view_id) const; private: const SkISize frame_size_; diff --git a/shell/platform/embedder/platform_view_embedder_unittests.cc b/shell/platform/embedder/platform_view_embedder_unittests.cc index f0a07cc8aa004..b04365c0d6967 100644 --- a/shell/platform/embedder/platform_view_embedder_unittests.cc +++ b/shell/platform/embedder/platform_view_embedder_unittests.cc @@ -22,8 +22,8 @@ class MockDelegate : public PlatformView::Delegate { MOCK_METHOD0(OnPlatformViewScheduleFrame, void()); MOCK_METHOD1(OnPlatformViewSetNextFrameCallback, void(const fml::closure& closure)); - MOCK_METHOD1(OnPlatformViewSetViewportMetrics, - void(const ViewportMetrics& metrics)); + MOCK_METHOD2(OnPlatformViewSetViewportMetrics, + void(int64_t view_id, const ViewportMetrics& metrics)); MOCK_METHOD1(OnPlatformViewDispatchPlatformMessage, void(std::unique_ptr message)); MOCK_METHOD1(OnPlatformViewDispatchPointerDataPacket, diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index f12a9e58b130a..dae2c4dc12110 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -362,6 +362,7 @@ void EmbedderConfigBuilder::SetCompositor(bool avoid_backing_store_cache) { }; compositor_.present_layers_callback = [](const FlutterLayer** layers, // size_t layers_count, // + int64_t view_id, // void* user_data // ) { return reinterpret_cast(user_data)->Present( diff --git a/shell/platform/embedder/tests/embedder_metal_unittests.mm b/shell/platform/embedder/tests/embedder_metal_unittests.mm index 7974dc32cf5ea..db452abd4701d 100644 --- a/shell/platform/embedder/tests/embedder_metal_unittests.mm +++ b/shell/platform/embedder/tests/embedder_metal_unittests.mm @@ -28,6 +28,8 @@ namespace flutter { namespace testing { +constexpr int64_t kDefaultViewId = 0ll; + using EmbedderTest = testing::EmbedderTest; TEST_F(EmbedderTest, CanRenderGradientWithMetal) { @@ -49,7 +51,7 @@ event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), kSuccess); // TODO (https://github.com/flutter/flutter/issues/73590): re-enable once // we are able to figure out why this fails on the bots. @@ -118,7 +120,7 @@ GrBackendTexture backend_texture(texture_size.width(), texture_size.height(), Gr event.width = texture_size.width(); event.height = texture_size.height(); event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), kSuccess); ASSERT_TRUE(ImageMatchesFixture("external_texture_metal.png", rendered_scene)); } @@ -200,7 +202,7 @@ GrBackendTexture backend_texture(texture_size.width(), texture_size.height(), Gr event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -225,7 +227,7 @@ GrBackendTexture backend_texture(texture_size.width(), texture_size.height(), Gr event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), kSuccess); ASSERT_TRUE(ImageMatchesFixture("scene_without_custom_compositor.png", rendered_scene)); } @@ -273,7 +275,7 @@ GrBackendTexture backend_texture(texture_size.width(), texture_size.height(), Gr event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), kSuccess); ASSERT_TRUE(engine.is_valid()); collect_context->latch.Wait(); @@ -427,7 +429,7 @@ GrBackendTexture backend_texture(texture_size.width(), texture_size.height(), Gr event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -485,7 +487,7 @@ void Collect() { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); } diff --git a/shell/platform/embedder/tests/embedder_unittests.cc b/shell/platform/embedder/tests/embedder_unittests.cc index 8b03077fb5878..1ca6fbe798205 100644 --- a/shell/platform/embedder/tests/embedder_unittests.cc +++ b/shell/platform/embedder/tests/embedder_unittests.cc @@ -52,6 +52,8 @@ static uint64_t NanosFromEpoch(int millis_from_now) { namespace flutter { namespace testing { +static constexpr int64_t kDefaultViewId = 0ll; + using EmbedderTest = testing::EmbedderTest; TEST(EmbedderTestNoFixture, MustNotRunWithInvalidArgs) { @@ -805,8 +807,9 @@ TEST_F(EmbedderTest, event.physical_view_inset_right = 0.0; event.physical_view_inset_bottom = 0.0; event.physical_view_inset_left = 0.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -921,8 +924,9 @@ TEST_F(EmbedderTest, NoLayerCreatedForTransparentOverlayOnTopOfPlatformLayer) { event.physical_view_inset_right = 0.0; event.physical_view_inset_bottom = 0.0; event.physical_view_inset_left = 0.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -1043,8 +1047,9 @@ TEST_F(EmbedderTest, NoLayerCreatedForNoOverlayOnTopOfPlatformLayer) { event.physical_view_inset_right = 0.0; event.physical_view_inset_bottom = 0.0; event.physical_view_inset_left = 0.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -1114,8 +1119,9 @@ TEST_F(EmbedderTest, CanDeinitializeAnEngine) { event.physical_view_inset_right = 0.0; event.physical_view_inset_bottom = 0.0; event.physical_view_inset_left = 0.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kInvalidArguments); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kInvalidArguments); engine.reset(); } @@ -1319,8 +1325,9 @@ TEST_F(EmbedderTest, VerifyB143464703WithSoftwareBackend) { event.physical_view_inset_right = 0.0; event.physical_view_inset_bottom = 0.0; event.physical_view_inset_left = 0.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); // wait for scene to be rendered. @@ -1811,8 +1818,9 @@ TEST_F(EmbedderTest, InvalidFlutterWindowMetricsEvent) { event.physical_view_inset_left = 0.0; // Pixel ratio must be positive. - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kInvalidArguments); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kInvalidArguments); event.pixel_ratio = 1.0; event.physical_view_inset_top = -1.0; @@ -1821,8 +1829,9 @@ TEST_F(EmbedderTest, InvalidFlutterWindowMetricsEvent) { event.physical_view_inset_left = -1.0; // Physical view insets must be non-negative. - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kInvalidArguments); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kInvalidArguments); event.physical_view_inset_top = 700; event.physical_view_inset_right = 900; @@ -1831,8 +1840,9 @@ TEST_F(EmbedderTest, InvalidFlutterWindowMetricsEvent) { // Top/bottom insets cannot be greater than height. // Left/right insets cannot be greater than width. - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kInvalidArguments); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kInvalidArguments); } static void expectSoftwareRenderingOutputMatches( @@ -1876,8 +1886,9 @@ static void expectSoftwareRenderingOutputMatches( event.width = 1; event.height = 1; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); ASSERT_TRUE(matches); @@ -2389,7 +2400,8 @@ TEST_F(EmbedderTest, VsyncCallbackPostedIntoFuture) { event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, + &event), kSuccess); }); @@ -2464,8 +2476,9 @@ TEST_F(EmbedderTest, CanSetNextFrameCallback) { event.physical_view_inset_right = 0.0; event.physical_view_inset_bottom = 0.0; event.physical_view_inset_left = 0.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); callback_latch.Wait(); } diff --git a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc index 901bd8c078e97..9d970c6489865 100644 --- a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc +++ b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc @@ -132,7 +132,8 @@ void FlatlandExternalViewEmbedder::EndFrame( void FlatlandExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - std::unique_ptr frame) { + std::unique_ptr frame, + int64_t window_view_id) { TRACE_EVENT0("flutter", "FlatlandExternalViewEmbedder::SubmitFrame"); std::vector> frame_surfaces; std::unordered_map frame_surface_indices; diff --git a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h index 00a845cde2e85..394de12c7887a 100644 --- a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h +++ b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h @@ -87,7 +87,8 @@ class FlatlandExternalViewEmbedder final // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) override; + std::unique_ptr frame, + int64_t window_view_id) override; // |ExternalViewEmbedder| void CancelFrame() override { Reset(); } diff --git a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc index 21c6810c4e11b..e34dfc5e64bc3 100644 --- a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc +++ b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc @@ -231,7 +231,8 @@ void GfxExternalViewEmbedder::EndFrame( void GfxExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - std::unique_ptr frame) { + std::unique_ptr frame, + int64_t window_view_id) { TRACE_EVENT0("flutter", "GfxExternalViewEmbedder::SubmitFrame"); std::vector> frame_surfaces; std::unordered_map frame_surface_indices; diff --git a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h index eb37d2e7e2d1f..7d2f545cf238e 100644 --- a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h +++ b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h @@ -110,7 +110,8 @@ class GfxExternalViewEmbedder final : public flutter::ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) override; + std::unique_ptr frame, + int64_t window_view_id) override; // |ExternalViewEmbedder| void CancelFrame() override { Reset(); } diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index be9bac1005a73..6f30c64e79e3a 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -55,7 +55,8 @@ class MockExternalViewEmbedder : public flutter::ExternalViewEmbedder { fml::RefPtr raster_thread_merger) override {} void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) override {} + std::unique_ptr frame, + int64_t window_view_id) override {} void PrerollCompositeEmbeddedView( int64_t view_id, diff --git a/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc b/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc index 22ce7acda3a7c..e01337c409eef 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc @@ -53,6 +53,8 @@ using ::testing::VariantWith; namespace flutter_runner::testing { namespace { +constexpr int64_t kDefaultViewId = 0ll; + constexpr static fuchsia::ui::composition::BlendMode kFirstLayerBlendMode{ fuchsia::ui::composition::BlendMode::SRC}; constexpr static fuchsia::ui::composition::BlendMode kUpperLayerBlendMode{ @@ -335,11 +337,13 @@ void DrawSimpleFrame(FlatlandExternalViewEmbedder& external_view_embedder, flutter::SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; external_view_embedder.SubmitFrame( - nullptr, std::make_unique( - nullptr, std::move(framebuffer_info), - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size)); + nullptr, + std::make_unique( + nullptr, std::move(framebuffer_info), + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size), + kDefaultViewId); } void DrawFrameWithView( @@ -365,11 +369,13 @@ void DrawFrameWithView( flutter::SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; external_view_embedder.SubmitFrame( - nullptr, std::make_unique( - nullptr, std::move(framebuffer_info), - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size)); + nullptr, + std::make_unique( + nullptr, std::move(framebuffer_info), + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size), + kDefaultViewId); } }; // namespace diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index 9b4a8524ae038..01326fc07a4ac 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -54,7 +54,8 @@ class MockExternalViewEmbedder : public flutter::ExternalViewEmbedder { fml::RefPtr raster_thread_merger) override {} void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) override {} + std::unique_ptr frame, + int64_t window_view_id) override {} void PrerollCompositeEmbeddedView( int64_t view_id, diff --git a/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc b/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc index 45f570075ca3a..14e5b58fb9274 100644 --- a/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc +++ b/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc @@ -54,6 +54,8 @@ using ::testing::VariantWith; namespace flutter_runner::testing { namespace { +constexpr int64_t kDefaultViewId = 0ll; + class FakeSurfaceProducerSurface : public SurfaceProducerSurface { public: explicit FakeSurfaceProducerSurface(scenic::Session* session, @@ -458,11 +460,13 @@ void DrawSimpleFrame(GfxExternalViewEmbedder& external_view_embedder, external_view_embedder.EndFrame(false, nullptr); flutter::SurfaceFrame::FramebufferInfo framebuffer_info; external_view_embedder.SubmitFrame( - nullptr, std::make_unique( - nullptr, framebuffer_info, - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size)); + nullptr, + std::make_unique( + nullptr, framebuffer_info, + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size), + kDefaultViewId); } void DrawFrameWithView( @@ -487,11 +491,13 @@ void DrawFrameWithView( external_view_embedder.EndFrame(false, nullptr); flutter::SurfaceFrame::FramebufferInfo framebuffer_info; external_view_embedder.SubmitFrame( - nullptr, std::make_unique( - nullptr, framebuffer_info, - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size)); + nullptr, + std::make_unique( + nullptr, framebuffer_info, + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size), + kDefaultViewId); } FramePresentedInfo MakeFramePresentedInfoForOnePresent( diff --git a/shell/platform/linux/fl_engine.cc b/shell/platform/linux/fl_engine.cc index 0ae331b328375..b8a6a1942dcc7 100644 --- a/shell/platform/linux/fl_engine.cc +++ b/shell/platform/linux/fl_engine.cc @@ -178,6 +178,7 @@ static bool compositor_collect_backing_store_callback( // Called when embedder should composite contents of each layer onto the screen. static bool compositor_present_layers_callback(const FlutterLayer** layers, size_t layers_count, + int64_t view_id, void* user_data) { g_return_val_if_fail(FL_IS_RENDERER(user_data), false); return fl_renderer_present_layers(FL_RENDERER(user_data), layers, diff --git a/shell/testing/tester_main.cc b/shell/testing/tester_main.cc index d0a3711505b44..c99aeb1c1005a 100644 --- a/shell/testing/tester_main.cc +++ b/shell/testing/tester_main.cc @@ -40,6 +40,8 @@ namespace flutter { +static constexpr int64_t kDefaultViewId = 0ll; + class TesterExternalViewEmbedder : public ExternalViewEmbedder { // |ExternalViewEmbedder| DlCanvas* GetRootCanvas() override { return nullptr; } @@ -357,7 +359,7 @@ int RunTester(const flutter::Settings& settings, metrics.device_pixel_ratio = 3.0; metrics.physical_width = 2400.0; // 800 at 3x resolution. metrics.physical_height = 1800.0; // 600 at 3x resolution. - shell->GetPlatformView()->SetViewportMetrics(metrics); + shell->GetPlatformView()->SetViewportMetrics(kDefaultViewId, metrics); // Run the message loop and wait for the script to do its thing. fml::MessageLoop::GetCurrent().Run(); From 6701a63914a3a291bef1f3316d415950f0d9f399 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 21 Apr 2023 13:23:42 -0700 Subject: [PATCH 078/142] Format --- lib/ui/window/platform_configuration.cc | 13 +++++++------ shell/common/shell_test_platform_view_metal.mm | 2 +- shell/gpu/gpu_studio_gl_impeller.cc | 3 ++- shell/gpu/gpu_studio_vulkan_impeller.cc | 3 ++- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/ui/window/platform_configuration.cc b/lib/ui/window/platform_configuration.cc index bd9a7744daaa9..fdf7a0b2f3337 100644 --- a/lib/ui/window/platform_configuration.cc +++ b/lib/ui/window/platform_configuration.cc @@ -50,7 +50,7 @@ void PlatformConfiguration::DidCreateIsolate() { add_view_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_addView"))); remove_view_.Set(tonic::DartState::Current(), - Dart_GetField(library, tonic::ToDart("_removeView"))); + Dart_GetField(library, tonic::ToDart("_removeView"))); update_locales_.Set(tonic::DartState::Current(), Dart_GetField(library, tonic::ToDart("_updateLocales"))); update_user_settings_data_.Set( @@ -112,21 +112,22 @@ void PlatformConfiguration::AddView(int64_t view_id) { tonic::DartState::Scope scope(dart_state); tonic::CheckAndHandleError( tonic::DartInvoke(add_view_.Get(), { - tonic::ToDart(view_id), - })); + tonic::ToDart(view_id), + })); } void PlatformConfiguration::RemoveView(int64_t view_id) { windows_.erase(view_id); - std::shared_ptr dart_state = remove_view_.dart_state().lock(); + std::shared_ptr dart_state = + remove_view_.dart_state().lock(); if (!dart_state) { return; } tonic::DartState::Scope scope(dart_state); tonic::CheckAndHandleError( tonic::DartInvoke(remove_view_.Get(), { - tonic::ToDart(view_id), - })); + tonic::ToDart(view_id), + })); } void PlatformConfiguration::UpdateLocales( diff --git a/shell/common/shell_test_platform_view_metal.mm b/shell/common/shell_test_platform_view_metal.mm index 5d44f04d3ab72..6ef2bbc5a1d81 100644 --- a/shell/common/shell_test_platform_view_metal.mm +++ b/shell/common/shell_test_platform_view_metal.mm @@ -111,7 +111,7 @@ GPUMTLTextureInfo offscreen_texture_info() const { std::unique_ptr ShellTestPlatformViewMetal::CreateRenderingStudio() { if (GetSettings().enable_impeller) { return std::make_unique(this, - [metal_context_->impeller_context() context]); + [metal_context_->impeller_context() context]); } return std::make_unique(this, [metal_context_->context() mainContext], sksl_precompiler_); diff --git a/shell/gpu/gpu_studio_gl_impeller.cc b/shell/gpu/gpu_studio_gl_impeller.cc index a64eefb170853..cae6e498f1e99 100644 --- a/shell/gpu/gpu_studio_gl_impeller.cc +++ b/shell/gpu/gpu_studio_gl_impeller.cc @@ -73,7 +73,8 @@ bool GPUStudioGLImpeller::EnableRasterCache() const { } // |Studio| -std::shared_ptr GPUStudioGLImpeller::GetAiksContext() const { +std::shared_ptr GPUStudioGLImpeller::GetAiksContext() + const { return aiks_context_; } diff --git a/shell/gpu/gpu_studio_vulkan_impeller.cc b/shell/gpu/gpu_studio_vulkan_impeller.cc index 0b5418405ec42..bc94f8e4a8bf4 100644 --- a/shell/gpu/gpu_studio_vulkan_impeller.cc +++ b/shell/gpu/gpu_studio_vulkan_impeller.cc @@ -54,7 +54,8 @@ bool GPUStudioVulkanImpeller::EnableRasterCache() const { } // |Studio| -std::shared_ptr GPUStudioVulkanImpeller::GetAiksContext() const { +std::shared_ptr GPUStudioVulkanImpeller::GetAiksContext() + const { return aiks_context_; } From 2391ce35c0876c2e7b19ee14470a062468d95652 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 21 Apr 2023 13:31:51 -0700 Subject: [PATCH 079/142] Compile --- shell/common/rasterizer.cc | 2 +- shell/common/rasterizer.h | 7 ++++--- shell/gpu/gpu_studio_metal_impeller.mm | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 78937353df8ce..a3ed3a9c64b7b 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -241,7 +241,7 @@ RasterStatus Rasterizer::Draw( std::unique_ptr frame_timings_recorder = std::move(item->frame_timings_recorder); int64_t view_id = item->view_id; - if (discard_callback(*layer_tree.get())) { + if (discard_callback(view_id, *layer_tree.get())) { draw_result.raster_status = RasterStatus::kDiscarded; } else { draw_result = DoDraw(view_id, std::move(frame_timings_recorder), diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 1de2050b0ab86..a982ada38712b 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -597,9 +597,10 @@ class Rasterizer final : public SnapshotDelegate, GrDirectContext* surface_context, bool compressed); - DoDrawResult DoDraw(int64_t view_id, - FrameTimingsRecorder& frame_timings_recorder, - std::shared_ptr layer_tree); + DoDrawResult DoDraw( + int64_t view_id, + std::unique_ptr frame_timings_recorder, + std::shared_ptr layer_tree); RasterStatus DrawToSurface(FrameTimingsRecorder& frame_timings_recorder, flutter::LayerTree* layer_tree, diff --git a/shell/gpu/gpu_studio_metal_impeller.mm b/shell/gpu/gpu_studio_metal_impeller.mm index b5b184bd98f21..4a9c140c0ca48 100644 --- a/shell/gpu/gpu_studio_metal_impeller.mm +++ b/shell/gpu/gpu_studio_metal_impeller.mm @@ -11,7 +11,7 @@ #include "flutter/fml/make_copyable.h" #include "flutter/fml/mapping.h" #include "flutter/fml/trace_event.h" -#include "flutter/impeller/display_list/display_list_dispatcher.h" +#include "flutter/impeller/display_list/dl_dispatcher.h" #include "flutter/impeller/renderer/backend/metal/surface_mtl.h" static_assert(!__has_feature(objc_arc), "ARC must be disabled."); From d934818d22754f38ff95317b1682f5aed5b3cc90 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 14:58:44 -0700 Subject: [PATCH 080/142] Create layer tree on taking --- flow/layers/layer_tree.cc | 14 ++-- flow/layers/layer_tree.h | 32 ++++----- flow/layers/layer_tree_unittests.cc | 55 +++++++++------ lib/ui/compositing/scene.cc | 55 +++++++++------ lib/ui/compositing/scene.h | 17 +++-- ...isplay_list_deferred_image_gpu_impeller.cc | 14 ++-- ...display_list_deferred_image_gpu_impeller.h | 6 +- .../display_list_deferred_image_gpu_skia.cc | 12 ++-- .../display_list_deferred_image_gpu_skia.h | 6 +- lib/ui/painting/picture.cc | 27 ++++---- lib/ui/painting/picture.h | 12 ++-- runtime/runtime_delegate.h | 2 +- shell/common/animator.cc | 2 +- shell/common/animator.h | 2 +- shell/common/animator_unittests.cc | 8 +-- shell/common/engine.cc | 2 +- shell/common/engine.h | 2 +- shell/common/engine_unittests.cc | 2 +- shell/common/pipeline.h | 4 +- shell/common/rasterizer.cc | 4 +- shell/common/rasterizer.h | 6 +- shell/common/rasterizer_unittests.cc | 69 +++++++++++-------- shell/common/shell_test.cc | 10 +-- 23 files changed, 202 insertions(+), 161 deletions(-) diff --git a/flow/layers/layer_tree.cc b/flow/layers/layer_tree.cc index d01b243ab3eb8..8a0cb890acef8 100644 --- a/flow/layers/layer_tree.cc +++ b/flow/layers/layer_tree.cc @@ -20,12 +20,16 @@ namespace flutter { -LayerTree::LayerTree(const SkISize& frame_size, float device_pixel_ratio) - : frame_size_(frame_size), +LayerTree::LayerTree(const Config& config, + const SkISize& frame_size, + float device_pixel_ratio) + : root_layer_(config.root_layer), + frame_size_(frame_size), device_pixel_ratio_(device_pixel_ratio), - rasterizer_tracing_threshold_(0), - checkerboard_raster_cache_images_(false), - checkerboard_offscreen_layers_(false) { + rasterizer_tracing_threshold_(config.rasterizer_tracing_threshold), + checkerboard_raster_cache_images_( + config.checkerboard_raster_cache_images), + checkerboard_offscreen_layers_(config.checkerboard_offscreen_layers) { FML_CHECK(device_pixel_ratio_ != 0.0f); } diff --git a/flow/layers/layer_tree.h b/flow/layers/layer_tree.h index a39cc2360076f..f01c1c80044ad 100644 --- a/flow/layers/layer_tree.h +++ b/flow/layers/layer_tree.h @@ -23,7 +23,16 @@ namespace flutter { class LayerTree { public: - LayerTree(const SkISize& frame_size, float device_pixel_ratio); + struct Config { + std::shared_ptr root_layer; + uint32_t rasterizer_tracing_threshold = 0; + bool checkerboard_raster_cache_images = false; + bool checkerboard_offscreen_layers = false; + }; + + LayerTree(const Config& config, + const SkISize& frame_size, + float device_pixel_ratio); // Perform a preroll pass on the tree and return information about // the tree that affects rendering this frame. @@ -50,11 +59,6 @@ class LayerTree { GrDirectContext* gr_context = nullptr); Layer* root_layer() const { return root_layer_.get(); } - - void set_root_layer(std::shared_ptr root_layer) { - root_layer_ = std::move(root_layer); - } - const SkISize& frame_size() const { return frame_size_; } float device_pixel_ratio() const { return device_pixel_ratio_; } @@ -62,24 +66,12 @@ class LayerTree { PaintRegionMap& paint_region_map() { return paint_region_map_; } // The number of frame intervals missed after which the compositor must - // trace the rasterized picture to a trace file. Specify 0 to disable all - // tracing - void set_rasterizer_tracing_threshold(uint32_t interval) { - rasterizer_tracing_threshold_ = interval; - } - + // trace the rasterized picture to a trace file. 0 stands for disabling all + // tracing. uint32_t rasterizer_tracing_threshold() const { return rasterizer_tracing_threshold_; } - void set_checkerboard_raster_cache_images(bool checkerboard) { - checkerboard_raster_cache_images_ = checkerboard; - } - - void set_checkerboard_offscreen_layers(bool checkerboard) { - checkerboard_offscreen_layers_ = checkerboard; - } - /// When `Paint` is called, if leaf layer tracing is enabled, additional /// metadata around raterization of leaf layers is collected. /// diff --git a/flow/layers/layer_tree_unittests.cc b/flow/layers/layer_tree_unittests.cc index ea655b5b44ae8..47673b8eb764b 100644 --- a/flow/layers/layer_tree_unittests.cc +++ b/flow/layers/layer_tree_unittests.cc @@ -19,8 +19,7 @@ namespace testing { class LayerTreeTest : public CanvasTest { public: LayerTreeTest() - : layer_tree_(SkISize::Make(64, 64), 1.0f), - root_transform_(SkMatrix::Translate(1.0f, 1.0f)), + : root_transform_(SkMatrix::Translate(1.0f, 1.0f)), scoped_frame_(compositor_context_.AcquireFrame(nullptr, &mock_canvas(), nullptr, @@ -31,12 +30,14 @@ class LayerTreeTest : public CanvasTest { nullptr, nullptr)) {} - LayerTree& layer_tree() { return layer_tree_; } CompositorContext::ScopedFrame& frame() { return *scoped_frame_.get(); } const SkMatrix& root_transform() { return root_transform_; } + std::unique_ptr BuildLayerTree(LayerTree::Config config) { + return std::make_unique(config, SkISize::Make(64, 64), 1.0f); + } + private: - LayerTree layer_tree_; CompositorContext compositor_context_; SkMatrix root_transform_; std::unique_ptr scoped_frame_; @@ -45,12 +46,14 @@ class LayerTreeTest : public CanvasTest { TEST_F(LayerTreeTest, PaintingEmptyLayerDies) { auto layer = std::make_shared(); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); + layer_tree->Preroll(frame()); EXPECT_EQ(layer->paint_bounds(), SkRect::MakeEmpty()); EXPECT_TRUE(layer->is_empty()); - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); } TEST_F(LayerTreeTest, PaintBeforePrerollDies) { @@ -61,13 +64,15 @@ TEST_F(LayerTreeTest, PaintBeforePrerollDies) { auto layer = std::make_shared(); layer->Add(mock_layer); - layer_tree().set_root_layer(layer); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); EXPECT_EQ(mock_layer->paint_bounds(), kEmptyRect); EXPECT_EQ(layer->paint_bounds(), kEmptyRect); EXPECT_TRUE(mock_layer->is_empty()); EXPECT_TRUE(layer->is_empty()); - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); EXPECT_EQ(mock_canvas().draw_calls(), std::vector()); } @@ -79,15 +84,17 @@ TEST_F(LayerTreeTest, Simple) { auto layer = std::make_shared(); layer->Add(mock_layer); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); + layer_tree->Preroll(frame()); EXPECT_EQ(mock_layer->paint_bounds(), child_bounds); EXPECT_EQ(layer->paint_bounds(), mock_layer->paint_bounds()); EXPECT_FALSE(mock_layer->is_empty()); EXPECT_FALSE(layer->is_empty()); EXPECT_EQ(mock_layer->parent_matrix(), root_transform()); - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); EXPECT_EQ(mock_canvas().draw_calls(), std::vector({MockCanvas::DrawCall{ 0, MockCanvas::DrawPathData{child_path, child_paint}}})); @@ -107,8 +114,10 @@ TEST_F(LayerTreeTest, Multiple) { SkRect expected_total_bounds = child_path1.getBounds(); expected_total_bounds.join(child_path2.getBounds()); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); + layer_tree->Preroll(frame()); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer->paint_bounds(), expected_total_bounds); @@ -121,7 +130,7 @@ TEST_F(LayerTreeTest, Multiple) { EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); // Siblings are independent - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); EXPECT_EQ( mock_canvas().draw_calls(), std::vector({MockCanvas::DrawCall{ @@ -140,8 +149,10 @@ TEST_F(LayerTreeTest, MultipleWithEmpty) { layer->Add(mock_layer1); layer->Add(mock_layer2); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); + layer_tree->Preroll(frame()); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), SkPath().getBounds()); EXPECT_EQ(layer->paint_bounds(), child_path1.getBounds()); @@ -153,7 +164,7 @@ TEST_F(LayerTreeTest, MultipleWithEmpty) { EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); EXPECT_EQ(mock_canvas().draw_calls(), std::vector({MockCanvas::DrawCall{ 0, MockCanvas::DrawPathData{child_path1, child_paint1}}})); @@ -172,8 +183,10 @@ TEST_F(LayerTreeTest, NeedsSystemComposite) { SkRect expected_total_bounds = child_path1.getBounds(); expected_total_bounds.join(child_path2.getBounds()); - layer_tree().set_root_layer(layer); - layer_tree().Preroll(frame()); + auto layer_tree = BuildLayerTree(LayerTree::Config{ + .root_layer = layer, + }); + layer_tree->Preroll(frame()); EXPECT_EQ(mock_layer1->paint_bounds(), child_path1.getBounds()); EXPECT_EQ(mock_layer2->paint_bounds(), child_path2.getBounds()); EXPECT_EQ(layer->paint_bounds(), expected_total_bounds); @@ -185,7 +198,7 @@ TEST_F(LayerTreeTest, NeedsSystemComposite) { EXPECT_EQ(mock_layer1->parent_cull_rect(), kGiantRect); EXPECT_EQ(mock_layer2->parent_cull_rect(), kGiantRect); - layer_tree().Paint(frame()); + layer_tree->Paint(frame()); EXPECT_EQ( mock_canvas().draw_calls(), std::vector({MockCanvas::DrawCall{ diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index c5070c6376091..f85397ac881b5 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -45,22 +45,23 @@ Scene::Scene(std::shared_ptr rootLayer, ->platform_configuration() ->get_window(0) ->viewport_metrics(); - - layer_tree_ = std::make_shared( - SkISize::Make(viewport_metrics.physical_width, - viewport_metrics.physical_height), - static_cast(viewport_metrics.device_pixel_ratio)); - layer_tree_->set_root_layer(std::move(rootLayer)); - layer_tree_->set_rasterizer_tracing_threshold(rasterizerTracingThreshold); - layer_tree_->set_checkerboard_raster_cache_images( - checkerboardRasterCacheImages); - layer_tree_->set_checkerboard_offscreen_layers(checkerboardOffscreenLayers); + device_width_ = viewport_metrics.physical_width; + device_height_ = viewport_metrics.physical_height; + device_pixel_ratio_ = static_cast(viewport_metrics.device_pixel_ratio); + + layer_tree_config_ = std::make_unique(); + layer_tree_config_->root_layer = std::move(rootLayer); + layer_tree_config_->rasterizer_tracing_threshold = rasterizerTracingThreshold; + layer_tree_config_->checkerboard_raster_cache_images = + checkerboardRasterCacheImages; + layer_tree_config_->checkerboard_offscreen_layers = + checkerboardOffscreenLayers; } Scene::~Scene() {} void Scene::dispose() { - layer_tree_.reset(); + layer_tree_config_.reset(); ClearDartWrapper(); } @@ -69,8 +70,8 @@ Dart_Handle Scene::toImageSync(uint32_t width, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); - if (!layer_tree_) { - return tonic::ToDart("Scene did not contain a layer tree."); + if (!layer_tree_config_) { + return tonic::ToDart("Scene's layer tree has been taken away."); } Scene::RasterizeToImage(width, height, raw_image_handle); @@ -82,17 +83,18 @@ Dart_Handle Scene::toImage(uint32_t width, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); - if (!layer_tree_) { - return tonic::ToDart("Scene did not contain a layer tree."); + if (!layer_tree_config_) { + return tonic::ToDart("Scene's layer tree has been taken away."); } - return Picture::RasterizeLayerTreeToImage(std::move(layer_tree_), width, - height, raw_image_callback); + return Picture::RasterizeLayerTreeToImage( + BuildLayerTree(device_width_, device_height_, device_pixel_ratio_), width, + height, raw_image_callback); } static sk_sp CreateDeferredImage( bool impeller, - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, uint32_t width, uint32_t height, fml::TaskRunnerAffineWeakPtr snapshot_delegate, @@ -126,15 +128,24 @@ void Scene::RasterizeToImage(uint32_t width, auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( - dart_state->IsImpellerEnabled(), layer_tree_, width, height, - std::move(snapshot_delegate), std::move(raster_task_runner), + dart_state->IsImpellerEnabled(), + BuildLayerTree(device_width_, device_height_, device_pixel_ratio_), width, + height, std::move(snapshot_delegate), std::move(raster_task_runner), std::move(unref_queue)); image->set_image(dl_image); image->AssociateWithDartWrapper(raw_image_handle); } -std::shared_ptr Scene::takeLayerTree() { - return std::move(layer_tree_); +std::unique_ptr Scene::takeLayerTree() { + return BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); +} + +std::unique_ptr Scene::BuildLayerTree(uint32_t width, + uint32_t height, + float pixel_ratio) { + FML_CHECK(layer_tree_config_ != nullptr); + return std::make_unique(*layer_tree_config_, + SkISize::Make(width, height), pixel_ratio); } } // namespace flutter diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index aca797836fcb1..e8b8c0cf0d2ff 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -26,7 +26,7 @@ class Scene : public RefCountedDartWrappable { bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); - std::shared_ptr takeLayerTree(); + std::unique_ptr takeLayerTree(); Dart_Handle toImageSync(uint32_t width, uint32_t height, @@ -48,12 +48,15 @@ class Scene : public RefCountedDartWrappable { uint32_t height, Dart_Handle raw_image_handle); - // This is a shared_ptr to support flattening the layer tree from the UI - // thread onto the raster thread - allowing access to the texture registry - // required to render TextureLayers. - // - // No longer valid after calling `takeLayerTree`. - std::shared_ptr layer_tree_; + std::unique_ptr BuildLayerTree(uint32_t width, + uint32_t height, + float pixel_ratio); + + // No longer valid after calling `takeLayerTreeConfig`. + std::unique_ptr layer_tree_config_; + float device_pixel_ratio_; + uint32_t device_width_; + uint32_t device_height_; }; } // namespace flutter diff --git a/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc b/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc index 40d09b8ff00c6..ffe33c079ebaa 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc @@ -3,14 +3,15 @@ // found in the LICENSE file. #include "flutter/lib/ui/painting/display_list_deferred_image_gpu_impeller.h" -#include "display_list_deferred_image_gpu_impeller.h" #include +#include "flutter/fml/make_copyable.h" + namespace flutter { sk_sp DlDeferredImageGPUImpeller::Make( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner) { @@ -106,7 +107,7 @@ DlDeferredImageGPUImpeller::ImageWrapper::Make( std::shared_ptr DlDeferredImageGPUImpeller::ImageWrapper::Make( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner) { @@ -152,10 +153,11 @@ bool DlDeferredImageGPUImpeller::ImageWrapper::isTextureBacked() const { } void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotDisplayList( - std::shared_ptr layer_tree) { + std::unique_ptr layer_tree) { fml::TaskRunner::RunNowOrPostTask( raster_task_runner_, - [weak_this = weak_from_this(), layer_tree = std::move(layer_tree)] { + fml::MakeCopyable([weak_this = weak_from_this(), + layer_tree = std::move(layer_tree)]() { TRACE_EVENT0("flutter", "SnapshotDisplayList (impeller)"); auto wrapper = weak_this.lock(); if (!wrapper) { @@ -183,7 +185,7 @@ void DlDeferredImageGPUImpeller::ImageWrapper::SnapshotDisplayList( return; } wrapper->texture_ = snapshot->impeller_texture(); - }); + })); } std::optional diff --git a/lib/ui/painting/display_list_deferred_image_gpu_impeller.h b/lib/ui/painting/display_list_deferred_image_gpu_impeller.h index 664818da8a0fc..bad93600cd395 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_impeller.h +++ b/lib/ui/painting/display_list_deferred_image_gpu_impeller.h @@ -18,7 +18,7 @@ namespace flutter { class DlDeferredImageGPUImpeller final : public DlImage { public: static sk_sp Make( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner); @@ -71,7 +71,7 @@ class DlDeferredImageGPUImpeller final : public DlImage { fml::RefPtr raster_task_runner); static std::shared_ptr Make( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner); @@ -107,7 +107,7 @@ class DlDeferredImageGPUImpeller final : public DlImage { // thread task spwaned by this method. After being flattened into a display // list, the image wrapper will be updated to hold this display list and the // layer tree can be dropped. - void SnapshotDisplayList(std::shared_ptr layer_tree = nullptr); + void SnapshotDisplayList(std::unique_ptr layer_tree = nullptr); // |ContextListener| void OnGrContextCreated() override; diff --git a/lib/ui/painting/display_list_deferred_image_gpu_skia.cc b/lib/ui/painting/display_list_deferred_image_gpu_skia.cc index a2bb4c0b94cda..0cec39c737a5d 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_skia.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu_skia.cc @@ -4,6 +4,7 @@ #include "flutter/lib/ui/painting/display_list_deferred_image_gpu_skia.h" +#include "flutter/fml/make_copyable.h" #include "third_party/skia/include/core/SkColorSpace.h" #include "third_party/skia/include/core/SkImage.h" #include "third_party/skia/include/gpu/ganesh/SkImageGanesh.h" @@ -25,7 +26,7 @@ sk_sp DlDeferredImageGPUSkia::Make( sk_sp DlDeferredImageGPUSkia::MakeFromLayerTree( const SkImageInfo& image_info, - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, const fml::RefPtr& raster_task_runner, fml::RefPtr unref_queue) { @@ -114,7 +115,7 @@ DlDeferredImageGPUSkia::ImageWrapper::Make( std::shared_ptr DlDeferredImageGPUSkia::ImageWrapper::MakeFromLayerTree( const SkImageInfo& image_info, - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { @@ -164,10 +165,11 @@ bool DlDeferredImageGPUSkia::ImageWrapper::isTextureBacked() const { } void DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList( - std::shared_ptr layer_tree) { + std::unique_ptr layer_tree) { fml::TaskRunner::RunNowOrPostTask( raster_task_runner_, - [weak_this = weak_from_this(), layer_tree = std::move(layer_tree)]() { + fml::MakeCopyable([weak_this = weak_from_this(), + layer_tree = std::move(layer_tree)]() mutable { auto wrapper = weak_this.lock(); if (!wrapper) { return; @@ -199,7 +201,7 @@ void DlDeferredImageGPUSkia::ImageWrapper::SnapshotDisplayList( std::scoped_lock lock(wrapper->error_mutex_); wrapper->error_ = result->error; } - }); + })); } std::optional DlDeferredImageGPUSkia::ImageWrapper::get_error() { diff --git a/lib/ui/painting/display_list_deferred_image_gpu_skia.h b/lib/ui/painting/display_list_deferred_image_gpu_skia.h index 2d6c9b53c5cf9..4e3558fbe9348 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_skia.h +++ b/lib/ui/painting/display_list_deferred_image_gpu_skia.h @@ -30,7 +30,7 @@ class DlDeferredImageGPUSkia final : public DlImage { static sk_sp MakeFromLayerTree( const SkImageInfo& image_info, - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, const fml::RefPtr& raster_task_runner, fml::RefPtr unref_queue); @@ -85,7 +85,7 @@ class DlDeferredImageGPUSkia final : public DlImage { static std::shared_ptr MakeFromLayerTree( const SkImageInfo& image_info, - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue); @@ -125,7 +125,7 @@ class DlDeferredImageGPUSkia final : public DlImage { // thread task spwaned by this method. After being flattened into a display // list, the image wrapper will be updated to hold this display list and the // layer tree can be dropped. - void SnapshotDisplayList(std::shared_ptr layer_tree = nullptr); + void SnapshotDisplayList(std::unique_ptr layer_tree = nullptr); // |ContextListener| void OnGrContextCreated() override; diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 53a9371277555..47318f7bb74f8 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -118,24 +118,24 @@ Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { - return RasterizeToImage(display_list, nullptr, width, height, - raw_image_callback); + return DoRasterizeToImage(display_list, nullptr, width, height, + raw_image_callback); } Dart_Handle Picture::RasterizeLayerTreeToImage( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { - return RasterizeToImage(nullptr, std::move(layer_tree), width, height, - raw_image_callback); + return DoRasterizeToImage(nullptr, std::move(layer_tree), width, height, + raw_image_callback); } -Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, - std::shared_ptr layer_tree, - uint32_t width, - uint32_t height, - Dart_Handle raw_image_callback) { +Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, + std::unique_ptr layer_tree, + uint32_t width, + uint32_t height, + Dart_Handle raw_image_callback) { if (Dart_IsNull(raw_image_callback) || !Dart_IsClosure(raw_image_callback)) { return tonic::ToDart("Image callback was invalid"); } @@ -198,8 +198,9 @@ Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, // Kick things off on the raster rask runner. fml::TaskRunner::RunNowOrPostTask( raster_task_runner, - [ui_task_runner, snapshot_delegate, display_list, picture_bounds, ui_task, - layer_tree = std::move(layer_tree)] { + fml::MakeCopyable([ui_task_runner, snapshot_delegate, display_list, + picture_bounds, ui_task, + layer_tree = std::move(layer_tree)]() mutable { sk_sp image; if (layer_tree) { auto display_list = layer_tree->Flatten( @@ -216,7 +217,7 @@ Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, fml::TaskRunner::RunNowOrPostTask( ui_task_runner, [ui_task, image]() { ui_task(image); }); - }); + })); return Dart_Null(); } diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index d0c2a0123fa1d..df8c17e6113f1 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -49,7 +49,7 @@ class Picture : public RefCountedDartWrappable { Dart_Handle raw_image_callback); static Dart_Handle RasterizeLayerTreeToImage( - std::shared_ptr layer_tree, + std::unique_ptr layer_tree, uint32_t width, uint32_t height, Dart_Handle raw_image_callback); @@ -57,11 +57,11 @@ class Picture : public RefCountedDartWrappable { // Callers may provide either a display list or a layer tree. If a layer tree // is provided, it will be flattened on the raster thread. In this case the // display list will be ignored. - static Dart_Handle RasterizeToImage(const sk_sp& display_list, - std::shared_ptr layer_tree, - uint32_t width, - uint32_t height, - Dart_Handle raw_image_callback); + static Dart_Handle DoRasterizeToImage(const sk_sp& display_list, + std::unique_ptr layer_tree, + uint32_t width, + uint32_t height, + Dart_Handle raw_image_callback); private: explicit Picture(sk_sp display_list); diff --git a/runtime/runtime_delegate.h b/runtime/runtime_delegate.h index 0fbb43391e113..6724085515abd 100644 --- a/runtime/runtime_delegate.h +++ b/runtime/runtime_delegate.h @@ -27,7 +27,7 @@ class RuntimeDelegate { virtual void ScheduleFrame(bool regenerate_layer_tree = true) = 0; - virtual void Render(std::shared_ptr layer_tree) = 0; + virtual void Render(std::unique_ptr layer_tree) = 0; virtual void UpdateSemantics(SemanticsNodeUpdates update, CustomAccessibilityActionUpdates actions) = 0; diff --git a/shell/common/animator.cc b/shell/common/animator.cc index 0b969c2ccbc0b..83498bc1535ba 100644 --- a/shell/common/animator.cc +++ b/shell/common/animator.cc @@ -128,7 +128,7 @@ void Animator::BeginFrame( } } -void Animator::Render(std::shared_ptr layer_tree) { +void Animator::Render(std::unique_ptr layer_tree) { has_rendered_ = true; last_layer_tree_size_ = layer_tree->frame_size(); diff --git a/shell/common/animator.h b/shell/common/animator.h index dfacb4a786bf3..c96a0f5536abb 100644 --- a/shell/common/animator.h +++ b/shell/common/animator.h @@ -54,7 +54,7 @@ class Animator final { void RequestFrame(bool regenerate_layer_tree = true); - void Render(std::shared_ptr layer_tree); + void Render(std::unique_ptr layer_tree); const std::weak_ptr GetVsyncWaiter() const; diff --git a/shell/common/animator_unittests.cc b/shell/common/animator_unittests.cc index 05c728c57ae16..b37de4fa0ccd5 100644 --- a/shell/common/animator_unittests.cc +++ b/shell/common/animator_unittests.cc @@ -155,8 +155,8 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyIdleBeforeRender) { task_runners.GetUITaskRunner()->PostDelayedTask( [&] { ASSERT_FALSE(delegate.notify_idle_called_); - auto layer_tree = - std::make_shared(SkISize::Make(600, 800), 1.0); + auto layer_tree = std::make_unique( + LayerTree::Config(), SkISize::Make(600, 800), 1.0); animator->Render(std::move(layer_tree)); task_runners.GetPlatformTaskRunner()->PostTask(flush_vsync_task); }, @@ -238,8 +238,8 @@ TEST_F(ShellTest, AnimatorDoesNotNotifyDelegateIfPipelineIsNotEmpty) { begin_frame_latch.Wait(); PostTaskSync(task_runners.GetUITaskRunner(), [&] { - auto layer_tree = - std::make_shared(SkISize::Make(600, 800), 1.0); + auto layer_tree = std::make_unique( + LayerTree::Config(), SkISize::Make(600, 800), 1.0); animator->Render(std::move(layer_tree)); }); } diff --git a/shell/common/engine.cc b/shell/common/engine.cc index 522ee89a52a7b..3e3613cef02e5 100644 --- a/shell/common/engine.cc +++ b/shell/common/engine.cc @@ -450,7 +450,7 @@ void Engine::ScheduleFrame(bool regenerate_layer_tree) { animator_->RequestFrame(regenerate_layer_tree); } -void Engine::Render(std::shared_ptr layer_tree) { +void Engine::Render(std::unique_ptr layer_tree) { if (!layer_tree) { return; } diff --git a/shell/common/engine.h b/shell/common/engine.h index c6ff37eae37a5..2b43b11932286 100644 --- a/shell/common/engine.h +++ b/shell/common/engine.h @@ -895,7 +895,7 @@ class Engine final : public RuntimeDelegate, PointerDataDispatcher::Delegate { std::string DefaultRouteName() override; // |RuntimeDelegate| - void Render(std::shared_ptr layer_tree) override; + void Render(std::unique_ptr layer_tree) override; // |RuntimeDelegate| void UpdateSemantics(SemanticsNodeUpdates update, diff --git a/shell/common/engine_unittests.cc b/shell/common/engine_unittests.cc index 3bfdd000c37eb..c2b2dccb9948b 100644 --- a/shell/common/engine_unittests.cc +++ b/shell/common/engine_unittests.cc @@ -51,7 +51,7 @@ class MockRuntimeDelegate : public RuntimeDelegate { MOCK_METHOD0(ImplicitViewEnabled, bool()); MOCK_METHOD0(DefaultRouteName, std::string()); MOCK_METHOD1(ScheduleFrame, void(bool)); - MOCK_METHOD1(Render, void(std::shared_ptr)); + MOCK_METHOD1(Render, void(std::unique_ptr)); MOCK_METHOD2(UpdateSemantics, void(SemanticsNodeUpdates, CustomAccessibilityActionUpdates)); MOCK_METHOD1(HandlePlatformMessage, void(std::unique_ptr)); diff --git a/shell/common/pipeline.h b/shell/common/pipeline.h index 1de4498e7f08c..df0acc6479a33 100644 --- a/shell/common/pipeline.h +++ b/shell/common/pipeline.h @@ -252,11 +252,11 @@ class Pipeline { }; struct LayerTreeItem { - LayerTreeItem(std::shared_ptr layer_tree, + LayerTreeItem(std::unique_ptr layer_tree, std::unique_ptr frame_timings_recorder) : layer_tree(std::move(layer_tree)), frame_timings_recorder(std::move(frame_timings_recorder)) {} - std::shared_ptr layer_tree; + std::unique_ptr layer_tree; std::unique_ptr frame_timings_recorder; }; diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 3b01c5c9bb0a9..3326a7dc6e547 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -195,7 +195,7 @@ RasterStatus Rasterizer::Draw( RasterStatus raster_status = RasterStatus::kFailed; LayerTreePipeline::Consumer consumer = [&](std::unique_ptr item) { - std::shared_ptr layer_tree = std::move(item->layer_tree); + std::unique_ptr layer_tree = std::move(item->layer_tree); std::unique_ptr frame_timings_recorder = std::move(item->frame_timings_recorder); if (discard_callback(*layer_tree.get())) { @@ -375,7 +375,7 @@ fml::Milliseconds Rasterizer::GetFrameBudget() const { RasterStatus Rasterizer::DoDraw( std::unique_ptr frame_timings_recorder, - std::shared_ptr layer_tree) { + std::unique_ptr layer_tree) { TRACE_EVENT_WITH_FRAME_NUMBER(frame_timings_recorder, "flutter", "Rasterizer::DoDraw"); FML_DCHECK(delegate_.GetTaskRunners() diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 23227f5d67618..fbb9386b19c3a 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -556,7 +556,7 @@ class Rasterizer final : public SnapshotDelegate, RasterStatus DoDraw( std::unique_ptr frame_timings_recorder, - std::shared_ptr layer_tree); + std::unique_ptr layer_tree); RasterStatus DrawToSurface(FrameTimingsRecorder& frame_timings_recorder, flutter::LayerTree& layer_tree); @@ -576,11 +576,11 @@ class Rasterizer final : public SnapshotDelegate, std::unique_ptr snapshot_surface_producer_; std::unique_ptr compositor_context_; // This is the last successfully rasterized layer tree. - std::shared_ptr last_layer_tree_; + std::unique_ptr last_layer_tree_; // Set when we need attempt to rasterize the layer tree again. This layer_tree // has not successfully rasterized. This can happen due to the change in the // thread configuration. This will be inserted to the front of the pipeline. - std::shared_ptr resubmitted_layer_tree_; + std::unique_ptr resubmitted_layer_tree_; std::unique_ptr resubmitted_recorder_; fml::closure next_frame_callback_; bool user_override_resource_cache_bytes_; diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 6ab77b53401ba..c9d9edc6bb707 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -185,8 +185,10 @@ TEST(RasterizerTest, fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = + std::make_unique(/*config=*/LayerTree::Config(), + /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -250,8 +252,9 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -321,7 +324,8 @@ TEST( rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), + auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), + /*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -395,7 +399,8 @@ TEST(RasterizerTest, rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), + auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), + /*frame_size=*/SkISize(), /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); @@ -444,8 +449,9 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -499,8 +505,9 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -601,8 +608,9 @@ TEST(RasterizerTest, fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -658,8 +666,9 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -715,8 +724,9 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -771,8 +781,9 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -826,8 +837,9 @@ TEST( fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder()); PipelineProduceResult result = @@ -904,9 +916,9 @@ TEST(RasterizerTest, rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { - auto layer_tree = - std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i])); PipelineProduceResult result = @@ -1075,9 +1087,9 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { - auto layer_tree = - std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder(timestamps[i])); PipelineProduceResult result = @@ -1155,8 +1167,9 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_shared(/*frame_size=*/SkISize(), - /*device_pixel_ratio=*/2.0f); + auto layer_tree = std::make_unique( + /*config=*/LayerTree::Config(), /*frame_size=*/SkISize(), + /*device_pixel_ratio=*/2.0f); auto layer_tree_item = std::make_unique( std::move(layer_tree), CreateFinishedBuildRecorder(first_timestamp)); PipelineProduceResult result = diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index a799e6bcb4811..215919ef82ae7 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -197,14 +197,14 @@ void ShellTest::PumpOneFrame(Shell* shell, fml::WeakPtr runtime_delegate = shell->weak_engine_; shell->GetTaskRunners().GetUITaskRunner()->PostTask( [&latch, runtime_delegate, &builder, viewport_metrics]() { - auto layer_tree = std::make_shared( - SkISize::Make(viewport_metrics.physical_width, - viewport_metrics.physical_height), - static_cast(viewport_metrics.device_pixel_ratio)); SkMatrix identity; identity.setIdentity(); auto root_layer = std::make_shared(identity); - layer_tree->set_root_layer(root_layer); + auto layer_tree = std::make_unique( + LayerTree::Config{.root_layer = root_layer}, + SkISize::Make(viewport_metrics.physical_width, + viewport_metrics.physical_height), + static_cast(viewport_metrics.device_pixel_ratio)); if (builder) { builder(root_layer); } From 474b357f8c45b9611e31969ddcc4f6f49d2c78e6 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 16:23:27 -0700 Subject: [PATCH 081/142] Let takeLayerTree remove config for now --- lib/ui/compositing/scene.cc | 11 +++++++++-- lib/ui/compositing/scene.h | 1 - 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index f85397ac881b5..77f4dc4a0f1b1 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -137,13 +137,20 @@ void Scene::RasterizeToImage(uint32_t width, } std::unique_ptr Scene::takeLayerTree() { - return BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); + if (layer_tree_config_ != nullptr) { + auto layer_tree = BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); + // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test it. + // Let's keep it this way for now. + layer_tree_config_.reset(); + return layer_tree; + } else { + return nullptr; + } } std::unique_ptr Scene::BuildLayerTree(uint32_t width, uint32_t height, float pixel_ratio) { - FML_CHECK(layer_tree_config_ != nullptr); return std::make_unique(*layer_tree_config_, SkISize::Make(width, height), pixel_ratio); } diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index e8b8c0cf0d2ff..4f8c240d6c447 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -52,7 +52,6 @@ class Scene : public RefCountedDartWrappable { uint32_t height, float pixel_ratio); - // No longer valid after calling `takeLayerTreeConfig`. std::unique_ptr layer_tree_config_; float device_pixel_ratio_; uint32_t device_width_; From 39a3a0927ea9a38692c99f9e30d3e1cec948d1f3 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 16:23:55 -0700 Subject: [PATCH 082/142] Format --- lib/ui/compositing/scene.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 77f4dc4a0f1b1..084b4ea5f03f5 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -138,9 +138,10 @@ void Scene::RasterizeToImage(uint32_t width, std::unique_ptr Scene::takeLayerTree() { if (layer_tree_config_ != nullptr) { - auto layer_tree = BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); - // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test it. - // Let's keep it this way for now. + auto layer_tree = + BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); + // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test + // it. Let's keep it this way for now. layer_tree_config_.reset(); return layer_tree; } else { From ba4b01adf913dfa32273038e1e1863261b5807e2 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 16:46:55 -0700 Subject: [PATCH 083/142] lint --- flow/layers/layer_tree_unittests.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow/layers/layer_tree_unittests.cc b/flow/layers/layer_tree_unittests.cc index 47673b8eb764b..6d45d39bdefbb 100644 --- a/flow/layers/layer_tree_unittests.cc +++ b/flow/layers/layer_tree_unittests.cc @@ -33,7 +33,7 @@ class LayerTreeTest : public CanvasTest { CompositorContext::ScopedFrame& frame() { return *scoped_frame_.get(); } const SkMatrix& root_transform() { return root_transform_; } - std::unique_ptr BuildLayerTree(LayerTree::Config config) { + std::unique_ptr BuildLayerTree(const LayerTree::Config& config) { return std::make_unique(config, SkISize::Make(64, 64), 1.0f); } From c8bd69b1be2a9f25866cc377fccaf2498f681e14 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 17:15:58 -0700 Subject: [PATCH 084/142] Compute layer tree size in RuntimeConfiguration --- lib/ui/compositing/scene.cc | 16 +++++++--------- lib/ui/compositing/scene.h | 5 ++--- lib/ui/compositing/scene_builder_unittests.cc | 2 +- runtime/runtime_controller.cc | 11 ++++++++++- 4 files changed, 20 insertions(+), 14 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 084b4ea5f03f5..b7e71fe66ebc2 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -45,8 +45,6 @@ Scene::Scene(std::shared_ptr rootLayer, ->platform_configuration() ->get_window(0) ->viewport_metrics(); - device_width_ = viewport_metrics.physical_width; - device_height_ = viewport_metrics.physical_height; device_pixel_ratio_ = static_cast(viewport_metrics.device_pixel_ratio); layer_tree_config_ = std::make_unique(); @@ -88,8 +86,8 @@ Dart_Handle Scene::toImage(uint32_t width, } return Picture::RasterizeLayerTreeToImage( - BuildLayerTree(device_width_, device_height_, device_pixel_ratio_), width, - height, raw_image_callback); + BuildLayerTree(width, height, device_pixel_ratio_), width, height, + raw_image_callback); } static sk_sp CreateDeferredImage( @@ -129,17 +127,17 @@ void Scene::RasterizeToImage(uint32_t width, auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( dart_state->IsImpellerEnabled(), - BuildLayerTree(device_width_, device_height_, device_pixel_ratio_), width, - height, std::move(snapshot_delegate), std::move(raster_task_runner), + BuildLayerTree(width, height, device_pixel_ratio_), width, height, + std::move(snapshot_delegate), std::move(raster_task_runner), std::move(unref_queue)); image->set_image(dl_image); image->AssociateWithDartWrapper(raw_image_handle); } -std::unique_ptr Scene::takeLayerTree() { +std::unique_ptr Scene::takeLayerTree(uint64_t width, + uint64_t height) { if (layer_tree_config_ != nullptr) { - auto layer_tree = - BuildLayerTree(device_width_, device_height_, device_pixel_ratio_); + auto layer_tree = BuildLayerTree(width, height, device_pixel_ratio_); // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test // it. Let's keep it this way for now. layer_tree_config_.reset(); diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index 4f8c240d6c447..5c9bf791135f8 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -26,7 +26,8 @@ class Scene : public RefCountedDartWrappable { bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); - std::unique_ptr takeLayerTree(); + std::unique_ptr takeLayerTree(uint64_t width, + uint64_t height); Dart_Handle toImageSync(uint32_t width, uint32_t height, @@ -54,8 +55,6 @@ class Scene : public RefCountedDartWrappable { std::unique_ptr layer_tree_config_; float device_pixel_ratio_; - uint32_t device_width_; - uint32_t device_height_; }; } // namespace flutter diff --git a/lib/ui/compositing/scene_builder_unittests.cc b/lib/ui/compositing/scene_builder_unittests.cc index 41efcdc64efd5..702d83bf61417 100644 --- a/lib/ui/compositing/scene_builder_unittests.cc +++ b/lib/ui/compositing/scene_builder_unittests.cc @@ -59,7 +59,7 @@ TEST_F(ShellTest, SceneBuilderBuildAndSceneDisposeReleasesLayerStack) { auto validate_scene_has_no_layers = [message_latch, &retained_scene](Dart_NativeArguments args) { - EXPECT_FALSE(retained_scene->takeLayerTree()); + EXPECT_FALSE(retained_scene->takeLayerTree(100, 100)); retained_scene->Release(); retained_scene = nullptr; message_latch->Signal(); diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 97664325fe4a0..50417a52ce797 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -316,7 +316,16 @@ void RuntimeController::ScheduleFrame() { // |PlatformConfigurationClient| void RuntimeController::Render(Scene* scene) { - client_.Render(scene->takeLayerTree()); + // TODO(dkwingsmt): Currently only supports a single window. + int64_t view_id = 0ll; + auto window = + UIDartState::Current()->platform_configuration()->get_window(view_id); + if (window == nullptr) { + return; + } + const auto& viewport_metrics = window->viewport_metrics(); + client_.Render(scene->takeLayerTree(viewport_metrics.physical_width, + viewport_metrics.physical_height)); } // |PlatformConfigurationClient| From 6a03556ddfa86305381f3b5b70ad061a4a63ea77 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 17:58:11 -0700 Subject: [PATCH 085/142] Resolve toImageSync --- lib/ui/compositing/scene.cc | 16 ++++++++-------- .../display_list_deferred_image_gpu_impeller.cc | 10 ++++------ .../display_list_deferred_image_gpu_impeller.h | 2 -- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index b7e71fe66ebc2..7d7bc4dd5acba 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -93,21 +93,21 @@ Dart_Handle Scene::toImage(uint32_t width, static sk_sp CreateDeferredImage( bool impeller, std::unique_ptr layer_tree, - uint32_t width, - uint32_t height, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner, fml::RefPtr unref_queue) { #if IMPELLER_SUPPORTS_RENDERING if (impeller) { - return DlDeferredImageGPUImpeller::Make( - std::move(layer_tree), SkISize::Make(width, height), - std::move(snapshot_delegate), std::move(raster_task_runner)); + return DlDeferredImageGPUImpeller::Make(std::move(layer_tree), + std::move(snapshot_delegate), + std::move(raster_task_runner)); } #endif // IMPELLER_SUPPORTS_RENDERING - const SkImageInfo image_info = SkImageInfo::Make( - width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType); + const auto& frame_size = layer_tree->frame_size(); + const SkImageInfo image_info = + SkImageInfo::Make(frame_size.width(), frame_size.height(), + kRGBA_8888_SkColorType, kPremul_SkAlphaType); return DlDeferredImageGPUSkia::MakeFromLayerTree( image_info, std::move(layer_tree), std::move(snapshot_delegate), raster_task_runner, std::move(unref_queue)); @@ -127,7 +127,7 @@ void Scene::RasterizeToImage(uint32_t width, auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( dart_state->IsImpellerEnabled(), - BuildLayerTree(width, height, device_pixel_ratio_), width, height, + BuildLayerTree(width, height, device_pixel_ratio_), std::move(snapshot_delegate), std::move(raster_task_runner), std::move(unref_queue)); image->set_image(dl_image); diff --git a/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc b/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc index ffe33c079ebaa..0c2a7de57cca4 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc +++ b/lib/ui/painting/display_list_deferred_image_gpu_impeller.cc @@ -12,12 +12,11 @@ namespace flutter { sk_sp DlDeferredImageGPUImpeller::Make( std::unique_ptr layer_tree, - const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner) { return sk_sp(new DlDeferredImageGPUImpeller( DlDeferredImageGPUImpeller::ImageWrapper::Make( - std::move(layer_tree), size, std::move(snapshot_delegate), + std::move(layer_tree), std::move(snapshot_delegate), std::move(raster_task_runner)))); } @@ -108,12 +107,11 @@ DlDeferredImageGPUImpeller::ImageWrapper::Make( std::shared_ptr DlDeferredImageGPUImpeller::ImageWrapper::Make( std::unique_ptr layer_tree, - const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner) { - auto wrapper = std::shared_ptr( - new ImageWrapper(nullptr, size, std::move(snapshot_delegate), - std::move(raster_task_runner))); + auto wrapper = std::shared_ptr(new ImageWrapper( + nullptr, layer_tree->frame_size(), std::move(snapshot_delegate), + std::move(raster_task_runner))); wrapper->SnapshotDisplayList(std::move(layer_tree)); return wrapper; } diff --git a/lib/ui/painting/display_list_deferred_image_gpu_impeller.h b/lib/ui/painting/display_list_deferred_image_gpu_impeller.h index bad93600cd395..7bcb27922423e 100644 --- a/lib/ui/painting/display_list_deferred_image_gpu_impeller.h +++ b/lib/ui/painting/display_list_deferred_image_gpu_impeller.h @@ -19,7 +19,6 @@ class DlDeferredImageGPUImpeller final : public DlImage { public: static sk_sp Make( std::unique_ptr layer_tree, - const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner); @@ -72,7 +71,6 @@ class DlDeferredImageGPUImpeller final : public DlImage { static std::shared_ptr Make( std::unique_ptr layer_tree, - const SkISize& size, fml::TaskRunnerAffineWeakPtr snapshot_delegate, fml::RefPtr raster_task_runner); From 30b95c67683d07d3f53bcf4489a7dd0fab2b244f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 18:55:51 -0700 Subject: [PATCH 086/142] Convert toImage --- lib/ui/compositing/scene.cc | 3 +-- lib/ui/painting/picture.cc | 7 +++---- lib/ui/painting/picture.h | 2 -- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 7d7bc4dd5acba..3dfffc0e6d0dc 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -86,8 +86,7 @@ Dart_Handle Scene::toImage(uint32_t width, } return Picture::RasterizeLayerTreeToImage( - BuildLayerTree(width, height, device_pixel_ratio_), width, height, - raw_image_callback); + BuildLayerTree(width, height, device_pixel_ratio_), raw_image_callback); } static sk_sp CreateDeferredImage( diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 47318f7bb74f8..c8cf17c9c511e 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -124,11 +124,10 @@ Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, Dart_Handle Picture::RasterizeLayerTreeToImage( std::unique_ptr layer_tree, - uint32_t width, - uint32_t height, Dart_Handle raw_image_callback) { - return DoRasterizeToImage(nullptr, std::move(layer_tree), width, height, - raw_image_callback); + auto frame_size = layer_tree->frame_size(); + return DoRasterizeToImage(nullptr, std::move(layer_tree), frame_size.width(), + frame_size.height(), raw_image_callback); } Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index df8c17e6113f1..14934eecded6a 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -50,8 +50,6 @@ class Picture : public RefCountedDartWrappable { static Dart_Handle RasterizeLayerTreeToImage( std::unique_ptr layer_tree, - uint32_t width, - uint32_t height, Dart_Handle raw_image_callback); // Callers may provide either a display list or a layer tree. If a layer tree From ae2c065b2266be09b43937ae55689a51c1dc827a Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 27 Apr 2023 20:51:14 -0700 Subject: [PATCH 087/142] Right before dart_ui.cc --- lib/ui/compositing/scene.cc | 27 +++++++++---------- lib/ui/compositing/scene.h | 6 +++-- lib/ui/compositing/scene_builder_unittests.cc | 2 +- lib/ui/painting/picture.cc | 7 ++++- lib/ui/painting/picture.h | 7 ++--- runtime/runtime_controller.cc | 3 ++- 6 files changed, 30 insertions(+), 22 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 3dfffc0e6d0dc..6424e1b1eb237 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -40,13 +40,6 @@ Scene::Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { - // Currently only supports a single window. - auto viewport_metrics = UIDartState::Current() - ->platform_configuration() - ->get_window(0) - ->viewport_metrics(); - device_pixel_ratio_ = static_cast(viewport_metrics.device_pixel_ratio); - layer_tree_config_ = std::make_unique(); layer_tree_config_->root_layer = std::move(rootLayer); layer_tree_config_->rasterizer_tracing_threshold = rasterizerTracingThreshold; @@ -67,12 +60,14 @@ Dart_Handle Scene::toImageSync(uint32_t width, uint32_t height, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); + double pixel_ratio = 1.0f; // TODO(dkwingsmt) if (!layer_tree_config_) { return tonic::ToDart("Scene's layer tree has been taken away."); } - Scene::RasterizeToImage(width, height, raw_image_handle); + Scene::RasterizeToImage(width, height, static_cast(pixel_ratio), + raw_image_handle); return Dart_Null(); } @@ -80,13 +75,15 @@ Dart_Handle Scene::toImage(uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); + double pixel_ratio = 1.0f; // TODO(dkwingsmt) if (!layer_tree_config_) { return tonic::ToDart("Scene's layer tree has been taken away."); } return Picture::RasterizeLayerTreeToImage( - BuildLayerTree(width, height, device_pixel_ratio_), raw_image_callback); + BuildLayerTree(width, height, static_cast(pixel_ratio)), + raw_image_callback); } static sk_sp CreateDeferredImage( @@ -114,6 +111,7 @@ static sk_sp CreateDeferredImage( void Scene::RasterizeToImage(uint32_t width, uint32_t height, + float pixel_ratio, Dart_Handle raw_image_handle) { auto* dart_state = UIDartState::Current(); if (!dart_state) { @@ -126,17 +124,17 @@ void Scene::RasterizeToImage(uint32_t width, auto image = CanvasImage::Create(); auto dl_image = CreateDeferredImage( dart_state->IsImpellerEnabled(), - BuildLayerTree(width, height, device_pixel_ratio_), - std::move(snapshot_delegate), std::move(raster_task_runner), - std::move(unref_queue)); + BuildLayerTree(width, height, pixel_ratio), std::move(snapshot_delegate), + std::move(raster_task_runner), std::move(unref_queue)); image->set_image(dl_image); image->AssociateWithDartWrapper(raw_image_handle); } std::unique_ptr Scene::takeLayerTree(uint64_t width, - uint64_t height) { + uint64_t height, + float pixel_ratio) { if (layer_tree_config_ != nullptr) { - auto layer_tree = BuildLayerTree(width, height, device_pixel_ratio_); + auto layer_tree = BuildLayerTree(width, height, pixel_ratio); // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test // it. Let's keep it this way for now. layer_tree_config_.reset(); @@ -149,6 +147,7 @@ std::unique_ptr Scene::takeLayerTree(uint64_t width, std::unique_ptr Scene::BuildLayerTree(uint32_t width, uint32_t height, float pixel_ratio) { + FML_CHECK(layer_tree_config_ != nullptr); return std::make_unique(*layer_tree_config_, SkISize::Make(width, height), pixel_ratio); } diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index 5c9bf791135f8..14fecc9a5ec2d 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -27,7 +27,8 @@ class Scene : public RefCountedDartWrappable { bool checkerboardOffscreenLayers); std::unique_ptr takeLayerTree(uint64_t width, - uint64_t height); + uint64_t height, + float pixel_ratio); Dart_Handle toImageSync(uint32_t width, uint32_t height, @@ -47,14 +48,15 @@ class Scene : public RefCountedDartWrappable { void RasterizeToImage(uint32_t width, uint32_t height, + float pixel_ratio, Dart_Handle raw_image_handle); std::unique_ptr BuildLayerTree(uint32_t width, uint32_t height, float pixel_ratio); + // No longer valid after calling `takeLayerTreeConfig`. std::unique_ptr layer_tree_config_; - float device_pixel_ratio_; }; } // namespace flutter diff --git a/lib/ui/compositing/scene_builder_unittests.cc b/lib/ui/compositing/scene_builder_unittests.cc index 702d83bf61417..93060ea6025c8 100644 --- a/lib/ui/compositing/scene_builder_unittests.cc +++ b/lib/ui/compositing/scene_builder_unittests.cc @@ -59,7 +59,7 @@ TEST_F(ShellTest, SceneBuilderBuildAndSceneDisposeReleasesLayerStack) { auto validate_scene_has_no_layers = [message_latch, &retained_scene](Dart_NativeArguments args) { - EXPECT_FALSE(retained_scene->takeLayerTree(100, 100)); + EXPECT_FALSE(retained_scene->takeLayerTree(100, 100, 1.0f)); retained_scene->Release(); retained_scene = nullptr; message_latch->Signal(); diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index c8cf17c9c511e..21104e2e41328 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -125,6 +125,7 @@ Dart_Handle Picture::RasterizeToImage(const sk_sp& display_list, Dart_Handle Picture::RasterizeLayerTreeToImage( std::unique_ptr layer_tree, Dart_Handle raw_image_callback) { + FML_DCHECK(layer_tree != nullptr); auto frame_size = layer_tree->frame_size(); return DoRasterizeToImage(nullptr, std::move(layer_tree), frame_size.width(), frame_size.height(), raw_image_callback); @@ -135,6 +136,9 @@ Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, uint32_t width, uint32_t height, Dart_Handle raw_image_callback) { + // Either display_list or layer_tree should be provided. + FML_DCHECK((display_list == nullptr) != (layer_tree == nullptr)); + if (Dart_IsNull(raw_image_callback) || !Dart_IsClosure(raw_image_callback)) { return tonic::ToDart("Image callback was invalid"); } @@ -198,10 +202,11 @@ Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, fml::TaskRunner::RunNowOrPostTask( raster_task_runner, fml::MakeCopyable([ui_task_runner, snapshot_delegate, display_list, - picture_bounds, ui_task, + &picture_bounds, ui_task, layer_tree = std::move(layer_tree)]() mutable { sk_sp image; if (layer_tree) { + FML_DCHECK(picture_bounds == layer_tree->frame_size()); auto display_list = layer_tree->Flatten( SkRect::MakeWH(picture_bounds.width(), picture_bounds.height()), snapshot_delegate->GetTextureRegistry(), diff --git a/lib/ui/painting/picture.h b/lib/ui/painting/picture.h index 14934eecded6a..89c84095336ed 100644 --- a/lib/ui/painting/picture.h +++ b/lib/ui/painting/picture.h @@ -52,9 +52,10 @@ class Picture : public RefCountedDartWrappable { std::unique_ptr layer_tree, Dart_Handle raw_image_callback); - // Callers may provide either a display list or a layer tree. If a layer tree - // is provided, it will be flattened on the raster thread. In this case the - // display list will be ignored. + // Callers may provide either a display list or a layer tree, but not both. + // + // If a layer tree is provided, it will be flattened on the raster thread, and + // picture_bounds should be the layer tree's frame_size(). static Dart_Handle DoRasterizeToImage(const sk_sp& display_list, std::unique_ptr layer_tree, uint32_t width, diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index 50417a52ce797..b53832ecb4bb5 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -325,7 +325,8 @@ void RuntimeController::Render(Scene* scene) { } const auto& viewport_metrics = window->viewport_metrics(); client_.Render(scene->takeLayerTree(viewport_metrics.physical_width, - viewport_metrics.physical_height)); + viewport_metrics.physical_height, + viewport_metrics.device_pixel_ratio)); } // |PlatformConfigurationClient| From d7fa9d67f6408dc075d8c950b86348b755fdf33d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 00:58:10 -0700 Subject: [PATCH 088/142] Fix crash --- lib/ui/painting/picture.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/ui/painting/picture.cc b/lib/ui/painting/picture.cc index 21104e2e41328..74c7b0dc78141 100644 --- a/lib/ui/painting/picture.cc +++ b/lib/ui/painting/picture.cc @@ -160,8 +160,6 @@ Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, // thread owns the sole reference to the layer tree. So we do it in the // raster thread. - auto picture_bounds = SkISize::Make(width, height); - auto ui_task = // The static leak checker gets confused by the use of fml::MakeCopyable. // NOLINTNEXTLINE(clang-analyzer-cplusplus.NewDeleteLeaks) @@ -201,16 +199,17 @@ Dart_Handle Picture::DoRasterizeToImage(const sk_sp& display_list, // Kick things off on the raster rask runner. fml::TaskRunner::RunNowOrPostTask( raster_task_runner, - fml::MakeCopyable([ui_task_runner, snapshot_delegate, display_list, - &picture_bounds, ui_task, + fml::MakeCopyable([ui_task_runner, snapshot_delegate, display_list, width, + height, ui_task, layer_tree = std::move(layer_tree)]() mutable { + auto picture_bounds = SkISize::Make(width, height); sk_sp image; if (layer_tree) { FML_DCHECK(picture_bounds == layer_tree->frame_size()); - auto display_list = layer_tree->Flatten( - SkRect::MakeWH(picture_bounds.width(), picture_bounds.height()), - snapshot_delegate->GetTextureRegistry(), - snapshot_delegate->GetGrContext()); + auto display_list = + layer_tree->Flatten(SkRect::MakeWH(width, height), + snapshot_delegate->GetTextureRegistry(), + snapshot_delegate->GetGrContext()); image = snapshot_delegate->MakeRasterSnapshot(display_list, picture_bounds); From 2ccc86975d839c9ccb7fb6411c035c3aa25a90a0 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 04:10:16 -0700 Subject: [PATCH 089/142] To dart:ui --- lib/ui/compositing.dart | 32 ++++++++++++++++++++++++-------- lib/ui/compositing/scene.cc | 4 ++-- lib/ui/compositing/scene.h | 2 ++ lib/ui/dart_ui.cc | 4 ++-- 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index f20ecff7349c6..e2e0cb11159f1 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -21,21 +21,27 @@ class Scene extends NativeFieldWrapperClass1 { /// Synchronously creates a handle to an image from this scene. /// /// {@macro dart.ui.painting.Picture.toImageSync} - Image toImageSync(int width, int height) { + /// + /// The value of `pixelRatio` does not affect the dimension of the resulting + /// image. Instead, it is used to calculate the device's physical dimension + /// (for example, the device's physical width will be `width` / `pixelRatio`), + /// which is used by some deprecated shapes (see + /// [SceneBuilder.pushPhysicalShape]). This argument defaults to 1.0. + Image toImageSync(int width, int height, [double pixelRatio = 1.0]) { if (width <= 0 || height <= 0) { throw Exception('Invalid image dimensions.'); } final _Image image = _Image._(); - final String? result = _toImageSync(width, height, image); + final String? result = _toImageSync(width, height, pixelRatio, image); if (result != null) { throw PictureRasterizationException._(result); } return Image._(image, image.width, image.height); } - @Native, Uint32, Uint32, Handle)>(symbol: 'Scene::toImageSync') - external String? _toImageSync(int width, int height, _Image outImage); + @Native, Uint32, Uint32, Double, Handle)>(symbol: 'Scene::toImageSync') + external String? _toImageSync(int width, int height, double pixelRatio, _Image outImage); /// Creates a raster image representation of the current state of the scene. /// @@ -44,11 +50,21 @@ class Scene extends NativeFieldWrapperClass1 { /// Callers must dispose the [Image] when they are done with it. If the result /// will be shared with other methods or classes, [Image.clone] should be used /// and each handle created must be disposed. - Future toImage(int width, int height) { + /// + /// The returned image will be `width` pixels wide and `height` pixels high. + /// The picture is rasterized within the 0 (left), 0 (top), `width` (right), + /// `height` (bottom) bounds. Content outside these bounds is clipped. + /// + /// The value of `pixelRatio` does not affect the dimension of the resulting + /// image. Instead, it is used to calculate the device's physical dimension + /// (for example, the device's physical width will be `width` / `pixelRatio`), + /// which is used by some deprecated shapes (see + /// [SceneBuilder.pushPhysicalShape]). This argument defaults to 1.0. + Future toImage(int width, int height, [double pixelRatio = 1.0]) { if (width <= 0 || height <= 0) { throw Exception('Invalid image dimensions.'); } - return _futurize((_Callback callback) => _toImage(width, height, (_Image? image) { + return _futurize((_Callback callback) => _toImage(width, height, pixelRatio, (_Image? image) { if (image == null) { callback(null); } else { @@ -58,8 +74,8 @@ class Scene extends NativeFieldWrapperClass1 { ); } - @Native, Uint32, Uint32, Handle)>(symbol: 'Scene::toImage') - external String? _toImage(int width, int height, _Callback<_Image?> callback); + @Native, Uint32, Uint32, Double, Handle)>(symbol: 'Scene::toImage') + external String? _toImage(int width, int height, double pixelRatio, _Callback<_Image?> callback); /// Releases the resources used by this scene. /// diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index 6424e1b1eb237..f28c00adafedf 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -58,9 +58,9 @@ void Scene::dispose() { Dart_Handle Scene::toImageSync(uint32_t width, uint32_t height, + double pixel_ratio, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); - double pixel_ratio = 1.0f; // TODO(dkwingsmt) if (!layer_tree_config_) { return tonic::ToDart("Scene's layer tree has been taken away."); @@ -73,9 +73,9 @@ Dart_Handle Scene::toImageSync(uint32_t width, Dart_Handle Scene::toImage(uint32_t width, uint32_t height, + double pixel_ratio, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); - double pixel_ratio = 1.0f; // TODO(dkwingsmt) if (!layer_tree_config_) { return tonic::ToDart("Scene's layer tree has been taken away."); diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index 14fecc9a5ec2d..e2494011e7d76 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -32,10 +32,12 @@ class Scene : public RefCountedDartWrappable { Dart_Handle toImageSync(uint32_t width, uint32_t height, + double pixel_ratio, Dart_Handle raw_image_handle); Dart_Handle toImage(uint32_t width, uint32_t height, + double pixel_ratio, Dart_Handle raw_image_handle); void dispose(); diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 57242c11ac9aa..7c6768497c666 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -293,8 +293,8 @@ typedef CanvasPath Path; V(SceneBuilder, setCheckerboardRasterCacheImages, 2) \ V(SceneBuilder, setRasterizerTracingThreshold, 2) \ V(Scene, dispose, 1) \ - V(Scene, toImage, 4) \ - V(Scene, toImageSync, 4) \ + V(Scene, toImage, 5) \ + V(Scene, toImageSync, 5) \ V(SemanticsUpdateBuilder, build, 2) \ V(SemanticsUpdateBuilder, updateCustomAction, 5) \ V(SemanticsUpdateBuilder, updateNode, 36) \ From 99bfd249a01f9ea8f786d125786529475a2bad51 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 12:21:24 -0700 Subject: [PATCH 090/142] config is no longer a ptr --- lib/ui/compositing/scene.cc | 39 +++++++++++++++++-------------------- lib/ui/compositing/scene.h | 6 ++++-- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index f28c00adafedf..ca56375627139 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -40,19 +40,22 @@ Scene::Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { - layer_tree_config_ = std::make_unique(); - layer_tree_config_->root_layer = std::move(rootLayer); - layer_tree_config_->rasterizer_tracing_threshold = rasterizerTracingThreshold; - layer_tree_config_->checkerboard_raster_cache_images = + layer_tree_config_.root_layer = std::move(rootLayer); + layer_tree_config_.rasterizer_tracing_threshold = rasterizerTracingThreshold; + layer_tree_config_.checkerboard_raster_cache_images = checkerboardRasterCacheImages; - layer_tree_config_->checkerboard_offscreen_layers = + layer_tree_config_.checkerboard_offscreen_layers = checkerboardOffscreenLayers; } Scene::~Scene() {} +bool Scene::valid() { + return layer_tree_config_.root_layer != nullptr; +} + void Scene::dispose() { - layer_tree_config_.reset(); + layer_tree_config_.root_layer.reset(); ClearDartWrapper(); } @@ -62,8 +65,8 @@ Dart_Handle Scene::toImageSync(uint32_t width, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); - if (!layer_tree_config_) { - return tonic::ToDart("Scene's layer tree has been taken away."); + if (!valid()) { + return tonic::ToDart("Scene has been disposed."); } Scene::RasterizeToImage(width, height, static_cast(pixel_ratio), @@ -77,8 +80,8 @@ Dart_Handle Scene::toImage(uint32_t width, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); - if (!layer_tree_config_) { - return tonic::ToDart("Scene's layer tree has been taken away."); + if (!valid()) { + return tonic::ToDart("Scene has been disposed."); } return Picture::RasterizeLayerTreeToImage( @@ -133,22 +136,16 @@ void Scene::RasterizeToImage(uint32_t width, std::unique_ptr Scene::takeLayerTree(uint64_t width, uint64_t height, float pixel_ratio) { - if (layer_tree_config_ != nullptr) { - auto layer_tree = BuildLayerTree(width, height, pixel_ratio); - // TODO(dkwingsmt): We don't need to reset here. But certain unit tests test - // it. Let's keep it this way for now. - layer_tree_config_.reset(); - return layer_tree; - } else { - return nullptr; - } + return BuildLayerTree(width, height, pixel_ratio); } std::unique_ptr Scene::BuildLayerTree(uint32_t width, uint32_t height, float pixel_ratio) { - FML_CHECK(layer_tree_config_ != nullptr); - return std::make_unique(*layer_tree_config_, + if (!valid()) { + return nullptr; + } + return std::make_unique(layer_tree_config_, SkISize::Make(width, height), pixel_ratio); } diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index e2494011e7d76..c8b9883de7e40 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -48,6 +48,9 @@ class Scene : public RefCountedDartWrappable { bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers); + // Returns true if `dispose()` has not been called. + bool valid(); + void RasterizeToImage(uint32_t width, uint32_t height, float pixel_ratio, @@ -57,8 +60,7 @@ class Scene : public RefCountedDartWrappable { uint32_t height, float pixel_ratio); - // No longer valid after calling `takeLayerTreeConfig`. - std::unique_ptr layer_tree_config_; + flutter::LayerTree::Config layer_tree_config_; }; } // namespace flutter From 768aa5ef8f4c595dab8cd540564025262dd36397 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 12:56:16 -0700 Subject: [PATCH 091/142] Implicit ratio --- lib/ui/compositing.dart | 32 ++++++++------------------------ lib/ui/compositing/scene.cc | 28 ++++++++++++++++++++++++---- lib/ui/compositing/scene.h | 15 +++++++++++++-- lib/ui/dart_ui.cc | 4 ++-- 4 files changed, 47 insertions(+), 32 deletions(-) diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index e2e0cb11159f1..f20ecff7349c6 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -21,27 +21,21 @@ class Scene extends NativeFieldWrapperClass1 { /// Synchronously creates a handle to an image from this scene. /// /// {@macro dart.ui.painting.Picture.toImageSync} - /// - /// The value of `pixelRatio` does not affect the dimension of the resulting - /// image. Instead, it is used to calculate the device's physical dimension - /// (for example, the device's physical width will be `width` / `pixelRatio`), - /// which is used by some deprecated shapes (see - /// [SceneBuilder.pushPhysicalShape]). This argument defaults to 1.0. - Image toImageSync(int width, int height, [double pixelRatio = 1.0]) { + Image toImageSync(int width, int height) { if (width <= 0 || height <= 0) { throw Exception('Invalid image dimensions.'); } final _Image image = _Image._(); - final String? result = _toImageSync(width, height, pixelRatio, image); + final String? result = _toImageSync(width, height, image); if (result != null) { throw PictureRasterizationException._(result); } return Image._(image, image.width, image.height); } - @Native, Uint32, Uint32, Double, Handle)>(symbol: 'Scene::toImageSync') - external String? _toImageSync(int width, int height, double pixelRatio, _Image outImage); + @Native, Uint32, Uint32, Handle)>(symbol: 'Scene::toImageSync') + external String? _toImageSync(int width, int height, _Image outImage); /// Creates a raster image representation of the current state of the scene. /// @@ -50,21 +44,11 @@ class Scene extends NativeFieldWrapperClass1 { /// Callers must dispose the [Image] when they are done with it. If the result /// will be shared with other methods or classes, [Image.clone] should be used /// and each handle created must be disposed. - /// - /// The returned image will be `width` pixels wide and `height` pixels high. - /// The picture is rasterized within the 0 (left), 0 (top), `width` (right), - /// `height` (bottom) bounds. Content outside these bounds is clipped. - /// - /// The value of `pixelRatio` does not affect the dimension of the resulting - /// image. Instead, it is used to calculate the device's physical dimension - /// (for example, the device's physical width will be `width` / `pixelRatio`), - /// which is used by some deprecated shapes (see - /// [SceneBuilder.pushPhysicalShape]). This argument defaults to 1.0. - Future toImage(int width, int height, [double pixelRatio = 1.0]) { + Future toImage(int width, int height) { if (width <= 0 || height <= 0) { throw Exception('Invalid image dimensions.'); } - return _futurize((_Callback callback) => _toImage(width, height, pixelRatio, (_Image? image) { + return _futurize((_Callback callback) => _toImage(width, height, (_Image? image) { if (image == null) { callback(null); } else { @@ -74,8 +58,8 @@ class Scene extends NativeFieldWrapperClass1 { ); } - @Native, Uint32, Uint32, Double, Handle)>(symbol: 'Scene::toImage') - external String? _toImage(int width, int height, double pixelRatio, _Callback<_Image?> callback); + @Native, Uint32, Uint32, Handle)>(symbol: 'Scene::toImage') + external String? _toImage(int width, int height, _Callback<_Image?> callback); /// Releases the resources used by this scene. /// diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index ca56375627139..cdffbd1211c5f 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -40,6 +40,7 @@ Scene::Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { + initializeDefaultViewPixelRatioIfNecessary(); layer_tree_config_.root_layer = std::move(rootLayer); layer_tree_config_.rasterizer_tracing_threshold = rasterizerTracingThreshold; layer_tree_config_.checkerboard_raster_cache_images = @@ -61,7 +62,6 @@ void Scene::dispose() { Dart_Handle Scene::toImageSync(uint32_t width, uint32_t height, - double pixel_ratio, Dart_Handle raw_image_handle) { TRACE_EVENT0("flutter", "Scene::toImageSync"); @@ -69,14 +69,13 @@ Dart_Handle Scene::toImageSync(uint32_t width, return tonic::ToDart("Scene has been disposed."); } - Scene::RasterizeToImage(width, height, static_cast(pixel_ratio), + Scene::RasterizeToImage(width, height, defaultViewPixelRatio(), raw_image_handle); return Dart_Null(); } Dart_Handle Scene::toImage(uint32_t width, uint32_t height, - double pixel_ratio, Dart_Handle raw_image_callback) { TRACE_EVENT0("flutter", "Scene::toImage"); @@ -85,7 +84,7 @@ Dart_Handle Scene::toImage(uint32_t width, } return Picture::RasterizeLayerTreeToImage( - BuildLayerTree(width, height, static_cast(pixel_ratio)), + BuildLayerTree(width, height, defaultViewPixelRatio()), raw_image_callback); } @@ -149,4 +148,25 @@ std::unique_ptr Scene::BuildLayerTree(uint32_t width, SkISize::Make(width, height), pixel_ratio); } +float Scene::default_view_pixel_ratio_ = -1.0f; + +void Scene::initializeDefaultViewPixelRatioIfNecessary() { + if (default_view_pixel_ratio_ > 0) { + return; + } + auto window = UIDartState::Current()->platform_configuration()->get_window(0); + if (window != nullptr) { + default_view_pixel_ratio_ = + static_cast(window->viewport_metrics().device_pixel_ratio); + } +} + +float Scene::defaultViewPixelRatio() { + if (default_view_pixel_ratio_ > 0) { + return default_view_pixel_ratio_; + } + // A default value. + return 2.0f; +} + } // namespace flutter diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index c8b9883de7e40..5ede01fec0438 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -32,12 +32,10 @@ class Scene : public RefCountedDartWrappable { Dart_Handle toImageSync(uint32_t width, uint32_t height, - double pixel_ratio, Dart_Handle raw_image_handle); Dart_Handle toImage(uint32_t width, uint32_t height, - double pixel_ratio, Dart_Handle raw_image_handle); void dispose(); @@ -61,6 +59,19 @@ class Scene : public RefCountedDartWrappable { float pixel_ratio); flutter::LayerTree::Config layer_tree_config_; + + static void initializeDefaultViewPixelRatioIfNecessary(); + static float defaultViewPixelRatio(); + + // The pixel ratio of window #0. + // + // Pixel ratio is used to render physical shapes (`PhysicalShapeLayer`), + // which have been deprecated. This field is used to keep backward + // compatibility, where physical shapes are drawn with the pixel ratio + // of window #0. Once `PhysicalShapeLayer` is removed as well as + // `{Preroll,Paint}Context.frame_device_pixel_ratio`, we should remove + // this field. + static float default_view_pixel_ratio_; }; } // namespace flutter diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index 7c6768497c666..57242c11ac9aa 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -293,8 +293,8 @@ typedef CanvasPath Path; V(SceneBuilder, setCheckerboardRasterCacheImages, 2) \ V(SceneBuilder, setRasterizerTracingThreshold, 2) \ V(Scene, dispose, 1) \ - V(Scene, toImage, 5) \ - V(Scene, toImageSync, 5) \ + V(Scene, toImage, 4) \ + V(Scene, toImageSync, 4) \ V(SemanticsUpdateBuilder, build, 2) \ V(SemanticsUpdateBuilder, updateCustomAction, 5) \ V(SemanticsUpdateBuilder, updateNode, 36) \ From 332f86aeee4ec7993a954c8a9ae7d6d174f5ea44 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 13:00:11 -0700 Subject: [PATCH 092/142] An easier way --- lib/ui/compositing/scene.cc | 22 +++++----------------- lib/ui/compositing/scene.h | 11 ----------- 2 files changed, 5 insertions(+), 28 deletions(-) diff --git a/lib/ui/compositing/scene.cc b/lib/ui/compositing/scene.cc index cdffbd1211c5f..1e59056be56c2 100644 --- a/lib/ui/compositing/scene.cc +++ b/lib/ui/compositing/scene.cc @@ -23,6 +23,8 @@ namespace flutter { +static constexpr float kFallbackPixelRatio = 2.0f; + IMPLEMENT_WRAPPERTYPEINFO(ui, Scene); void Scene::create(Dart_Handle scene_handle, @@ -40,7 +42,6 @@ Scene::Scene(std::shared_ptr rootLayer, uint32_t rasterizerTracingThreshold, bool checkerboardRasterCacheImages, bool checkerboardOffscreenLayers) { - initializeDefaultViewPixelRatioIfNecessary(); layer_tree_config_.root_layer = std::move(rootLayer); layer_tree_config_.rasterizer_tracing_threshold = rasterizerTracingThreshold; layer_tree_config_.checkerboard_raster_cache_images = @@ -148,25 +149,12 @@ std::unique_ptr Scene::BuildLayerTree(uint32_t width, SkISize::Make(width, height), pixel_ratio); } -float Scene::default_view_pixel_ratio_ = -1.0f; - -void Scene::initializeDefaultViewPixelRatioIfNecessary() { - if (default_view_pixel_ratio_ > 0) { - return; - } +float Scene::defaultViewPixelRatio() { auto window = UIDartState::Current()->platform_configuration()->get_window(0); if (window != nullptr) { - default_view_pixel_ratio_ = - static_cast(window->viewport_metrics().device_pixel_ratio); - } -} - -float Scene::defaultViewPixelRatio() { - if (default_view_pixel_ratio_ > 0) { - return default_view_pixel_ratio_; + return static_cast(window->viewport_metrics().device_pixel_ratio); } - // A default value. - return 2.0f; + return kFallbackPixelRatio; } } // namespace flutter diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index 5ede01fec0438..ac4967b79bd96 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -60,18 +60,7 @@ class Scene : public RefCountedDartWrappable { flutter::LayerTree::Config layer_tree_config_; - static void initializeDefaultViewPixelRatioIfNecessary(); static float defaultViewPixelRatio(); - - // The pixel ratio of window #0. - // - // Pixel ratio is used to render physical shapes (`PhysicalShapeLayer`), - // which have been deprecated. This field is used to keep backward - // compatibility, where physical shapes are drawn with the pixel ratio - // of window #0. Once `PhysicalShapeLayer` is removed as well as - // `{Preroll,Paint}Context.frame_device_pixel_ratio`, we should remove - // this field. - static float default_view_pixel_ratio_; }; } // namespace flutter From c829f37c97e13c38d5f7ba9d2fab81cc59b839a3 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 28 Apr 2023 15:29:44 -0700 Subject: [PATCH 093/142] Add TODO and comment --- lib/ui/compositing/scene.h | 15 +++++++++++++++ runtime/runtime_controller.cc | 4 +++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/lib/ui/compositing/scene.h b/lib/ui/compositing/scene.h index ac4967b79bd96..ed529b27a705a 100644 --- a/lib/ui/compositing/scene.h +++ b/lib/ui/compositing/scene.h @@ -60,6 +60,21 @@ class Scene : public RefCountedDartWrappable { flutter::LayerTree::Config layer_tree_config_; + // Fetches the pixel ratio from view 0, or if the window doesn't exist, + // fallback to 2.0f. + // + // The pixel ratio is used in toImage() and toImageSync(), and its only effect + // is to calculate the device's physical dimension, which is used by some + // physical shapes (see PhysicalShapeLayer). + // + // Physical shapes have been deprecated and should be removed soon. This + // method aims to keep the legacy behavior in single-window Flutter, which + // feeds the toImage and toImageSync with the pixel ratio of the only window. + // + // TODO(dkwingsmt): If PhysicalShapeLayer has been removed as well as + // {Preroll,Paint}Context.frame_device_pixel_ratio, remove this method and its + // related logic. + // https://github.com/flutter/flutter/issues/125720 static float defaultViewPixelRatio(); }; diff --git a/runtime/runtime_controller.cc b/runtime/runtime_controller.cc index b53832ecb4bb5..d85bdaa4326ed 100644 --- a/runtime/runtime_controller.cc +++ b/runtime/runtime_controller.cc @@ -20,6 +20,8 @@ namespace flutter { +const uint64_t kFlutterDefaultViewId = 0llu; + RuntimeController::RuntimeController(RuntimeDelegate& p_client, const TaskRunners& task_runners) : client_(p_client), vm_(nullptr), context_(task_runners) {} @@ -317,7 +319,7 @@ void RuntimeController::ScheduleFrame() { // |PlatformConfigurationClient| void RuntimeController::Render(Scene* scene) { // TODO(dkwingsmt): Currently only supports a single window. - int64_t view_id = 0ll; + int64_t view_id = kFlutterDefaultViewId; auto window = UIDartState::Current()->platform_configuration()->get_window(view_id); if (window == nullptr) { From 1c6d74d7d8b1b53871ce55b618a9bcb571b805d3 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 1 May 2023 13:12:28 -0700 Subject: [PATCH 094/142] Fix compile --- shell/gpu/gpu_studio_gl_impeller.cc | 2 +- shell/gpu/gpu_studio_vulkan_impeller.cc | 2 +- .../android/platform_view_android_jni_impl.cc | 5 +- .../fuchsia/flutter/flatland_platform_view.cc | 49 ++++++++++--------- .../fuchsia/flutter/gfx_platform_view.cc | 46 +++++++++-------- shell/platform/linux/fl_engine.cc | 6 ++- shell/platform/linux/fl_engine_test.cc | 21 ++++---- shell/platform/linux/testing/mock_engine.cc | 1 + .../windows/flutter_windows_engine.cc | 3 +- .../platform/windows/flutter_windows_engine.h | 3 +- .../platform/windows/flutter_windows_view.cc | 6 ++- .../windows/flutter_windows_view_unittests.cc | 2 +- .../platform/windows/testing/test_keyboard.cc | 2 +- 13 files changed, 85 insertions(+), 63 deletions(-) diff --git a/shell/gpu/gpu_studio_gl_impeller.cc b/shell/gpu/gpu_studio_gl_impeller.cc index cae6e498f1e99..1ce359d28f92f 100644 --- a/shell/gpu/gpu_studio_gl_impeller.cc +++ b/shell/gpu/gpu_studio_gl_impeller.cc @@ -5,7 +5,7 @@ #include "flutter/shell/gpu/gpu_studio_gl_impeller.h" #include "flutter/fml/make_copyable.h" -#include "flutter/impeller/display_list/display_list_dispatcher.h" +#include "flutter/impeller/display_list/dl_dispatcher.h" #include "flutter/impeller/renderer/backend/gles/surface_gles.h" #include "flutter/impeller/renderer/renderer.h" diff --git a/shell/gpu/gpu_studio_vulkan_impeller.cc b/shell/gpu/gpu_studio_vulkan_impeller.cc index bc94f8e4a8bf4..7dc5d69d15f7a 100644 --- a/shell/gpu/gpu_studio_vulkan_impeller.cc +++ b/shell/gpu/gpu_studio_vulkan_impeller.cc @@ -5,7 +5,7 @@ #include "flutter/shell/gpu/gpu_studio_vulkan_impeller.h" #include "flutter/fml/make_copyable.h" -#include "flutter/impeller/display_list/display_list_dispatcher.h" +#include "flutter/impeller/display_list/dl_dispatcher.h" #include "flutter/impeller/renderer/renderer.h" #include "impeller/renderer/backend/vulkan/context_vk.h" diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index 031ec1057eb22..69b3bf7697b25 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -37,6 +37,8 @@ namespace flutter { +static constexpr int64_t kFlutterDefaultViewId = 0ll; + static fml::jni::ScopedJavaGlobalRef* g_flutter_callback_info_class = nullptr; @@ -337,7 +339,8 @@ static void SetViewportMetrics(JNIEnv* env, displayFeaturesState, }; - ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics(metrics); + ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics( + kFlutterDefaultViewId, metrics); } static jobject GetBitmap(JNIEnv* env, jobject jcaller, jlong shell_holder) { diff --git a/shell/platform/fuchsia/flutter/flatland_platform_view.cc b/shell/platform/fuchsia/flutter/flatland_platform_view.cc index 2206e3cc642c2..ba213774af070 100644 --- a/shell/platform/fuchsia/flutter/flatland_platform_view.cc +++ b/shell/platform/fuchsia/flutter/flatland_platform_view.cc @@ -8,6 +8,8 @@ namespace flutter_runner { +static constexpr int64_t kFlutterDefaultViewId = 0ll; + FlatlandPlatformView::FlatlandPlatformView( flutter::PlatformView::Delegate& delegate, flutter::TaskRunners task_runners, @@ -85,29 +87,30 @@ void FlatlandPlatformView::OnGetLayout( float pixel_ratio = view_pixel_ratio_ ? *view_pixel_ratio_ : 1.0f; - SetViewportMetrics({ - pixel_ratio, // device_pixel_ratio - std::round(view_logical_size_.value()[0] * - pixel_ratio), // physical_width - std::round(view_logical_size_.value()[1] * - pixel_ratio), // physical_height - 0.0f, // physical_padding_top - 0.0f, // physical_padding_right - 0.0f, // physical_padding_bottom - 0.0f, // physical_padding_left - 0.0f, // physical_view_inset_top - 0.0f, // physical_view_inset_right - 0.0f, // physical_view_inset_bottom - 0.0f, // physical_view_inset_left - 0.0f, // p_physical_system_gesture_inset_top - 0.0f, // p_physical_system_gesture_inset_right - 0.0f, // p_physical_system_gesture_inset_bottom - 0.0f, // p_physical_system_gesture_inset_left, - -1.0, // p_physical_touch_slop, - {}, // p_physical_display_features_bounds - {}, // p_physical_display_features_type - {}, // p_physical_display_features_state - }); + SetViewportMetrics(kFlutterDefaultViewId, + { + pixel_ratio, // device_pixel_ratio + std::round(view_logical_size_.value()[0] * + pixel_ratio), // physical_width + std::round(view_logical_size_.value()[1] * + pixel_ratio), // physical_height + 0.0f, // physical_padding_top + 0.0f, // physical_padding_right + 0.0f, // physical_padding_bottom + 0.0f, // physical_padding_left + 0.0f, // physical_view_inset_top + 0.0f, // physical_view_inset_right + 0.0f, // physical_view_inset_bottom + 0.0f, // physical_view_inset_left + 0.0f, // p_physical_system_gesture_inset_top + 0.0f, // p_physical_system_gesture_inset_right + 0.0f, // p_physical_system_gesture_inset_bottom + 0.0f, // p_physical_system_gesture_inset_left, + -1.0, // p_physical_touch_slop, + {}, // p_physical_display_features_bounds + {}, // p_physical_display_features_type + {}, // p_physical_display_features_state + }); parent_viewport_watcher_->GetLayout( fit::bind_member(this, &FlatlandPlatformView::OnGetLayout)); diff --git a/shell/platform/fuchsia/flutter/gfx_platform_view.cc b/shell/platform/fuchsia/flutter/gfx_platform_view.cc index 1dcb2c2e8c534..12cecee4f85d7 100644 --- a/shell/platform/fuchsia/flutter/gfx_platform_view.cc +++ b/shell/platform/fuchsia/flutter/gfx_platform_view.cc @@ -8,6 +8,8 @@ namespace flutter_runner { +static constexpr int64_t kFlutterDefaultViewId = 0ll; + GfxPlatformView::GfxPlatformView( flutter::PlatformView::Delegate& delegate, flutter::TaskRunners task_runners, @@ -213,27 +215,29 @@ void GfxPlatformView::OnScenicEvent( metrics_changed) { const float pixel_ratio = *view_pixel_ratio_; const std::array logical_size = *view_logical_size_; - SetViewportMetrics({ - pixel_ratio, // device_pixel_ratio - std::round(logical_size[0] * pixel_ratio), // physical_width - std::round(logical_size[1] * pixel_ratio), // physical_height - 0.0f, // physical_padding_top - 0.0f, // physical_padding_right - 0.0f, // physical_padding_bottom - 0.0f, // physical_padding_left - 0.0f, // physical_view_inset_top - 0.0f, // physical_view_inset_right - 0.0f, // physical_view_inset_bottom - 0.0f, // physical_view_inset_left - 0.0f, // p_physical_system_gesture_inset_top - 0.0f, // p_physical_system_gesture_inset_right - 0.0f, // p_physical_system_gesture_inset_bottom - 0.0f, // p_physical_system_gesture_inset_left, - -1.0, // p_physical_touch_slop, - {}, // p_physical_display_features_bounds - {}, // p_physical_display_features_type - {}, // p_physical_display_features_state - }); + SetViewportMetrics( + kFlutterDefaultViewId, + { + pixel_ratio, // device_pixel_ratio + std::round(logical_size[0] * pixel_ratio), // physical_width + std::round(logical_size[1] * pixel_ratio), // physical_height + 0.0f, // physical_padding_top + 0.0f, // physical_padding_right + 0.0f, // physical_padding_bottom + 0.0f, // physical_padding_left + 0.0f, // physical_view_inset_top + 0.0f, // physical_view_inset_right + 0.0f, // physical_view_inset_bottom + 0.0f, // physical_view_inset_left + 0.0f, // p_physical_system_gesture_inset_top + 0.0f, // p_physical_system_gesture_inset_right + 0.0f, // p_physical_system_gesture_inset_bottom + 0.0f, // p_physical_system_gesture_inset_left, + -1.0, // p_physical_touch_slop, + {}, // p_physical_display_features_bounds + {}, // p_physical_display_features_type + {}, // p_physical_display_features_state + }); } } diff --git a/shell/platform/linux/fl_engine.cc b/shell/platform/linux/fl_engine.cc index b8a6a1942dcc7..4d339ab9a0e2d 100644 --- a/shell/platform/linux/fl_engine.cc +++ b/shell/platform/linux/fl_engine.cc @@ -24,6 +24,8 @@ #include "flutter/shell/platform/linux/fl_texture_registrar_private.h" #include "flutter/shell/platform/linux/public/flutter_linux/fl_plugin_registry.h" +static constexpr int64_t kFlutterDefaultViewId = 0ll; + // Unique number associated with platform tasks. static constexpr size_t kPlatformTaskRunnerIdentifier = 1; @@ -732,12 +734,14 @@ void fl_engine_send_window_metrics_event(FlEngine* self, return; } + // TODO(dkwingsmt) + int64_t view_id = kFlutterDefaultViewId; FlutterWindowMetricsEvent event = {}; event.struct_size = sizeof(FlutterWindowMetricsEvent); event.width = width; event.height = height; event.pixel_ratio = pixel_ratio; - self->embedder_api.SendWindowMetricsEvent(self->engine, &event); + self->embedder_api.SendWindowMetricsEvent(self->engine, view_id, &event); } void fl_engine_send_mouse_pointer_event(FlEngine* self, diff --git a/shell/platform/linux/fl_engine_test.cc b/shell/platform/linux/fl_engine_test.cc index a1d6e1d650eaf..d4e0a79466bee 100644 --- a/shell/platform/linux/fl_engine_test.cc +++ b/shell/platform/linux/fl_engine_test.cc @@ -20,16 +20,17 @@ TEST(FlEngineTest, WindowMetrics) { FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine); bool called = false; - embedder_api->SendWindowMetricsEvent = MOCK_ENGINE_PROC( - SendWindowMetricsEvent, - ([&called](auto engine, const FlutterWindowMetricsEvent* event) { - called = true; - EXPECT_EQ(event->width, static_cast(3840)); - EXPECT_EQ(event->height, static_cast(2160)); - EXPECT_EQ(event->pixel_ratio, 2.0); - - return kSuccess; - })); + embedder_api->SendWindowMetricsEvent = + MOCK_ENGINE_PROC(SendWindowMetricsEvent, + ([&called](auto engine, int64_t view_id, + const FlutterWindowMetricsEvent* event) { + called = true; + EXPECT_EQ(event->width, static_cast(3840)); + EXPECT_EQ(event->height, static_cast(2160)); + EXPECT_EQ(event->pixel_ratio, 2.0); + + return kSuccess; + })); g_autoptr(GError) error = nullptr; EXPECT_TRUE(fl_engine_start(engine, &error)); diff --git a/shell/platform/linux/testing/mock_engine.cc b/shell/platform/linux/testing/mock_engine.cc index eac0cb3809cc9..d704aaaf0608a 100644 --- a/shell/platform/linux/testing/mock_engine.cc +++ b/shell/platform/linux/testing/mock_engine.cc @@ -221,6 +221,7 @@ FlutterEngineResult FlutterEngineDeinitialize(FLUTTER_API_SYMBOL(FlutterEngine) FlutterEngineResult FlutterEngineSendWindowMetricsEvent( FLUTTER_API_SYMBOL(FlutterEngine) engine, + int64_t view_id, const FlutterWindowMetricsEvent* event) { EXPECT_TRUE(engine->running); return kSuccess; diff --git a/shell/platform/windows/flutter_windows_engine.cc b/shell/platform/windows/flutter_windows_engine.cc index 39dbe8ea6be05..95b8f8ebe25e8 100644 --- a/shell/platform/windows/flutter_windows_engine.cc +++ b/shell/platform/windows/flutter_windows_engine.cc @@ -462,9 +462,10 @@ void FlutterWindowsEngine::AddPluginRegistrarDestructionCallback( } void FlutterWindowsEngine::SendWindowMetricsEvent( + int64_t view_id, const FlutterWindowMetricsEvent& event) { if (engine_) { - embedder_api_.SendWindowMetricsEvent(engine_, &event); + embedder_api_.SendWindowMetricsEvent(engine_, view_id, &event); } } diff --git a/shell/platform/windows/flutter_windows_engine.h b/shell/platform/windows/flutter_windows_engine.h index 797cc2142da3c..700942bb85bb5 100644 --- a/shell/platform/windows/flutter_windows_engine.h +++ b/shell/platform/windows/flutter_windows_engine.h @@ -153,7 +153,8 @@ class FlutterWindowsEngine { } // Informs the engine that the window metrics have changed. - void SendWindowMetricsEvent(const FlutterWindowMetricsEvent& event); + void SendWindowMetricsEvent(int64_t view_id, + const FlutterWindowMetricsEvent& event); // Informs the engine of an incoming pointer event. void SendPointerEvent(const FlutterPointerEvent& event); diff --git a/shell/platform/windows/flutter_windows_view.cc b/shell/platform/windows/flutter_windows_view.cc index 4107546669a1e..741b4ce04df69 100644 --- a/shell/platform/windows/flutter_windows_view.cc +++ b/shell/platform/windows/flutter_windows_view.cc @@ -15,6 +15,8 @@ namespace flutter { namespace { +static constexpr int64_t kFlutterDefaultViewId = 0ll; + // The maximum duration to block the platform thread for while waiting // for a window resize operation to complete. constexpr std::chrono::milliseconds kWindowResizeTimeout{100}; @@ -268,12 +270,14 @@ void FlutterWindowsView::OnResetImeComposing() { void FlutterWindowsView::SendWindowMetrics(size_t width, size_t height, double dpiScale) const { + // TODO(dkwingsmt) + int64_t view_id = kFlutterDefaultViewId; FlutterWindowMetricsEvent event = {}; event.struct_size = sizeof(event); event.width = width; event.height = height; event.pixel_ratio = dpiScale; - engine_->SendWindowMetricsEvent(event); + engine_->SendWindowMetricsEvent(view_id, event); } void FlutterWindowsView::SendInitialBounds() { diff --git a/shell/platform/windows/flutter_windows_view_unittests.cc b/shell/platform/windows/flutter_windows_view_unittests.cc index 89082dd46cba1..ae24ae3e5c7a0 100644 --- a/shell/platform/windows/flutter_windows_view_unittests.cc +++ b/shell/platform/windows/flutter_windows_view_unittests.cc @@ -739,7 +739,7 @@ TEST(FlutterWindowsViewTest, WindowResizeTests) { fml::AutoResetWaitableEvent metrics_sent_latch; modifier.embedder_api().SendWindowMetricsEvent = MOCK_ENGINE_PROC( SendWindowMetricsEvent, - ([&metrics_sent_latch](auto engine, + ([&metrics_sent_latch](auto engine, int64_t view_id, const FlutterWindowMetricsEvent* event) { metrics_sent_latch.Signal(); return kSuccess; diff --git a/shell/platform/windows/testing/test_keyboard.cc b/shell/platform/windows/testing/test_keyboard.cc index 4d2109a657108..e9140088c38c7 100644 --- a/shell/platform/windows/testing/test_keyboard.cc +++ b/shell/platform/windows/testing/test_keyboard.cc @@ -192,7 +192,7 @@ void MockEmbedderApiForKeyboard( return kSuccess; }; modifier.embedder_api().SendWindowMetricsEvent = - [](auto engine, const FlutterWindowMetricsEvent* event) { + [](auto engine, int64_t view_id, const FlutterWindowMetricsEvent* event) { return kSuccess; }; modifier.embedder_api().Shutdown = [](auto engine) { return kSuccess; }; From aa02906702e426669072be94ad7604c7de459f3b Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 1 May 2023 14:00:02 -0700 Subject: [PATCH 095/142] Fix more --- .../ios/framework/Source/FlutterEngine.mm | 4 +- .../darwin/ios/ios_external_view_embedder.mm | 3 +- .../darwin/ios/ios_surface_metal_impeller.mm | 2 +- .../embedder/tests/embedder_gl_unittests.cc | 273 +++++++++++------- shell/platform/glfw/flutter_glfw.cc | 4 +- 5 files changed, 174 insertions(+), 112 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm index 10b87e099a50b..b7838f5bf1357 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEngine.mm @@ -38,6 +38,8 @@ #import "flutter/shell/platform/darwin/ios/rendering_api_selection.h" #include "flutter/shell/profiling/sampling_profiler.h" +static constexpr int64_t kFlutterDefaultViewId = 0ll; + /// Inheriting ThreadConfigurer and use iOS platform thread API to configure the thread priorities /// Using iOS platform thread API to configure thread priority static void IOSPlatformThreadConfigSetter(const fml::Thread::ThreadConfig& config) { @@ -308,7 +310,7 @@ - (void)updateViewportMetrics:(flutter::ViewportMetrics)viewportMetrics { if (!self.platformView) { return; } - self.platformView->SetViewportMetrics(viewportMetrics); + self.platformView->SetViewportMetrics(kFlutterDefaultViewId, viewportMetrics); } - (void)dispatchPointerDataPacket:(std::unique_ptr)packet { diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.mm b/shell/platform/darwin/ios/ios_external_view_embedder.mm index d93d8cb1ee76d..e0351b8ae74b0 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.mm +++ b/shell/platform/darwin/ios/ios_external_view_embedder.mm @@ -69,7 +69,8 @@ // |ExternalViewEmbedder| void IOSExternalViewEmbedder::SubmitFrame(GrDirectContext* context, - std::unique_ptr frame) { + std::unique_ptr frame, + int64_t window_view_id) { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::SubmitFrame"); FML_CHECK(platform_views_controller_); // TODO(dkwingsmt) diff --git a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm index 35e0701f6ce1f..5f56d54f54af0 100644 --- a/shell/platform/darwin/ios/ios_surface_metal_impeller.mm +++ b/shell/platform/darwin/ios/ios_surface_metal_impeller.mm @@ -39,7 +39,7 @@ // |IOSSurface| std::unique_ptr IOSSurfaceMetalImpeller::CreateGPUStudio(GrDirectContext*) { impeller_context_->UpdateOffscreenLayerPixelFormat( - InferOffscreenLayerPixelFormat(impeller::FromMTLPixelFormat(layer_.get().pixelFormat))); + impeller::FromMTLPixelFormat(layer_.get().pixelFormat)); return std::make_unique(this, // impeller_context_ // ); diff --git a/shell/platform/embedder/tests/embedder_gl_unittests.cc b/shell/platform/embedder/tests/embedder_gl_unittests.cc index 65d698d01448b..aa90c76430d11 100644 --- a/shell/platform/embedder/tests/embedder_gl_unittests.cc +++ b/shell/platform/embedder/tests/embedder_gl_unittests.cc @@ -43,6 +43,8 @@ namespace flutter { namespace testing { +static constexpr int64_t kDefaultViewId = 0ll; + using EmbedderTest = testing::EmbedderTest; TEST_F(EmbedderTest, CanGetVulkanEmbedderContext) { @@ -161,8 +163,9 @@ TEST_F(EmbedderTest, CompositorMustBeAbleToRenderToOpenGLFramebuffer) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -254,8 +257,9 @@ TEST_F(EmbedderTest, RasterCacheDisabledWithPlatformViews) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); setup.Wait(); @@ -326,8 +330,9 @@ TEST_F(EmbedderTest, RasterCacheEnabled) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); setup.Wait(); @@ -427,8 +432,9 @@ TEST_F(EmbedderTest, CompositorMustBeAbleToRenderToOpenGLTexture) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -519,8 +525,9 @@ TEST_F(EmbedderTest, CompositorMustBeAbleToRenderToSoftwareBuffer) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -684,8 +691,9 @@ TEST_F(EmbedderTest, CompositorMustBeAbleToRenderKnownScene) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -804,7 +812,8 @@ TEST_F(EmbedderTest, CustomCompositorMustWorkWithCustomTaskRunner) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, + &event), kSuccess); ASSERT_TRUE(engine.is_valid()); sync_latch.Signal(); @@ -878,8 +887,9 @@ TEST_F(EmbedderTest, CompositorMustBeAbleToRenderWithRootLayerOnly) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -988,8 +998,9 @@ TEST_F(EmbedderTest, CompositorMustBeAbleToRenderWithPlatformLayerOnBottom) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -1169,8 +1180,9 @@ TEST_F(EmbedderTest, event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -1198,8 +1210,9 @@ TEST_F(EmbedderTest, CanRenderSceneWithoutCustomCompositor) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(ImageMatchesFixture("scene_without_custom_compositor.png", rendered_scene)); @@ -1231,8 +1244,9 @@ TEST_F(EmbedderTest, CanRenderSceneWithoutCustomCompositorWithTransformation) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(ImageMatchesFixture( "scene_without_custom_compositor_with_xform.png", rendered_scene)); @@ -1258,8 +1272,9 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithoutCompositor) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(ImageMatchesFixture( FixtureNameForBackend(backend, "gradient.png"), rendered_scene)); @@ -1292,8 +1307,9 @@ TEST_F(EmbedderTest, CanRenderGradientWithoutCompositorWithXform) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(ImageMatchesFixture("gradient_xform.png", rendered_scene)); } @@ -1320,8 +1336,9 @@ TEST_P(EmbedderTestMultiBackend, CanRenderGradientWithCompositor) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(ImageMatchesFixture( FixtureNameForBackend(backend, "gradient.png"), rendered_scene)); @@ -1358,8 +1375,9 @@ TEST_F(EmbedderTest, CanRenderGradientWithCompositorWithXform) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(ImageMatchesFixture("gradient_xform.png", rendered_scene)); } @@ -1462,8 +1480,9 @@ TEST_P(EmbedderTestMultiBackend, event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(ImageMatchesFixture( FixtureNameForBackend(backend, "gradient.png"), rendered_scene)); @@ -1577,8 +1596,9 @@ TEST_F(EmbedderTest, CanRenderGradientWithCompositorOnNonRootLayerWithXform) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(ImageMatchesFixture("gradient_xform.png", rendered_scene)); } @@ -1680,8 +1700,9 @@ TEST_F(EmbedderTest, VerifyB141980393) { event.width = flutter_application_rect.width(); event.height = flutter_application_rect.height(); event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -1725,8 +1746,9 @@ TEST_F(EmbedderTest, CanCreateEmbedderWithCustomRenderTaskRunner) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); task_latch.Wait(); ASSERT_TRUE(task_executed); ASSERT_EQ(FlutterEngineDeinitialize(engine.get()), kSuccess); @@ -1786,7 +1808,8 @@ TEST_P(EmbedderTestMultiBackend, event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, + &event), kSuccess); }); @@ -1895,8 +1918,9 @@ TEST_P(EmbedderTestMultiBackend, event.width = 400 * 2.0; event.height = 300 * 2.0; event.pixel_ratio = 2.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -1991,8 +2015,9 @@ TEST_F( event.width = 400 * 2.0; event.height = 300 * 2.0; event.pixel_ratio = 2.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -2025,8 +2050,9 @@ TEST_F(EmbedderTest, event.width = 1024; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); constexpr size_t frames_expected = 10; @@ -2065,8 +2091,9 @@ TEST_F(EmbedderTest, event.width = 1024; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); constexpr size_t frames_expected = 10; @@ -2172,8 +2199,9 @@ TEST_P(EmbedderTestMultiBackend, PlatformViewMutatorsAreValid) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -2268,8 +2296,9 @@ TEST_F(EmbedderTest, PlatformViewMutatorsAreValidWithPixelRatio) { event.width = 800; event.height = 600; event.pixel_ratio = 2.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -2371,8 +2400,9 @@ TEST_F(EmbedderTest, event.width = 800; event.height = 600; event.pixel_ratio = 2.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -2399,8 +2429,9 @@ TEST_F(EmbedderTest, EmptySceneIsAcceptable) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); } @@ -2427,8 +2458,9 @@ TEST_F(EmbedderTest, SceneWithNoRootContainerIsAcceptable) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); } @@ -2462,8 +2494,9 @@ TEST_F(EmbedderTest, ArcEndCapsAreDrawnCorrectly) { event.width = 800; event.height = 1024; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(ImageMatchesFixture("arc_end_caps.png", scene_image)); } @@ -2541,8 +2574,9 @@ TEST_F(EmbedderTest, ClipsAreCorrectlyCalculated) { event.width = 400; event.height = 300; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); } @@ -2625,8 +2659,9 @@ TEST_F(EmbedderTest, ComplexClipsAreCorrectlyCalculated) { event.width = 1024; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); } @@ -2855,8 +2890,9 @@ TEST_F(EmbedderTest, CompositorCanPostZeroLayersForPresentation) { event.width = 300; event.height = 200; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -2918,8 +2954,9 @@ TEST_F(EmbedderTest, CompositorCanPostOnlyPlatformViews) { event.width = 300; event.height = 200; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); @@ -2957,8 +2994,9 @@ TEST_F(EmbedderTest, CompositorRenderTargetsAreRecycled) { event.width = 300; event.height = 200; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); ASSERT_EQ(context.GetCompositor().GetPendingBackingStoresCount(), 10u); @@ -3034,8 +3072,9 @@ TEST_F(EmbedderTest, CompositorRenderTargetsAreInStableOrder) { event.width = 300; event.height = 200; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); } @@ -3060,8 +3099,9 @@ TEST_F(EmbedderTest, FrameInfoContainsValidWidthAndHeight) { event.width = 1024; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); static fml::CountDownLatch frame_latch(10); @@ -3191,8 +3231,9 @@ TEST_F(EmbedderTest, PresentInfoContainsValidFBOId) { event.width = 1024; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); static fml::CountDownLatch frame_latch(10); @@ -3265,8 +3306,9 @@ TEST_F(EmbedderTest, event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); // Because it's the same as the first frame, the second frame damage should // be empty but, because there was a full existing buffer damage, the buffer @@ -3287,8 +3329,9 @@ TEST_F(EmbedderTest, ASSERT_EQ(present_info.buffer_damage.damage->bottom, 600); }); - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); } TEST_F(EmbedderTest, PresentInfoReceivesEmptyDamage) { @@ -3341,8 +3384,9 @@ TEST_F(EmbedderTest, PresentInfoReceivesEmptyDamage) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); // Because it's the same as the first frame, the second frame should not be // rerendered assuming there is no existing damage. @@ -3362,8 +3406,9 @@ TEST_F(EmbedderTest, PresentInfoReceivesEmptyDamage) { ASSERT_EQ(present_info.buffer_damage.damage->bottom, 0); }); - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); } TEST_F(EmbedderTest, PresentInfoReceivesPartialDamage) { @@ -3416,8 +3461,9 @@ TEST_F(EmbedderTest, PresentInfoReceivesPartialDamage) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); // Because it's the same as the first frame, the second frame damage should be // empty but, because there was a partial existing damage, the buffer damage @@ -3438,8 +3484,9 @@ TEST_F(EmbedderTest, PresentInfoReceivesPartialDamage) { ASSERT_EQ(present_info.buffer_damage.damage->bottom, 300); }); - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); } TEST_F(EmbedderTest, PopulateExistingDamageReceivesValidID) { @@ -3473,8 +3520,9 @@ TEST_F(EmbedderTest, PopulateExistingDamageReceivesValidID) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); } TEST_F(EmbedderTest, PopulateExistingDamageReceivesInvalidID) { @@ -3519,8 +3567,9 @@ TEST_F(EmbedderTest, PopulateExistingDamageReceivesInvalidID) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); } TEST_F(EmbedderTest, SetSingleDisplayConfigurationWithDisplayId) { @@ -3559,8 +3608,9 @@ TEST_F(EmbedderTest, SetSingleDisplayConfigurationWithDisplayId) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); } @@ -3601,8 +3651,9 @@ TEST_F(EmbedderTest, SetSingleDisplayConfigurationWithoutDisplayId) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); } @@ -3650,8 +3701,9 @@ TEST_F(EmbedderTest, SetValidMultiDisplayConfiguration) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); } @@ -3696,8 +3748,9 @@ TEST_F(EmbedderTest, MultipleDisplaysWithSingleDisplayTrueIsInvalid) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); } @@ -3742,8 +3795,9 @@ TEST_F(EmbedderTest, MultipleDisplaysWithSameDisplayIdIsInvalid) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); } @@ -3783,8 +3837,9 @@ TEST_F(EmbedderTest, CompositorRenderTargetsNotRecycledWhenAvoidsCacheSet) { event.width = 300; event.height = 200; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); latch.Wait(); @@ -3945,8 +4000,9 @@ TEST_F(EmbedderTest, CreateInvalidBackingstoreOpenGLTexture) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); } @@ -4008,8 +4064,9 @@ TEST_F(EmbedderTest, CreateInvalidBackingstoreOpenGLFramebuffer) { event.width = 800; event.height = 600; event.pixel_ratio = 1.0; - ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), - kSuccess); + ASSERT_EQ( + FlutterEngineSendWindowMetricsEvent(engine.get(), kDefaultViewId, &event), + kSuccess); ASSERT_TRUE(engine.is_valid()); latch.Wait(); } diff --git a/shell/platform/glfw/flutter_glfw.cc b/shell/platform/glfw/flutter_glfw.cc index d50871bd6f14c..de7dcb61fe11f 100644 --- a/shell/platform/glfw/flutter_glfw.cc +++ b/shell/platform/glfw/flutter_glfw.cc @@ -41,6 +41,7 @@ static_assert(FLUTTER_ENGINE_VERSION == 1, ""); const int kFlutterDesktopDontCare = GLFW_DONT_CARE; static constexpr double kDpPerInch = 160.0; +static constexpr int64_t kFlutterDefaultViewId = 0ll; // Struct for storing state within an instance of the GLFW Window. struct FlutterDesktopWindowControllerState { @@ -281,6 +282,7 @@ static void SendWindowMetrics(FlutterDesktopWindowControllerState* controller, double dpi = controller->window_wrapper->pixels_per_screen_coordinate * controller->monitor_screen_coordinates_per_inch; + int64_t view_id = kFlutterDefaultViewId; FlutterWindowMetricsEvent event = {}; event.struct_size = sizeof(event); event.width = width; @@ -294,7 +296,7 @@ static void SendWindowMetrics(FlutterDesktopWindowControllerState* controller, event.pixel_ratio = controller->window_wrapper->pixel_ratio_override; } FlutterEngineSendWindowMetricsEvent(controller->engine->flutter_engine, - &event); + view_id, &event); } // Populates |task_runner| with a description that uses |engine_state|'s event From 2f000544f5e02528a12abb61090b094e3eef36b7 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 1 May 2023 23:00:22 -0700 Subject: [PATCH 096/142] Fix some compile --- lib/ui/compositing.dart | 8 ++++---- lib/ui/dart_ui.cc | 2 +- shell/platform/fuchsia/flutter/engine.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/ui/compositing.dart b/lib/ui/compositing.dart index cfb4e1908064b..f20ecff7349c6 100644 --- a/lib/ui/compositing.dart +++ b/lib/ui/compositing.dart @@ -231,12 +231,12 @@ class PhysicalShapeEngineLayer extends _EngineLayerWrapper { class SceneBuilder extends NativeFieldWrapperClass1 { /// Creates an empty [SceneBuilder] object. @pragma('vm:entry-point') - SceneBuilder([Object viewId = 0]) { - _constructor(viewId as int); + SceneBuilder() { + _constructor(); } - @Native(symbol: 'SceneBuilder::Create') - external void _constructor(int viewId); + @Native(symbol: 'SceneBuilder::Create') + external void _constructor(); // Layers used in this scene. // diff --git a/lib/ui/dart_ui.cc b/lib/ui/dart_ui.cc index f9e4c29a378ec..e26aeb307fd55 100644 --- a/lib/ui/dart_ui.cc +++ b/lib/ui/dart_ui.cc @@ -81,7 +81,7 @@ typedef CanvasPath Path; V(PathMeasure::Create, 3) \ V(Path::Create, 1) \ V(PictureRecorder::Create, 1) \ - V(SceneBuilder::Create, 2) \ + V(SceneBuilder::Create, 1) \ V(SemanticsUpdateBuilder::Create, 1) \ /* Other */ \ V(FontCollection::LoadFontFromList, 3) \ diff --git a/shell/platform/fuchsia/flutter/engine.h b/shell/platform/fuchsia/flutter/engine.h index f17c48832f6f2..dd5b6049c4311 100644 --- a/shell/platform/fuchsia/flutter/engine.h +++ b/shell/platform/fuchsia/flutter/engine.h @@ -149,7 +149,7 @@ class Engine final : public fuchsia::memorypressure::Watcher { std::unique_ptr CreateStudio(); - std::unique_ptr CreateSurface(int64_t view_id); + std::unique_ptr CreateSurface(); Delegate& delegate_; From 8bd5109e054b025818c9033d0b56493787ff31ef Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 1 May 2023 23:38:49 -0700 Subject: [PATCH 097/142] More compile errors --- .../ios/framework/Source/FlutterEnginePlatformViewTest.mm | 2 +- .../darwin/ios/framework/Source/FlutterPlatformViewsTest.mm | 2 +- .../darwin/ios/framework/Source/accessibility_bridge_test.mm | 2 +- shell/platform/fuchsia/flutter/platform_view_unittest.cc | 2 +- .../fuchsia/flutter/tests/flatland_platform_view_unittest.cc | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm index 61c3fdcb6ef52..beef56f3fa087 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterEnginePlatformViewTest.mm @@ -24,7 +24,7 @@ void OnPlatformViewCreated() override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} - void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {} + void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {} const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; } void OnPlatformViewDispatchPlatformMessage(std::unique_ptr message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index d7a4c2a0876e6..f1a15c061881e 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -96,7 +96,7 @@ void OnPlatformViewCreated() override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} - void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {} + void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {} const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; } void OnPlatformViewDispatchPlatformMessage(std::unique_ptr message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm index a0db444553f29..9ff01fb153fa1 100644 --- a/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm +++ b/shell/platform/darwin/ios/framework/Source/accessibility_bridge_test.mm @@ -77,7 +77,7 @@ void OnPlatformViewCreated() override {} void OnPlatformViewDestroyed() override {} void OnPlatformViewScheduleFrame() override {} void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) override {} - void OnPlatformViewSetViewportMetrics(const ViewportMetrics& metrics) override {} + void OnPlatformViewSetViewportMetrics(int64_t view_id, const ViewportMetrics& metrics) override {} const flutter::Settings& OnPlatformViewGetSettings() const override { return settings_; } void OnPlatformViewDispatchPlatformMessage(std::unique_ptr message) override {} void OnPlatformViewDispatchPointerDataPacket(std::unique_ptr packet) override { diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index 6f30c64e79e3a..23eed34073197 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -87,7 +87,7 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {} // |flutter::PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( - const flutter::ViewportMetrics& metrics) { + int64_t view_id, const flutter::ViewportMetrics& metrics) { metrics_ = metrics; } // |flutter::PlatformView::Delegate| diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index 01326fc07a4ac..d10155ad40eeb 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -86,7 +86,7 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {} // |flutter::PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( - const flutter::ViewportMetrics& metrics) { + int64_t view_id, const flutter::ViewportMetrics& metrics) { metrics_ = metrics; } // |flutter::PlatformView::Delegate| From af9c6a7a1d62acc6f95c2c1ac305bc9812d743cc Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 1 May 2023 23:39:24 -0700 Subject: [PATCH 098/142] Format --- shell/platform/fuchsia/flutter/platform_view_unittest.cc | 3 ++- .../fuchsia/flutter/tests/flatland_platform_view_unittest.cc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/shell/platform/fuchsia/flutter/platform_view_unittest.cc b/shell/platform/fuchsia/flutter/platform_view_unittest.cc index 23eed34073197..6f5b4d5fd444c 100644 --- a/shell/platform/fuchsia/flutter/platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/platform_view_unittest.cc @@ -87,7 +87,8 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {} // |flutter::PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( - int64_t view_id, const flutter::ViewportMetrics& metrics) { + int64_t view_id, + const flutter::ViewportMetrics& metrics) { metrics_ = metrics; } // |flutter::PlatformView::Delegate| diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index d10155ad40eeb..0de1588d7b511 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -86,7 +86,8 @@ class MockPlatformViewDelegate : public flutter::PlatformView::Delegate { void OnPlatformViewSetNextFrameCallback(const fml::closure& closure) {} // |flutter::PlatformView::Delegate| void OnPlatformViewSetViewportMetrics( - int64_t view_id, const flutter::ViewportMetrics& metrics) { + int64_t view_id, + const flutter::ViewportMetrics& metrics) { metrics_ = metrics; } // |flutter::PlatformView::Delegate| From 0a4eb92bf27671ac9b105068354f56a2ac324513 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 2 May 2023 00:29:06 -0700 Subject: [PATCH 099/142] Fix crash --- shell/common/snapshot_controller_impeller.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/common/snapshot_controller_impeller.cc b/shell/common/snapshot_controller_impeller.cc index 77a8c2502ba48..ea68bd91188a4 100644 --- a/shell/common/snapshot_controller_impeller.cc +++ b/shell/common/snapshot_controller_impeller.cc @@ -37,7 +37,7 @@ sk_sp SnapshotControllerImpeller::DoMakeRasterSnapshot( impeller::DlDispatcher dispatcher; display_list->Dispatch(dispatcher); impeller::Picture picture = dispatcher.EndRecordingAsPicture(); - auto context = GetDelegate().GetStudio()->GetAiksContext(); + auto context = GetDelegate().GetAiksContext(); if (context) { auto max_size = context->GetContext() ->GetResourceAllocator() From e5fe6dfdc9480ca2c2b771bcb8cbc25c1425cc63 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 4 May 2023 16:56:57 -0700 Subject: [PATCH 100/142] Remove embedderSurface::CreateResourceContext --- shell/platform/embedder/embedder_surface.h | 2 -- shell/platform/embedder/embedder_surface_gl.cc | 5 ----- shell/platform/embedder/embedder_surface_gl.h | 3 --- shell/platform/embedder/embedder_surface_metal.h | 3 --- shell/platform/embedder/embedder_surface_metal.mm | 4 ---- shell/platform/embedder/embedder_surface_software.cc | 5 ----- shell/platform/embedder/embedder_surface_software.h | 3 --- shell/platform/embedder/embedder_surface_vulkan.cc | 5 ----- shell/platform/embedder/embedder_surface_vulkan.h | 3 --- 9 files changed, 33 deletions(-) diff --git a/shell/platform/embedder/embedder_surface.h b/shell/platform/embedder/embedder_surface.h index ed8dbff74b8d0..aae2e5d27585b 100644 --- a/shell/platform/embedder/embedder_surface.h +++ b/shell/platform/embedder/embedder_surface.h @@ -21,8 +21,6 @@ class EmbedderSurface { virtual std::unique_ptr CreateGPUSurface() = 0; - virtual sk_sp CreateResourceContext() const = 0; - private: FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurface); }; diff --git a/shell/platform/embedder/embedder_surface_gl.cc b/shell/platform/embedder/embedder_surface_gl.cc index 6159a15e68af5..3fb102ded3692 100644 --- a/shell/platform/embedder/embedder_surface_gl.cc +++ b/shell/platform/embedder/embedder_surface_gl.cc @@ -37,9 +37,4 @@ std::unique_ptr EmbedderSurfaceGL::CreateGPUSurface() { ); } -// |EmbedderSurface| -sk_sp EmbedderSurfaceGL::CreateResourceContext() const { - return studio_->CreateResourceContext(); -} - } // namespace flutter diff --git a/shell/platform/embedder/embedder_surface_gl.h b/shell/platform/embedder/embedder_surface_gl.h index 05456635661de..f9ed3a2fd5b22 100644 --- a/shell/platform/embedder/embedder_surface_gl.h +++ b/shell/platform/embedder/embedder_surface_gl.h @@ -32,9 +32,6 @@ class EmbedderSurfaceGL final : public EmbedderSurface { // |EmbedderSurface| std::unique_ptr CreateGPUSurface() override; - // |EmbedderSurface| - sk_sp CreateResourceContext() const override; - FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceGL); }; diff --git a/shell/platform/embedder/embedder_surface_metal.h b/shell/platform/embedder/embedder_surface_metal.h index 63bc238dbefd6..168b3d7093cdc 100644 --- a/shell/platform/embedder/embedder_surface_metal.h +++ b/shell/platform/embedder/embedder_surface_metal.h @@ -38,9 +38,6 @@ class EmbedderSurfaceMetal final : public EmbedderSurface { // |EmbedderSurface| std::unique_ptr CreateGPUSurface() override; - // |EmbedderSurface| - sk_sp CreateResourceContext() const override; - FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceMetal); }; diff --git a/shell/platform/embedder/embedder_surface_metal.mm b/shell/platform/embedder/embedder_surface_metal.mm index 32b9a34409c4d..1c164013d92c0 100644 --- a/shell/platform/embedder/embedder_surface_metal.mm +++ b/shell/platform/embedder/embedder_surface_metal.mm @@ -50,8 +50,4 @@ return surface; } -sk_sp EmbedderSurfaceMetal::CreateResourceContext() const { - return studio_->CreateResourceContext(); -} - } // namespace flutter diff --git a/shell/platform/embedder/embedder_surface_software.cc b/shell/platform/embedder/embedder_surface_software.cc index 6db94313126b1..8e270bbf4a7ba 100644 --- a/shell/platform/embedder/embedder_surface_software.cc +++ b/shell/platform/embedder/embedder_surface_software.cc @@ -41,9 +41,4 @@ std::unique_ptr EmbedderSurfaceSoftware::CreateGPUSurface() { return surface; } -// |EmbedderSurface| -sk_sp EmbedderSurfaceSoftware::CreateResourceContext() const { - return nullptr; -} - } // namespace flutter diff --git a/shell/platform/embedder/embedder_surface_software.h b/shell/platform/embedder/embedder_surface_software.h index 6d938b6627f29..858afc4c9eb86 100644 --- a/shell/platform/embedder/embedder_surface_software.h +++ b/shell/platform/embedder/embedder_surface_software.h @@ -32,9 +32,6 @@ class EmbedderSurfaceSoftware final : public EmbedderSurface { // |EmbedderSurface| std::unique_ptr CreateGPUSurface() override; - // |EmbedderSurface| - sk_sp CreateResourceContext() const override; - FML_DISALLOW_COPY_AND_ASSIGN(EmbedderSurfaceSoftware); }; diff --git a/shell/platform/embedder/embedder_surface_vulkan.cc b/shell/platform/embedder/embedder_surface_vulkan.cc index de92ed3babc0c..0f80a7786d511 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.cc +++ b/shell/platform/embedder/embedder_surface_vulkan.cc @@ -38,9 +38,4 @@ std::unique_ptr EmbedderSurfaceVulkan::CreateGPUSurface() { render_to_surface_); } -// |EmbedderSurface| -sk_sp EmbedderSurfaceVulkan::CreateResourceContext() const { - return studio_->CreateResourceContext(); -} - } // namespace flutter diff --git a/shell/platform/embedder/embedder_surface_vulkan.h b/shell/platform/embedder/embedder_surface_vulkan.h index f26a44591d407..df25d52c8a5fd 100644 --- a/shell/platform/embedder/embedder_surface_vulkan.h +++ b/shell/platform/embedder/embedder_surface_vulkan.h @@ -36,9 +36,6 @@ class EmbedderSurfaceVulkan final : public EmbedderSurface { // |EmbedderSurface| std::unique_ptr CreateGPUSurface() override; - // |EmbedderSurface| - sk_sp CreateResourceContext() const override; - sk_sp CreateGrContext(VkInstance instance, uint32_t version, size_t instance_extension_count, From bda89f01fb2fe6fc15f8094baba9edbe2bcc0baa Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 8 May 2023 17:18:29 -0700 Subject: [PATCH 101/142] No more shared synchronizers, but passed from engine --- lib/ui/compositing/scene_builder.cc | 8 +++++ .../macos/framework/Source/FlutterEngine.mm | 10 ++++++- .../framework/Source/FlutterEngineTest.mm | 2 +- .../framework/Source/FlutterEngine_Internal.h | 2 ++ .../Source/FlutterThreadSynchronizer.mm | 23 ++++++++++++++- .../macos/framework/Source/FlutterView.h | 13 +-------- .../macos/framework/Source/FlutterView.mm | 29 +++++++------------ .../framework/Source/FlutterViewController.mm | 6 ++++ .../macos/framework/Source/FlutterViewTest.mm | 2 ++ 9 files changed, 61 insertions(+), 34 deletions(-) diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index 9f6d58de31ac9..439e004cc2f44 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -214,14 +214,20 @@ void SceneBuilder::addPicture(double dx, double dy, Picture* picture, int hints) { + printf("SceneBuilder::addPicture start\n"); + fflush(stdout); if (!picture) { // Picture::dispose was called and it has been collected. + printf("SceneBuilder::addPicture ret 1\n"); + fflush(stdout); return; } // Explicitly check for display_list, since the picture object might have // been disposed but not collected yet, but the display list is null. if (picture->display_list()) { + printf("SceneBuilder::addPicture actual\n"); + fflush(stdout); auto layer = std::make_unique( SkPoint::Make(SafeNarrow(dx), SafeNarrow(dy)), picture->display_list(), !!(hints & 1), !!(hints & 2)); @@ -294,6 +300,8 @@ void SceneBuilder::AddLayer(std::shared_ptr layer) { FML_DCHECK(layer); if (!layer_stack_.empty()) { + printf("SceneBuilder::AddLayer actual\n"); + fflush(stdout); layer_stack_.back()->Add(std::move(layer)); } } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 3f3b9489db950..75ae047976dc8 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -382,6 +382,8 @@ @implementation FlutterEngine { // A method channel for miscellaneous platform functionality. FlutterMethodChannel* _platformChannel; + FlutterThreadSynchronizer* _synchronizer; + int _nextViewId; } @@ -421,6 +423,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix object:nil]; _platformViewController = [[FlutterPlatformViewController alloc] init]; + _synchronizer = [[FlutterThreadSynchronizer alloc] init]; [self setUpPlatformViewChannel]; [self setUpAccessibilityChannel]; [self setUpNotificationCenterListeners]; @@ -897,7 +900,8 @@ - (void)shutDownEngine { } NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator]; - [[FlutterView sharedThreadSynchronizer] shutdown]; + [_synchronizer shutdown]; + _synchronizer = nil; FlutterViewController* nextViewController; while ((nextViewController = [viewControllerEnumerator nextObject])) { [nextViewController.flutterView shutdown]; @@ -1065,6 +1069,10 @@ - (NSPasteboard*)pasteboard { return flutter::GetSwitchesFromEnvironment(); } +- (FlutterThreadSynchronizer*)synchronizer { + return _synchronizer; +} + #pragma mark - FlutterBinaryMessenger - (void)sendOnChannel:(nonnull NSString*)channel message:(nullable NSData*)message { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index fd5a82370db8e..4322509ebc227 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -437,7 +437,7 @@ - (nonnull NSView*)createWithViewIdentifier:(int64_t)viewId arguments:(nullable result:^(id result){ }]; - [viewController.flutterView.threadSynchronizer blockUntilFrameAvailable]; + [engine.synchronizer blockUntilFrameAvailable]; CALayer* rootLayer = viewController.flutterView.layer; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h index e291094eaa342..72ad411e31cfb 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h @@ -107,6 +107,8 @@ typedef NS_ENUM(NSInteger, FlutterAppExitResponse) { */ @property(nonatomic, readonly) FlutterEngineTerminationHandler* terminationHandler; +@property(nonatomic, readonly) FlutterThreadSynchronizer* synchronizer; + /** * Attach a view controller to the engine as its default controller. * diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm index bf4506994e3cd..82f65f932e61d 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm @@ -21,8 +21,20 @@ @interface FlutterThreadSynchronizer () { std::condition_variable _condBlockBeginResize; } +/** + * Returns true if all existing views have a non-zero size. + * + * If there are no views, still returns true. + */ - (BOOL)allViewsHaveFrame; +/** + * Returns true if there are any views that have a non-zero size. + * + * If there are no views, returns false. + */ +- (BOOL)someViewsHaveFrame; + @end @implementation FlutterThreadSynchronizer @@ -36,6 +48,15 @@ - (BOOL)allViewsHaveFrame { return YES; } +- (BOOL)someViewsHaveFrame { + for (auto const& [viewId, contentSize] : _contentSizes) { + if (!CGSizeEqualToSize(contentSize, CGSizeZero)) { + return YES; + } + } + return NO; +} + - (void)drain { FML_DCHECK([NSThread isMainThread]); @@ -53,7 +74,7 @@ - (void)blockUntilFrameAvailable { _beginResizeWaiting = YES; - while (![self allViewsHaveFrame] && !_shuttingDown) { + while (![self someViewsHaveFrame] && !_shuttingDown) { _condBlockBeginResize.wait(lock); [self drain]; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.h b/shell/platform/darwin/macos/framework/Source/FlutterView.h index 0881c4f6bc6ab..579f7b4fcfdc4 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.h @@ -44,6 +44,7 @@ constexpr FlutterViewId kFlutterDefaultViewId = 0ll; - (nullable instancetype)initWithMTLDevice:(nonnull id)device commandQueue:(nonnull id)commandQueue reshapeListener:(nonnull id)reshapeListener + synchronizer:(nonnull FlutterThreadSynchronizer*)synchronizer viewId:(int64_t)viewId NS_DESIGNATED_INITIALIZER; - (nullable instancetype)initWithFrame:(NSRect)frameRect @@ -73,16 +74,4 @@ constexpr FlutterViewId kFlutterDefaultViewId = 0ll; */ - (void)setBackgroundColor:(nonnull NSColor*)color; -+ (nonnull FlutterThreadSynchronizer*)sharedThreadSynchronizer; - -@end - -@interface FlutterView (FlutterViewPrivate) - -/** - * Returns FlutterThreadSynchronizer for this view. - * Used for FlutterEngineTest. - */ -- (nonnull FlutterThreadSynchronizer*)threadSynchronizer; - @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.mm b/shell/platform/darwin/macos/framework/Source/FlutterView.mm index a5be0767e783a..3bd59f6a6b758 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.mm @@ -13,6 +13,7 @@ @interface FlutterView () { int64_t _viewId; __weak id _reshapeListener; FlutterSurfaceManager* _surfaceManager; + FlutterThreadSynchronizer* _synchronizer; } @end @@ -22,6 +23,7 @@ @implementation FlutterView - (instancetype)initWithMTLDevice:(id)device commandQueue:(id)commandQueue reshapeListener:(id)reshapeListener + synchronizer:(FlutterThreadSynchronizer*)synchronizer viewId:(int64_t)viewId { self = [super initWithFrame:NSZeroRect]; if (self) { @@ -30,34 +32,31 @@ - (instancetype)initWithMTLDevice:(id)device [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawDuringViewResize]; _viewId = viewId; _reshapeListener = reshapeListener; + _synchronizer = synchronizer; _surfaceManager = [[FlutterSurfaceManager alloc] initWithDevice:device commandQueue:commandQueue layer:self.layer delegate:self]; - [[FlutterView sharedThreadSynchronizer] registerView:viewId]; + [_synchronizer registerView:viewId]; } return self; } - (void)onPresent:(CGSize)frameSize withBlock:(dispatch_block_t)block { - [[FlutterView sharedThreadSynchronizer] performCommitForView:_viewId size:frameSize notify:block]; + [_synchronizer performCommitForView:_viewId size:frameSize notify:block]; } - (FlutterSurfaceManager*)surfaceManager { return _surfaceManager; } -- (FlutterThreadSynchronizer*)threadSynchronizer { - return [FlutterView sharedThreadSynchronizer]; -} - - (void)reshaped { CGSize scaledSize = [self convertSizeToBacking:self.bounds.size]; - [[FlutterView sharedThreadSynchronizer] beginResizeForView:_viewId - size:scaledSize - notify:^{ - [_reshapeListener viewDidReshape:self]; - }]; + [_synchronizer beginResizeForView:_viewId + size:scaledSize + notify:^{ + [_reshapeListener viewDidReshape:self]; + }]; } - (void)setBackgroundColor:(NSColor*)color { @@ -139,12 +138,4 @@ - (NSString*)accessibilityLabel { return applicationName; } -static FlutterThreadSynchronizer* _synchronizer; -+ (FlutterThreadSynchronizer*)sharedThreadSynchronizer { - if (_synchronizer == nil) { - _synchronizer = [[FlutterThreadSynchronizer alloc] init]; - } - return _synchronizer; -} - @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index 33d73932d09cc..540c16cd4a9a6 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -372,6 +372,10 @@ @implementation FlutterViewController { std::shared_ptr _bridge; FlutterViewId _id; + + // FlutterViewController does not actually uses the synchronizer, but only + // passes it to FlutterView. + __weak FlutterThreadSynchronizer* _weakSynchronizer; } @synthesize viewId = _viewId; @@ -398,6 +402,7 @@ static void CommonInit(FlutterViewController* controller, FlutterEngine* engine) controller.engine, controller.viewId); controller->_mouseTrackingMode = FlutterMouseTrackingModeInKeyWindow; controller->_textInputPlugin = [[FlutterTextInputPlugin alloc] initWithViewController:controller]; + controller->_weakSynchronizer = engine.synchronizer; [controller initializeKeyboard]; [controller notifySemanticsEnabledChanged]; // macOS fires this message when changing IMEs. @@ -863,6 +868,7 @@ - (nonnull FlutterView*)createFlutterViewWithMTLDevice:(id)device return [[FlutterView alloc] initWithMTLDevice:device commandQueue:commandQueue reshapeListener:self + synchronizer:_weakSynchronizer viewId:_viewId]; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm index 40faed5b13efd..82906119f98ee 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm @@ -25,9 +25,11 @@ - (void)viewDidReshape:(nonnull NSView*)view { id device = MTLCreateSystemDefaultDevice(); id queue = [device newCommandQueue]; TestReshapeListener* listener = [[TestReshapeListener alloc] init]; + FlutterThreadSynchronizer* synchronizer = [[FlutterThreadSynchronizer alloc] init]; FlutterView* view = [[FlutterView alloc] initWithMTLDevice:device commandQueue:queue reshapeListener:listener + synchronizer:synchronizer viewId:kDefaultViewId]; EXPECT_EQ([view layer:view.layer shouldInheritContentsScale:3.0 fromWindow:view.window], YES); } From f6be4c1585b23f7ab24b6793fa67be64e82b7d17 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 8 May 2023 18:00:11 -0700 Subject: [PATCH 102/142] Fix TestCreate bug --- .../darwin/macos/framework/Source/FlutterCompositorTest.mm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm index f7ac37e01be68..d447f75ca05d4 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm @@ -95,7 +95,8 @@ - (nullable FlutterView*)viewForId:(FlutterViewId)viewId { config.struct_size = sizeof(FlutterBackingStoreConfig); config.size.width = 800; config.size.height = 600; - macos_compositor->CreateBackingStore(&config, &backing_store); + config.view_id = 0; + ASSERT_TRUE(macos_compositor->CreateBackingStore(&config, &backing_store)); ASSERT_EQ(backing_store.type, kFlutterBackingStoreTypeMetal); ASSERT_NE(backing_store.metal.texture.texture, nil); From ff3bfd0e96bfa4c08f48089e9b1ec2e2ff8cf83a Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 8 May 2023 18:05:38 -0700 Subject: [PATCH 103/142] Fix compile error in last merge --- lib/ui/hooks.dart | 1 + .../android/platform_view_android_jni_impl.cc | 3 +- .../fuchsia/flutter/flatland_platform_view.cc | 49 ++++++++++--------- .../fuchsia/flutter/gfx_platform_view.cc | 46 ++++++++--------- 4 files changed, 52 insertions(+), 47 deletions(-) diff --git a/lib/ui/hooks.dart b/lib/ui/hooks.dart index f2131600bd91a..08c5ddb8cf191 100644 --- a/lib/ui/hooks.dart +++ b/lib/ui/hooks.dart @@ -18,6 +18,7 @@ void _removeView( PlatformDispatcher.instance._removeView(id); } +@pragma('vm:entry-point') void _updateDisplays( List ids, List widths, diff --git a/shell/platform/android/platform_view_android_jni_impl.cc b/shell/platform/android/platform_view_android_jni_impl.cc index a68799f358b27..05637727521f8 100644 --- a/shell/platform/android/platform_view_android_jni_impl.cc +++ b/shell/platform/android/platform_view_android_jni_impl.cc @@ -340,7 +340,8 @@ static void SetViewportMetrics(JNIEnv* env, 0, // Display ID }; - ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics(metrics); + ANDROID_SHELL_HOLDER->GetPlatformView()->SetViewportMetrics( + kFlutterDefaultViewId, metrics); } static void UpdateDisplayMetrics(JNIEnv* env, diff --git a/shell/platform/fuchsia/flutter/flatland_platform_view.cc b/shell/platform/fuchsia/flutter/flatland_platform_view.cc index 7ed7099ac96dc..11a46d0c7ff80 100644 --- a/shell/platform/fuchsia/flutter/flatland_platform_view.cc +++ b/shell/platform/fuchsia/flutter/flatland_platform_view.cc @@ -87,30 +87,31 @@ void FlatlandPlatformView::OnGetLayout( float pixel_ratio = view_pixel_ratio_ ? *view_pixel_ratio_ : 1.0f; - SetViewportMetrics({ - pixel_ratio, // device_pixel_ratio - std::round(view_logical_size_.value()[0] * - pixel_ratio), // physical_width - std::round(view_logical_size_.value()[1] * - pixel_ratio), // physical_height - 0.0f, // physical_padding_top - 0.0f, // physical_padding_right - 0.0f, // physical_padding_bottom - 0.0f, // physical_padding_left - 0.0f, // physical_view_inset_top - 0.0f, // physical_view_inset_right - 0.0f, // physical_view_inset_bottom - 0.0f, // physical_view_inset_left - 0.0f, // p_physical_system_gesture_inset_top - 0.0f, // p_physical_system_gesture_inset_right - 0.0f, // p_physical_system_gesture_inset_bottom - 0.0f, // p_physical_system_gesture_inset_left, - -1.0, // p_physical_touch_slop, - {}, // p_physical_display_features_bounds - {}, // p_physical_display_features_type - {}, // p_physical_display_features_state - kFlutterDefaultViewId, // p_display_id - }); + SetViewportMetrics(kFlutterDefaultViewId, + { + pixel_ratio, // device_pixel_ratio + std::round(view_logical_size_.value()[0] * + pixel_ratio), // physical_width + std::round(view_logical_size_.value()[1] * + pixel_ratio), // physical_height + 0.0f, // physical_padding_top + 0.0f, // physical_padding_right + 0.0f, // physical_padding_bottom + 0.0f, // physical_padding_left + 0.0f, // physical_view_inset_top + 0.0f, // physical_view_inset_right + 0.0f, // physical_view_inset_bottom + 0.0f, // physical_view_inset_left + 0.0f, // p_physical_system_gesture_inset_top + 0.0f, // p_physical_system_gesture_inset_right + 0.0f, // p_physical_system_gesture_inset_bottom + 0.0f, // p_physical_system_gesture_inset_left, + -1.0, // p_physical_touch_slop, + {}, // p_physical_display_features_bounds + {}, // p_physical_display_features_type + {}, // p_physical_display_features_state + 0, // p_display_id + }); parent_viewport_watcher_->GetLayout( fit::bind_member(this, &FlatlandPlatformView::OnGetLayout)); diff --git a/shell/platform/fuchsia/flutter/gfx_platform_view.cc b/shell/platform/fuchsia/flutter/gfx_platform_view.cc index f4eacd6353915..d79826483d448 100644 --- a/shell/platform/fuchsia/flutter/gfx_platform_view.cc +++ b/shell/platform/fuchsia/flutter/gfx_platform_view.cc @@ -215,28 +215,30 @@ void GfxPlatformView::OnScenicEvent( metrics_changed) { const float pixel_ratio = *view_pixel_ratio_; const std::array logical_size = *view_logical_size_; - SetViewportMetrics({ - pixel_ratio, // device_pixel_ratio - std::round(logical_size[0] * pixel_ratio), // physical_width - std::round(logical_size[1] * pixel_ratio), // physical_height - 0.0f, // physical_padding_top - 0.0f, // physical_padding_right - 0.0f, // physical_padding_bottom - 0.0f, // physical_padding_left - 0.0f, // physical_view_inset_top - 0.0f, // physical_view_inset_right - 0.0f, // physical_view_inset_bottom - 0.0f, // physical_view_inset_left - 0.0f, // p_physical_system_gesture_inset_top - 0.0f, // p_physical_system_gesture_inset_right - 0.0f, // p_physical_system_gesture_inset_bottom - 0.0f, // p_physical_system_gesture_inset_left, - -1.0, // p_physical_touch_slop, - {}, // p_physical_display_features_bounds - {}, // p_physical_display_features_type - {}, // p_physical_display_features_state - kFlutterDefaultViewId, // pdisplay_id - }); + SetViewportMetrics( + kFlutterDefaultViewId, + { + pixel_ratio, // device_pixel_ratio + std::round(logical_size[0] * pixel_ratio), // physical_width + std::round(logical_size[1] * pixel_ratio), // physical_height + 0.0f, // physical_padding_top + 0.0f, // physical_padding_right + 0.0f, // physical_padding_bottom + 0.0f, // physical_padding_left + 0.0f, // physical_view_inset_top + 0.0f, // physical_view_inset_right + 0.0f, // physical_view_inset_bottom + 0.0f, // physical_view_inset_left + 0.0f, // p_physical_system_gesture_inset_top + 0.0f, // p_physical_system_gesture_inset_right + 0.0f, // p_physical_system_gesture_inset_bottom + 0.0f, // p_physical_system_gesture_inset_left, + -1.0, // p_physical_touch_slop, + {}, // p_physical_display_features_bounds + {}, // p_physical_display_features_type + {}, // p_physical_display_features_state + 0, // pdisplay_id + }); } } From 44ab24bf7c71670001c981fc667805a9bef288b6 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 8 May 2023 20:14:50 -0700 Subject: [PATCH 104/142] Fix compile --- .../ios/framework/Source/FlutterPlatformViewsTest.mm | 8 ++++---- shell/platform/darwin/ios/ios_external_view_embedder.mm | 4 +--- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index f1a15c061881e..4e63e60fcb462 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -2863,8 +2863,8 @@ - (void)testDisposingViewInCompositionOrderDoNotCrash { std::move(mock_sk_surface), framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, + std::move(mock_surface))); // Disposing won't remove embedded views until the view is removed from the composition_order_ XCTAssertEqual(flutterPlatformViewsController->EmbeddedViewCount(), 2UL); @@ -2890,8 +2890,8 @@ - (void)testDisposingViewInCompositionOrderDoNotCrash { std::move(mock_sk_surface), framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue( - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); + XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, + std::move(mock_surface))); // Disposing won't remove embedded views until the view is removed from the composition_order_ XCTAssertEqual(flutterPlatformViewsController->EmbeddedViewCount(), 1UL); diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.mm b/shell/platform/darwin/ios/ios_external_view_embedder.mm index e0351b8ae74b0..7c34af1a1a843 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.mm +++ b/shell/platform/darwin/ios/ios_external_view_embedder.mm @@ -73,9 +73,7 @@ int64_t window_view_id) { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::SubmitFrame"); FML_CHECK(platform_views_controller_); - // TODO(dkwingsmt) - platform_views_controller_->SubmitFrame(context, ios_context_, kFlutterDefaultViewId, - std::move(frame)); + platform_views_controller_->SubmitFrame(context, ios_context_, window_view_id, std::move(frame)); TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::DidSubmitFrame"); } From 9bb4a01910d1ff2ee817a035dd18c900c1d0c309 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 8 May 2023 20:18:13 -0700 Subject: [PATCH 105/142] Remove print --- lib/ui/compositing/scene_builder.cc | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib/ui/compositing/scene_builder.cc b/lib/ui/compositing/scene_builder.cc index 439e004cc2f44..9f6d58de31ac9 100644 --- a/lib/ui/compositing/scene_builder.cc +++ b/lib/ui/compositing/scene_builder.cc @@ -214,20 +214,14 @@ void SceneBuilder::addPicture(double dx, double dy, Picture* picture, int hints) { - printf("SceneBuilder::addPicture start\n"); - fflush(stdout); if (!picture) { // Picture::dispose was called and it has been collected. - printf("SceneBuilder::addPicture ret 1\n"); - fflush(stdout); return; } // Explicitly check for display_list, since the picture object might have // been disposed but not collected yet, but the display list is null. if (picture->display_list()) { - printf("SceneBuilder::addPicture actual\n"); - fflush(stdout); auto layer = std::make_unique( SkPoint::Make(SafeNarrow(dx), SafeNarrow(dy)), picture->display_list(), !!(hints & 1), !!(hints & 2)); @@ -300,8 +294,6 @@ void SceneBuilder::AddLayer(std::shared_ptr layer) { FML_DCHECK(layer); if (!layer_stack_.empty()) { - printf("SceneBuilder::AddLayer actual\n"); - fflush(stdout); layer_stack_.back()->Add(std::move(layer)); } } From 4121d972b04daeaf385fb507d3f05024e5df068f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 8 May 2023 21:06:38 -0700 Subject: [PATCH 106/142] Remove unused var --- shell/platform/darwin/ios/ios_external_view_embedder.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.mm b/shell/platform/darwin/ios/ios_external_view_embedder.mm index 7c34af1a1a843..dde57241ee2a7 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.mm +++ b/shell/platform/darwin/ios/ios_external_view_embedder.mm @@ -6,8 +6,6 @@ namespace flutter { -constexpr int64_t kFlutterDefaultViewId = 0ll; - IOSExternalViewEmbedder::IOSExternalViewEmbedder( const std::shared_ptr& platform_views_controller, std::shared_ptr context) From f9936440f4439a709a5bdfcfc14bcdb08ffb8ad4 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 8 May 2023 21:07:07 -0700 Subject: [PATCH 107/142] Add more view_id to config --- .../darwin/macos/framework/Source/FlutterCompositorTest.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm index d447f75ca05d4..e8903c1667c79 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm @@ -121,6 +121,7 @@ - (nullable FlutterView*)viewForId:(FlutterViewId)viewId { config.struct_size = sizeof(FlutterBackingStoreConfig); config.size.width = 800; config.size.height = 600; + config.view_id = 0; macos_compositor->CreateBackingStore(&config, &backing_store); FlutterLayer layers[] = {{ From 783e34e13a32354ed7627b63586e8ed52af46520 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Wed, 10 May 2023 14:38:46 -0700 Subject: [PATCH 108/142] Impl --- .../macos/framework/Source/FlutterEngine.mm | 9 +++ .../framework/Source/FlutterEngineTest.mm | 11 +-- .../framework/Source/FlutterEngine_Internal.h | 2 + .../Source/FlutterThreadSynchronizer.h | 12 +++- .../Source/FlutterThreadSynchronizer.mm | 69 ++++++++++++++++--- .../macos/framework/Source/FlutterView.h | 13 +--- .../macos/framework/Source/FlutterView.mm | 25 +++---- .../framework/Source/FlutterViewController.mm | 9 ++- .../macos/framework/Source/FlutterViewTest.mm | 7 +- 9 files changed, 117 insertions(+), 40 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 16e8405a6fcdd..4f09c1a1b95e6 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -382,6 +382,8 @@ @implementation FlutterEngine { // A method channel for miscellaneous platform functionality. FlutterMethodChannel* _platformChannel; + FlutterThreadSynchronizer* _threadSynchronizer; + int _nextViewId; } @@ -421,6 +423,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix object:nil]; _platformViewController = [[FlutterPlatformViewController alloc] init]; + _threadSynchronizer = [[FlutterThreadSynchronizer alloc] init]; [self setUpPlatformViewChannel]; [self setUpAccessibilityChannel]; [self setUpNotificationCenterListeners]; @@ -905,6 +908,8 @@ - (void)shutDownEngine { } NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator]; + [_threadSynchronizer shutdown]; + _threadSynchronizer = nil; FlutterViewController* nextViewController; while ((nextViewController = [viewControllerEnumerator nextObject])) { [nextViewController.flutterView shutdown]; @@ -1072,6 +1077,10 @@ - (NSPasteboard*)pasteboard { return flutter::GetSwitchesFromEnvironment(); } +- (FlutterThreadSynchronizer*)threadSynchronizer { + return _threadSynchronizer; +} + #pragma mark - FlutterBinaryMessenger - (void)sendOnChannel:(nonnull NSString*)channel message:(nullable NSData*)message { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index d7aa813ca2fbf..8018c5f8d2bee 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -24,6 +24,8 @@ // CREATE_NATIVE_ENTRY and MOCK_ENGINE_PROC are leaky by design // NOLINTBEGIN(clang-analyzer-core.StackAddressEscape) +constexpr int64_t kDefaultViewId = 0ll; + @interface FlutterEngine (Test) /** * The FlutterCompositor object currently in use by the FlutterEngine. @@ -435,7 +437,7 @@ - (nonnull NSView*)createWithViewIdentifier:(int64_t)viewId arguments:(nullable result:^(id result){ }]; - [viewController.flutterView.threadSynchronizer blockUntilFrameAvailable]; + [engine.threadSynchronizer blockUntilFrameAvailable]; CALayer* rootLayer = viewController.flutterView.layer; @@ -626,9 +628,10 @@ - (nonnull NSView*)createWithViewIdentifier:(int64_t)viewId arguments:(nullable [threadSynchronizer shutdown]; std::thread rasterThread([&threadSynchronizer] { - [threadSynchronizer performCommit:CGSizeMake(100, 100) - notify:^{ - }]; + [threadSynchronizer performCommitForView:kDefaultViewId + size:CGSizeMake(100, 100) + notify:^{ + }]; }); rasterThread.join(); diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h index e291094eaa342..e5b185c492b03 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h @@ -107,6 +107,8 @@ typedef NS_ENUM(NSInteger, FlutterAppExitResponse) { */ @property(nonatomic, readonly) FlutterEngineTerminationHandler* terminationHandler; +@property(nonatomic, readonly) FlutterThreadSynchronizer* threadSynchronizer; + /** * Attach a view controller to the engine as its default controller. * diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h index 8eca9611f0f48..5cc399cb33279 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h @@ -15,7 +15,9 @@ * Called from platform thread. Blocks until commit with given size (or empty) * is requested. */ -- (void)beginResize:(CGSize)size notify:(nonnull dispatch_block_t)notify; +- (void)beginResizeForView:(int64_t)viewId + size:(CGSize)size + notify:(nonnull dispatch_block_t)notify; /** * Called from raster thread. Schedules the given block on platform thread @@ -26,7 +28,13 @@ * * The notify block is guaranteed to be called within a core animation transaction. */ -- (void)performCommit:(CGSize)size notify:(nonnull dispatch_block_t)notify; +- (void)performCommitForView:(int64_t)viewId + size:(CGSize)size + notify:(nonnull dispatch_block_t)notify; + +- (void)registerView:(int64_t)viewId; + +- (void)deregisterView:(int64_t)viewId; /** * Called when shutting down. Unblocks everything and prevents any further synchronization. diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm index cb442ea768ffb..82f65f932e61d 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm @@ -3,6 +3,7 @@ #import #include +#include #include #import "flutter/fml/logging.h" @@ -11,7 +12,7 @@ @interface FlutterThreadSynchronizer () { std::mutex _mutex; BOOL _shuttingDown; - CGSize _contentSize; + std::unordered_map _contentSizes; std::vector _scheduledBlocks; BOOL _beginResizeWaiting; @@ -20,10 +21,42 @@ @interface FlutterThreadSynchronizer () { std::condition_variable _condBlockBeginResize; } +/** + * Returns true if all existing views have a non-zero size. + * + * If there are no views, still returns true. + */ +- (BOOL)allViewsHaveFrame; + +/** + * Returns true if there are any views that have a non-zero size. + * + * If there are no views, returns false. + */ +- (BOOL)someViewsHaveFrame; + @end @implementation FlutterThreadSynchronizer +- (BOOL)allViewsHaveFrame { + for (auto const& [viewId, contentSize] : _contentSizes) { + if (CGSizeEqualToSize(contentSize, CGSizeZero)) { + return NO; + } + } + return YES; +} + +- (BOOL)someViewsHaveFrame { + for (auto const& [viewId, contentSize] : _contentSizes) { + if (!CGSizeEqualToSize(contentSize, CGSizeZero)) { + return YES; + } + } + return NO; +} + - (void)drain { FML_DCHECK([NSThread isMainThread]); @@ -41,7 +74,7 @@ - (void)blockUntilFrameAvailable { _beginResizeWaiting = YES; - while (CGSizeEqualToSize(_contentSize, CGSizeZero) && !_shuttingDown) { + while (![self someViewsHaveFrame] && !_shuttingDown) { _condBlockBeginResize.wait(lock); [self drain]; } @@ -49,10 +82,12 @@ - (void)blockUntilFrameAvailable { _beginResizeWaiting = NO; } -- (void)beginResize:(CGSize)size notify:(nonnull dispatch_block_t)notify { +- (void)beginResizeForView:(int64_t)viewId + size:(CGSize)size + notify:(nonnull dispatch_block_t)notify { std::unique_lock lock(_mutex); - if (CGSizeEqualToSize(_contentSize, CGSizeZero) || _shuttingDown) { + if (![self allViewsHaveFrame] || _shuttingDown) { // No blocking until framework produces at least one frame notify(); return; @@ -62,12 +97,18 @@ - (void)beginResize:(CGSize)size notify:(nonnull dispatch_block_t)notify { notify(); - _contentSize = CGSizeMake(-1, -1); + _contentSizes[viewId] = CGSizeMake(-1, -1); _beginResizeWaiting = YES; - while (!CGSizeEqualToSize(_contentSize, size) && // - !CGSizeEqualToSize(_contentSize, CGSizeZero) && !_shuttingDown) { + while (true) { + if (_shuttingDown) { + break; + } + const CGSize& contentSize = _contentSizes[viewId]; + if (CGSizeEqualToSize(contentSize, size) || CGSizeEqualToSize(contentSize, CGSizeZero)) { + break; + } _condBlockBeginResize.wait(lock); [self drain]; } @@ -75,7 +116,9 @@ - (void)beginResize:(CGSize)size notify:(nonnull dispatch_block_t)notify { _beginResizeWaiting = NO; } -- (void)performCommit:(CGSize)size notify:(nonnull dispatch_block_t)notify { +- (void)performCommitForView:(int64_t)viewId + size:(CGSize)size + notify:(nonnull dispatch_block_t)notify { fml::AutoResetWaitableEvent event; { std::unique_lock lock(_mutex); @@ -87,7 +130,7 @@ - (void)performCommit:(CGSize)size notify:(nonnull dispatch_block_t)notify { fml::AutoResetWaitableEvent& e = event; _scheduledBlocks.push_back(^{ notify(); - _contentSize = size; + _contentSizes[viewId] = size; e.Signal(); }); if (_beginResizeWaiting) { @@ -102,6 +145,14 @@ - (void)performCommit:(CGSize)size notify:(nonnull dispatch_block_t)notify { event.Wait(); } +- (void)registerView:(int64_t)viewId { + _contentSizes[viewId] = CGSizeZero; +} + +- (void)deregisterView:(int64_t)viewId { + _contentSizes.erase(viewId); +} + - (void)shutdown { std::unique_lock lock(_mutex); _shuttingDown = YES; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.h b/shell/platform/darwin/macos/framework/Source/FlutterView.h index f581079574bdc..fe2d55aac554d 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.h @@ -44,7 +44,8 @@ constexpr FlutterViewId kFlutterDefaultViewId = 0ll; - (nullable instancetype)initWithMTLDevice:(nonnull id)device commandQueue:(nonnull id)commandQueue reshapeListener:(nonnull id)reshapeListener - NS_DESIGNATED_INITIALIZER; + threadSynchronizer:(nonnull FlutterThreadSynchronizer*)threadSynchronizer + viewId:(int64_t)viewId NS_DESIGNATED_INITIALIZER; - (nullable instancetype)initWithFrame:(NSRect)frameRect pixelFormat:(nullable NSOpenGLPixelFormat*)format NS_UNAVAILABLE; @@ -74,13 +75,3 @@ constexpr FlutterViewId kFlutterDefaultViewId = 0ll; - (void)setBackgroundColor:(nonnull NSColor*)color; @end - -@interface FlutterView (FlutterViewPrivate) - -/** - * Returns FlutterThreadSynchronizer for this view. - * Used for FlutterEngineTest. - */ -- (nonnull FlutterThreadSynchronizer*)threadSynchronizer; - -@end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.mm b/shell/platform/darwin/macos/framework/Source/FlutterView.mm index c3f802d43ed9e..db20790f07b57 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.mm @@ -10,6 +10,7 @@ #import @interface FlutterView () { + int64_t _viewId; __weak id _reshapeListener; FlutterThreadSynchronizer* _threadSynchronizer; FlutterSurfaceManager* _surfaceManager; @@ -21,40 +22,41 @@ @implementation FlutterView - (instancetype)initWithMTLDevice:(id)device commandQueue:(id)commandQueue - reshapeListener:(id)reshapeListener { + reshapeListener:(id)reshapeListener + threadSynchronizer:(FlutterThreadSynchronizer*)threadSynchronizer + viewId:(int64_t)viewId { self = [super initWithFrame:NSZeroRect]; if (self) { [self setWantsLayer:YES]; [self setBackgroundColor:[NSColor blackColor]]; [self setLayerContentsRedrawPolicy:NSViewLayerContentsRedrawDuringViewResize]; + _viewId = viewId; _reshapeListener = reshapeListener; - _threadSynchronizer = [[FlutterThreadSynchronizer alloc] init]; + _threadSynchronizer = threadSynchronizer; _surfaceManager = [[FlutterSurfaceManager alloc] initWithDevice:device commandQueue:commandQueue layer:self.layer delegate:self]; + [_threadSynchronizer registerView:viewId]; } return self; } - (void)onPresent:(CGSize)frameSize withBlock:(dispatch_block_t)block { - [_threadSynchronizer performCommit:frameSize notify:block]; + [_threadSynchronizer performCommitForView:_viewId size:frameSize notify:block]; } - (FlutterSurfaceManager*)surfaceManager { return _surfaceManager; } -- (FlutterThreadSynchronizer*)threadSynchronizer { - return _threadSynchronizer; -} - - (void)reshaped { CGSize scaledSize = [self convertSizeToBacking:self.bounds.size]; - [_threadSynchronizer beginResize:scaledSize - notify:^{ - [_reshapeListener viewDidReshape:self]; - }]; + [_threadSynchronizer beginResizeForView:_viewId + size:scaledSize + notify:^{ + [_reshapeListener viewDidReshape:self]; + }]; } - (void)setBackgroundColor:(NSColor*)color { @@ -113,7 +115,6 @@ - (BOOL)layer:(CALayer*)layer } - (void)shutdown { - [_threadSynchronizer shutdown]; } #pragma mark - NSAccessibility overrides diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index f6e9aa3eb957f..f7c082b694323 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -372,6 +372,10 @@ @implementation FlutterViewController { std::shared_ptr _bridge; FlutterViewId _id; + + // FlutterViewController does not actually uses the synchronizer, but only + // passes it to FlutterView. + __weak FlutterThreadSynchronizer* _weakViewThreadSynchronizer; } @synthesize viewId = _viewId; @@ -398,6 +402,7 @@ static void CommonInit(FlutterViewController* controller, FlutterEngine* engine) controller.engine, controller.viewId); controller->_mouseTrackingMode = FlutterMouseTrackingModeInKeyWindow; controller->_textInputPlugin = [[FlutterTextInputPlugin alloc] initWithViewController:controller]; + controller->_weakViewThreadSynchronizer = engine.threadSynchronizer; [controller initializeKeyboard]; [controller notifySemanticsEnabledChanged]; // macOS fires this message when changing IMEs. @@ -858,7 +863,9 @@ - (nonnull FlutterView*)createFlutterViewWithMTLDevice:(id)device commandQueue:(id)commandQueue { return [[FlutterView alloc] initWithMTLDevice:device commandQueue:commandQueue - reshapeListener:self]; + reshapeListener:self + threadSynchronizer:_weakViewThreadSynchronizer + viewId:_viewId]; } - (void)onKeyboardLayoutChanged { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm index 15ca078042fd8..7599b66e8b0ec 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewTest.mm @@ -8,6 +8,8 @@ #import "flutter/testing/testing.h" +constexpr int64_t kDefaultViewId = 0ll; + @interface TestReshapeListener : NSObject @end @@ -23,8 +25,11 @@ - (void)viewDidReshape:(nonnull NSView*)view { id device = MTLCreateSystemDefaultDevice(); id queue = [device newCommandQueue]; TestReshapeListener* listener = [[TestReshapeListener alloc] init]; + FlutterThreadSynchronizer* threadSynchronizer = [[FlutterThreadSynchronizer alloc] init]; FlutterView* view = [[FlutterView alloc] initWithMTLDevice:device commandQueue:queue - reshapeListener:listener]; + reshapeListener:listener + threadSynchronizer:threadSynchronizer + viewId:kDefaultViewId]; EXPECT_EQ([view layer:view.layer shouldInheritContentsScale:3.0 fromWindow:view.window], YES); } From f174bd44475ef55e984991df3e2f12e94d9cc5d4 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 16 May 2023 01:29:43 -0700 Subject: [PATCH 109/142] Fix 1 --- shell/platform/android/android_surface_gl_skia.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index ce7b3c63d50ba..91e98c9836085 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -222,7 +222,7 @@ sk_sp AndroidSurfaceGLSkia::GetGLInterface() const { return GPUSurfaceGLDelegate::GetGLInterface(); } -std::unique_ptr AndroidSurfaceGLSkia::CreateSnapshotSurface() { +std::unique_ptr AndroidSurfaceGLSkia::CreateSnapshotStudio() { if (!onscreen_surface_ || !onscreen_surface_->IsValid()) { onscreen_surface_ = android_context_->CreatePbufferSurface(); } From ecbb1a9f4b33700e6e95bc317ce5452e5ea6407f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 16 May 2023 01:36:16 -0700 Subject: [PATCH 110/142] Fix more --- shell/platform/android/android_surface_gl_impeller.cc | 8 ++++---- shell/platform/android/android_surface_gl_skia.h | 3 +++ shell/platform/android/android_surface_vulkan_impeller.cc | 3 ++- .../ios/framework/Source/FlutterPlatformViewsTest.mm | 3 ++- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/shell/platform/android/android_surface_gl_impeller.cc b/shell/platform/android/android_surface_gl_impeller.cc index 532fbb3bbb879..646a53ab0f7a3 100644 --- a/shell/platform/android/android_surface_gl_impeller.cc +++ b/shell/platform/android/android_surface_gl_impeller.cc @@ -36,10 +36,10 @@ bool AndroidSurfaceGLImpeller::IsValid() const { // |AndroidSurface| std::unique_ptr AndroidSurfaceGLImpeller::CreateGPUStudio( GrDirectContext* gr_context) { - auto studio = - std::make_unique(this, // delegate - impeller_context_ // context - ); + auto studio = std::make_unique( + this, // delegate + android_context_->GetImpellerContext() // context + ); if (!studio->IsValid()) { return nullptr; } diff --git a/shell/platform/android/android_surface_gl_skia.h b/shell/platform/android/android_surface_gl_skia.h index df6bb29861aea..98a6d84346f95 100644 --- a/shell/platform/android/android_surface_gl_skia.h +++ b/shell/platform/android/android_surface_gl_skia.h @@ -89,6 +89,9 @@ class AndroidSurfaceGLSkia final : public GPUSurfaceGLDelegate, std::unique_ptr onscreen_surface_; std::unique_ptr offscreen_surface_; + sk_sp UseExistingMainContextOrCreate( + GrDirectContext* gr_context); + FML_DISALLOW_COPY_AND_ASSIGN(AndroidSurfaceGLSkia); }; diff --git a/shell/platform/android/android_surface_vulkan_impeller.cc b/shell/platform/android/android_surface_vulkan_impeller.cc index 238e2c6e5a681..76dbcfad08d67 100644 --- a/shell/platform/android/android_surface_vulkan_impeller.cc +++ b/shell/platform/android/android_surface_vulkan_impeller.cc @@ -40,7 +40,8 @@ std::unique_ptr AndroidSurfaceVulkanImpeller::CreateGPUStudio( } std::unique_ptr studio = - std::make_unique(impeller_context_); + std::make_unique( + android_context_->GetImpellerContext()); if (!studio->IsValid()) { return nullptr; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index 00fb2e05bc85d..0891cbe184242 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -2955,7 +2955,8 @@ - (void)testOnlyPlatformViewsAreRemovedWhenReset { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface)); + flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, + std::move(mock_surface)); UIView* someView = [[[UIView alloc] init] autorelease]; [mockFlutterView addSubview:someView]; From ea97d923968cbcee0ece402fc20d1e802a3fa1ba Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 16 May 2023 11:35:15 -0700 Subject: [PATCH 111/142] Fix compile --- impeller/renderer/backend/vulkan/command_encoder_vk.cc | 4 ++-- impeller/renderer/backend/vulkan/descriptor_pool_vk.cc | 2 +- shell/platform/android/android_surface_gl_skia.cc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/impeller/renderer/backend/vulkan/command_encoder_vk.cc b/impeller/renderer/backend/vulkan/command_encoder_vk.cc index 7b234b470c1dc..4e5857ef18fd4 100644 --- a/impeller/renderer/backend/vulkan/command_encoder_vk.cc +++ b/impeller/renderer/backend/vulkan/command_encoder_vk.cc @@ -16,7 +16,7 @@ class TrackedObjectsVK { public: explicit TrackedObjectsVK(std::weak_ptr device_holder, const std::shared_ptr& pool) - : desc_pool_(device_holder) { + : desc_pool_(std::move(device_holder)) { if (!pool) { return; } @@ -96,7 +96,7 @@ class TrackedObjectsVK { }; CommandEncoderVK::CommandEncoderVK( - std::weak_ptr device_holder, + const std::weak_ptr& device_holder, const std::shared_ptr& queue, const std::shared_ptr& pool, std::shared_ptr fence_waiter) diff --git a/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc b/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc index 7d2a6c4c5eccb..8c58ddfff1cd0 100644 --- a/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc +++ b/impeller/renderer/backend/vulkan/descriptor_pool_vk.cc @@ -10,7 +10,7 @@ namespace impeller { DescriptorPoolVK::DescriptorPoolVK( - std::weak_ptr device_holder) + const std::weak_ptr& device_holder) : device_holder_(device_holder) { FML_DCHECK(device_holder.lock()); } diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index 91e98c9836085..f4b7c34b97fc5 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -60,7 +60,7 @@ sk_sp AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( main_skia_context = GPUStudioGLSkia::MakeGLContext(this); android_context_->SetMainSkiaContext(main_skia_context); } - FML_DCHECK(GLContextPtr()->GetMainSkiaContext() == main_skia_context); + FML_DCHECK(android_context_()->GetMainSkiaContext() == main_skia_context); return main_skia_context; } } From f757ab7faf40dd0a01493797723facfcd162f603 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 16 May 2023 11:55:53 -0700 Subject: [PATCH 112/142] Compile --- impeller/renderer/backend/vulkan/command_encoder_vk.h | 2 +- impeller/renderer/backend/vulkan/descriptor_pool_vk.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/impeller/renderer/backend/vulkan/command_encoder_vk.h b/impeller/renderer/backend/vulkan/command_encoder_vk.h index d160385472702..e7b5d4c74f270 100644 --- a/impeller/renderer/backend/vulkan/command_encoder_vk.h +++ b/impeller/renderer/backend/vulkan/command_encoder_vk.h @@ -76,7 +76,7 @@ class CommandEncoderVK { std::shared_ptr tracked_objects_; bool is_valid_ = false; - CommandEncoderVK(std::weak_ptr device_holder, + CommandEncoderVK(const std::weak_ptr& device_holder, const std::shared_ptr& queue, const std::shared_ptr& pool, std::shared_ptr fence_waiter); diff --git a/impeller/renderer/backend/vulkan/descriptor_pool_vk.h b/impeller/renderer/backend/vulkan/descriptor_pool_vk.h index 5fb05d5827cb9..72b2da38408c6 100644 --- a/impeller/renderer/backend/vulkan/descriptor_pool_vk.h +++ b/impeller/renderer/backend/vulkan/descriptor_pool_vk.h @@ -27,7 +27,8 @@ namespace impeller { /// class DescriptorPoolVK { public: - explicit DescriptorPoolVK(std::weak_ptr device_holder); + explicit DescriptorPoolVK( + const std::weak_ptr& device_holder); ~DescriptorPoolVK(); From cad24e3aaf841714ae394dbe0444d8408ba61ac3 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 16 May 2023 12:45:49 -0700 Subject: [PATCH 113/142] Fix compile --- impeller/renderer/backend/vulkan/command_encoder_vk.cc | 5 +++-- shell/platform/android/android_surface_gl_skia.cc | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/impeller/renderer/backend/vulkan/command_encoder_vk.cc b/impeller/renderer/backend/vulkan/command_encoder_vk.cc index 4e5857ef18fd4..979b6969df038 100644 --- a/impeller/renderer/backend/vulkan/command_encoder_vk.cc +++ b/impeller/renderer/backend/vulkan/command_encoder_vk.cc @@ -14,8 +14,9 @@ namespace impeller { class TrackedObjectsVK { public: - explicit TrackedObjectsVK(std::weak_ptr device_holder, - const std::shared_ptr& pool) + explicit TrackedObjectsVK( + const std::weak_ptr& device_holder, + const std::shared_ptr& pool) : desc_pool_(std::move(device_holder)) { if (!pool) { return; diff --git a/shell/platform/android/android_surface_gl_skia.cc b/shell/platform/android/android_surface_gl_skia.cc index f4b7c34b97fc5..abd44d205345a 100644 --- a/shell/platform/android/android_surface_gl_skia.cc +++ b/shell/platform/android/android_surface_gl_skia.cc @@ -60,7 +60,7 @@ sk_sp AndroidSurfaceGLSkia::UseExistingMainContextOrCreate( main_skia_context = GPUStudioGLSkia::MakeGLContext(this); android_context_->SetMainSkiaContext(main_skia_context); } - FML_DCHECK(android_context_()->GetMainSkiaContext() == main_skia_context); + FML_DCHECK(android_context_->GetMainSkiaContext() == main_skia_context); return main_skia_context; } } From da84c2f26b5fb9334633b617818acb1b92123e62 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 16 May 2023 13:27:29 -0700 Subject: [PATCH 114/142] Fix lint --- impeller/renderer/backend/vulkan/command_encoder_vk.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/impeller/renderer/backend/vulkan/command_encoder_vk.cc b/impeller/renderer/backend/vulkan/command_encoder_vk.cc index 979b6969df038..d90e5caa4b211 100644 --- a/impeller/renderer/backend/vulkan/command_encoder_vk.cc +++ b/impeller/renderer/backend/vulkan/command_encoder_vk.cc @@ -17,7 +17,7 @@ class TrackedObjectsVK { explicit TrackedObjectsVK( const std::weak_ptr& device_holder, const std::shared_ptr& pool) - : desc_pool_(std::move(device_holder)) { + : desc_pool_(device_holder) { if (!pool) { return; } From df41175f67a7225fc3e00ea77c6081ad9cd7125f Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 19 May 2023 00:05:11 -0700 Subject: [PATCH 115/142] Remove Surface::GetContext --- flow/surface.h | 2 -- shell/gpu/gpu_surface_gl_impeller.cc | 6 ------ shell/gpu/gpu_surface_gl_impeller.h | 3 --- shell/gpu/gpu_surface_gl_skia.cc | 5 ----- shell/gpu/gpu_surface_gl_skia.h | 3 --- shell/gpu/gpu_surface_metal_impeller.h | 3 --- shell/gpu/gpu_surface_metal_impeller.mm | 5 ----- shell/gpu/gpu_surface_metal_skia.h | 3 --- shell/gpu/gpu_surface_metal_skia.mm | 7 +------ shell/gpu/gpu_surface_software.cc | 6 ------ shell/gpu/gpu_surface_software.h | 3 --- shell/gpu/gpu_surface_vulkan.cc | 4 ---- shell/gpu/gpu_surface_vulkan.h | 3 --- shell/gpu/gpu_surface_vulkan_impeller.cc | 6 ------ shell/gpu/gpu_surface_vulkan_impeller.h | 3 --- .../external_view_embedder_unittests.cc | 2 -- 16 files changed, 1 insertion(+), 63 deletions(-) diff --git a/flow/surface.h b/flow/surface.h index 947a6b8603a10..6de182275a90e 100644 --- a/flow/surface.h +++ b/flow/surface.h @@ -40,8 +40,6 @@ class Surface { virtual SkMatrix GetRootTransformation() const = 0; - virtual GrDirectContext* GetContext() = 0; - /// Capture the `SurfaceData` currently present in the surface. /// /// Not guaranteed to work on all setups and not intended to be used in diff --git a/shell/gpu/gpu_surface_gl_impeller.cc b/shell/gpu/gpu_surface_gl_impeller.cc index e024a3f5fb439..e8a75f216dfab 100644 --- a/shell/gpu/gpu_surface_gl_impeller.cc +++ b/shell/gpu/gpu_surface_gl_impeller.cc @@ -134,10 +134,4 @@ SkMatrix GPUSurfaceGLImpeller::GetRootTransformation() const { return {}; } -// |Surface| -GrDirectContext* GPUSurfaceGLImpeller::GetContext() { - // Impeller != Skia. - return nullptr; -} - } // namespace flutter diff --git a/shell/gpu/gpu_surface_gl_impeller.h b/shell/gpu/gpu_surface_gl_impeller.h index aaec9cb13c57d..49a750d5de2a6 100644 --- a/shell/gpu/gpu_surface_gl_impeller.h +++ b/shell/gpu/gpu_surface_gl_impeller.h @@ -41,9 +41,6 @@ class GPUSurfaceGLImpeller final : public Surface { // |Surface| SkMatrix GetRootTransformation() const override; - // |Surface| - GrDirectContext* GetContext() override; - FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceGLImpeller); }; diff --git a/shell/gpu/gpu_surface_gl_skia.cc b/shell/gpu/gpu_surface_gl_skia.cc index b5f86d63882f0..2a66d7e8862a5 100644 --- a/shell/gpu/gpu_surface_gl_skia.cc +++ b/shell/gpu/gpu_surface_gl_skia.cc @@ -284,9 +284,4 @@ sk_sp GPUSurfaceGLSkia::AcquireRenderSurface( return onscreen_surface_; } -// |Surface| -GrDirectContext* GPUSurfaceGLSkia::GetContext() { - return context_.get(); -} - } // namespace flutter diff --git a/shell/gpu/gpu_surface_gl_skia.h b/shell/gpu/gpu_surface_gl_skia.h index 6367c8112584d..ba666f35a43cf 100644 --- a/shell/gpu/gpu_surface_gl_skia.h +++ b/shell/gpu/gpu_surface_gl_skia.h @@ -39,9 +39,6 @@ class GPUSurfaceGLSkia : public Surface { // |Surface| SkMatrix GetRootTransformation() const override; - // |Surface| - GrDirectContext* GetContext() override; - private: bool CreateOrUpdateSurfaces(const SkISize& size); diff --git a/shell/gpu/gpu_surface_metal_impeller.h b/shell/gpu/gpu_surface_metal_impeller.h index 89e77094fe32c..905acc850d36e 100644 --- a/shell/gpu/gpu_surface_metal_impeller.h +++ b/shell/gpu/gpu_surface_metal_impeller.h @@ -49,9 +49,6 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalImpeller : public Surface { // |Surface| SkMatrix GetRootTransformation() const override; - // |Surface| - GrDirectContext* GetContext() override; - FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceMetalImpeller); }; diff --git a/shell/gpu/gpu_surface_metal_impeller.mm b/shell/gpu/gpu_surface_metal_impeller.mm index 6ddfc68bab320..3c4d509298736 100644 --- a/shell/gpu/gpu_surface_metal_impeller.mm +++ b/shell/gpu/gpu_surface_metal_impeller.mm @@ -163,11 +163,6 @@ return {}; } -// |Surface| -GrDirectContext* GPUSurfaceMetalImpeller::GetContext() { - return nullptr; -} - Surface::SurfaceData GPUSurfaceMetalImpeller::GetSurfaceData() const { if (!(last_drawable_ && [last_drawable_ conformsToProtocol:@protocol(CAMetalDrawable)])) { return {}; diff --git a/shell/gpu/gpu_surface_metal_skia.h b/shell/gpu/gpu_surface_metal_skia.h index f828a4e9a9938..38920f02dbdc1 100644 --- a/shell/gpu/gpu_surface_metal_skia.h +++ b/shell/gpu/gpu_surface_metal_skia.h @@ -52,9 +52,6 @@ class SK_API_AVAILABLE_CA_METAL_LAYER GPUSurfaceMetalSkia : public Surface { // |Surface| SkMatrix GetRootTransformation() const override; - // |Surface| - GrDirectContext* GetContext() override; - // |Surface| std::unique_ptr AcquireFrameFromCAMetalLayer( const SkISize& frame_info); diff --git a/shell/gpu/gpu_surface_metal_skia.mm b/shell/gpu/gpu_surface_metal_skia.mm index 6130265089e55..e5566b42a6f50 100644 --- a/shell/gpu/gpu_surface_metal_skia.mm +++ b/shell/gpu/gpu_surface_metal_skia.mm @@ -96,7 +96,7 @@ [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { return true; }, frame_size); } - sksl_precompiler_->PrecompileKnownSkSLsIfNecessary(GetContext()); + sksl_precompiler_->PrecompileKnownSkSLsIfNecessary(context_.get()); switch (render_target_type_) { case MTLRenderTargetType::kCAMetalLayer: @@ -242,9 +242,4 @@ return {}; } -// |Surface| -GrDirectContext* GPUSurfaceMetalSkia::GetContext() { - return context_.get(); -} - } // namespace flutter diff --git a/shell/gpu/gpu_surface_software.cc b/shell/gpu/gpu_surface_software.cc index d61cf66dc93c3..e4a71ca5355f4 100644 --- a/shell/gpu/gpu_surface_software.cc +++ b/shell/gpu/gpu_surface_software.cc @@ -91,10 +91,4 @@ SkMatrix GPUSurfaceSoftware::GetRootTransformation() const { return matrix; } -// |Surface| -GrDirectContext* GPUSurfaceSoftware::GetContext() { - // There is no GrContext associated with a software surface. - return nullptr; -} - } // namespace flutter diff --git a/shell/gpu/gpu_surface_software.h b/shell/gpu/gpu_surface_software.h index 2c9a2fc73c373..0acd344a9d04d 100644 --- a/shell/gpu/gpu_surface_software.h +++ b/shell/gpu/gpu_surface_software.h @@ -29,9 +29,6 @@ class GPUSurfaceSoftware : public Surface { // |Surface| SkMatrix GetRootTransformation() const override; - // |Surface| - GrDirectContext* GetContext() override; - private: GPUSurfaceSoftwareDelegate* delegate_; // TODO(38466): Refactor GPU surface APIs take into account the fact that an diff --git a/shell/gpu/gpu_surface_vulkan.cc b/shell/gpu/gpu_surface_vulkan.cc index b07b986add019..5997f23a53875 100644 --- a/shell/gpu/gpu_surface_vulkan.cc +++ b/shell/gpu/gpu_surface_vulkan.cc @@ -94,10 +94,6 @@ SkMatrix GPUSurfaceVulkan::GetRootTransformation() const { return matrix; } -GrDirectContext* GPUSurfaceVulkan::GetContext() { - return skia_context_.get(); -} - sk_sp GPUSurfaceVulkan::CreateSurfaceFromVulkanImage( const VkImage image, const VkFormat format, diff --git a/shell/gpu/gpu_surface_vulkan.h b/shell/gpu/gpu_surface_vulkan.h index 7b32f7da9bc40..a7ef9df141981 100644 --- a/shell/gpu/gpu_surface_vulkan.h +++ b/shell/gpu/gpu_surface_vulkan.h @@ -46,9 +46,6 @@ class GPUSurfaceVulkan : public Surface { // |Surface| SkMatrix GetRootTransformation() const override; - // |Surface| - GrDirectContext* GetContext() override; - static SkColorType ColorTypeFromFormat(const VkFormat format); private: diff --git a/shell/gpu/gpu_surface_vulkan_impeller.cc b/shell/gpu/gpu_surface_vulkan_impeller.cc index 81ee597e94e1d..16aadcfa85817 100644 --- a/shell/gpu/gpu_surface_vulkan_impeller.cc +++ b/shell/gpu/gpu_surface_vulkan_impeller.cc @@ -104,10 +104,4 @@ SkMatrix GPUSurfaceVulkanImpeller::GetRootTransformation() const { return {}; } -// |Surface| -GrDirectContext* GPUSurfaceVulkanImpeller::GetContext() { - // Impeller != Skia. - return nullptr; -} - } // namespace flutter diff --git a/shell/gpu/gpu_surface_vulkan_impeller.h b/shell/gpu/gpu_surface_vulkan_impeller.h index d3421fa1d834b..5f6aee9f13530 100644 --- a/shell/gpu/gpu_surface_vulkan_impeller.h +++ b/shell/gpu/gpu_surface_vulkan_impeller.h @@ -38,9 +38,6 @@ class GPUSurfaceVulkanImpeller final : public Surface { // |Surface| SkMatrix GetRootTransformation() const override; - // |Surface| - GrDirectContext* GetContext() override; - FML_DISALLOW_COPY_AND_ASSIGN(GPUSurfaceVulkanImpeller); }; 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 c3800020b79ec..1d9792f92b4f7 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 @@ -57,8 +57,6 @@ class SurfaceMock : public Surface { (override)); MOCK_METHOD(SkMatrix, GetRootTransformation, (), (const, override)); - - MOCK_METHOD(GrDirectContext*, GetContext, (), (override)); }; fml::RefPtr GetThreadMergerFromPlatformThread( From 6d33a118bb220ec964c4dedbf5db848564d4a08a Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 19 May 2023 14:04:59 -0700 Subject: [PATCH 116/142] Update shell_test_platform_view_vulkan.h --- shell/common/shell_test_platform_view_vulkan.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 54067aa11de76..8775f0ef4e8c1 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -35,8 +35,6 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { ~OffScreenContext(); - sk_sp GetContext() { return context_; } - private: fml::RefPtr vk_; std::unique_ptr application_; From 6eef03009819e2bb304e8c32db2a40c7546527e0 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 19 May 2023 14:11:18 -0700 Subject: [PATCH 117/142] Compile --- shell/common/shell_test_platform_view_vulkan.cc | 6 +----- shell/common/shell_test_platform_view_vulkan.h | 5 ++--- .../darwin/macos/framework/Source/FlutterEngineTest.mm | 4 ++-- shell/platform/fuchsia/flutter/surface.cc | 5 ----- shell/platform/fuchsia/flutter/surface.h | 3 --- 5 files changed, 5 insertions(+), 18 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 60bfd7ba49697..ee8132f4d2283 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -204,7 +204,7 @@ ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( ShellTestPlatformViewVulkan::OffScreenSurface::~OffScreenSurface() {} bool ShellTestPlatformViewVulkan::OffScreenSurface::IsValid() { - return GetContext(); + return offscreen_context_->GetContext(); } std::unique_ptr @@ -229,10 +229,6 @@ ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame( /*frame_size=*/SkISize::Make(800, 600)); } -GrDirectContext* ShellTestPlatformViewVulkan::OffScreenSurface::GetContext() { - return offscreen_context_->GetContext().get(); -} - SkMatrix ShellTestPlatformViewVulkan::OffScreenSurface::GetRootTransformation() const { SkMatrix matrix; diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 8775f0ef4e8c1..6ffa904dd1afc 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -35,6 +35,8 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { ~OffScreenContext(); + sk_sp GetContext() { return context_; } + private: fml::RefPtr vk_; std::unique_ptr application_; @@ -91,9 +93,6 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { // |Surface| SkMatrix GetRootTransformation() const override; - // |Surface| - GrDirectContext* GetContext() override; - private: std::shared_ptr shell_test_external_view_embedder_; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index 450d5499de259..c1e9ca2412170 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -830,8 +830,8 @@ - (nonnull NSView*)createWithViewIdentifier:(int64_t)viewId arguments:(nullable FlutterEngine* engine = GetFlutterEngine(); auto original_set_viewport_metrics = engine.embedderAPI.SendWindowMetricsEvent; engine.embedderAPI.SendWindowMetricsEvent = MOCK_ENGINE_PROC( - SendWindowMetricsEvent, - ([&updated, &original_set_viewport_metrics](auto engine, auto* window_metrics) { + SendWindowMetricsEvent, ([&updated, &original_set_viewport_metrics]( + auto engine, int64_t view_id, auto* window_metrics) { updated = YES; return original_set_viewport_metrics(engine, window_metrics); })); diff --git a/shell/platform/fuchsia/flutter/surface.cc b/shell/platform/fuchsia/flutter/surface.cc index 13ff5f7c8a110..c0d8136b01404 100644 --- a/shell/platform/fuchsia/flutter/surface.cc +++ b/shell/platform/fuchsia/flutter/surface.cc @@ -40,11 +40,6 @@ std::unique_ptr Surface::AcquireFrame( size); } -// |flutter::Surface| -GrDirectContext* Surface::GetContext() { - return gr_context_; -} - // |flutter::Surface| SkMatrix Surface::GetRootTransformation() const { // This backend does not support delegating to the underlying platform to diff --git a/shell/platform/fuchsia/flutter/surface.h b/shell/platform/fuchsia/flutter/surface.h index b3e6621db5f09..a2eea7b28de86 100644 --- a/shell/platform/fuchsia/flutter/surface.h +++ b/shell/platform/fuchsia/flutter/surface.h @@ -34,9 +34,6 @@ class Surface final : public flutter::Surface { int64_t view_id, const SkISize& size) override; - // |flutter::Surface| - GrDirectContext* GetContext() override; - // |flutter::Surface| SkMatrix GetRootTransformation() const override; From 9b8ec84b50d9236a0398235959b3e9e80d97b1f2 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 19 May 2023 15:18:32 -0700 Subject: [PATCH 118/142] Compile --- shell/common/shell_test_platform_view_vulkan.cc | 6 +++++- shell/common/shell_test_platform_view_vulkan.h | 2 ++ .../darwin/macos/framework/Source/FlutterEngineTest.mm | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index ee8132f4d2283..0c10083be8abd 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -204,7 +204,7 @@ ShellTestPlatformViewVulkan::OffScreenSurface::OffScreenSurface( ShellTestPlatformViewVulkan::OffScreenSurface::~OffScreenSurface() {} bool ShellTestPlatformViewVulkan::OffScreenSurface::IsValid() { - return offscreen_context_->GetContext(); + return GetContext(); } std::unique_ptr @@ -229,6 +229,10 @@ ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame( /*frame_size=*/SkISize::Make(800, 600)); } +GrDirectContext* ShellTestPlatformViewVulkan::OffScreenSurface::GetContext() { + return offscreen_context_->GetContext(); +} + SkMatrix ShellTestPlatformViewVulkan::OffScreenSurface::GetRootTransformation() const { SkMatrix matrix; diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 6ffa904dd1afc..a2c762259eb58 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -94,6 +94,8 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { SkMatrix GetRootTransformation() const override; private: + GrDirectContext* GetContext(); + std::shared_ptr shell_test_external_view_embedder_; std::shared_ptr offscreen_context_; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index c1e9ca2412170..992704f2aba23 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -833,7 +833,7 @@ - (nonnull NSView*)createWithViewIdentifier:(int64_t)viewId arguments:(nullable SendWindowMetricsEvent, ([&updated, &original_set_viewport_metrics]( auto engine, int64_t view_id, auto* window_metrics) { updated = YES; - return original_set_viewport_metrics(engine, window_metrics); + return original_set_viewport_metrics(engine, view_id, window_metrics); })); EXPECT_TRUE([engine runWithEntrypoint:@"main"]); From 9e592956b75167d3e71fb0e293c43c3941986fa0 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 19 May 2023 15:26:18 -0700 Subject: [PATCH 119/142] Compile --- shell/common/shell_test_platform_view_vulkan.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 0c10083be8abd..60bfd7ba49697 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -230,7 +230,7 @@ ShellTestPlatformViewVulkan::OffScreenSurface::AcquireFrame( } GrDirectContext* ShellTestPlatformViewVulkan::OffScreenSurface::GetContext() { - return offscreen_context_->GetContext(); + return offscreen_context_->GetContext().get(); } SkMatrix ShellTestPlatformViewVulkan::OffScreenSurface::GetRootTransformation() From 931cb91bb93a3e8b4ee7d606065be903212bd947 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sat, 20 May 2023 22:17:17 -0700 Subject: [PATCH 120/142] Fix fuchsia compile --- shell/platform/fuchsia/flutter/surface.cc | 4 +--- shell/platform/fuchsia/flutter/surface.h | 4 ---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/shell/platform/fuchsia/flutter/surface.cc b/shell/platform/fuchsia/flutter/surface.cc index c0d8136b01404..5b8e1d29623fe 100644 --- a/shell/platform/fuchsia/flutter/surface.cc +++ b/shell/platform/fuchsia/flutter/surface.cc @@ -16,9 +16,7 @@ namespace flutter_runner { Surface::Surface(std::string debug_label, std::shared_ptr view_embedder, GrDirectContext* gr_context) - : debug_label_(std::move(debug_label)), - view_embedder_(view_embedder), - gr_context_(gr_context) {} + : debug_label_(std::move(debug_label)) {} Surface::~Surface() = default; diff --git a/shell/platform/fuchsia/flutter/surface.h b/shell/platform/fuchsia/flutter/surface.h index a2eea7b28de86..acfaff43659c0 100644 --- a/shell/platform/fuchsia/flutter/surface.h +++ b/shell/platform/fuchsia/flutter/surface.h @@ -22,10 +22,6 @@ class Surface final : public flutter::Surface { ~Surface() override; private: - const std::string debug_label_; - std::shared_ptr view_embedder_; - GrDirectContext* gr_context_; - // |flutter::Surface| bool IsValid() override; From 70d4fc68a47e01d139f495335c6f0390a338a1d3 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sun, 21 May 2023 02:08:28 -0700 Subject: [PATCH 121/142] Lint --- impeller/renderer/backend/vulkan/pipeline_vk.cc | 2 +- impeller/renderer/backend/vulkan/shader_library_vk.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/impeller/renderer/backend/vulkan/pipeline_vk.cc b/impeller/renderer/backend/vulkan/pipeline_vk.cc index bc971cd7695a9..c1ca1e3084765 100644 --- a/impeller/renderer/backend/vulkan/pipeline_vk.cc +++ b/impeller/renderer/backend/vulkan/pipeline_vk.cc @@ -14,7 +14,7 @@ PipelineVK::PipelineVK(std::weak_ptr device_holder, vk::UniquePipelineLayout layout, vk::UniqueDescriptorSetLayout descriptor_set_layout) : Pipeline(std::move(library), desc), - device_holder_(device_holder), + device_holder_(std::move(device_holder)), pipeline_(std::move(pipeline)), render_pass_(std::move(render_pass)), layout_(std::move(layout)), diff --git a/impeller/renderer/backend/vulkan/shader_library_vk.cc b/impeller/renderer/backend/vulkan/shader_library_vk.cc index 3988e156a6e51..ea92c36258b94 100644 --- a/impeller/renderer/backend/vulkan/shader_library_vk.cc +++ b/impeller/renderer/backend/vulkan/shader_library_vk.cc @@ -55,7 +55,7 @@ static std::string VKShaderNameToShaderKeyName(const std::string& name, ShaderLibraryVK::ShaderLibraryVK( std::weak_ptr device_holder, const std::vector>& shader_libraries_data) - : device_holder_(device_holder) { + : device_holder_(std::move(device_holder)) { TRACE_EVENT0("impeller", "CreateShaderLibrary"); bool success = true; auto iterator = [&](auto type, // From 3bcd96a552a85fd351ce787b7f6037de31809c16 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Sun, 21 May 2023 21:19:11 -0700 Subject: [PATCH 122/142] Move back debug_label_ --- shell/platform/fuchsia/flutter/surface.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shell/platform/fuchsia/flutter/surface.h b/shell/platform/fuchsia/flutter/surface.h index acfaff43659c0..e6876392c7499 100644 --- a/shell/platform/fuchsia/flutter/surface.h +++ b/shell/platform/fuchsia/flutter/surface.h @@ -22,6 +22,8 @@ class Surface final : public flutter::Surface { ~Surface() override; private: + const std::string debug_label_; + // |flutter::Surface| bool IsValid() override; From b9226c9ae7efebd80bbb52765a31c057956d917e Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 22 May 2023 15:18:09 -0700 Subject: [PATCH 123/142] Basic test --- ci/licenses_golden/licenses_flutter | 4 ++++ shell/platform/darwin/macos/BUILD.gn | 1 + .../Source/FlutterThreadSynchronizer.h | 13 ++++++++++ .../Source/FlutterThreadSynchronizer.mm | 24 +++++++++++++++++-- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index c673eb20437be..efbcf647cab2a 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -2720,6 +2720,9 @@ ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTex ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextInputSemanticsObjectTest.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextureRegistrar.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextureRegistrar.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterUmbrellaImportTests.m + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.mm + ../../../flutter/LICENSE @@ -5362,6 +5365,7 @@ FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextu FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterTextureRegistrar.mm FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm +FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterUmbrellaImportTests.m FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.h FILE: ../../../flutter/shell/platform/darwin/macos/framework/Source/FlutterView.mm diff --git a/shell/platform/darwin/macos/BUILD.gn b/shell/platform/darwin/macos/BUILD.gn index edebb4ebfd3b1..16ffb24cd3f19 100644 --- a/shell/platform/darwin/macos/BUILD.gn +++ b/shell/platform/darwin/macos/BUILD.gn @@ -182,6 +182,7 @@ executable("flutter_desktop_darwin_unittests") { "framework/Source/FlutterSurfaceManagerTest.mm", "framework/Source/FlutterTextInputPluginTest.mm", "framework/Source/FlutterTextInputSemanticsObjectTest.mm", + "framework/Source/FlutterThreadSynchronizerTest.mm", "framework/Source/FlutterViewControllerTest.mm", "framework/Source/FlutterViewControllerTestUtils.h", "framework/Source/FlutterViewControllerTestUtils.mm", diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h index 5cc399cb33279..4f0e1f7ad14ef 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h @@ -1,3 +1,7 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + #import /** @@ -5,6 +9,8 @@ */ @interface FlutterThreadSynchronizer : NSObject +- (nullable instancetype)init; + /** * Blocks current thread until there is frame available. * Used in FlutterEngineTest. @@ -42,3 +48,10 @@ - (void)shutdown; @end + +@interface FlutterThreadSynchronizer (Test) + +- (nullable instancetype)initWithMainQueue:(nonnull dispatch_queue_t)queue + mainThread:(nonnull NSThread*)thread; + +@end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm index 82f65f932e61d..43ba3853ff8fe 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm @@ -1,3 +1,7 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h" #import @@ -10,6 +14,8 @@ #import "flutter/fml/synchronization/waitable_event.h" @interface FlutterThreadSynchronizer () { + dispatch_queue_t _queue; + __weak NSThread* _queueThread; std::mutex _mutex; BOOL _shuttingDown; std::unordered_map _contentSizes; @@ -39,6 +45,20 @@ - (BOOL)someViewsHaveFrame; @implementation FlutterThreadSynchronizer +- (instancetype)init { + return [self initWithMainQueue:dispatch_get_main_queue() mainThread:[NSThread mainThread]]; +} + +- (instancetype)initWithMainQueue:(dispatch_queue_t)queue + mainThread:(NSThread*)thread { + self = [super init]; + if (self != nil) { + _queue = queue; + _queueThread = thread; + } + return self; +} + - (BOOL)allViewsHaveFrame { for (auto const& [viewId, contentSize] : _contentSizes) { if (CGSizeEqualToSize(contentSize, CGSizeZero)) { @@ -58,7 +78,7 @@ - (BOOL)someViewsHaveFrame { } - (void)drain { - FML_DCHECK([NSThread isMainThread]); + FML_DCHECK([NSThread currentThread] == _queueThread); [CATransaction begin]; [CATransaction setDisableActions:YES]; @@ -136,7 +156,7 @@ - (void)performCommitForView:(int64_t)viewId if (_beginResizeWaiting) { _condBlockBeginResize.notify_all(); } else { - dispatch_async(dispatch_get_main_queue(), ^{ + dispatch_async(_queue, ^{ std::unique_lock lock(_mutex); [self drain]; }); From 57e159f9bde5557a87a1cbe2316ca3c9e2165161 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 22 May 2023 17:31:37 -0700 Subject: [PATCH 124/142] Use set specific to check main --- .../Source/FlutterThreadSynchronizer.h | 3 +-- .../Source/FlutterThreadSynchronizer.mm | 22 ++++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h index 4f0e1f7ad14ef..6c424bf5d9fb8 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h @@ -51,7 +51,6 @@ @interface FlutterThreadSynchronizer (Test) -- (nullable instancetype)initWithMainQueue:(nonnull dispatch_queue_t)queue - mainThread:(nonnull NSThread*)thread; +- (nullable instancetype)initWithMainQueue:(nonnull dispatch_queue_t)queue; @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm index 43ba3853ff8fe..4bdc672e79f5e 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm @@ -13,9 +13,10 @@ #import "flutter/fml/logging.h" #import "flutter/fml/synchronization/waitable_event.h" +static constexpr intptr_t _kMainQueueContext = 0x1234ABCD; + @interface FlutterThreadSynchronizer () { dispatch_queue_t _queue; - __weak NSThread* _queueThread; std::mutex _mutex; BOOL _shuttingDown; std::unordered_map _contentSizes; @@ -41,24 +42,29 @@ - (BOOL)allViewsHaveFrame; */ - (BOOL)someViewsHaveFrame; +- (const void*)mainQueueKey; + @end @implementation FlutterThreadSynchronizer - (instancetype)init { - return [self initWithMainQueue:dispatch_get_main_queue() mainThread:[NSThread mainThread]]; + return [self initWithMainQueue:dispatch_get_main_queue()]; } -- (instancetype)initWithMainQueue:(dispatch_queue_t)queue - mainThread:(NSThread*)thread { +- (instancetype)initWithMainQueue:(dispatch_queue_t)queue { self = [super init]; if (self != nil) { _queue = queue; - _queueThread = thread; + dispatch_queue_set_specific(_queue, [self mainQueueKey], (void*)_kMainQueueContext, NULL); } return self; } +- (void)dealloc { + dispatch_queue_set_specific(_queue, [self mainQueueKey], NULL, NULL); +} + - (BOOL)allViewsHaveFrame { for (auto const& [viewId, contentSize] : _contentSizes) { if (CGSizeEqualToSize(contentSize, CGSizeZero)) { @@ -78,7 +84,7 @@ - (BOOL)someViewsHaveFrame { } - (void)drain { - FML_DCHECK([NSThread currentThread] == _queueThread); + FML_DCHECK(dispatch_get_specific([self mainQueueKey]) == (void*)_kMainQueueContext); [CATransaction begin]; [CATransaction setDisableActions:YES]; @@ -180,4 +186,8 @@ - (void)shutdown { [self drain]; } +- (const void*)mainQueueKey { + return (__bridge const void*)self; +} + @end From 85b1262719917475f0b04632c0f0d3605783688c Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Mon, 22 May 2023 17:50:49 -0700 Subject: [PATCH 125/142] Use set specific to check main --- .../framework/Source/FlutterThreadSynchronizer.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h index 6c424bf5d9fb8..3141b7b001cb6 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h @@ -12,13 +12,7 @@ - (nullable instancetype)init; /** - * Blocks current thread until there is frame available. - * Used in FlutterEngineTest. - */ -- (void)blockUntilFrameAvailable; - -/** - * Called from platform thread. Blocks until commit with given size (or empty) + * Called from platform thread. Blocks until a commit with given size (or empty) * is requested. */ - (void)beginResizeForView:(int64_t)viewId @@ -53,4 +47,10 @@ - (nullable instancetype)initWithMainQueue:(nonnull dispatch_queue_t)queue; +/** + * Blocks current thread until there is frame available. + * Used in FlutterEngineTest. + */ +- (void)blockUntilFrameAvailable; + @end From 23c3851c788ce2efd9640bb373f3d30acad3e246 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 23 May 2023 01:13:50 -0700 Subject: [PATCH 126/142] FinishResizingOnlyWhenCommittingMatchingSize --- .../Source/FlutterThreadSynchronizer.h | 2 + .../Source/FlutterThreadSynchronizer.mm | 22 +-- .../Source/FlutterThreadSynchronizerTest.mm | 161 ++++++++++++++++++ 3 files changed, 170 insertions(+), 15 deletions(-) create mode 100644 shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h index 3141b7b001cb6..6c9279e8d0e85 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h @@ -47,6 +47,8 @@ - (nullable instancetype)initWithMainQueue:(nonnull dispatch_queue_t)queue; +- (BOOL)isWaitingWhenMutexIsAvailable; + /** * Blocks current thread until there is frame available. * Used in FlutterEngineTest. diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm index 4bdc672e79f5e..82229bbd5fa5f 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm @@ -13,10 +13,8 @@ #import "flutter/fml/logging.h" #import "flutter/fml/synchronization/waitable_event.h" -static constexpr intptr_t _kMainQueueContext = 0x1234ABCD; - @interface FlutterThreadSynchronizer () { - dispatch_queue_t _queue; + dispatch_queue_t _mainQueue; std::mutex _mutex; BOOL _shuttingDown; std::unordered_map _contentSizes; @@ -42,8 +40,6 @@ - (BOOL)allViewsHaveFrame; */ - (BOOL)someViewsHaveFrame; -- (const void*)mainQueueKey; - @end @implementation FlutterThreadSynchronizer @@ -55,16 +51,11 @@ - (instancetype)init { - (instancetype)initWithMainQueue:(dispatch_queue_t)queue { self = [super init]; if (self != nil) { - _queue = queue; - dispatch_queue_set_specific(_queue, [self mainQueueKey], (void*)_kMainQueueContext, NULL); + _mainQueue = queue; } return self; } -- (void)dealloc { - dispatch_queue_set_specific(_queue, [self mainQueueKey], NULL, NULL); -} - - (BOOL)allViewsHaveFrame { for (auto const& [viewId, contentSize] : _contentSizes) { if (CGSizeEqualToSize(contentSize, CGSizeZero)) { @@ -84,7 +75,7 @@ - (BOOL)someViewsHaveFrame { } - (void)drain { - FML_DCHECK(dispatch_get_specific([self mainQueueKey]) == (void*)_kMainQueueContext); + dispatch_assert_queue(_mainQueue); [CATransaction begin]; [CATransaction setDisableActions:YES]; @@ -162,7 +153,7 @@ - (void)performCommitForView:(int64_t)viewId if (_beginResizeWaiting) { _condBlockBeginResize.notify_all(); } else { - dispatch_async(_queue, ^{ + dispatch_async(_mainQueue, ^{ std::unique_lock lock(_mutex); [self drain]; }); @@ -186,8 +177,9 @@ - (void)shutdown { [self drain]; } -- (const void*)mainQueueKey { - return (__bridge const void*)self; +- (BOOL)isWaitingWhenMutexIsAvailable { + std::unique_lock lock(_mutex); + return _beginResizeWaiting; } @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm new file mode 100644 index 0000000000000..0f886c77ab3b7 --- /dev/null +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm @@ -0,0 +1,161 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h" + +#import +#import "flutter/testing/testing.h" +#import "flutter/fml/synchronization/waitable_event.h" + +namespace flutter::testing { + +namespace { + +} // namespace + +} // namespace flutter::testing + +@interface FlutterThreadSynchronizerTestScaffold : NSObject + +@property(nonatomic, readonly, nonnull) FlutterThreadSynchronizer* synchronizer; + +- (nullable instancetype)init; +- (void)dispatchMainTask:(nonnull void(^)())task; +- (void)dispatchRenderTask:(nonnull void(^)())task; +- (void)joinMain; +- (void)joinRender; +@end + +@implementation FlutterThreadSynchronizerTestScaffold { + dispatch_queue_t _mainQueue; + std::shared_ptr _mainLatch; + + dispatch_queue_t _renderQueue; + std::shared_ptr _renderLatch; + + FlutterThreadSynchronizer* _synchronizer; +} + +@synthesize synchronizer = _synchronizer; + +- (nullable instancetype)init { + self = [super init]; + if (self != nil) { + _mainQueue = dispatch_queue_create("MAIN", DISPATCH_QUEUE_SERIAL); + _renderQueue = dispatch_queue_create("RENDER", DISPATCH_QUEUE_SERIAL); + _synchronizer = [[FlutterThreadSynchronizer alloc] initWithMainQueue:_mainQueue]; + } + return self; +} + +- (void)dispatchMainTask:(nonnull void(^)())task { + dispatch_async(_mainQueue, task); +} + +- (void)dispatchRenderTask:(nonnull void(^)())task { + dispatch_async(_renderQueue, task); +} + +- (void)joinMain { + fml::AutoResetWaitableEvent latch; + fml::AutoResetWaitableEvent* pLatch = &latch; + dispatch_async(_mainQueue, ^{ pLatch->Signal(); }); + latch.Wait(); +} + +- (void)joinRender { + fml::AutoResetWaitableEvent latch; + fml::AutoResetWaitableEvent* pLatch = &latch; + dispatch_async(_renderQueue, ^{ pLatch->Signal(); }); + latch.Wait(); +} + +@end + +TEST(FlutterThreadSynchronizerTest, FinishResizingImmediatelyWhenSizeMatches) { + FlutterThreadSynchronizerTestScaffold* scaffold = [[FlutterThreadSynchronizerTestScaffold alloc] init]; + FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; + + [synchronizer registerView:1]; + + // Initial resize: does not block until the first frame. + __block int notifiedResize = 0; + [scaffold dispatchMainTask:^{ + [synchronizer beginResizeForView:1 size:CGSize{5, 5} notify:^{ + notifiedResize += 1; + }]; + }]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + [scaffold joinMain]; + EXPECT_EQ(notifiedResize, 1); + + // Still does not block. + [scaffold dispatchMainTask:^{ + [synchronizer beginResizeForView:1 size:CGSize{7, 7} notify:^{ + notifiedResize += 1; + }]; + }]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + [scaffold joinMain]; + EXPECT_EQ(notifiedResize, 2); + + // First frame + __block int notifiedCommit = 0; + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 size:CGSize{7, 7} notify:^{ + notifiedCommit += 1; + }]; + }]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + [scaffold joinRender]; + EXPECT_EQ(notifiedCommit, 1); +} + +TEST(FlutterThreadSynchronizerTest, FinishResizingOnlyWhenCommittingMatchingSize) { + FlutterThreadSynchronizerTestScaffold* scaffold = [[FlutterThreadSynchronizerTestScaffold alloc] init]; + FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; + fml::AutoResetWaitableEvent begunResizingLatch; + __block fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch; + + [synchronizer registerView:1]; + + // Initial resize: does not block until the first frame. + [scaffold dispatchMainTask:^{ + [synchronizer beginResizeForView:1 size:CGSize{5, 5} notify:^{}]; + }]; + [scaffold joinMain]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + + // First frame. + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 size:CGSize{5, 5} notify:^{}]; + }]; + [scaffold joinRender]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + + // Resize to (7, 7): blocks since there's a frame until the next frame. + [scaffold dispatchMainTask:^{ + [synchronizer beginResizeForView:1 size:CGSize{7, 7} notify:^{ + begunResizing->Signal(); + }]; + }]; + begunResizing->Wait(); + EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]); + + // Render with old size. + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 size:CGSize{5, 5} notify:^{}]; + }]; + [scaffold joinRender]; + EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]); + + // Render with new size. + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 size:CGSize{7, 7} notify:^{}]; + }]; + [scaffold joinRender]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + + [scaffold joinMain]; +} From b3cbb05c4ac492aa621272e7ca12c83f76808436 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 23 May 2023 14:30:30 -0700 Subject: [PATCH 127/142] FinishResizingWhenShuttingDown --- .../Source/FlutterThreadSynchronizer.h | 8 +- .../Source/FlutterThreadSynchronizer.mm | 3 + .../Source/FlutterThreadSynchronizerTest.mm | 143 ++++++++++++++---- 3 files changed, 123 insertions(+), 31 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h index 6c9279e8d0e85..74653956354ed 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h @@ -37,7 +37,9 @@ - (void)deregisterView:(int64_t)viewId; /** - * Called when shutting down. Unblocks everything and prevents any further synchronization. + * Called from platform thread when shutting down. + * + * Prevents any further synchronization and no longer blocks any threads. */ - (void)shutdown; @@ -47,6 +49,10 @@ - (nullable instancetype)initWithMainQueue:(nonnull dispatch_queue_t)queue; +/** + * Blocks current thread until the mutex is available, then return whether the + * synchronizer is waiting for a correct commit during resizing. + */ - (BOOL)isWaitingWhenMutexIsAvailable; /** diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm index 82229bbd5fa5f..a0561e4d30e8e 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm @@ -102,6 +102,7 @@ - (void)blockUntilFrameAvailable { - (void)beginResizeForView:(int64_t)viewId size:(CGSize)size notify:(nonnull dispatch_block_t)notify { + dispatch_assert_queue(_mainQueue); std::unique_lock lock(_mutex); if (![self allViewsHaveFrame] || _shuttingDown) { @@ -136,6 +137,7 @@ - (void)beginResizeForView:(int64_t)viewId - (void)performCommitForView:(int64_t)viewId size:(CGSize)size notify:(nonnull dispatch_block_t)notify { + dispatch_assert_queue_not(_mainQueue); fml::AutoResetWaitableEvent event; { std::unique_lock lock(_mutex); @@ -171,6 +173,7 @@ - (void)deregisterView:(int64_t)viewId { } - (void)shutdown { + dispatch_assert_queue(_mainQueue); std::unique_lock lock(_mutex); _shuttingDown = YES; _condBlockBeginResize.notify_all(); diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm index 0f886c77ab3b7..ef97b62a3785a 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm @@ -5,14 +5,12 @@ #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h" #import -#import "flutter/testing/testing.h" #import "flutter/fml/synchronization/waitable_event.h" +#import "flutter/testing/testing.h" namespace flutter::testing { -namespace { - -} // namespace +namespace {} // namespace } // namespace flutter::testing @@ -21,8 +19,8 @@ @interface FlutterThreadSynchronizerTestScaffold : NSObject @property(nonatomic, readonly, nonnull) FlutterThreadSynchronizer* synchronizer; - (nullable instancetype)init; -- (void)dispatchMainTask:(nonnull void(^)())task; -- (void)dispatchRenderTask:(nonnull void(^)())task; +- (void)dispatchMainTask:(nonnull void (^)())task; +- (void)dispatchRenderTask:(nonnull void (^)())task; - (void)joinMain; - (void)joinRender; @end @@ -49,32 +47,37 @@ - (nullable instancetype)init { return self; } -- (void)dispatchMainTask:(nonnull void(^)())task { +- (void)dispatchMainTask:(nonnull void (^)())task { dispatch_async(_mainQueue, task); } -- (void)dispatchRenderTask:(nonnull void(^)())task { +- (void)dispatchRenderTask:(nonnull void (^)())task { dispatch_async(_renderQueue, task); } - (void)joinMain { fml::AutoResetWaitableEvent latch; fml::AutoResetWaitableEvent* pLatch = &latch; - dispatch_async(_mainQueue, ^{ pLatch->Signal(); }); + dispatch_async(_mainQueue, ^{ + pLatch->Signal(); + }); latch.Wait(); } - (void)joinRender { fml::AutoResetWaitableEvent latch; fml::AutoResetWaitableEvent* pLatch = &latch; - dispatch_async(_renderQueue, ^{ pLatch->Signal(); }); + dispatch_async(_renderQueue, ^{ + pLatch->Signal(); + }); latch.Wait(); } @end TEST(FlutterThreadSynchronizerTest, FinishResizingImmediatelyWhenSizeMatches) { - FlutterThreadSynchronizerTestScaffold* scaffold = [[FlutterThreadSynchronizerTestScaffold alloc] init]; + FlutterThreadSynchronizerTestScaffold* scaffold = + [[FlutterThreadSynchronizerTestScaffold alloc] init]; FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; [synchronizer registerView:1]; @@ -82,9 +85,11 @@ - (void)joinRender { // Initial resize: does not block until the first frame. __block int notifiedResize = 0; [scaffold dispatchMainTask:^{ - [synchronizer beginResizeForView:1 size:CGSize{5, 5} notify:^{ - notifiedResize += 1; - }]; + [synchronizer beginResizeForView:1 + size:CGSize{5, 5} + notify:^{ + notifiedResize += 1; + }]; }]; EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); [scaffold joinMain]; @@ -92,9 +97,11 @@ - (void)joinRender { // Still does not block. [scaffold dispatchMainTask:^{ - [synchronizer beginResizeForView:1 size:CGSize{7, 7} notify:^{ - notifiedResize += 1; - }]; + [synchronizer beginResizeForView:1 + size:CGSize{7, 7} + notify:^{ + notifiedResize += 1; + }]; }]; EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); [scaffold joinMain]; @@ -103,9 +110,11 @@ - (void)joinRender { // First frame __block int notifiedCommit = 0; [scaffold dispatchRenderTask:^{ - [synchronizer performCommitForView:1 size:CGSize{7, 7} notify:^{ - notifiedCommit += 1; - }]; + [synchronizer performCommitForView:1 + size:CGSize{7, 7} + notify:^{ + notifiedCommit += 1; + }]; }]; EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); [scaffold joinRender]; @@ -113,49 +122,123 @@ - (void)joinRender { } TEST(FlutterThreadSynchronizerTest, FinishResizingOnlyWhenCommittingMatchingSize) { - FlutterThreadSynchronizerTestScaffold* scaffold = [[FlutterThreadSynchronizerTestScaffold alloc] init]; + FlutterThreadSynchronizerTestScaffold* scaffold = + [[FlutterThreadSynchronizerTestScaffold alloc] init]; FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; + // A latch to ensure that a beginResizeForView: call has at least executed + // something, so that the isWaitingWhenMutexIsAvailable: call correctly stops + // at either when beginResizeForView: finishes or waits half way. fml::AutoResetWaitableEvent begunResizingLatch; - __block fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch; + fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch; [synchronizer registerView:1]; // Initial resize: does not block until the first frame. [scaffold dispatchMainTask:^{ - [synchronizer beginResizeForView:1 size:CGSize{5, 5} notify:^{}]; + [synchronizer beginResizeForView:1 + size:CGSize{5, 5} + notify:^{ + }]; }]; [scaffold joinMain]; EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); // First frame. [scaffold dispatchRenderTask:^{ - [synchronizer performCommitForView:1 size:CGSize{5, 5} notify:^{}]; + [synchronizer performCommitForView:1 + size:CGSize{5, 5} + notify:^{ + }]; }]; [scaffold joinRender]; EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); - // Resize to (7, 7): blocks since there's a frame until the next frame. + // Resize to (7, 7): blocks until the next frame. [scaffold dispatchMainTask:^{ - [synchronizer beginResizeForView:1 size:CGSize{7, 7} notify:^{ - begunResizing->Signal(); - }]; + [synchronizer beginResizeForView:1 + size:CGSize{7, 7} + notify:^{ + begunResizing->Signal(); + }]; }]; begunResizing->Wait(); EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]); // Render with old size. [scaffold dispatchRenderTask:^{ - [synchronizer performCommitForView:1 size:CGSize{5, 5} notify:^{}]; + [synchronizer performCommitForView:1 + size:CGSize{5, 5} + notify:^{ + }]; }]; [scaffold joinRender]; EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]); // Render with new size. [scaffold dispatchRenderTask:^{ - [synchronizer performCommitForView:1 size:CGSize{7, 7} notify:^{}]; + [synchronizer performCommitForView:1 + size:CGSize{7, 7} + notify:^{ + }]; }]; [scaffold joinRender]; EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); [scaffold joinMain]; } + +TEST(FlutterThreadSynchronizerTest, FinishResizingWhenShuttingDown) { + FlutterThreadSynchronizerTestScaffold* scaffold = + [[FlutterThreadSynchronizerTestScaffold alloc] init]; + FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; + fml::AutoResetWaitableEvent begunResizingLatch; + fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch; + + [synchronizer registerView:1]; + + // Initial resize + [scaffold dispatchMainTask:^{ + [synchronizer beginResizeForView:1 + size:CGSize{5, 5} + notify:^{ + }]; + }]; + [scaffold joinMain]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + + // Push a frame. + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 + size:CGSize{5, 5} + notify:^{ + }]; + }]; + [scaffold joinRender]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + + [scaffold dispatchMainTask:^{ + [synchronizer shutdown]; + }]; + + // Resize to (7, 7). Should not block any frames since it has shut down. + [scaffold dispatchMainTask:^{ + [synchronizer beginResizeForView:1 + size:CGSize{7, 7} + notify:^{ + begunResizing->Signal(); + }]; + }]; + begunResizing->Wait(); + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + [scaffold joinMain]; + + // All further calls should be unblocking. + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 + size:CGSize{9, 9} + notify:^{ + }]; + }]; + [scaffold joinRender]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); +} From dc05a5a20715708f30ec6b25e3a20f811e6584d1 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 23 May 2023 16:33:20 -0700 Subject: [PATCH 128/142] multi view tests --- .../Source/FlutterThreadSynchronizer.h | 12 ++ .../Source/FlutterThreadSynchronizerTest.mm | 150 +++++++++++++++++- 2 files changed, 159 insertions(+), 3 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h index 74653956354ed..1cd4ee64dfa49 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h @@ -52,6 +52,18 @@ /** * Blocks current thread until the mutex is available, then return whether the * synchronizer is waiting for a correct commit during resizing. + * + * After calling an operation of the thread synchronizer, call this method, + * and when it returns, the thread synchronizer can be at one of the following 3 + * states: + * + * 1. The operation has not started at all (with a return value FALSE.) + * 2. The operation has ended (with a return value FALSE.) + * 3. beginResizeForView: is in progress, waiting (with a return value TRUE.) + * + * By eliminating the 1st case (such as using the notify callback), we can use + * this return value to decide whether the synchronizer is in case 2 or case 3, + * that is whether the resizing is blocked by a mismatching commit. */ - (BOOL)isWaitingWhenMutexIsAvailable; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm index ef97b62a3785a..4e27103f88091 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm @@ -75,7 +75,7 @@ - (void)joinRender { @end -TEST(FlutterThreadSynchronizerTest, FinishResizingImmediatelyWhenSizeMatches) { +TEST(FlutterThreadSynchronizerTest, RegularCommit) { FlutterThreadSynchronizerTestScaffold* scaffold = [[FlutterThreadSynchronizerTestScaffold alloc] init]; FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; @@ -121,7 +121,7 @@ - (void)joinRender { EXPECT_EQ(notifiedCommit, 1); } -TEST(FlutterThreadSynchronizerTest, FinishResizingOnlyWhenCommittingMatchingSize) { +TEST(FlutterThreadSynchronizerTest, ResizingBlocksRenderingUntilSizeMatches) { FlutterThreadSynchronizerTestScaffold* scaffold = [[FlutterThreadSynchronizerTestScaffold alloc] init]; FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; @@ -187,7 +187,7 @@ - (void)joinRender { [scaffold joinMain]; } -TEST(FlutterThreadSynchronizerTest, FinishResizingWhenShuttingDown) { +TEST(FlutterThreadSynchronizerTest, ShutdownMakesEverythingNonBlocking) { FlutterThreadSynchronizerTestScaffold* scaffold = [[FlutterThreadSynchronizerTestScaffold alloc] init]; FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; @@ -242,3 +242,147 @@ - (void)joinRender { [scaffold joinRender]; EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); } + +TEST(FlutterThreadSynchronizerTest, RegularCommitForMultipleViews) { + FlutterThreadSynchronizerTestScaffold* scaffold = + [[FlutterThreadSynchronizerTestScaffold alloc] init]; + FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; + fml::AutoResetWaitableEvent begunResizingLatch; + fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch; + + [synchronizer registerView:1]; + [synchronizer registerView:2]; + + // Initial resize: does not block until the first frame. + [scaffold dispatchMainTask:^{ + [synchronizer beginResizeForView:1 + size:CGSize{5, 5} + notify:^{ + }]; + [synchronizer beginResizeForView:2 + size:CGSize{15, 15} + notify:^{ + begunResizing->Signal(); + }]; + }]; + begunResizing->Wait(); + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + [scaffold joinMain]; + + // Still does not block. + [scaffold dispatchMainTask:^{ + [synchronizer beginResizeForView:1 + size:CGSize{7, 7} + notify:^{ + begunResizing->Signal(); + }]; + }]; + begunResizing->Signal(); + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + [scaffold joinMain]; + + // First frame + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 + size:CGSize{7, 7} + notify:^{ + }]; + [synchronizer performCommitForView:2 + size:CGSize{15, 15} + notify:^{ + }]; + }]; + [scaffold joinRender]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); +} + +TEST(FlutterThreadSynchronizerTest, ResizingForMultipleViews) { + FlutterThreadSynchronizerTestScaffold* scaffold = + [[FlutterThreadSynchronizerTestScaffold alloc] init]; + FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; + fml::AutoResetWaitableEvent begunResizingLatch; + fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch; + + [synchronizer registerView:1]; + [synchronizer registerView:2]; + + // Initial resize: does not block until the first frame. + [scaffold dispatchMainTask:^{ + [synchronizer beginResizeForView:1 + size:CGSize{5, 5} + notify:^{ + }]; + [synchronizer beginResizeForView:2 + size:CGSize{15, 15} + notify:^{ + }]; + }]; + [scaffold joinMain]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + + // First frame. + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 + size:CGSize{5, 5} + notify:^{ + }]; + [synchronizer performCommitForView:2 + size:CGSize{15, 15} + notify:^{ + }]; + }]; + [scaffold joinRender]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); + + // Resize view 2 to (17, 17): blocks until the next frame. + [scaffold dispatchMainTask:^{ + [synchronizer beginResizeForView:2 + size:CGSize{17, 17} + notify:^{ + begunResizing->Signal(); + }]; + }]; + begunResizing->Wait(); + EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]); + + // Render view 1 with the size. Still blocking. + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 + size:CGSize{5, 5} + notify:^{ + }]; + }]; + [scaffold joinRender]; + EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]); + + // Render view 2 with the old size. Still blocking. + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 + size:CGSize{15, 15} + notify:^{ + }]; + }]; + [scaffold joinRender]; + EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]); + + // Render view 1 with the size. + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:1 + size:CGSize{5, 5} + notify:^{ + }]; + }]; + [scaffold joinRender]; + EXPECT_TRUE([synchronizer isWaitingWhenMutexIsAvailable]); + + // Render view 2 with the new size. Unblocks. + [scaffold dispatchRenderTask:^{ + [synchronizer performCommitForView:2 + size:CGSize{17, 17} + notify:^{ + }]; + }]; + [scaffold joinRender]; + [scaffold joinMain]; + EXPECT_FALSE([synchronizer isWaitingWhenMutexIsAvailable]); +} From 98b4013fc988adc4f04c8c64238541e904aacd7e Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 23 May 2023 17:13:49 -0700 Subject: [PATCH 129/142] Docs and locs --- .../Source/FlutterThreadSynchronizer.h | 30 ++++++++++++++++--- .../Source/FlutterThreadSynchronizer.mm | 4 +++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h index 1cd4ee64dfa49..b1a2570159282 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h @@ -6,14 +6,20 @@ /** * Takes care of synchronization between raster and platform thread. + * + * All methods of this class must be called from the platform thread, + * except for performCommitForView:size:notify:. */ @interface FlutterThreadSynchronizer : NSObject +/** + * Creates a FlutterThreadSynchronizer that uses the OS main thread as the + * platform thread. + */ - (nullable instancetype)init; /** - * Called from platform thread. Blocks until a commit with given size (or empty) - * is requested. + * Blocks until all views have a commit with their given sizes (or empty) is requested. */ - (void)beginResizeForView:(int64_t)viewId size:(CGSize)size @@ -32,12 +38,24 @@ size:(CGSize)size notify:(nonnull dispatch_block_t)notify; +/** + * Requests the synchronizer to track another view. + * + * A view must be registered before calling begineResizeForView: or + * performCommitForView:. It is typically done when the view controller is + * created. + */ - (void)registerView:(int64_t)viewId; +/** + * Requests the synchronizer to no longer track a view. + * + * It is typically done when the view controller is created. + */ - (void)deregisterView:(int64_t)viewId; /** - * Called from platform thread when shutting down. + * Called when the engine shuts down. * * Prevents any further synchronization and no longer blocks any threads. */ @@ -45,8 +63,12 @@ @end -@interface FlutterThreadSynchronizer (Test) +@interface FlutterThreadSynchronizer (TestUtils) +/** + * Creates a FlutterThreadSynchronizer that uses the specified queue as the + * platform thread. + */ - (nullable instancetype)initWithMainQueue:(nonnull dispatch_queue_t)queue; /** diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm index a0561e4d30e8e..75a4ff5037210 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.mm @@ -165,10 +165,14 @@ - (void)performCommitForView:(int64_t)viewId } - (void)registerView:(int64_t)viewId { + dispatch_assert_queue(_mainQueue); + std::unique_lock lock(_mutex); _contentSizes[viewId] = CGSizeZero; } - (void)deregisterView:(int64_t)viewId { + dispatch_assert_queue(_mainQueue); + std::unique_lock lock(_mutex); _contentSizes.erase(viewId); } From 31b54305dc0be59144537fdaed7c7fc781036d4c Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 23 May 2023 17:27:12 -0700 Subject: [PATCH 130/142] Use better way, and fix tests --- .../macos/framework/Source/FlutterEngine.mm | 4 ++-- .../framework/Source/FlutterEngineTest.mm | 3 ++- .../framework/Source/FlutterEngine_Internal.h | 6 ++++-- .../Source/FlutterThreadSynchronizerTest.mm | 19 +++++++------------ .../framework/Source/FlutterViewController.mm | 6 ++++-- .../Source/FlutterViewController_Internal.h | 9 ++++++--- 6 files changed, 25 insertions(+), 22 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 41269b6e94dd7..ad8d3e870ce20 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -592,7 +592,7 @@ - (void)registerViewController:(FlutterViewController*)controller forId:(Flutter NSAssert(![controller attached], @"The incoming view controller is already attached to an engine."); NSAssert([_viewControllers objectForKey:@(viewId)] == nil, @"The requested view ID is occupied."); - [controller attachToEngine:self withId:viewId]; + [controller setUpWithEngine:self viewId:viewId threadSynchronizer:_threadSynchronizer]; NSAssert(controller.viewId == viewId, @"Failed to assign view ID."); [_viewControllers setObject:controller forKey:@(viewId)]; } @@ -1122,7 +1122,7 @@ - (NSPasteboard*)pasteboard { return flutter::GetSwitchesFromEnvironment(); } -- (FlutterThreadSynchronizer*)threadSynchronizer { +- (FlutterThreadSynchronizer*)testThreadSynchronizer { return _threadSynchronizer; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index 5b3e111e89086..cf81a8ad798c2 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -34,6 +34,7 @@ @interface FlutterEngine (Test) * May be nil if the compositor has not been initialized yet. */ @property(nonatomic, readonly, nullable) flutter::FlutterCompositor* macOSCompositor; + @end @interface TestPlatformViewFactory : NSObject @@ -440,7 +441,7 @@ - (nonnull NSView*)createWithViewIdentifier:(int64_t)viewId arguments:(nullable result:^(id result){ }]; - [engine.threadSynchronizer blockUntilFrameAvailable]; + [engine.testThreadSynchronizer blockUntilFrameAvailable]; CALayer* rootLayer = viewController.flutterView.layer; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h index ba11b19851478..be973222ca95d 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h @@ -108,8 +108,6 @@ typedef NS_ENUM(NSInteger, FlutterAppExitResponse) { */ @property(nonatomic, readonly) FlutterEngineTerminationHandler* terminationHandler; -@property(nonatomic, readonly) FlutterThreadSynchronizer* threadSynchronizer; - /** * Attach a view controller to the engine as its default controller. * @@ -197,4 +195,8 @@ typedef NS_ENUM(NSInteger, FlutterAppExitResponse) { @end +@interface FlutterEngine (Tests) +- (nonnull FlutterThreadSynchronizer*)testThreadSynchronizer; +@end + NS_ASSUME_NONNULL_END diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm index 4e27103f88091..2541f8675576d 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizerTest.mm @@ -80,11 +80,10 @@ - (void)joinRender { [[FlutterThreadSynchronizerTestScaffold alloc] init]; FlutterThreadSynchronizer* synchronizer = scaffold.synchronizer; - [synchronizer registerView:1]; - // Initial resize: does not block until the first frame. __block int notifiedResize = 0; [scaffold dispatchMainTask:^{ + [synchronizer registerView:1]; [synchronizer beginResizeForView:1 size:CGSize{5, 5} notify:^{ @@ -131,10 +130,9 @@ - (void)joinRender { fml::AutoResetWaitableEvent begunResizingLatch; fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch; - [synchronizer registerView:1]; - // Initial resize: does not block until the first frame. [scaffold dispatchMainTask:^{ + [synchronizer registerView:1]; [synchronizer beginResizeForView:1 size:CGSize{5, 5} notify:^{ @@ -194,10 +192,9 @@ - (void)joinRender { fml::AutoResetWaitableEvent begunResizingLatch; fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch; - [synchronizer registerView:1]; - // Initial resize [scaffold dispatchMainTask:^{ + [synchronizer registerView:1]; [synchronizer beginResizeForView:1 size:CGSize{5, 5} notify:^{ @@ -250,11 +247,10 @@ - (void)joinRender { fml::AutoResetWaitableEvent begunResizingLatch; fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch; - [synchronizer registerView:1]; - [synchronizer registerView:2]; - // Initial resize: does not block until the first frame. [scaffold dispatchMainTask:^{ + [synchronizer registerView:1]; + [synchronizer registerView:2]; [synchronizer beginResizeForView:1 size:CGSize{5, 5} notify:^{ @@ -303,11 +299,10 @@ - (void)joinRender { fml::AutoResetWaitableEvent begunResizingLatch; fml::AutoResetWaitableEvent* begunResizing = &begunResizingLatch; - [synchronizer registerView:1]; - [synchronizer registerView:2]; - // Initial resize: does not block until the first frame. [scaffold dispatchMainTask:^{ + [synchronizer registerView:1]; + [synchronizer registerView:2]; [synchronizer beginResizeForView:1 size:CGSize{5, 5} notify:^{ diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index f7c082b694323..007a7559945f6 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -402,7 +402,6 @@ static void CommonInit(FlutterViewController* controller, FlutterEngine* engine) controller.engine, controller.viewId); controller->_mouseTrackingMode = FlutterMouseTrackingModeInKeyWindow; controller->_textInputPlugin = [[FlutterTextInputPlugin alloc] initWithViewController:controller]; - controller->_weakViewThreadSynchronizer = engine.threadSynchronizer; [controller initializeKeyboard]; [controller notifySemanticsEnabledChanged]; // macOS fires this message when changing IMEs. @@ -546,10 +545,13 @@ - (void)notifySemanticsEnabledChanged { return _bridge; } -- (void)attachToEngine:(nonnull FlutterEngine*)engine withId:(FlutterViewId)viewId { +- (void)setUpWithEngine:(FlutterEngine*)engine + viewId:(FlutterViewId)viewId + threadSynchronizer:(FlutterThreadSynchronizer*)threadSynchronizer { NSAssert(_engine == nil, @"Already attached to an engine %@.", _engine); _engine = engine; _viewId = viewId; + _weakViewThreadSynchronizer = threadSynchronizer; } - (void)detachFromEngine { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h b/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h index 62801f9bce739..4ffeffac4bb17 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController_Internal.h @@ -39,11 +39,14 @@ - (BOOL)isDispatchingKeyEvent:(nonnull NSEvent*)event; /** - * Set the `engine` and `id` of this controller. + * Set up the controller with `engine` and `id`, and other engine-level classes. * - * This method is called by FlutterEngine. + * This method is called by FlutterEngine. A view controller must be set up + * before being used, and must be set up only once until detachFromEngine:. */ -- (void)attachToEngine:(nonnull FlutterEngine*)engine withId:(FlutterViewId)viewId; +- (void)setUpWithEngine:(nonnull FlutterEngine*)engine + viewId:(FlutterViewId)viewId + threadSynchronizer:(nonnull FlutterThreadSynchronizer*)threadSynchronizer; /** * Reset the `engine` and `id` of this controller. From 9cb1f69b2e1b638ed99b70e680bf4baa66ed6ebb Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 25 May 2023 13:31:22 -0700 Subject: [PATCH 131/142] Make FVC reg/dereg --- .../macos/framework/Source/FlutterThreadSynchronizer.h | 2 +- .../darwin/macos/framework/Source/FlutterView.mm | 1 - .../macos/framework/Source/FlutterViewController.mm | 9 ++++++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h index b1a2570159282..8d8d248bdefdb 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterThreadSynchronizer.h @@ -50,7 +50,7 @@ /** * Requests the synchronizer to no longer track a view. * - * It is typically done when the view controller is created. + * It is typically done when the view controller is destroyed. */ - (void)deregisterView:(int64_t)viewId; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.mm b/shell/platform/darwin/macos/framework/Source/FlutterView.mm index db20790f07b57..2c30a7457dc8a 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.mm @@ -37,7 +37,6 @@ - (instancetype)initWithMTLDevice:(id)device commandQueue:commandQueue layer:self.layer delegate:self]; - [_threadSynchronizer registerView:viewId]; } return self; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm index 007a7559945f6..af56e910904fc 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterViewController.mm @@ -375,7 +375,7 @@ @implementation FlutterViewController { // FlutterViewController does not actually uses the synchronizer, but only // passes it to FlutterView. - __weak FlutterThreadSynchronizer* _weakViewThreadSynchronizer; + FlutterThreadSynchronizer* _threadSynchronizer; } @synthesize viewId = _viewId; @@ -551,11 +551,14 @@ - (void)setUpWithEngine:(FlutterEngine*)engine NSAssert(_engine == nil, @"Already attached to an engine %@.", _engine); _engine = engine; _viewId = viewId; - _weakViewThreadSynchronizer = threadSynchronizer; + _threadSynchronizer = threadSynchronizer; + [_threadSynchronizer registerView:_viewId]; } - (void)detachFromEngine { NSAssert(_engine != nil, @"Not attached to any engine."); + [_threadSynchronizer deregisterView:_viewId]; + _threadSynchronizer = nil; _engine = nil; } @@ -866,7 +869,7 @@ - (nonnull FlutterView*)createFlutterViewWithMTLDevice:(id)device return [[FlutterView alloc] initWithMTLDevice:device commandQueue:commandQueue reshapeListener:self - threadSynchronizer:_weakViewThreadSynchronizer + threadSynchronizer:_threadSynchronizer viewId:_viewId]; } From da1530460b463cd4c9ef8f82a5a729a549921f51 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Thu, 25 May 2023 13:33:03 -0700 Subject: [PATCH 132/142] Remove FV:shutdown --- .../platform/darwin/macos/framework/Source/FlutterEngine.mm | 5 ----- shell/platform/darwin/macos/framework/Source/FlutterView.h | 6 ------ shell/platform/darwin/macos/framework/Source/FlutterView.mm | 2 -- 3 files changed, 13 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index ad8d3e870ce20..d4f194cfca01e 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -931,13 +931,8 @@ - (void)shutDownEngine { return; } - NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator]; [_threadSynchronizer shutdown]; _threadSynchronizer = nil; - FlutterViewController* nextViewController; - while ((nextViewController = [viewControllerEnumerator nextObject])) { - [nextViewController.flutterView shutdown]; - } FlutterEngineResult result = _embedderAPI.Deinitialize(_engine); if (result != kSuccess) { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.h b/shell/platform/darwin/macos/framework/Source/FlutterView.h index fe2d55aac554d..0c468d4c58d08 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.h @@ -59,12 +59,6 @@ constexpr FlutterViewId kFlutterDefaultViewId = 0ll; */ @property(readonly, nonatomic, nonnull) FlutterSurfaceManager* surfaceManager; -/** - * Must be called when shutting down. Unblocks raster thread and prevents any further - * synchronization. - */ -- (void)shutdown; - /** * By default, the `FlutterSurfaceManager` creates two layers to manage Flutter * content, the content layer and containing layer. To set the native background diff --git a/shell/platform/darwin/macos/framework/Source/FlutterView.mm b/shell/platform/darwin/macos/framework/Source/FlutterView.mm index 2c30a7457dc8a..89bbdb9153828 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterView.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterView.mm @@ -113,8 +113,6 @@ - (BOOL)layer:(CALayer*)layer return YES; } -- (void)shutdown { -} #pragma mark - NSAccessibility overrides - (BOOL)isAccessibilityElement { From 0a9a5847e00ea2b646728ea98c8331164217f026 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 26 May 2023 14:09:00 -0700 Subject: [PATCH 133/142] Short variant --- lib/ui/compositing/scene_builder_unittests.cc | 4 +- lib/ui/hooks_unittests.cc | 2 +- lib/ui/painting/image_dispose_unittests.cc | 2 +- lib/ui/painting/image_encoding_unittests.cc | 4 +- lib/ui/painting/paint_unittests.cc | 2 +- lib/ui/painting/path_unittests.cc | 6 +- .../painting/single_frame_codec_unittests.cc | 2 +- .../semantics_update_builder_unittests.cc | 2 +- .../platform_configuration_unittests.cc | 12 +- ...rm_message_response_dart_port_unittests.cc | 2 +- ...latform_message_response_dart_unittests.cc | 2 +- shell/common/input_events_unittests.cc | 15 +- shell/common/shell_test.cc | 60 ++--- shell/common/shell_test.h | 33 ++- shell/common/shell_test_platform_view.h | 2 +- shell/common/shell_unittests.cc | 238 +++++++++--------- .../ios/platform_message_handler_ios_test.mm | 4 +- 17 files changed, 203 insertions(+), 189 deletions(-) diff --git a/lib/ui/compositing/scene_builder_unittests.cc b/lib/ui/compositing/scene_builder_unittests.cc index 702d83bf61417..d83e15350d64c 100644 --- a/lib/ui/compositing/scene_builder_unittests.cc +++ b/lib/ui/compositing/scene_builder_unittests.cc @@ -82,7 +82,7 @@ TEST_F(ShellTest, SceneBuilderBuildAndSceneDisposeReleasesLayerStack) { AddNativeCallback("ValidateSceneHasNoLayers", CREATE_NATIVE_ENTRY(validate_scene_has_no_layers)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -141,7 +141,7 @@ TEST_F(ShellTest, EngineLayerDisposeReleasesReference) { AddNativeCallback("ValidateEngineLayerDispose", CREATE_NATIVE_ENTRY(validate_engine_layer_dispose)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); diff --git a/lib/ui/hooks_unittests.cc b/lib/ui/hooks_unittests.cc index 8fc69f42dcd7d..c386c462f9487 100644 --- a/lib/ui/hooks_unittests.cc +++ b/lib/ui/hooks_unittests.cc @@ -35,7 +35,7 @@ TEST_F(HooksTest, HooksUnitTests) { auto message_latch = std::make_shared(); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto call_hook = [](Dart_NativeArguments args) { diff --git a/lib/ui/painting/image_dispose_unittests.cc b/lib/ui/painting/image_dispose_unittests.cc index 0f8bb6d027062..2d1a648bdf6bc 100644 --- a/lib/ui/painting/image_dispose_unittests.cc +++ b/lib/ui/painting/image_dispose_unittests.cc @@ -69,7 +69,7 @@ TEST_F(ImageDisposeTest, ImageReleasedAfterFrameAndDisposePictureAndLayer) { CREATE_NATIVE_ENTRY(native_capture_image_and_picture)); AddNativeCallback("Finish", CREATE_NATIVE_ENTRY(native_finish)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); diff --git a/lib/ui/painting/image_encoding_unittests.cc b/lib/ui/painting/image_encoding_unittests.cc index 8a111167fc64d..833dfc11856f8 100644 --- a/lib/ui/painting/image_encoding_unittests.cc +++ b/lib/ui/painting/image_encoding_unittests.cc @@ -106,7 +106,7 @@ TEST_F(ShellTest, EncodeImageGivesExternalTypedData) { AddNativeCallback("ValidateExternal", CREATE_NATIVE_ENTRY(nativeValidateExternal)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -170,7 +170,7 @@ TEST_F(ShellTest, EncodeImageAccessesSyncSwitch) { AddNativeCallback("EncodeImage", CREATE_NATIVE_ENTRY(native_encode_image)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); diff --git a/lib/ui/painting/paint_unittests.cc b/lib/ui/painting/paint_unittests.cc index 1324568cb2347..1986cc8d78701 100644 --- a/lib/ui/painting/paint_unittests.cc +++ b/lib/ui/painting/paint_unittests.cc @@ -36,7 +36,7 @@ TEST_F(ShellTest, ConvertPaintToDlPaint) { AddNativeCallback("ConvertPaintToDlPaint", CREATE_NATIVE_ENTRY(nativeToDlPaint)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); diff --git a/lib/ui/painting/path_unittests.cc b/lib/ui/painting/path_unittests.cc index f02b72ff5a511..e9f39b3ba73c8 100644 --- a/lib/ui/painting/path_unittests.cc +++ b/lib/ui/painting/path_unittests.cc @@ -50,7 +50,7 @@ TEST_F(ShellTest, PathVolatilityOldPathsBecomeNonVolatile) { AddNativeCallback("ValidatePath", CREATE_NATIVE_ENTRY(native_validate_path)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -108,7 +108,7 @@ TEST_F(ShellTest, PathVolatilityGCRemovesPathFromTracker) { AddNativeCallback("ValidatePath", CREATE_NATIVE_ENTRY(native_validate_path)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -164,7 +164,7 @@ TEST_F(ShellTest, DeterministicRenderingDisablesPathVolatility) { AddNativeCallback("ValidatePath", CREATE_NATIVE_ENTRY(native_validate_path)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); diff --git a/lib/ui/painting/single_frame_codec_unittests.cc b/lib/ui/painting/single_frame_codec_unittests.cc index d9a76af262ed5..2cbb2254442a4 100644 --- a/lib/ui/painting/single_frame_codec_unittests.cc +++ b/lib/ui/painting/single_frame_codec_unittests.cc @@ -41,7 +41,7 @@ TEST_F(ShellTest, SingleFrameCodecAccuratelyReportsSize) { AddNativeCallback("ValidateCodec", CREATE_NATIVE_ENTRY(validate_codec)); AddNativeCallback("Finish", CREATE_NATIVE_ENTRY(finish)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); diff --git a/lib/ui/semantics/semantics_update_builder_unittests.cc b/lib/ui/semantics/semantics_update_builder_unittests.cc index 004d7f8f78296..197314fbd3160 100644 --- a/lib/ui/semantics/semantics_update_builder_unittests.cc +++ b/lib/ui/semantics/semantics_update_builder_unittests.cc @@ -74,7 +74,7 @@ TEST_F(SemanticsUpdateBuilderTest, CanHandleAttributedStrings) { AddNativeCallback("SemanticsUpdate", CREATE_NATIVE_ENTRY(nativeSemanticsUpdate)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); diff --git a/lib/ui/window/platform_configuration_unittests.cc b/lib/ui/window/platform_configuration_unittests.cc index e89a5cc7d381c..64648093b7d75 100644 --- a/lib/ui/window/platform_configuration_unittests.cc +++ b/lib/ui/window/platform_configuration_unittests.cc @@ -49,7 +49,7 @@ TEST_F(ShellTest, PlatformConfigurationInitialization) { AddNativeCallback("ValidateConfiguration", CREATE_NATIVE_ENTRY(nativeValidateConfiguration)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto run_configuration = RunConfiguration::InferFromSettings(settings); @@ -99,7 +99,7 @@ TEST_F(ShellTest, PlatformConfigurationWindowMetricsUpdate) { AddNativeCallback("ValidateConfiguration", CREATE_NATIVE_ENTRY(nativeValidateConfiguration)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto run_configuration = RunConfiguration::InferFromSettings(settings); @@ -137,7 +137,7 @@ TEST_F(ShellTest, PlatformConfigurationOnErrorHandlesError) { CreateNewThread() // io ); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto run_configuration = RunConfiguration::InferFromSettings(settings); @@ -187,7 +187,7 @@ TEST_F(ShellTest, PlatformConfigurationOnErrorDoesNotHandleError) { CreateNewThread() // io ); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto run_configuration = RunConfiguration::InferFromSettings(settings); @@ -238,7 +238,7 @@ TEST_F(ShellTest, PlatformConfigurationOnErrorThrows) { CreateNewThread() // io ); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto run_configuration = RunConfiguration::InferFromSettings(settings); @@ -286,7 +286,7 @@ TEST_F(ShellTest, PlatformConfigurationSetDartPerformanceMode) { CreateNewThread() // io ); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto run_configuration = RunConfiguration::InferFromSettings(settings); diff --git a/lib/ui/window/platform_message_response_dart_port_unittests.cc b/lib/ui/window/platform_message_response_dart_port_unittests.cc index 7dda83049d926..32422be053bfc 100644 --- a/lib/ui/window/platform_message_response_dart_port_unittests.cc +++ b/lib/ui/window/platform_message_response_dart_port_unittests.cc @@ -53,7 +53,7 @@ TEST_F(ShellTest, PlatformMessageResponseDartPort) { Settings settings = CreateSettingsForFixture(); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); diff --git a/lib/ui/window/platform_message_response_dart_unittests.cc b/lib/ui/window/platform_message_response_dart_unittests.cc index a9a29198bcf4d..d2f0863719c94 100644 --- a/lib/ui/window/platform_message_response_dart_unittests.cc +++ b/lib/ui/window/platform_message_response_dart_unittests.cc @@ -52,7 +52,7 @@ TEST_F(ShellTest, PlatformMessageResponseDart) { Settings settings = CreateSettingsForFixture(); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); diff --git a/shell/common/input_events_unittests.cc b/shell/common/input_events_unittests.cc index 3f117c006c65f..f84cddbfbe5d2 100644 --- a/shell/common/input_events_unittests.cc +++ b/shell/common/input_events_unittests.cc @@ -54,7 +54,10 @@ static void TestSimulatedInputEvents( bool restart_engine = false) { ///// Begin constructing shell /////////////////////////////////////////////// auto settings = fixture->CreateSettingsForFixture(); - std::unique_ptr shell = fixture->CreateShell(settings, true); + std::unique_ptr shell = fixture->CreateShell({ + .settings = settings, + .simulate_vsync = true, + }); auto configuration = RunConfiguration::InferFromSettings(settings); configuration.SetEntrypoint("onPointerDataPacketMain"); @@ -300,7 +303,10 @@ TEST_F(ShellTest, HandlesActualIphoneXsInputEvents) { TEST_F(ShellTest, CanCorrectlyPipePointerPacket) { // Sets up shell with test fixture. auto settings = CreateSettingsForFixture(); - std::unique_ptr shell = CreateShell(settings, true); + std::unique_ptr shell = CreateShell({ + .settings = settings, + .simulate_vsync = true, + }); auto configuration = RunConfiguration::InferFromSettings(settings); configuration.SetEntrypoint("onPointerDataPacketMain"); @@ -361,7 +367,10 @@ TEST_F(ShellTest, CanCorrectlyPipePointerPacket) { TEST_F(ShellTest, CanCorrectlySynthesizePointerPacket) { // Sets up shell with test fixture. auto settings = CreateSettingsForFixture(); - std::unique_ptr shell = CreateShell(settings, true); + std::unique_ptr shell = CreateShell({ + .settings = settings, + .simulate_vsync = true, + }); auto configuration = RunConfiguration::InferFromSettings(settings); configuration.SetEntrypoint("onPointerDataPacketMain"); diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index 8be076930b11b..7467d79491907 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -321,23 +321,21 @@ fml::TimePoint ShellTest::GetLatestFrameTargetTime(Shell* shell) const { } std::unique_ptr ShellTest::CreateShell(const Settings& settings, - bool simulate_vsync) { - return CreateShell(settings, GetTaskRunnersForFixture(), simulate_vsync); + const TaskRunners* task_runners) { + return CreateShell({ + .settings = settings, + .task_runners = task_runners, + }); } -std::unique_ptr ShellTest::CreateShell( - const Settings& settings, - TaskRunners task_runners, - bool simulate_vsync, - const std::shared_ptr& - shell_test_external_view_embedder, - bool is_gpu_disabled, - ShellTestPlatformView::BackendType rendering_backend, - Shell::CreateCallback platform_view_create_callback) { +std::unique_ptr ShellTest::CreateShell(const Config& config) { const auto vsync_clock = std::make_shared(); + TaskRunners task_runners = config.task_runners != nullptr + ? *config.task_runners + : GetTaskRunnersForFixture(); CreateVsyncWaiter create_vsync_waiter = [&]() { - if (simulate_vsync) { + if (config.simulate_vsync) { return static_cast>( std::make_unique(task_runners, vsync_clock)); } else { @@ -346,23 +344,27 @@ std::unique_ptr ShellTest::CreateShell( } }; + Shell::CreateCallback platform_view_create_callback = + std::move(config.platform_view_create_callback); if (!platform_view_create_callback) { - platform_view_create_callback = [vsync_clock, // - &create_vsync_waiter, // - shell_test_external_view_embedder, // - rendering_backend // + platform_view_create_callback = + [vsync_clock, // + &create_vsync_waiter, // + shell_test_external_view_embedder = + config.shell_test_external_view_embedder, // + rendering_backend = config.rendering_backend // ](Shell& shell) { - return ShellTestPlatformView::Create( - shell, // - shell.GetTaskRunners(), // - vsync_clock, // - create_vsync_waiter, // - rendering_backend, // - shell_test_external_view_embedder, // - shell.GetConcurrentWorkerTaskRunner(), // - shell.GetIsGpuDisabledSyncSwitch() // - ); - }; + return ShellTestPlatformView::Create( + shell, // + shell.GetTaskRunners(), // + vsync_clock, // + create_vsync_waiter, // + rendering_backend, // + shell_test_external_view_embedder, // + shell.GetConcurrentWorkerTaskRunner(), // + shell.GetIsGpuDisabledSyncSwitch() // + ); + }; } Shell::CreateCallback rasterizer_create_callback = @@ -370,10 +372,10 @@ std::unique_ptr ShellTest::CreateShell( return Shell::Create(flutter::PlatformData(), // task_runners, // - settings, // + config.settings, // platform_view_create_callback, // rasterizer_create_callback, // - is_gpu_disabled // + config.is_gpu_disabled // ); } diff --git a/shell/common/shell_test.h b/shell/common/shell_test.h index b9e95cc590e8b..c748e93ff3438 100644 --- a/shell/common/shell_test.h +++ b/shell/common/shell_test.h @@ -31,22 +31,31 @@ namespace testing { class ShellTest : public FixtureTest { public: + struct Config { + // Required. + const Settings& settings; + // Defaults to &GetTaskRunnersForFixture(). + const TaskRunners* task_runners; + // Defaults to false. + bool simulate_vsync; + // Defaults to nullptr. + std::shared_ptr + shell_test_external_view_embedder; + // Defaults to false. + bool is_gpu_disabled; + // Defaults to kDefaultBackend. + ShellTestPlatformView::BackendType rendering_backend; + // Defaults to calling ShellTestPlatformView::Create with the provided + // arguments. + Shell::CreateCallback platform_view_create_callback; + }; + ShellTest(); Settings CreateSettingsForFixture() override; std::unique_ptr CreateShell(const Settings& settings, - bool simulate_vsync = false); - std::unique_ptr CreateShell( - const Settings& settings, - TaskRunners task_runners, - bool simulate_vsync = false, - const std::shared_ptr& - shell_test_external_view_embedder = nullptr, - bool is_gpu_disabled = false, - ShellTestPlatformView::BackendType rendering_backend = - ShellTestPlatformView::BackendType::kDefaultBackend, - Shell::CreateCallback platform_view_create_callback = - nullptr); + const TaskRunners* task_runners = nullptr); + std::unique_ptr CreateShell(const Config& config); void DestroyShell(std::unique_ptr shell); void DestroyShell(std::unique_ptr shell, const TaskRunners& task_runners); diff --git a/shell/common/shell_test_platform_view.h b/shell/common/shell_test_platform_view.h index ebb96c87dd23e..3dd518bdaa27a 100644 --- a/shell/common/shell_test_platform_view.h +++ b/shell/common/shell_test_platform_view.h @@ -15,10 +15,10 @@ namespace testing { class ShellTestPlatformView : public PlatformView { public: enum class BackendType { + kDefaultBackend = 0, // Default value kGLBackend, kVulkanBackend, kMetalBackend, - kDefaultBackend, }; static std::unique_ptr Create( diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 2edc3b173d82b..81b52d03082d1 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -330,7 +330,7 @@ TEST_F(ShellTest, InitializeWithInvalidThreads) { ASSERT_FALSE(DartVMRef::IsInstanceRunning()); Settings settings = CreateSettingsForFixture(); TaskRunners task_runners("test", nullptr, nullptr, nullptr, nullptr); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_FALSE(shell); ASSERT_FALSE(DartVMRef::IsInstanceRunning()); } @@ -348,7 +348,7 @@ TEST_F(ShellTest, InitializeWithDifferentThreads) { thread_host.raster_thread->GetTaskRunner(), thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner()); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(ValidateShell(shell.get())); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); DestroyShell(std::move(shell), task_runners); @@ -363,7 +363,7 @@ TEST_F(ShellTest, InitializeWithSingleThread) { auto task_runner = thread_host.platform_thread->GetTaskRunner(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); ASSERT_TRUE(ValidateShell(shell.get())); DestroyShell(std::move(shell), task_runners); @@ -377,7 +377,7 @@ TEST_F(ShellTest, InitializeWithSingleThreadWhichIsTheCallingThread) { auto task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(ValidateShell(shell.get())); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); DestroyShell(std::move(shell), task_runners); @@ -428,9 +428,11 @@ TEST_F(ShellTest, InitializeWithDisabledGpu) { auto task_runner = thread_host.platform_thread->GetTaskRunner(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - auto shell = CreateShell(settings, task_runners, /*simulate_vsync=*/false, - /*shell_test_external_view_embedder=*/nullptr, - /*is_gpu_disabled=*/true); + auto shell = CreateShell({ + .settings = settings, + .task_runners = &task_runners, + .is_gpu_disabled = true, + }); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); ASSERT_TRUE(ValidateShell(shell.get())); @@ -456,7 +458,7 @@ TEST_F(ShellTest, InitializeWithGPUAndPlatformThreadsTheSame) { thread_host.ui_thread->GetTaskRunner(), // ui thread_host.io_thread->GetTaskRunner() // io ); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); ASSERT_TRUE(ValidateShell(shell.get())); DestroyShell(std::move(shell), task_runners); @@ -794,8 +796,10 @@ TEST_F(ShellTest, ExternalEmbedderNoThreadMerger) { }; auto external_view_embedder = std::make_shared( end_frame_callback, PostPrerollResult::kResubmitFrame, false); - auto shell = CreateShell(settings, GetTaskRunnersForFixture(), false, - external_view_embedder); + auto shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -851,8 +855,10 @@ TEST_F(ShellTest, PushBackdropFilterToVisitedPlatformViews) { external_view_embedder = std::make_shared( end_frame_callback, PostPrerollResult::kResubmitFrame, false); - auto shell = CreateShell(settings, GetTaskRunnersForFixture(), false, - external_view_embedder); + auto shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -920,8 +926,10 @@ TEST_F(ShellTest, }; auto external_view_embedder = std::make_shared( end_frame_callback, PostPrerollResult::kResubmitFrame, true); - auto shell = CreateShell(settings, GetTaskRunnersForFixture(), false, - external_view_embedder); + auto shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -961,8 +969,10 @@ TEST_F(ShellTest, OnPlatformViewDestroyDisablesThreadMerger) { auto external_view_embedder = std::make_shared( end_frame_callback, PostPrerollResult::kSuccess, true); - auto shell = CreateShell(settings, GetTaskRunnersForFixture(), false, - external_view_embedder); + auto shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1023,8 +1033,10 @@ TEST_F(ShellTest, OnPlatformViewDestroyAfterMergingThreads) { // Set resubmit once to trigger thread merging. external_view_embedder->UpdatePostPrerollResult( PostPrerollResult::kResubmitFrame); - auto shell = CreateShell(settings, GetTaskRunnersForFixture(), false, - external_view_embedder); + auto shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1087,8 +1099,10 @@ TEST_F(ShellTest, OnPlatformViewDestroyWhenThreadsAreMerging) { auto external_view_embedder = std::make_shared( end_frame_callback, PostPrerollResult::kSuccess, true); - auto shell = CreateShell(settings, GetTaskRunnersForFixture(), false, - external_view_embedder); + auto shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1150,8 +1164,10 @@ TEST_F(ShellTest, }; auto external_view_embedder = std::make_shared( end_frame_callback, PostPrerollResult::kSuccess, true); - auto shell = CreateShell(settings, GetTaskRunnersForFixture(), false, - external_view_embedder); + auto shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1189,8 +1205,7 @@ TEST_F(ShellTest, TEST_F(ShellTest, OnPlatformViewDestroyWithoutRasterThreadMerger) { auto settings = CreateSettingsForFixture(); - auto shell = - CreateShell(settings, GetTaskRunnersForFixture(), false, nullptr); + auto shell = CreateShell(settings); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1250,8 +1265,11 @@ TEST_F(ShellTest, OnPlatformViewDestroyWithStaticThreadMerging) { thread_host.ui_thread->GetTaskRunner(), // ui thread_host.io_thread->GetTaskRunner() // io ); - auto shell = - CreateShell(settings, task_runners, false, external_view_embedder); + auto shell = CreateShell({ + .settings = settings, + .task_runners = &task_runners, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1291,8 +1309,10 @@ TEST_F(ShellTest, GetUsedThisFrameShouldBeSetBeforeEndFrame) { }; external_view_embedder = std::make_shared( end_frame_callback, PostPrerollResult::kSuccess, true); - auto shell = CreateShell(settings, GetTaskRunnersForFixture(), false, - external_view_embedder); + auto shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1342,8 +1362,10 @@ TEST_F(ShellTest, DISABLED_SkipAndSubmitFrame) { external_view_embedder = std::make_shared( end_frame_callback, PostPrerollResult::kSkipAndRetryFrame, true); - auto shell = CreateShell(settings, GetTaskRunnersForFixture(), false, - external_view_embedder); + auto shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); PlatformViewNotifyCreated(shell.get()); @@ -1507,7 +1529,7 @@ TEST_F(ShellTest, WaitForFirstFrameInlined) { auto task_runner = CreateNewThread(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1568,15 +1590,11 @@ TEST_F(ShellTest, MultipleFluttersSetResourceCacheBytes) { return result; }; - auto shell = CreateShell( - /*settings=*/settings, - /*task_runners=*/task_runners, - /*simulate_vsync=*/false, - /*shell_test_external_view_embedder=*/nullptr, - /*is_gpu_disabled=*/false, - /*rendering_backend=*/ - ShellTestPlatformView::BackendType::kDefaultBackend, - /*platform_view_create_callback=*/platform_view_create_callback); + auto shell = CreateShell({ + .settings = settings, + .task_runners = &task_runners, + .platform_view_create_callback = platform_view_create_callback, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1672,7 +1690,7 @@ TEST_F(ShellTest, SetResourceCacheSize) { auto task_runner = CreateNewThread(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1734,7 +1752,7 @@ TEST_F(ShellTest, SetResourceCacheSizeEarly) { auto task_runner = CreateNewThread(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { @@ -1761,7 +1779,7 @@ TEST_F(ShellTest, SetResourceCacheSizeNotifiesDart) { auto task_runner = CreateNewThread(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); fml::TaskRunner::RunNowOrPostTask( shell->GetTaskRunners().GetPlatformTaskRunner(), [&shell]() { @@ -1800,7 +1818,7 @@ TEST_F(ShellTest, CanCreateImagefromDecompressedBytes) { TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -1869,7 +1887,7 @@ TEST_F(ShellTest, TextureFrameMarkedAvailableAndUnregister) { auto task_runner = CreateNewThread(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(ValidateShell(shell.get())); PlatformViewNotifyCreated(shell.get()); @@ -1923,7 +1941,7 @@ TEST_F(ShellTest, IsolateCanAccessPersistentIsolateData) { message_latch.Signal(); })); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -1950,7 +1968,7 @@ TEST_F(ShellTest, CanScheduleFrameFromPlatform) { CREATE_NATIVE_ENTRY([&](Dart_NativeArguments args) { check_latch.Signal(); })); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -1984,7 +2002,7 @@ TEST_F(ShellTest, SecondaryVsyncCallbackShouldBeCalledAfterVsyncCallback) { is_on_begin_frame_called = true; count_down_latch.CountDown(); })); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -2334,7 +2352,7 @@ TEST_F(ShellTest, RasterizerScreenshot) { auto task_runner = CreateNewThread(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(ValidateShell(shell.get())); PlatformViewNotifyCreated(shell.get()); @@ -2364,7 +2382,7 @@ TEST_F(ShellTest, RasterizerMakeRasterSnapshot) { auto task_runner = CreateNewThread(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); ASSERT_TRUE(ValidateShell(shell.get())); PlatformViewNotifyCreated(shell.get()); @@ -2618,8 +2636,10 @@ TEST_F(ShellTest, DISABLED_DiscardLayerTreeOnResize) { }; auto external_view_embedder = std::make_shared( std::move(end_frame_callback), PostPrerollResult::kSuccess, false); - std::unique_ptr shell = CreateShell( - settings, GetTaskRunnersForFixture(), false, external_view_embedder); + std::unique_ptr shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -2691,8 +2711,10 @@ TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) { external_view_embedder = std::make_shared( std::move(end_frame_callback), PostPrerollResult::kResubmitFrame, true); - std::unique_ptr shell = CreateShell( - settings, GetTaskRunnersForFixture(), false, external_view_embedder); + std::unique_ptr shell = CreateShell({ + .settings = settings, + .shell_test_external_view_embedder = external_view_embedder, + }); // Create the surface needed by rasterizer PlatformViewNotifyCreated(shell.get()); @@ -2776,7 +2798,7 @@ TEST_F(ShellTest, IgnoresInvalidMetrics) { AddNativeCallback("ReportMetrics", CREATE_NATIVE_ENTRY(native_report_device_pixel_ratio)); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); auto configuration = RunConfiguration::InferFromSettings(settings); configuration.SetEntrypoint("reportMetrics"); @@ -3377,7 +3399,7 @@ TEST_F(ShellTest, UpdateAssetResolverByTypeReplaces) { auto task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); ASSERT_TRUE(ValidateShell(shell.get())); @@ -3422,7 +3444,7 @@ TEST_F(ShellTest, UpdateAssetResolverByTypeAppends) { auto task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); ASSERT_TRUE(ValidateShell(shell.get())); @@ -3463,7 +3485,7 @@ TEST_F(ShellTest, UpdateAssetResolverByTypeNull) { auto task_runner = thread_host.platform_thread->GetTaskRunner(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); ASSERT_TRUE(ValidateShell(shell.get())); @@ -3500,7 +3522,7 @@ TEST_F(ShellTest, UpdateAssetResolverByTypeDoesNotReplaceMismatchType) { auto task_runner = fml::MessageLoop::GetCurrent().GetTaskRunner(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); ASSERT_TRUE(ValidateShell(shell.get())); @@ -3545,14 +3567,10 @@ TEST_F(ShellTest, CanCreateShellsWithGLBackend) { GTEST_SKIP(); #endif // !SHELL_ENABLE_GL auto settings = CreateSettingsForFixture(); - std::unique_ptr shell = - CreateShell(settings, // - GetTaskRunnersForFixture(), // - false, // - nullptr, // - false, // - ShellTestPlatformView::BackendType::kGLBackend // - ); + std::unique_ptr shell = CreateShell({ + .settings = settings, + .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend, + }); ASSERT_NE(shell, nullptr); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -3569,14 +3587,10 @@ TEST_F(ShellTest, CanCreateShellsWithVulkanBackend) { GTEST_SKIP(); #endif // !SHELL_ENABLE_VULKAN auto settings = CreateSettingsForFixture(); - std::unique_ptr shell = - CreateShell(settings, // - GetTaskRunnersForFixture(), // - false, // - nullptr, // - false, // - ShellTestPlatformView::BackendType::kVulkanBackend // - ); + std::unique_ptr shell = CreateShell({ + .settings = settings, + .rendering_backend = ShellTestPlatformView::BackendType::kVulkanBackend, + }); ASSERT_NE(shell, nullptr); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -3593,14 +3607,10 @@ TEST_F(ShellTest, CanCreateShellsWithMetalBackend) { GTEST_SKIP(); #endif // !SHELL_ENABLE_METAL auto settings = CreateSettingsForFixture(); - std::unique_ptr shell = - CreateShell(settings, // - GetTaskRunnersForFixture(), // - false, // - nullptr, // - false, // - ShellTestPlatformView::BackendType::kMetalBackend // - ); + std::unique_ptr shell = CreateShell({ + .settings = settings, + .rendering_backend = ShellTestPlatformView::BackendType::kMetalBackend, + }); ASSERT_NE(shell, nullptr); ASSERT_TRUE(shell->IsSetup()); auto configuration = RunConfiguration::InferFromSettings(settings); @@ -3764,15 +3774,11 @@ TEST_F(ShellTest, UsesPlatformMessageHandler) { .WillOnce(Return(platform_message_handler)); return result; }; - auto shell = CreateShell( - /*settings=*/settings, - /*task_runners=*/task_runners, - /*simulate_vsync=*/false, - /*shell_test_external_view_embedder=*/nullptr, - /*is_gpu_disabled=*/false, - /*rendering_backend=*/ - ShellTestPlatformView::BackendType::kDefaultBackend, - /*platform_view_create_callback=*/platform_view_create_callback); + auto shell = CreateShell({ + .settings = settings, + .task_runners = &task_runners, + .platform_view_create_callback = platform_view_create_callback, + }); EXPECT_EQ(platform_message_handler, shell->GetPlatformMessageHandler()); PostSync(task_runners.GetUITaskRunner(), [&shell]() { @@ -3864,7 +3870,7 @@ TEST_F(ShellTest, ImmutableBufferLoadsAssetOnBackgroundThread) { auto task_runner = CreateNewThread(); TaskRunners task_runners("test", task_runner, task_runner, task_runner, task_runner); - std::unique_ptr shell = CreateShell(settings, task_runners); + std::unique_ptr shell = CreateShell(settings, &task_runners); fml::CountDownLatch latch(1); AddNativeCallback("NotifyNative", @@ -3898,14 +3904,10 @@ TEST_F(ShellTest, PictureToImageSync) { GTEST_SKIP(); #endif // !SHELL_ENABLE_GL auto settings = CreateSettingsForFixture(); - std::unique_ptr shell = - CreateShell(settings, // - GetTaskRunnersForFixture(), // - false, // - nullptr, // - false, // - ShellTestPlatformView::BackendType::kGLBackend // - ); + std::unique_ptr shell = CreateShell({ + .settings = settings, + .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend, + }); AddNativeCallback("NativeOnBeforeToImageSync", CREATE_NATIVE_ENTRY([&](auto args) { @@ -3941,14 +3943,10 @@ TEST_F(ShellTest, PictureToImageSyncImpellerNoSurface) { #endif // !SHELL_ENABLE_METAL auto settings = CreateSettingsForFixture(); settings.enable_impeller = true; - std::unique_ptr shell = - CreateShell(settings, // - GetTaskRunnersForFixture(), // - false, // - nullptr, // - false, // - ShellTestPlatformView::BackendType::kMetalBackend // - ); + std::unique_ptr shell = CreateShell({ + .settings = settings, + .rendering_backend = ShellTestPlatformView::BackendType::kMetalBackend, + }); AddNativeCallback("NativeOnBeforeToImageSync", CREATE_NATIVE_ENTRY([&](auto args) { @@ -3993,14 +3991,11 @@ TEST_F(ShellTest, PictureToImageSyncWithTrampledContext) { task_runner); auto settings = CreateSettingsForFixture(); - std::unique_ptr shell = - CreateShell(settings, // - task_runners, // - false, // - nullptr, // - false, // - ShellTestPlatformView::BackendType::kGLBackend // - ); + std::unique_ptr shell = CreateShell({ + .settings = settings, + .task_runners = &task_runners, + .rendering_backend = ShellTestPlatformView::BackendType::kGLBackend, + }); AddNativeCallback( "NativeOnBeforeToImageSync", CREATE_NATIVE_ENTRY([&](auto args) { @@ -4035,8 +4030,7 @@ TEST_F(ShellTest, PictureToImageSyncWithTrampledContext) { TEST_F(ShellTest, PluginUtilitiesCallbackHandleErrorHandling) { auto settings = CreateSettingsForFixture(); - std::unique_ptr shell = - CreateShell(settings, GetTaskRunnersForFixture()); + std::unique_ptr shell = CreateShell(settings); fml::AutoResetWaitableEvent latch; bool test_passed; @@ -4074,7 +4068,7 @@ TEST_F(ShellTest, NotifyIdleRejectsPastAndNearFuture) { thread_host.raster_thread->GetTaskRunner(), thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner()); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); ASSERT_TRUE(ValidateShell(shell.get())); @@ -4119,7 +4113,7 @@ TEST_F(ShellTest, NotifyIdleNotCalledInLatencyMode) { thread_host.raster_thread->GetTaskRunner(), thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner()); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); ASSERT_TRUE(ValidateShell(shell.get())); @@ -4162,7 +4156,7 @@ TEST_F(ShellTest, NotifyDestroyed) { thread_host.raster_thread->GetTaskRunner(), thread_host.ui_thread->GetTaskRunner(), thread_host.io_thread->GetTaskRunner()); - auto shell = CreateShell(settings, task_runners); + auto shell = CreateShell(settings, &task_runners); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); ASSERT_TRUE(ValidateShell(shell.get())); diff --git a/shell/platform/darwin/ios/platform_message_handler_ios_test.mm b/shell/platform/darwin/ios/platform_message_handler_ios_test.mm index f1af3bef93ab0..92164577651af 100644 --- a/shell/platform/darwin/ios/platform_message_handler_ios_test.mm +++ b/shell/platform/darwin/ios/platform_message_handler_ios_test.mm @@ -44,8 +44,8 @@ @interface PlatformMessageHandlerIosTest : XCTestCase @implementation PlatformMessageHandlerIosTest - (void)testCreate { - flutter::TaskRunners task_runners("test", GetCurrentTaskRunner(), CreateNewThread("raster"), - CreateNewThread("ui"), CreateNewThread("io")); + TaskRunners task_runners("test", GetCurrentTaskRunner(), CreateNewThread("raster"), + CreateNewThread("ui"), CreateNewThread("io")); auto handler = std::make_unique(task_runners.GetPlatformTaskRunner()); XCTAssertTrue(handler); } From 1841648adfe3adbaa3ac7639ea464e4d6b3ecbf9 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 26 May 2023 21:51:15 -0700 Subject: [PATCH 134/142] Move support_thread_merging to PlatformView --- flow/embedded_views.cc | 4 -- flow/embedded_views.h | 7 ---- shell/common/animator_unittests.cc | 2 +- shell/common/platform_view.cc | 4 ++ shell/common/platform_view.h | 5 +++ shell/common/rasterizer.cc | 20 +++++----- shell/common/rasterizer.h | 2 +- shell/common/rasterizer_unittests.cc | 32 ++++++++-------- shell/common/shell.cc | 3 +- shell/common/shell_test.cc | 7 ++-- shell/common/shell_test.h | 1 + .../shell_test_external_view_embedder.cc | 8 +--- .../shell_test_external_view_embedder.h | 7 +--- shell/common/shell_test_platform_view.cc | 9 +++-- shell/common/shell_test_platform_view.h | 4 +- shell/common/shell_test_platform_view_gl.cc | 11 +++++- shell/common/shell_test_platform_view_gl.h | 8 +++- shell/common/shell_test_platform_view_metal.h | 8 +++- .../common/shell_test_platform_view_metal.mm | 11 +++++- .../common/shell_test_platform_view_vulkan.cc | 11 +++++- .../common/shell_test_platform_view_vulkan.h | 4 +- shell/common/shell_unittests.cc | 38 ++++++++++++------- .../external_view_embedder.cc | 5 --- .../external_view_embedder.h | 2 - .../external_view_embedder_unittests.cc | 16 ++++---- .../platform/android/platform_view_android.cc | 5 +++ .../platform/android/platform_view_android.h | 3 ++ .../darwin/ios/ios_external_view_embedder.h | 3 -- .../darwin/ios/ios_external_view_embedder.mm | 5 --- shell/platform/darwin/ios/platform_view_ios.h | 3 ++ .../platform/darwin/ios/platform_view_ios.mm | 5 +++ 31 files changed, 144 insertions(+), 109 deletions(-) diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc index b89ed606fcc14..2065ecd8747c3 100644 --- a/flow/embedded_views.cc +++ b/flow/embedded_views.cc @@ -111,10 +111,6 @@ 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 c9ee05430d0ab..37743843eeabf 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -433,13 +433,6 @@ class ExternalViewEmbedder { bool should_resubmit_frame, fml::RefPtr raster_thread_merger) {} - // Whether the embedder should support dynamic thread merging. - // - // Returning `true` results a |RasterThreadMerger| instance to be created. - // * See also |BegineFrame| and |EndFrame| for getting the - // |RasterThreadMerger| instance. - virtual bool SupportsDynamicThreadMerging(); - // Called when the rasterizer is being torn down. // This method provides a way to release resources associated with the current // embedder. diff --git a/shell/common/animator_unittests.cc b/shell/common/animator_unittests.cc index 77698532a2305..130f344ca40de 100644 --- a/shell/common/animator_unittests.cc +++ b/shell/common/animator_unittests.cc @@ -85,7 +85,7 @@ TEST_F(ShellTest, VSyncTargetTime) { shell, shell.GetTaskRunners(), vsync_clock, create_vsync_waiter, ShellTestPlatformView::BackendType::kDefaultBackend, nullptr, shell.GetConcurrentWorkerTaskRunner(), - shell.GetIsGpuDisabledSyncSwitch()); + shell.GetIsGpuDisabledSyncSwitch(), false); }, [](Shell& shell) { return std::make_unique(shell); }); ASSERT_TRUE(DartVMRef::IsInstanceRunning()); diff --git a/shell/common/platform_view.cc b/shell/common/platform_view.cc index cff0b1c797643..e5d52d82ebe30 100644 --- a/shell/common/platform_view.cc +++ b/shell/common/platform_view.cc @@ -173,6 +173,10 @@ PlatformView::CreateExternalViewEmbedder() { return nullptr; } +bool PlatformView::SupportsDynamicThreadMerging() { + return false; +} + void PlatformView::SetNextFrameCallback(const fml::closure& closure) { if (!closure) { return; diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 3c12332c1d276..287ba91330ad4 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -683,8 +683,13 @@ class PlatformView { ComputePlatformResolvedLocales( const std::vector& supported_locale_data); + /// @brief Returns the external view embedder for the implicit view. + /// Those of non-implicit views should be set by + /// Shell::AddRenderSurface. virtual std::shared_ptr CreateExternalViewEmbedder(); + virtual bool SupportsDynamicThreadMerging(); + //-------------------------------------------------------------------------- /// @brief Invoked when the dart VM requests that a deferred library /// be loaded. Notifies the engine that the deferred library diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 28a294a279f68..f73a226827f5c 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -59,7 +59,8 @@ void Rasterizer::SetImpellerContext( impeller_context_ = std::move(impeller_context); } -void Rasterizer::Setup(std::unique_ptr studio) { +void Rasterizer::Setup(std::unique_ptr studio, + bool support_thread_merging) { studio_ = std::move(studio); if (max_cache_bytes_.has_value()) { @@ -72,9 +73,7 @@ void Rasterizer::Setup(std::unique_ptr studio) { compositor_context_->OnGrContextCreated(); } - if (external_view_embedder_ && - external_view_embedder_->SupportsDynamicThreadMerging() && - !raster_thread_merger_) { + if (support_thread_merging && !raster_thread_merger_) { const auto platform_id = delegate_.GetTaskRunners().GetPlatformTaskRunner()->GetTaskQueueId(); const auto gpu_id = @@ -193,10 +192,10 @@ int Rasterizer::DrawLastLayerTree( } int success_count = 0; bool should_resubmit_frame = false; - for (auto& record_pair : surfaces_) { - Surface* surface = record_pair.second.surface.get(); - flutter::LayerTree* layer_tree = record_pair.second.last_tree.get(); - float device_pixel_ratio = record_pair.second.last_pixel_ratio; + for (auto& [view_id, surface_record] : surfaces_) { + Surface* surface = surface_record.surface.get(); + flutter::LayerTree* layer_tree = surface_record.last_tree.get(); + float device_pixel_ratio = surface_record.last_pixel_ratio; if (!surface || !layer_tree) { continue; } @@ -205,7 +204,7 @@ int Rasterizer::DrawLastLayerTree( } RasterStatus raster_status = DrawToSurface(*frame_timings_recorder, layer_tree, device_pixel_ratio, - &record_pair.second); + &surface_record); if (enable_leaf_layer_tracing) { layer_tree->enable_leaf_layer_tracing(false); } @@ -449,8 +448,7 @@ Rasterizer::DoDrawResult Rasterizer::DoDraw( return DoDrawResult{ .raster_status = raster_status, .resubmitted_layer_tree_item = std::make_unique( - view_id, - std::move(layer_tree), + view_id, std::move(layer_tree), frame_timings_recorder->CloneUntil( FrameTimingsRecorder::State::kBuildEnd), device_pixel_ratio), diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 7a3ea2bc880da..65442b44f9a2e 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -171,7 +171,7 @@ class Rasterizer final : public SnapshotDelegate, /// /// @param[in] studio The on-screen render studio. /// - void Setup(std::unique_ptr studio); + void Setup(std::unique_ptr studio, bool support_thread_merging); //---------------------------------------------------------------------------- /// @brief Releases the previously set up on-screen render surface and diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 2d131f64a247f..7f3ce48010a99 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -136,7 +136,7 @@ TEST(RasterizerTest, drawEmptyPipeline) { auto surface = std::make_unique>(); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { @@ -199,7 +199,7 @@ TEST(RasterizerTest, nullptr))) .Times(1); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { @@ -268,7 +268,7 @@ TEST( /*raster_thread_merger=*/_)) .Times(1); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { @@ -343,7 +343,7 @@ TEST( /*raster_thread_merger=*/_)) .Times(1); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); @@ -420,7 +420,7 @@ TEST(RasterizerTest, /*raster_thread_merger=*/_)) .Times(2); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); @@ -514,7 +514,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { std::shared_ptr> external_view_embedder = std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); EXPECT_CALL(*external_view_embedder, @@ -574,7 +574,7 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { std::shared_ptr> external_view_embedder = std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); EXPECT_CALL( @@ -634,7 +634,7 @@ TEST(RasterizerTest, EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { @@ -694,7 +694,7 @@ TEST( EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { @@ -754,7 +754,7 @@ TEST( EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { @@ -813,7 +813,7 @@ TEST( EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { @@ -871,7 +871,7 @@ TEST( EXPECT_CALL(*surface, AcquireFrame(kDefaultViewId, SkISize())); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { @@ -953,7 +953,7 @@ TEST(RasterizerTest, }); thread_host.raster_thread->GetTaskRunner()->PostTask([&] { - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { @@ -1009,7 +1009,7 @@ TEST(RasterizerTest, TeardownFreesResourceCache) { }); EXPECT_CALL(*studio, GetContext()).WillRepeatedly(Return(context.get())); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); EXPECT_EQ(context->getResourceCacheLimit(), 0ul); @@ -1128,7 +1128,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { [] { return std::make_unique(true); })); thread_host.raster_thread->GetTaskRunner()->PostTask([&] { - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { @@ -1211,7 +1211,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { [] { return std::make_unique(true); })); thread_host.raster_thread->GetTaskRunner()->PostTask([&] { - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), false); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 42f2cc20d08d7..199ee8dac331e 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -804,7 +804,8 @@ void Shell::OnPlatformViewCreated() { // Enables the thread merger which may be used by the external view // embedder. rasterizer->EnableThreadMergerIfNeeded(); - rasterizer->Setup(std::move(studio)); + rasterizer->Setup(std::move(studio), + platform_view->SupportsDynamicThreadMerging()); rasterizer->AddSurface(kFlutterDefaultViewId, std::move(surface)); } diff --git a/shell/common/shell_test.cc b/shell/common/shell_test.cc index 91f4e18c2e7ba..e5d06e119aeb0 100644 --- a/shell/common/shell_test.cc +++ b/shell/common/shell_test.cc @@ -355,8 +355,8 @@ std::unique_ptr ShellTest::CreateShell(const Config& config) { &create_vsync_waiter, // shell_test_external_view_embedder = config.shell_test_external_view_embedder, // - rendering_backend = config.rendering_backend // - ](Shell& shell) { + rendering_backend = config.rendering_backend, // + support_thread_merging = config.support_thread_merging](Shell& shell) { return ShellTestPlatformView::Create( shell, // shell.GetTaskRunners(), // @@ -365,7 +365,8 @@ std::unique_ptr ShellTest::CreateShell(const Config& config) { rendering_backend, // shell_test_external_view_embedder, // shell.GetConcurrentWorkerTaskRunner(), // - shell.GetIsGpuDisabledSyncSwitch() // + shell.GetIsGpuDisabledSyncSwitch(), // + support_thread_merging // ); }; } diff --git a/shell/common/shell_test.h b/shell/common/shell_test.h index c748e93ff3438..158a245474e2c 100644 --- a/shell/common/shell_test.h +++ b/shell/common/shell_test.h @@ -48,6 +48,7 @@ class ShellTest : public FixtureTest { // Defaults to calling ShellTestPlatformView::Create with the provided // arguments. Shell::CreateCallback platform_view_create_callback; + bool support_thread_merging; }; ShellTest(); diff --git a/shell/common/shell_test_external_view_embedder.cc b/shell/common/shell_test_external_view_embedder.cc index 475de0cd501da..f9ece8067b3c3 100644 --- a/shell/common/shell_test_external_view_embedder.cc +++ b/shell/common/shell_test_external_view_embedder.cc @@ -8,11 +8,9 @@ namespace flutter { ShellTestExternalViewEmbedder::ShellTestExternalViewEmbedder( const EndFrameCallBack& end_frame_call_back, - PostPrerollResult post_preroll_result, - bool support_thread_merging) + PostPrerollResult post_preroll_result) : end_frame_call_back_(end_frame_call_back), post_preroll_result_(post_preroll_result), - support_thread_merging_(support_thread_merging), submitted_frame_count_(0) {} void ShellTestExternalViewEmbedder::UpdatePostPrerollResult( @@ -118,8 +116,4 @@ DlCanvas* ShellTestExternalViewEmbedder::GetRootCanvas() { return nullptr; } -bool ShellTestExternalViewEmbedder::SupportsDynamicThreadMerging() { - return support_thread_merging_; -} - } // namespace flutter diff --git a/shell/common/shell_test_external_view_embedder.h b/shell/common/shell_test_external_view_embedder.h index 4aacfc6f7c401..cd5c7481b40bf 100644 --- a/shell/common/shell_test_external_view_embedder.h +++ b/shell/common/shell_test_external_view_embedder.h @@ -20,8 +20,7 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder { std::function)>; ShellTestExternalViewEmbedder(const EndFrameCallBack& end_frame_call_back, - PostPrerollResult post_preroll_result, - bool support_thread_merging); + PostPrerollResult post_preroll_result); ~ShellTestExternalViewEmbedder() = default; @@ -86,14 +85,10 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| DlCanvas* GetRootCanvas() override; - // |ExternalViewEmbedder| - bool SupportsDynamicThreadMerging() override; - const EndFrameCallBack end_frame_call_back_; PostPrerollResult post_preroll_result_; - bool support_thread_merging_; SkISize frame_size_; std::map> slices_; std::map mutators_stacks_; diff --git a/shell/common/shell_test_platform_view.cc b/shell/common/shell_test_platform_view.cc index a683d372d8d0a..9ccdd0e912124 100644 --- a/shell/common/shell_test_platform_view.cc +++ b/shell/common/shell_test_platform_view.cc @@ -26,7 +26,8 @@ std::unique_ptr ShellTestPlatformView::Create( const std::shared_ptr& shell_test_external_view_embedder, const std::shared_ptr& worker_task_runner, - const std::shared_ptr& is_gpu_disabled_sync_switch) { + const std::shared_ptr& is_gpu_disabled_sync_switch, + bool support_thread_merging) { // TODO(gw280): https://github.com/flutter/flutter/issues/50298 // Make this fully runtime configurable switch (backend) { @@ -35,20 +36,20 @@ std::unique_ptr ShellTestPlatformView::Create( case BackendType::kGLBackend: return std::make_unique( delegate, task_runners, vsync_clock, create_vsync_waiter, - shell_test_external_view_embedder); + shell_test_external_view_embedder, support_thread_merging); #endif // SHELL_ENABLE_GL #ifdef SHELL_ENABLE_VULKAN case BackendType::kVulkanBackend: return std::make_unique( delegate, task_runners, vsync_clock, create_vsync_waiter, - shell_test_external_view_embedder); + shell_test_external_view_embedder, support_thread_merging); #endif // SHELL_ENABLE_VULKAN #ifdef SHELL_ENABLE_METAL case BackendType::kMetalBackend: return std::make_unique( delegate, task_runners, vsync_clock, create_vsync_waiter, shell_test_external_view_embedder, worker_task_runner, - is_gpu_disabled_sync_switch); + is_gpu_disabled_sync_switch, support_thread_merging); #endif // SHELL_ENABLE_METAL default: diff --git a/shell/common/shell_test_platform_view.h b/shell/common/shell_test_platform_view.h index 3dd518bdaa27a..8b46417af9505 100644 --- a/shell/common/shell_test_platform_view.h +++ b/shell/common/shell_test_platform_view.h @@ -30,8 +30,8 @@ class ShellTestPlatformView : public PlatformView { const std::shared_ptr& shell_test_external_view_embedder, const std::shared_ptr& worker_task_runner, - const std::shared_ptr& - is_gpu_disabled_sync_switch); + const std::shared_ptr& is_gpu_disabled_sync_switch, + bool support_thread_merging); virtual void SimulateVSync() = 0; diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index 1e36400d96939..ae437e989360b 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -18,13 +18,15 @@ ShellTestPlatformViewGL::ShellTestPlatformViewGL( std::shared_ptr vsync_clock, CreateVsyncWaiter create_vsync_waiter, std::shared_ptr - shell_test_external_view_embedder) + shell_test_external_view_embedder, + bool support_thread_merging) : ShellTestPlatformView(delegate, task_runners), gl_surface_(SkISize::Make(800, 600)), create_vsync_waiter_(std::move(create_vsync_waiter)), vsync_clock_(std::move(vsync_clock)), shell_test_external_view_embedder_( - std::move(shell_test_external_view_embedder)) {} + std::move(shell_test_external_view_embedder), ), + support_thread_merging_(support_thread_merging) {} ShellTestPlatformViewGL::~ShellTestPlatformViewGL() = default; @@ -60,6 +62,11 @@ ShellTestPlatformViewGL::CreateExternalViewEmbedder() { return shell_test_external_view_embedder_; } +// |PlatformView| +bool ShellTestPlatformViewGL::SupportsDynamicThreadMerging() { + return support_thread_merging_; +} + // |PlatformView| PointerDataDispatcherMaker ShellTestPlatformViewGL::GetDispatcherMaker() { return [](DefaultPointerDataDispatcher::Delegate& delegate) { diff --git a/shell/common/shell_test_platform_view_gl.h b/shell/common/shell_test_platform_view_gl.h index 635bba96efa03..ed4c489579b0d 100644 --- a/shell/common/shell_test_platform_view_gl.h +++ b/shell/common/shell_test_platform_view_gl.h @@ -21,7 +21,8 @@ class ShellTestPlatformViewGL : public ShellTestPlatformView, std::shared_ptr vsync_clock, CreateVsyncWaiter create_vsync_waiter, std::shared_ptr - shell_test_external_view_embedder); + shell_test_external_view_embedder, + bool support_thread_merging); // |ShellTestPlatformView| virtual ~ShellTestPlatformViewGL() override; @@ -41,6 +42,8 @@ class ShellTestPlatformViewGL : public ShellTestPlatformView, sk_sp main_context_; + bool support_thread_merging_; + // |PlatformView| std::unique_ptr CreateRenderingStudio() override; @@ -50,6 +53,9 @@ class ShellTestPlatformViewGL : public ShellTestPlatformView, // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; + // |PlatformView| + bool SupportsDynamicThreadMerging() override; + // |PlatformView| std::unique_ptr CreateVSyncWaiter() override; diff --git a/shell/common/shell_test_platform_view_metal.h b/shell/common/shell_test_platform_view_metal.h index 32c6d1dc50751..c07258783f59c 100644 --- a/shell/common/shell_test_platform_view_metal.h +++ b/shell/common/shell_test_platform_view_metal.h @@ -25,8 +25,8 @@ class ShellTestPlatformViewMetal final : public ShellTestPlatformView, std::shared_ptr shell_test_external_view_embedder, const std::shared_ptr& worker_task_runner, - const std::shared_ptr& - is_gpu_disabled_sync_switch); + const std::shared_ptr& is_gpu_disabled_sync_switch, + bool support_thread_merging); // |ShellTestPlatformView| virtual ~ShellTestPlatformViewMetal() override; @@ -38,6 +38,7 @@ class ShellTestPlatformViewMetal final : public ShellTestPlatformView, const std::shared_ptr vsync_clock_; const std::shared_ptr shell_test_external_view_embedder_; + bool support_thread_merging_; // |ShellTestPlatformView| virtual void SimulateVSync() override; @@ -48,6 +49,9 @@ class ShellTestPlatformViewMetal final : public ShellTestPlatformView, // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; + // |PlatformView| + bool SupportsDynamicThreadMerging() override; + // |PlatformView| PointerDataDispatcherMaker GetDispatcherMaker() override; diff --git a/shell/common/shell_test_platform_view_metal.mm b/shell/common/shell_test_platform_view_metal.mm index 48ded17a43af3..9d82156f6f26c 100644 --- a/shell/common/shell_test_platform_view_metal.mm +++ b/shell/common/shell_test_platform_view_metal.mm @@ -77,7 +77,8 @@ GPUMTLTextureInfo offscreen_texture_info() const { CreateVsyncWaiter create_vsync_waiter, std::shared_ptr shell_test_external_view_embedder, const std::shared_ptr& worker_task_runner, - const std::shared_ptr& is_gpu_disabled_sync_switch) + const std::shared_ptr& is_gpu_disabled_sync_switch, + bool support_thread_merging) : ShellTestPlatformView(delegate, task_runners), GPUSurfaceMetalDelegate(MTLRenderTargetType::kMTLTexture), metal_context_(std::make_unique(GetSettings().enable_impeller, @@ -85,7 +86,8 @@ GPUMTLTextureInfo offscreen_texture_info() const { is_gpu_disabled_sync_switch)), create_vsync_waiter_(std::move(create_vsync_waiter)), vsync_clock_(std::move(vsync_clock)), - shell_test_external_view_embedder_(std::move(shell_test_external_view_embedder)) { + shell_test_external_view_embedder_(std::move(shell_test_external_view_embedder)), + support_thread_merging_(support_thread_merging) { sksl_precompiler_ = std::make_shared(); if (GetSettings().enable_impeller) { FML_CHECK([metal_context_->impeller_context() context] != nil); @@ -110,6 +112,11 @@ GPUMTLTextureInfo offscreen_texture_info() const { return shell_test_external_view_embedder_; } +// |PlatformView| +bool ShellTestPlatformViewMetal::SupportsDynamicThreadMerging() { + return support_thread_merging_; +} + // |PlatformView| PointerDataDispatcherMaker ShellTestPlatformViewMetal::GetDispatcherMaker() { return [](DefaultPointerDataDispatcher::Delegate& delegate) { diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 60bfd7ba49697..cd89d06b8955d 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -35,13 +35,15 @@ ShellTestPlatformViewVulkan::ShellTestPlatformViewVulkan( std::shared_ptr vsync_clock, CreateVsyncWaiter create_vsync_waiter, std::shared_ptr - shell_test_external_view_embedder) + shell_test_external_view_embedder, + bool support_thread_merging) : ShellTestPlatformView(delegate, task_runners), create_vsync_waiter_(std::move(create_vsync_waiter)), vsync_clock_(std::move(vsync_clock)), proc_table_(fml::MakeRefCounted(VULKAN_SO_PATH)), shell_test_external_view_embedder_( - std::move(shell_test_external_view_embedder)) {} + std::move(shell_test_external_view_embedder)), + support_thread_merging_(support_thread_merging) {} ShellTestPlatformViewVulkan::~ShellTestPlatformViewVulkan() = default; @@ -77,6 +79,11 @@ ShellTestPlatformViewVulkan::CreateExternalViewEmbedder() { return shell_test_external_view_embedder_; } +// |PlatformView| +bool ShellTestPlatformViewVulkan::SupportsDynamicThreadMerging() { + return support_thread_merging_; +} + // |PlatformView| PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() { return [](DefaultPointerDataDispatcher::Delegate& delegate) { diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index a2c762259eb58..fcc3a4bdeaa47 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -22,7 +22,8 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { std::shared_ptr vsync_clock, CreateVsyncWaiter create_vsync_waiter, std::shared_ptr - shell_test_external_view_embedder); + shell_test_external_view_embedder, + bool support_thread_merging); ~ShellTestPlatformViewVulkan() override; @@ -43,6 +44,7 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { std::unique_ptr logical_device_; sk_sp memory_allocator_; sk_sp context_; + bool support_thread_merging_; bool CreateSkiaGrContext(); bool CreateSkiaBackendContext(GrVkBackendContext* context); diff --git a/shell/common/shell_unittests.cc b/shell/common/shell_unittests.cc index 2e1260761cbbc..c21a3f50e68ea 100644 --- a/shell/common/shell_unittests.cc +++ b/shell/common/shell_unittests.cc @@ -421,9 +421,11 @@ TEST_F(ShellTest, return static_cast>( std::make_unique(task_runners)); }, - ShellTestPlatformView::BackendType::kDefaultBackend, nullptr, + ShellTestPlatformView::BackendType::kDefaultBackend, + /*external_view_embedder=*/nullptr, shell.GetConcurrentWorkerTaskRunner(), - shell.GetIsGpuDisabledSyncSwitch()); + shell.GetIsGpuDisabledSyncSwitch(), + /*support_thread_merging=*/false); }, [](Shell& shell) { return std::make_unique(shell); }); ASSERT_TRUE(ValidateShell(shell.get())); @@ -807,7 +809,7 @@ TEST_F(ShellTest, ExternalEmbedderNoThreadMerger) { end_frame_latch.Signal(); }; auto external_view_embedder = std::make_shared( - end_frame_callback, PostPrerollResult::kResubmitFrame, false); + end_frame_callback, PostPrerollResult::kResubmitFrame); auto shell = CreateShell({ .settings = settings, .shell_test_external_view_embedder = external_view_embedder, @@ -866,7 +868,7 @@ TEST_F(ShellTest, PushBackdropFilterToVisitedPlatformViews) { }; external_view_embedder = std::make_shared( - end_frame_callback, PostPrerollResult::kResubmitFrame, false); + end_frame_callback, PostPrerollResult::kResubmitFrame); auto shell = CreateShell({ .settings = settings, .shell_test_external_view_embedder = external_view_embedder, @@ -937,10 +939,11 @@ TEST_F(ShellTest, end_frame_latch.Signal(); }; auto external_view_embedder = std::make_shared( - end_frame_callback, PostPrerollResult::kResubmitFrame, true); + end_frame_callback, PostPrerollResult::kResubmitFrame); auto shell = CreateShell({ .settings = settings, .shell_test_external_view_embedder = external_view_embedder, + .support_thread_merging = true, }); // Create the surface needed by rasterizer @@ -979,11 +982,12 @@ TEST_F(ShellTest, OnPlatformViewDestroyDisablesThreadMerger) { raster_thread_merger = std::move(thread_merger); }; auto external_view_embedder = std::make_shared( - end_frame_callback, PostPrerollResult::kSuccess, true); + end_frame_callback, PostPrerollResult::kSuccess); auto shell = CreateShell({ .settings = settings, .shell_test_external_view_embedder = external_view_embedder, + .support_thread_merging = true, }); // Create the surface needed by rasterizer @@ -1041,13 +1045,14 @@ TEST_F(ShellTest, OnPlatformViewDestroyAfterMergingThreads) { end_frame_latch.Signal(); }; external_view_embedder = std::make_shared( - end_frame_callback, PostPrerollResult::kSuccess, true); + end_frame_callback, PostPrerollResult::kSuccess); // Set resubmit once to trigger thread merging. external_view_embedder->UpdatePostPrerollResult( PostPrerollResult::kResubmitFrame); auto shell = CreateShell({ .settings = settings, .shell_test_external_view_embedder = external_view_embedder, + .support_thread_merging = true, }); // Create the surface needed by rasterizer @@ -1109,11 +1114,12 @@ TEST_F(ShellTest, OnPlatformViewDestroyWhenThreadsAreMerging) { // can later check if the rasterizer is tore down using // |ValidateDestroyPlatformView| auto external_view_embedder = std::make_shared( - end_frame_callback, PostPrerollResult::kSuccess, true); + end_frame_callback, PostPrerollResult::kSuccess); auto shell = CreateShell({ .settings = settings, .shell_test_external_view_embedder = external_view_embedder, + .support_thread_merging = true, }); // Create the surface needed by rasterizer @@ -1175,10 +1181,11 @@ TEST_F(ShellTest, end_frame_latch.Signal(); }; auto external_view_embedder = std::make_shared( - end_frame_callback, PostPrerollResult::kSuccess, true); + end_frame_callback, PostPrerollResult::kSuccess); auto shell = CreateShell({ .settings = settings, .shell_test_external_view_embedder = external_view_embedder, + .support_thread_merging = true, }); // Create the surface needed by rasterizer @@ -1266,7 +1273,7 @@ TEST_F(ShellTest, OnPlatformViewDestroyWithStaticThreadMerging) { end_frame_latch.Signal(); }; auto external_view_embedder = std::make_shared( - end_frame_callback, PostPrerollResult::kSuccess, true); + end_frame_callback, PostPrerollResult::kSuccess); ThreadHost thread_host( "io.flutter.test." + GetCurrentTestName() + ".", ThreadHost::Type::Platform | ThreadHost::Type::IO | ThreadHost::Type::UI); @@ -1281,6 +1288,7 @@ TEST_F(ShellTest, OnPlatformViewDestroyWithStaticThreadMerging) { .settings = settings, .task_runners = &task_runners, .shell_test_external_view_embedder = external_view_embedder, + .support_thread_merging = true, }); // Create the surface needed by rasterizer @@ -1320,10 +1328,11 @@ TEST_F(ShellTest, GetUsedThisFrameShouldBeSetBeforeEndFrame) { end_frame_latch.Signal(); }; external_view_embedder = std::make_shared( - end_frame_callback, PostPrerollResult::kSuccess, true); + end_frame_callback, PostPrerollResult::kSuccess); auto shell = CreateShell({ .settings = settings, .shell_test_external_view_embedder = external_view_embedder, + .support_thread_merging = true, }); // Create the surface needed by rasterizer @@ -1372,11 +1381,12 @@ TEST_F(ShellTest, DISABLED_SkipAndSubmitFrame) { end_frame_latch.Signal(); }; external_view_embedder = std::make_shared( - end_frame_callback, PostPrerollResult::kSkipAndRetryFrame, true); + end_frame_callback, PostPrerollResult::kSkipAndRetryFrame); auto shell = CreateShell({ .settings = settings, .shell_test_external_view_embedder = external_view_embedder, + .support_thread_merging = true, }); PlatformViewNotifyCreated(shell.get()); @@ -2658,7 +2668,7 @@ TEST_F(ShellTest, DISABLED_DiscardLayerTreeOnResize) { end_frame_latch.Signal(); }; auto external_view_embedder = std::make_shared( - std::move(end_frame_callback), PostPrerollResult::kSuccess, false); + std::move(end_frame_callback), PostPrerollResult::kSuccess); std::unique_ptr shell = CreateShell({ .settings = settings, .shell_test_external_view_embedder = external_view_embedder, @@ -2733,7 +2743,7 @@ TEST_F(ShellTest, DISABLED_DiscardResubmittedLayerTreeOnResize) { }; external_view_embedder = std::make_shared( - std::move(end_frame_callback), PostPrerollResult::kResubmitFrame, true); + std::move(end_frame_callback), PostPrerollResult::kResubmitFrame); std::unique_ptr shell = CreateShell({ .settings = settings, 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 5d2692e3d89aa..cf846608196ef 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc @@ -299,11 +299,6 @@ void AndroidExternalViewEmbedder::EndFrame( } } -// |ExternalViewEmbedder| -bool AndroidExternalViewEmbedder::SupportsDynamicThreadMerging() { - return true; -} - // |ExternalViewEmbedder| void AndroidExternalViewEmbedder::Teardown() { DestroySurfaces(); 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 2038b4190478c..7cd72ca3d8173 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.h +++ b/shell/platform/android/external_view_embedder/external_view_embedder.h @@ -71,8 +71,6 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder { bool should_resubmit_frame, fml::RefPtr raster_thread_merger) override; - bool SupportsDynamicThreadMerging() override; - void Teardown() override; // Gets the rect based on the device pixel ratio of a platform view displayed 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 0c932d21c397a..ac3148eba8770 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 @@ -929,13 +929,15 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { GetThreadMergerFromRasterThread(&platform_thread)); } -TEST(AndroidExternalViewEmbedder, SupportsDynamicThreadMerging) { - auto jni_mock = std::make_shared(); - auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); - auto embedder = std::make_unique( - android_context, jni_mock, nullptr, GetTaskRunnersForFixture()); - ASSERT_TRUE(embedder->SupportsDynamicThreadMerging()); -} +// TODO(dkwingsmt): Migrate to a unit test for PlatformViewAndroid, which +// however doesn't have unit tests at all... +// TEST(AndroidExternalViewEmbedder, SupportsDynamicThreadMerging) { +// auto jni_mock = std::make_shared(); +// auto android_context = AndroidContext(AndroidRenderingAPI::kSoftware); +// auto embedder = std::make_unique( +// android_context, jni_mock, nullptr, GetTaskRunnersForFixture()); +// ASSERT_TRUE(embedder->SupportsDynamicThreadMerging()); +// } TEST(AndroidExternalViewEmbedder, DisableThreadMerger) { auto jni_mock = std::make_shared(); diff --git a/shell/platform/android/platform_view_android.cc b/shell/platform/android/platform_view_android.cc index 6ed55925bfd7c..fd680263a652a 100644 --- a/shell/platform/android/platform_view_android.cc +++ b/shell/platform/android/platform_view_android.cc @@ -320,6 +320,11 @@ PlatformViewAndroid::CreateExternalViewEmbedder() { *android_context_, jni_facade_, surface_factory_, task_runners_); } +// |PlatformView| +bool PlatformViewAndroid::SupportsDynamicThreadMerging() { + return true; +} + // |PlatformView| std::unique_ptr PlatformViewAndroid::CreateSnapshotSurfaceProducer() { diff --git a/shell/platform/android/platform_view_android.h b/shell/platform/android/platform_view_android.h index cedd4086b1268..25c5786dc71b2 100644 --- a/shell/platform/android/platform_view_android.h +++ b/shell/platform/android/platform_view_android.h @@ -151,6 +151,9 @@ class PlatformViewAndroid final : public PlatformView { // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; + // |PlatformView| + bool SupportsDynamicThreadMerging() override; + // |PlatformView| std::unique_ptr CreateSnapshotSurfaceProducer() override; diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.h b/shell/platform/darwin/ios/ios_external_view_embedder.h index 3b94df3888f2e..1192dba92d02e 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.h +++ b/shell/platform/darwin/ios/ios_external_view_embedder.h @@ -59,9 +59,6 @@ class IOSExternalViewEmbedder : public ExternalViewEmbedder { bool should_resubmit_frame, fml::RefPtr raster_thread_merger) override; - // |ExternalViewEmbedder| - bool SupportsDynamicThreadMerging() override; - // |ExternalViewEmbedder| void PushFilterToVisitedPlatformViews( std::shared_ptr filter, diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.mm b/shell/platform/darwin/ios/ios_external_view_embedder.mm index dde57241ee2a7..98713d914e1a7 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.mm +++ b/shell/platform/darwin/ios/ios_external_view_embedder.mm @@ -82,11 +82,6 @@ platform_views_controller_->EndFrame(should_resubmit_frame, raster_thread_merger); } -// |ExternalViewEmbedder| -bool IOSExternalViewEmbedder::SupportsDynamicThreadMerging() { - return true; -} - // |ExternalViewEmbedder| void IOSExternalViewEmbedder::PushFilterToVisitedPlatformViews( std::shared_ptr filter, diff --git a/shell/platform/darwin/ios/platform_view_ios.h b/shell/platform/darwin/ios/platform_view_ios.h index 43f2b5d2962cd..510d51deba038 100644 --- a/shell/platform/darwin/ios/platform_view_ios.h +++ b/shell/platform/darwin/ios/platform_view_ios.h @@ -159,6 +159,9 @@ class PlatformViewIOS final : public PlatformView { // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; + // |PlatformView| + bool SupportsDynamicThreadMerging() override; + // |PlatformView| sk_sp CreateResourceContext() const override; diff --git a/shell/platform/darwin/ios/platform_view_ios.mm b/shell/platform/darwin/ios/platform_view_ios.mm index eacdf25e3d00a..2bcef0a1b5677 100644 --- a/shell/platform/darwin/ios/platform_view_ios.mm +++ b/shell/platform/darwin/ios/platform_view_ios.mm @@ -170,6 +170,11 @@ new PlatformMessageHandlerIos(task_runners.GetPlatformTaskRunner())) {} return std::make_shared(platform_views_controller_, ios_context_); } +// |PlatformView| +bool PlatformViewIOS::SupportsDynamicThreadMerging() { + return true; +} + // |PlatformView| sk_sp PlatformViewIOS::CreateResourceContext() const { return ios_context_->CreateResourceContext(); From b93035129ec9b4d79c63ffd4d8f2f450ce3430ca Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Fri, 26 May 2023 22:16:56 -0700 Subject: [PATCH 135/142] Fix raster test and fuchsia compile --- shell/common/rasterizer_unittests.cc | 13 +++---------- shell/common/shell_test_platform_view_gl.cc | 2 +- shell/common/shell_test_platform_view_vulkan.h | 3 ++- .../flutter/flatland_external_view_embedder.h | 3 --- .../fuchsia/flutter/gfx_external_view_embedder.h | 3 --- 5 files changed, 6 insertions(+), 18 deletions(-) diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 7f3ce48010a99..6708125c84004 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -91,7 +91,6 @@ class MockExternalViewEmbedder : public ExternalViewEmbedder { MOCK_METHOD2(EndFrame, void(bool should_resubmit_frame, fml::RefPtr raster_thread_merger)); - MOCK_METHOD0(SupportsDynamicThreadMerging, bool()); }; } // namespace @@ -244,8 +243,6 @@ TEST( std::shared_ptr> external_view_embedder = std::make_shared>(); rasterizer->SetExternalViewEmbedder(external_view_embedder); - EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging) - .WillRepeatedly(Return(true)); SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; auto surface_frame = std::make_unique( @@ -268,7 +265,7 @@ TEST( /*raster_thread_merger=*/_)) .Times(1); - rasterizer->Setup(std::move(studio), false); + rasterizer->Setup(std::move(studio), /*support_thread_merging=*/true); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { @@ -330,8 +327,6 @@ TEST( .WillOnce(Return(ByMove(std::move(surface_frame)))); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging) - .WillRepeatedly(Return(true)); EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, @@ -343,7 +338,7 @@ TEST( /*raster_thread_merger=*/_)) .Times(1); - rasterizer->Setup(std::move(studio), false); + rasterizer->Setup(std::move(studio), /*support_thread_merging=*/true); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); @@ -407,8 +402,6 @@ TEST(RasterizerTest, .WillOnce(Return(ByMove(std::move(surface_frame2)))); EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); - EXPECT_CALL(*external_view_embedder, SupportsDynamicThreadMerging) - .WillRepeatedly(Return(true)); EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, @@ -420,7 +413,7 @@ TEST(RasterizerTest, /*raster_thread_merger=*/_)) .Times(2); - rasterizer->Setup(std::move(studio), false); + rasterizer->Setup(std::move(studio), /*support_thread_merging=*/true); rasterizer->AddSurface(kDefaultViewId, std::move(surface)); auto pipeline = std::make_shared(/*depth=*/10); diff --git a/shell/common/shell_test_platform_view_gl.cc b/shell/common/shell_test_platform_view_gl.cc index ae437e989360b..6ba0d60fbcfff 100644 --- a/shell/common/shell_test_platform_view_gl.cc +++ b/shell/common/shell_test_platform_view_gl.cc @@ -25,7 +25,7 @@ ShellTestPlatformViewGL::ShellTestPlatformViewGL( create_vsync_waiter_(std::move(create_vsync_waiter)), vsync_clock_(std::move(vsync_clock)), shell_test_external_view_embedder_( - std::move(shell_test_external_view_embedder), ), + std::move(shell_test_external_view_embedder)), support_thread_merging_(support_thread_merging) {} ShellTestPlatformViewGL::~ShellTestPlatformViewGL() = default; diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index fcc3a4bdeaa47..845604640d0fe 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -44,7 +44,6 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { std::unique_ptr logical_device_; sk_sp memory_allocator_; sk_sp context_; - bool support_thread_merging_; bool CreateSkiaGrContext(); bool CreateSkiaBackendContext(GrVkBackendContext* context); @@ -116,6 +115,8 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { std::shared_ptr offscreen_context_; + bool support_thread_merging_; + // |PlatformView| std::unique_ptr CreateRenderingStudio() override; diff --git a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h index 394de12c7887a..c637aad11d1eb 100644 --- a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h +++ b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h @@ -93,9 +93,6 @@ class FlatlandExternalViewEmbedder final // |ExternalViewEmbedder| void CancelFrame() override { Reset(); } - // |ExternalViewEmbedder| - bool SupportsDynamicThreadMerging() override { return false; } - // View manipulation. // |SetViewProperties| doesn't manipulate the view directly -- it sets pending // properties for the next |UpdateView| call. diff --git a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h index 7d2f545cf238e..54ed5d6261b43 100644 --- a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h +++ b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h @@ -116,9 +116,6 @@ class GfxExternalViewEmbedder final : public flutter::ExternalViewEmbedder { // |ExternalViewEmbedder| void CancelFrame() override { Reset(); } - // |ExternalViewEmbedder| - bool SupportsDynamicThreadMerging() override { return false; } - // View manipulation. // |SetViewProperties| doesn't manipulate the view directly -- it sets pending // properties for the next |UpdateView| call. From 9e4b4950267c300c584844dcb005fd9cf5f5f654 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 30 May 2023 11:12:14 -0700 Subject: [PATCH 136/142] Fix compile --- shell/common/shell_test_platform_view_vulkan.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index cd89d06b8955d..5ff444495d5f0 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -79,11 +79,6 @@ ShellTestPlatformViewVulkan::CreateExternalViewEmbedder() { return shell_test_external_view_embedder_; } -// |PlatformView| -bool ShellTestPlatformViewVulkan::SupportsDynamicThreadMerging() { - return support_thread_merging_; -} - // |PlatformView| PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() { return [](DefaultPointerDataDispatcher::Delegate& delegate) { From e4832a3048bcf613f58a8d9d7fd60f1d5e8b55e4 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 30 May 2023 11:20:55 -0700 Subject: [PATCH 137/142] Fix test parameter --- shell/common/shell_test_platform_view_vulkan.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/shell/common/shell_test_platform_view_vulkan.cc b/shell/common/shell_test_platform_view_vulkan.cc index 5ff444495d5f0..cd89d06b8955d 100644 --- a/shell/common/shell_test_platform_view_vulkan.cc +++ b/shell/common/shell_test_platform_view_vulkan.cc @@ -79,6 +79,11 @@ ShellTestPlatformViewVulkan::CreateExternalViewEmbedder() { return shell_test_external_view_embedder_; } +// |PlatformView| +bool ShellTestPlatformViewVulkan::SupportsDynamicThreadMerging() { + return support_thread_merging_; +} + // |PlatformView| PointerDataDispatcherMaker ShellTestPlatformViewVulkan::GetDispatcherMaker() { return [](DefaultPointerDataDispatcher::Delegate& delegate) { From 3eb95bdfcf5e0d90523ebfc1b37c30f41c558369 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 30 May 2023 12:40:40 -0700 Subject: [PATCH 138/142] Fix compile --- shell/common/shell_test_platform_view_vulkan.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shell/common/shell_test_platform_view_vulkan.h b/shell/common/shell_test_platform_view_vulkan.h index 845604640d0fe..1bc3f98e20271 100644 --- a/shell/common/shell_test_platform_view_vulkan.h +++ b/shell/common/shell_test_platform_view_vulkan.h @@ -126,6 +126,9 @@ class ShellTestPlatformViewVulkan : public ShellTestPlatformView { // |PlatformView| std::shared_ptr CreateExternalViewEmbedder() override; + // |PlatformView| + bool SupportsDynamicThreadMerging() override; + // |PlatformView| std::unique_ptr CreateVSyncWaiter() override; From 6892eb62344ac5006abc76bdf4c77bd0d436bd96 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 30 May 2023 14:01:30 -0700 Subject: [PATCH 139/142] Move assigning view embedder to add surface --- shell/common/rasterizer.cc | 15 +++-- shell/common/rasterizer.h | 14 +---- shell/common/rasterizer_unittests.cc | 90 +++++++--------------------- shell/common/shell.cc | 9 +-- 4 files changed, 39 insertions(+), 89 deletions(-) diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index 30e533da2038a..bf2e7f6e527fd 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -152,7 +152,15 @@ void Rasterizer::NotifyLowMemoryWarning() const { context->performDeferredCleanup(std::chrono::milliseconds(0)); } -void Rasterizer::AddSurface(int64_t view_id, std::unique_ptr surface) { +void Rasterizer::AddSurface( + int64_t view_id, + std::unique_ptr surface, + std::shared_ptr view_embedder) { + if (!external_view_embedder_) { + external_view_embedder_ = view_embedder; + } else { + FML_DCHECK(external_view_embedder_ == view_embedder); + } bool insertion_happened = surfaces_ .try_emplace(/* map key=*/view_id, /*constructor args:*/ view_id, @@ -859,11 +867,6 @@ 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::SetSnapshotSurfaceProducer( std::unique_ptr producer) { snapshot_surface_producer_ = std::move(producer); diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 65442b44f9a2e..1848a33a545d9 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -206,7 +206,9 @@ class Rasterizer final : public SnapshotDelegate, fml::TaskRunnerAffineWeakPtr GetSnapshotDelegate() const; - void AddSurface(int64_t view_id, std::unique_ptr surface); + void AddSurface(int64_t view_id, + std::unique_ptr surface, + std::shared_ptr view_embedder); void RemoveSurface(int64_t view_id); @@ -400,16 +402,6 @@ 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 Set the snapshot surface producer. This is done on shell /// initialization. This is non-null on platforms that support taking diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index 6708125c84004..d803e1c082507 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -136,7 +136,7 @@ TEST(RasterizerTest, drawEmptyPipeline) { EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), nullptr); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -169,7 +169,6 @@ TEST(RasterizerTest, std::shared_ptr> external_view_embedder = std::make_shared>(); - rasterizer->SetExternalViewEmbedder(external_view_embedder); SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; @@ -199,7 +198,8 @@ TEST(RasterizerTest, .Times(1); rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), + external_view_embedder); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -242,7 +242,6 @@ TEST( auto surface = std::make_unique>(); std::shared_ptr> external_view_embedder = std::make_shared>(); - rasterizer->SetExternalViewEmbedder(external_view_embedder); SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; auto surface_frame = std::make_unique( @@ -266,7 +265,8 @@ TEST( .Times(1); rasterizer->Setup(std::move(studio), /*support_thread_merging=*/true); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), + external_view_embedder); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -313,7 +313,6 @@ TEST( std::shared_ptr> external_view_embedder = std::make_shared>(); - rasterizer->SetExternalViewEmbedder(external_view_embedder); SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; @@ -339,7 +338,8 @@ TEST( .Times(1); rasterizer->Setup(std::move(studio), /*support_thread_merging=*/true); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), + external_view_embedder); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), @@ -381,7 +381,6 @@ TEST(RasterizerTest, std::shared_ptr> external_view_embedder = std::make_shared>(); - rasterizer->SetExternalViewEmbedder(external_view_embedder); SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; @@ -414,7 +413,8 @@ TEST(RasterizerTest, .Times(2); rasterizer->Setup(std::move(studio), /*support_thread_merging=*/true); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), + external_view_embedder); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique(/*config=*/LayerTree::Config(), @@ -436,52 +436,6 @@ TEST(RasterizerTest, rasterizer->DrawLastLayerTree(CreateFinishedBuildRecorder()); } -TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNoSurfaceIsSet) { - std::string test_name = - ::testing::UnitTest::GetInstance()->current_test_info()->name(); - ThreadHost thread_host("io.flutter.test." + test_name + ".", - ThreadHost::Type::Platform | ThreadHost::Type::RASTER | - ThreadHost::Type::IO | ThreadHost::Type::UI); - 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)); - auto rasterizer = std::make_unique(delegate); - - std::shared_ptr> external_view_embedder = - std::make_shared>(); - rasterizer->SetExternalViewEmbedder(external_view_embedder); - - EXPECT_CALL( - *external_view_embedder, - EndFrame(/*should_resubmit_frame=*/false, - /*raster_thread_merger=*/fml::RefPtr( - nullptr))) - .Times(0); - - fml::AutoResetWaitableEvent latch; - thread_host.raster_thread->GetTaskRunner()->PostTask([&] { - auto pipeline = std::make_shared(/*depth=*/10); - auto layer_tree = std::make_unique( - /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); - auto layer_tree_item = std::make_unique( - kDefaultViewId, std::move(layer_tree), CreateFinishedBuildRecorder(), - kDevicePixelRatio); - PipelineProduceResult result = - pipeline->Produce().Complete(std::move(layer_tree_item)); - EXPECT_TRUE(result.success); - auto no_discard = [](int64_t, LayerTree&) { return false; }; - rasterizer->Draw(pipeline, no_discard); - latch.Signal(); - }); - latch.Wait(); -} - TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { std::string test_name = ::testing::UnitTest::GetInstance()->current_test_info()->name(); @@ -506,9 +460,9 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenNotUsedThisFrame) { std::shared_ptr> external_view_embedder = std::make_shared>(); - rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), + external_view_embedder); EXPECT_CALL(*external_view_embedder, BeginFrame(/*frame_size=*/SkISize(), /*context=*/nullptr, @@ -566,9 +520,9 @@ TEST(RasterizerTest, externalViewEmbedderDoesntEndFrameWhenPipelineIsEmpty) { std::shared_ptr> external_view_embedder = std::make_shared>(); - rasterizer->SetExternalViewEmbedder(external_view_embedder); rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), + external_view_embedder); EXPECT_CALL( *external_view_embedder, @@ -628,7 +582,7 @@ TEST(RasterizerTest, .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), nullptr); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -688,7 +642,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), nullptr); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -748,7 +702,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), nullptr); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -807,7 +761,7 @@ TEST( .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), nullptr); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -865,7 +819,7 @@ TEST( EXPECT_CALL(*studio, MakeRenderContextCurrent()) .WillOnce(Return(ByMove(std::make_unique(true)))); rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), nullptr); fml::AutoResetWaitableEvent latch; thread_host.raster_thread->GetTaskRunner()->PostTask([&] { auto pipeline = std::make_shared(/*depth=*/10); @@ -947,7 +901,7 @@ TEST(RasterizerTest, thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), nullptr); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = std::make_unique( @@ -1003,7 +957,7 @@ TEST(RasterizerTest, TeardownFreesResourceCache) { EXPECT_CALL(*studio, GetContext()).WillRepeatedly(Return(context.get())); rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), nullptr); EXPECT_EQ(context->getResourceCacheLimit(), 0ul); rasterizer->SetResourceCacheMaxBytes(10000000, false); @@ -1122,7 +1076,7 @@ TEST(RasterizerTest, presentationTimeSetWhenVsyncTargetInFuture) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), nullptr); auto pipeline = std::make_shared(/*depth=*/10); for (int i = 0; i < 2; i++) { auto layer_tree = std::make_unique( @@ -1205,7 +1159,7 @@ TEST(RasterizerTest, presentationTimeNotSetWhenVsyncTargetInPast) { thread_host.raster_thread->GetTaskRunner()->PostTask([&] { rasterizer->Setup(std::move(studio), false); - rasterizer->AddSurface(kDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kDefaultViewId, std::move(surface), nullptr); auto pipeline = std::make_shared(/*depth=*/10); auto layer_tree = std::make_unique( /*config=*/LayerTree::Config(), /*frame_size=*/SkISize()); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 1eb566b493910..4f85cefbf26b9 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -682,8 +682,6 @@ bool Shell::Setup(std::unique_ptr platform_view, io_manager_ = io_manager; // Set the external view embedder for the rasterizer. - auto view_embedder = platform_view_->CreateExternalViewEmbedder(); - rasterizer_->SetExternalViewEmbedder(view_embedder); rasterizer_->SetSnapshotSurfaceProducer( platform_view_->CreateSnapshotSurfaceProducer()); @@ -803,13 +801,15 @@ void Shell::OnPlatformViewCreated() { ]() mutable { std::unique_ptr surface = platform_view->CreateSurface(kFlutterDefaultViewId); + auto view_embedder = platform_view->CreateExternalViewEmbedder(); if (rasterizer) { // Enables the thread merger which may be used by the external view // embedder. rasterizer->EnableThreadMergerIfNeeded(); rasterizer->Setup(std::move(studio), platform_view->SupportsDynamicThreadMerging()); - rasterizer->AddSurface(kFlutterDefaultViewId, std::move(surface)); + rasterizer->AddSurface(kFlutterDefaultViewId, std::move(surface), + view_embedder); } waiting_for_first_frame.store(true); @@ -2024,10 +2024,11 @@ void Shell::AddRenderSurface(int64_t view_id) { view_id // ]() mutable { if (platform_view && rasterizer) { + auto view_embedder = platform_view->CreateExternalViewEmbedder(); std::unique_ptr surface = platform_view->CreateSurface(view_id); if (surface) { - rasterizer->AddSurface(view_id, std::move(surface)); + rasterizer->AddSurface(view_id, std::move(surface), view_embedder); } } })); From cd7960ae13299b0f8afd7d9dfc54f8b69ca0140d Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 30 May 2023 21:07:53 -0700 Subject: [PATCH 140/142] View record --- .../macos/framework/Source/FlutterEngine.mm | 98 +++++++++++-------- 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index bc51c76d9afb0..79133a59f4a7a 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -77,6 +77,30 @@ - (instancetype)initWithConnection:(NSNumber*)connection #pragma mark - +@interface FlutterEngineViewRecord : NSObject + +- (instancetype)initWithViewController:(nonnull FlutterViewController*)controller; + +@property(nonatomic, weak) FlutterViewController* controller; + +@end + +@implementation FlutterEngineViewRecord { + __weak FlutterViewController* _controller; +} + +@synthesize controller = _controller; + +- (instancetype)initWithViewController:(FlutterViewController*)controller { + self = [super init]; + NSAssert(self, @"Super init cannot be nil"); + _controller = controller; + return self; +} +@end + +#pragma mark - + /** * Private interface declaration for FlutterEngine. */ @@ -366,9 +390,7 @@ @implementation FlutterEngine { std::unique_ptr _macOSCompositor; // The information of all views attached to this engine mapped from IDs. - // - // It can't use NSDictionary, because the values need to be weak references. - NSMapTable* _viewControllers; + NSMutableDictionary* _viewRecords; // FlutterCompositor is copied and used in embedder.cc. FlutterCompositor _compositor; @@ -429,7 +451,7 @@ - (instancetype)initWithName:(NSString*)labelPrefix _embedderAPI.struct_size = sizeof(FlutterEngineProcTable); FlutterEngineGetProcAddresses(&_embedderAPI); - _viewControllers = [NSMapTable weakToWeakObjectsMapTable]; + _viewRecords = [NSMutableDictionary dictionary]; _renderer = [[FlutterRenderer alloc] initWithFlutterEngine:self]; NSNotificationCenter* notificationCenter = [NSNotificationCenter defaultCenter]; @@ -471,7 +493,7 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { return NO; } - if (!_allowHeadlessExecution && [_viewControllers count] == 0) { + if (!_allowHeadlessExecution && [_viewRecords count] == 0) { NSLog(@"Attempted to run an engine with no view controller without headless mode enabled."); return NO; } @@ -566,10 +588,8 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { [self sendUserLocales]; // Update window metric for all view controllers. - NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator]; - FlutterViewController* nextViewController; - while ((nextViewController = [viewControllerEnumerator nextObject])) { - [self updateWindowMetricsForViewController:nextViewController]; + for (id viewId in _viewRecords) { + [self updateWindowMetricsForViewController:_viewRecords[viewId].controller]; } [self updateDisplayConfig]; @@ -609,41 +629,40 @@ - (void)registerViewController:(FlutterViewController*)controller forId:(Flutter NSAssert(controller != nil, @"The controller must not be nil."); NSAssert(![controller attached], @"The incoming view controller is already attached to an engine."); - NSAssert([_viewControllers objectForKey:@(viewId)] == nil, @"The requested view ID is occupied."); + NSAssert(_viewRecords[@(viewId)] == nil, @"The requested view ID is occupied."); [controller setUpWithEngine:self viewId:viewId threadSynchronizer:_threadSynchronizer]; NSAssert(controller.viewId == viewId, @"Failed to assign view ID."); - [_viewControllers setObject:controller forKey:@(viewId)]; + _viewRecords[@(viewId)] = [[FlutterEngineViewRecord alloc] initWithViewController:controller]; } - (void)deregisterViewControllerForId:(FlutterViewId)viewId { - FlutterViewController* oldController = [self viewControllerForId:viewId]; - if (oldController != nil) { - [oldController detachFromEngine]; - [_viewControllers removeObjectForKey:@(viewId)]; + FlutterEngineViewRecord* oldRecord = _viewRecords[@(viewId)]; + if (oldRecord.controller != nil) { + [oldRecord.controller detachFromEngine]; } + [_viewRecords removeObjectForKey:@(viewId)]; } - (void)shutDownIfNeeded { - if ([_viewControllers count] == 0 && !_allowHeadlessExecution) { + if ([_viewRecords count] == 0 && !_allowHeadlessExecution) { [self shutDownEngine]; } } - (FlutterViewController*)viewControllerForId:(FlutterViewId)viewId { - FlutterViewController* controller = [_viewControllers objectForKey:@(viewId)]; - NSAssert(controller == nil || controller.viewId == viewId, + FlutterEngineViewRecord* viewRecord = _viewRecords[@(viewId)]; + NSAssert(viewRecord == nil || viewRecord.controller.viewId == viewId, @"The stored controller has unexpected view ID."); - return controller; + return viewRecord.controller; } - (void)setViewController:(FlutterViewController*)controller { - FlutterViewController* currentController = - [_viewControllers objectForKey:@(kFlutterDefaultViewId)]; - if (currentController == controller) { + FlutterEngineViewRecord* currentViewRecord = _viewRecords[@(kFlutterDefaultViewId)]; + if (currentViewRecord.controller == controller) { // From nil to nil, or from non-nil to the same controller. return; } - if (currentController == nil && controller != nil) { + if (currentViewRecord == nil && controller != nil) { // From nil to non-nil. NSAssert(controller.engine == nil, @"Failed to set view controller to the engine: " @@ -652,9 +671,10 @@ - (void)setViewController:(FlutterViewController*)controller { @"you should use FlutterViewController#init(engine:, nibName, bundle:) instead.", controller.engine); [self registerViewController:controller forId:kFlutterDefaultViewId]; - } else if (currentController != nil && controller == nil) { - NSAssert(currentController.viewId == kFlutterDefaultViewId, - @"The default controller has an unexpected ID %llu", currentController.viewId); + } else if (currentViewRecord != nil && controller == nil) { + NSAssert(currentViewRecord.controller.viewId == kFlutterDefaultViewId, + @"The default controller has an unexpected ID %llu", + currentViewRecord.controller.viewId); // From non-nil to nil. [self deregisterViewControllerForId:kFlutterDefaultViewId]; [self shutDownIfNeeded]; @@ -665,7 +685,7 @@ - (void)setViewController:(FlutterViewController*)controller { @"The engine already has a default view controller %@. " @"If you wanted to make the default view render in a different window, " @"you should attach the current view controller to the window instead.", - [_viewControllers objectForKey:@(kFlutterDefaultViewId)]); + currentViewRecord.controller); } } @@ -842,10 +862,8 @@ - (void)setSemanticsEnabled:(BOOL)enabled { _semanticsEnabled = enabled; // Update all view controllers' bridges. - NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator]; - FlutterViewController* nextViewController; - while ((nextViewController = [viewControllerEnumerator nextObject])) { - [nextViewController notifySemanticsEnabledChanged]; + for (id viewId in _viewRecords) { + [_viewRecords[viewId].controller notifySemanticsEnabledChanged]; } _embedderAPI.UpdateSemanticsEnabled(_engine, _semanticsEnabled); @@ -926,10 +944,8 @@ - (void)engineCallbackOnPlatformMessage:(const FlutterPlatformMessage*)message { } - (void)engineCallbackOnPreEngineRestart { - NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator]; - FlutterViewController* nextViewController; - while ((nextViewController = [viewControllerEnumerator nextObject])) { - [nextViewController onPreEngineRestart]; + for (id viewId in _viewRecords) { + [_viewRecords[viewId].controller onPreEngineRestart]; } } @@ -1026,19 +1042,15 @@ - (void)applicationWillTerminate:(NSNotification*)notification { - (void)windowDidChangeScreen:(NSNotification*)notification { // Update window metric for all view controllers since the display_id has // changed. - NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator]; - FlutterViewController* nextViewController; - while ((nextViewController = [viewControllerEnumerator nextObject])) { - [self updateWindowMetricsForViewController:nextViewController]; + for (id viewId in _viewRecords) { + [self updateWindowMetricsForViewController:_viewRecords[viewId].controller]; } } - (void)onAccessibilityStatusChanged:(NSNotification*)notification { BOOL enabled = [notification.userInfo[kEnhancedUserInterfaceKey] boolValue]; - NSEnumerator* viewControllerEnumerator = [_viewControllers objectEnumerator]; - FlutterViewController* nextViewController; - while ((nextViewController = [viewControllerEnumerator nextObject])) { - [nextViewController onAccessibilityStatusChanged:enabled]; + for (id viewId in _viewRecords) { + [_viewRecords[viewId].controller onAccessibilityStatusChanged:enabled]; } self.semanticsEnabled = enabled; From 52f0aa77d33b7b3f2059196b35f9b6920f5bf4f0 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 30 May 2023 22:15:22 -0700 Subject: [PATCH 141/142] Change to multiple view embedder and multiple compositor --- flow/embedded_views.cc | 3 +- flow/embedded_views.h | 3 +- shell/common/platform_view.h | 6 + shell/common/rasterizer.cc | 78 ++++++------ shell/common/rasterizer.h | 21 +++- shell/common/rasterizer_unittests.cc | 5 +- shell/common/shell.cc | 9 +- shell/common/shell.h | 8 +- .../shell_test_external_view_embedder.cc | 3 +- .../shell_test_external_view_embedder.h | 3 +- .../external_view_embedder.cc | 3 +- .../external_view_embedder.h | 3 +- .../external_view_embedder_unittests.cc | 27 ++--- .../framework/Source/FlutterPlatformViews.mm | 5 +- .../Source/FlutterPlatformViewsTest.mm | 33 +++--- .../Source/FlutterPlatformViews_Internal.h | 1 - .../darwin/ios/ios_external_view_embedder.h | 3 +- .../darwin/ios/ios_external_view_embedder.mm | 5 +- .../framework/Source/FlutterCompositor.h | 13 +- .../framework/Source/FlutterCompositor.mm | 12 +- .../framework/Source/FlutterCompositorTest.mm | 8 +- .../macos/framework/Source/FlutterEngine.mm | 112 +++++++++++------- .../framework/Source/FlutterEngineTest.mm | 1 + .../framework/Source/FlutterEngine_Internal.h | 1 - shell/platform/embedder/embedder.cc | 19 +-- shell/platform/embedder/embedder.h | 24 ++-- .../embedder_external_view_embedder.cc | 11 +- .../embedder_external_view_embedder.h | 6 +- shell/platform/embedder/embedder_layers.cc | 6 +- shell/platform/embedder/embedder_layers.h | 6 +- .../embedder/tests/embedder_config_builder.cc | 1 - .../flatland_external_view_embedder.cc | 3 +- .../flutter/flatland_external_view_embedder.h | 3 +- .../flutter/gfx_external_view_embedder.cc | 3 +- .../flutter/gfx_external_view_embedder.h | 3 +- ...atland_external_view_embedder_unittests.cc | 26 ++-- .../tests/flatland_platform_view_unittest.cc | 3 +- .../gfx_external_view_embedder_unittests.cc | 26 ++-- 38 files changed, 262 insertions(+), 244 deletions(-) diff --git a/flow/embedded_views.cc b/flow/embedded_views.cc index 2065ecd8747c3..406f3c476aa07 100644 --- a/flow/embedded_views.cc +++ b/flow/embedded_views.cc @@ -43,8 +43,7 @@ bool DisplayListEmbedderViewSlice::recording_ended() { } void ExternalViewEmbedder::SubmitFrame(GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) { + std::unique_ptr frame) { frame->Submit(); }; diff --git a/flow/embedded_views.h b/flow/embedded_views.h index 37743843eeabf..f382c161c6451 100644 --- a/flow/embedded_views.h +++ b/flow/embedded_views.h @@ -415,8 +415,7 @@ class ExternalViewEmbedder { // // It can also allocate frames for overlay surfaces to compose hybrid views. virtual void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id); + std::unique_ptr frame); // This method provides the embedder a way to do additional tasks after // |SubmitFrame|. For example, merge task runners if `should_resubmit_frame` diff --git a/shell/common/platform_view.h b/shell/common/platform_view.h index 287ba91330ad4..5c85107b547e4 100644 --- a/shell/common/platform_view.h +++ b/shell/common/platform_view.h @@ -688,6 +688,12 @@ class PlatformView { /// Shell::AddRenderSurface. virtual std::shared_ptr CreateExternalViewEmbedder(); + /// Whether the embedder should support dynamic thread merging. + /// + /// Returning `true` results a |RasterThreadMerger| instance to be created by + /// |Rasterizer|. + /// * See also |BegineFrame| and |EndFrame| of |ExternalViewEmbedder| for + /// getting the |RasterThreadMerger| instance. virtual bool SupportsDynamicThreadMerging(); //-------------------------------------------------------------------------- diff --git a/shell/common/rasterizer.cc b/shell/common/rasterizer.cc index a75ad8ab10f46..7eaecabffb9fc 100644 --- a/shell/common/rasterizer.cc +++ b/shell/common/rasterizer.cc @@ -39,6 +39,7 @@ Rasterizer::Rasterizer(Delegate& delegate, user_override_resource_cache_bytes_(false), snapshot_controller_( SnapshotController::Make(*this, delegate.GetSettings())), + requires_view_embedder_(false), weak_factory_(this) { FML_DCHECK(compositor_context_); } @@ -92,8 +93,9 @@ void Rasterizer::Setup(std::unique_ptr studio, } void Rasterizer::TeardownExternalViewEmbedder() { - if (external_view_embedder_) { - external_view_embedder_->Teardown(); + for (auto& surface_record : surfaces_) { + surface_record.second.view_embedder->Teardown(); + surface_record.second.view_embedder = nullptr; } } @@ -153,15 +155,20 @@ void Rasterizer::AddSurface( int64_t view_id, std::unique_ptr surface, std::shared_ptr view_embedder) { - if (!external_view_embedder_) { - external_view_embedder_ = view_embedder; - } else { - FML_DCHECK(external_view_embedder_ == view_embedder); + // Only allows having no view embedders if there is one surface and there has + // never been an view embedder. + if (!requires_view_embedder_) { + if (view_embedder || !surfaces_.empty()) { + requires_view_embedder_ = true; + } + } + if (requires_view_embedder_) { + FML_DCHECK(view_embedder); } bool insertion_happened = surfaces_ .try_emplace(/* map key=*/view_id, /*constructor args:*/ view_id, - std::move(surface)) + view_embedder, std::move(surface)) .second; if (!insertion_happened) { FML_DLOG(INFO) << "Rasterizer::AddSurface called with an existing view ID " @@ -202,6 +209,7 @@ int Rasterizer::DrawLastLayerTree( bool should_resubmit_frame = false; for (auto& [view_id, surface_record] : surfaces_) { Surface* surface = surface_record.surface.get(); + auto view_embedder = surface_record.view_embedder; flutter::LayerTree* layer_tree = surface_record.last_tree.get(); float device_pixel_ratio = surface_record.last_pixel_ratio; if (!surface || !layer_tree) { @@ -219,14 +227,14 @@ int Rasterizer::DrawLastLayerTree( should_resubmit_frame = should_resubmit_frame || ShouldResubmitFrame(raster_status); success_count += 1; - } - // EndFrame should perform cleanups for the external_view_embedder. - if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) { - external_view_embedder_->SetUsedThisFrame(false); - external_view_embedder_->EndFrame(should_resubmit_frame, - raster_thread_merger_); + // EndFrame should perform cleanups for the external_view_embedder. + if (view_embedder && view_embedder->GetUsedThisFrame()) { + view_embedder->SetUsedThisFrame(false); + view_embedder->EndFrame(should_resubmit_frame, raster_thread_merger_); + } } + return success_count; } @@ -252,6 +260,7 @@ RasterStatus Rasterizer::Draw( std::move(item->frame_timings_recorder); float device_pixel_ratio = item->device_pixel_ratio; int64_t view_id = item->view_id; + draw_result.view_id = view_id; if (discard_callback(view_id, *layer_tree.get())) { draw_result.raster_status = RasterStatus::kDiscarded; } else { @@ -280,10 +289,12 @@ RasterStatus Rasterizer::Draw( } // EndFrame should perform cleanups for the external_view_embedder. - if (external_view_embedder_ && external_view_embedder_->GetUsedThisFrame()) { - external_view_embedder_->SetUsedThisFrame(false); - external_view_embedder_->EndFrame(should_resubmit_frame, - raster_thread_merger_); + auto surface_record = surfaces_.find(draw_result.view_id); + FML_DCHECK(surface_record != surfaces_.end()); + auto view_embedder = surface_record->second.view_embedder; + if (view_embedder && view_embedder->GetUsedThisFrame()) { + view_embedder->SetUsedThisFrame(false); + view_embedder->EndFrame(should_resubmit_frame, raster_thread_merger_); } // Consume as many pipeline items as possible. But yield the event loop @@ -578,19 +589,19 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( float device_pixel_ratio, SurfaceRecord* surface_record) { Surface* surface = surface_record->surface.get(); + auto view_embedder = surface_record->view_embedder; FML_DCHECK(surface); compositor_context_->ui_time().SetLapTime( frame_timings_recorder.GetBuildDuration()); DlCanvas* embedder_root_canvas = nullptr; - if (external_view_embedder_) { - FML_DCHECK(!external_view_embedder_->GetUsedThisFrame()); - external_view_embedder_->SetUsedThisFrame(true); - external_view_embedder_->BeginFrame( - layer_tree->frame_size(), studio_->GetContext(), device_pixel_ratio, - raster_thread_merger_); - embedder_root_canvas = external_view_embedder_->GetRootCanvas(); + if (view_embedder) { + FML_DCHECK(!view_embedder->GetUsedThisFrame()); + view_embedder->SetUsedThisFrame(true); + view_embedder->BeginFrame(layer_tree->frame_size(), studio_->GetContext(), + device_pixel_ratio, raster_thread_merger_); + embedder_root_canvas = view_embedder->GetRootCanvas(); } frame_timings_recorder.RecordRasterStart(fml::TimePoint::Now()); @@ -617,11 +628,11 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( embedder_root_canvas ? embedder_root_canvas : frame->Canvas(); auto compositor_frame = compositor_context_->AcquireFrame( - studio_->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 + studio_->GetContext(), // skia GrContext + root_surface_canvas, // root surface canvas + view_embedder.get(), // external view embedder + root_surface_transformation, // root surface transformation + true, // instrumentation enabled frame->framebuffer_info() .supports_readback, // surface supports pixel reads raster_thread_merger_, // thread merger @@ -636,12 +647,12 @@ RasterStatus 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 view_embedder SubmitFrame 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. bool force_full_repaint = - external_view_embedder_ && + view_embedder && (!raster_thread_merger_ || raster_thread_merger_->IsMerged()); damage = std::make_unique(); @@ -687,11 +698,10 @@ RasterStatus Rasterizer::DrawToSurfaceUnsafe( frame->set_submit_info(submit_info); - if (external_view_embedder_ && + if (view_embedder && (!raster_thread_merger_ || raster_thread_merger_->IsMerged())) { FML_DCHECK(!frame->IsSubmitted()); - external_view_embedder_->SubmitFrame( - studio_->GetContext(), std::move(frame), surface_record->view_id); + view_embedder->SubmitFrame(studio_->GetContext(), std::move(frame)); } else { frame->Submit(); } diff --git a/shell/common/rasterizer.h b/shell/common/rasterizer.h index 1848a33a545d9..20a7db54ee0ac 100644 --- a/shell/common/rasterizer.h +++ b/shell/common/rasterizer.h @@ -206,6 +206,8 @@ class Rasterizer final : public SnapshotDelegate, fml::TaskRunnerAffineWeakPtr GetSnapshotDelegate() const; + //---------------------------------------------------------------------------- + /// @brief Add a surface, implicit or not. void AddSurface(int64_t view_id, std::unique_ptr surface, std::shared_ptr view_embedder); @@ -504,17 +506,22 @@ class Rasterizer final : public SnapshotDelegate, // front of the pipeline. struct DoDrawResult { RasterStatus raster_status = RasterStatus::kFailed; - + int64_t view_id; std::unique_ptr resubmitted_layer_tree_item; }; struct SurfaceRecord { - SurfaceRecord(int64_t view_id, std::unique_ptr surface) - : view_id(view_id), surface(std::move(surface)) {} + SurfaceRecord(int64_t view_id, + std::shared_ptr view_embedder, + std::unique_ptr surface) + : view_id(view_id), + view_embedder(std::move(view_embedder)), + surface(std::move(surface)) {} int64_t view_id; - + std::shared_ptr view_embedder; std::unique_ptr surface; + // This is the information for the last successfully drawing. // // Sometimes, it may be necessary to render the same frame again without @@ -630,8 +637,12 @@ class Rasterizer final : public SnapshotDelegate, bool user_override_resource_cache_bytes_; std::optional max_cache_bytes_; fml::RefPtr raster_thread_merger_; - std::shared_ptr external_view_embedder_; std::unique_ptr snapshot_controller_; + // The Rasterizer allows having no view embedder, but only in a legacy mode + // where there is only one surface (the implicit surface), and no view + // embedder is provided ever. In other cases, the Rasterizer should always + // have a view embedder. + bool requires_view_embedder_; // WeakPtrFactory must be the last member. fml::TaskRunnerAffineWeakPtrFactory weak_factory_; diff --git a/shell/common/rasterizer_unittests.cc b/shell/common/rasterizer_unittests.cc index d803e1c082507..0c7226a23eb2c 100644 --- a/shell/common/rasterizer_unittests.cc +++ b/shell/common/rasterizer_unittests.cc @@ -84,10 +84,9 @@ class MockExternalViewEmbedder : public ExternalViewEmbedder { PostPrerollResult( fml::RefPtr raster_thread_merger)); MOCK_METHOD1(CompositeEmbeddedView, DlCanvas*(int64_t view_id)); - MOCK_METHOD3(SubmitFrame, + MOCK_METHOD2(SubmitFrame, void(GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id)); + std::unique_ptr frame)); MOCK_METHOD2(EndFrame, void(bool should_resubmit_frame, fml::RefPtr raster_thread_merger)); diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 4f85cefbf26b9..96ed75ad05aef 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -2001,17 +2001,16 @@ bool Shell::OnServiceProtocolReloadAssetFonts( return true; } -void Shell::AddRenderSurface(int64_t view_id) { +void Shell::AddRenderSurface( + int64_t view_id, + std::unique_ptr external_view_embedder) { TRACE_EVENT0("flutter", "Shell::AddRenderSurface"); FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); + FML_DCHECK(view_id != kFlutterDefaultViewId); if (!engine_) { return; } - if (view_id == kFlutterDefaultViewId) { - return; - } - task_runners_.GetUITaskRunner()->PostTask([engine = engine_->GetWeakPtr(), // view_id // ] { engine->AddView(view_id); }); diff --git a/shell/common/shell.h b/shell/common/shell.h index 78cbd49d626fa..1f5b1d2974630 100644 --- a/shell/common/shell.h +++ b/shell/common/shell.h @@ -298,7 +298,13 @@ class Shell final : public PlatformView::Delegate, /// bool IsSetup() const; - void AddRenderSurface(int64_t view_id); + /// @brief Add a non-implicit render surface. The implicit render surface + /// is created in OnPlatformViewCreated. + /// @param view_id + /// @param external_view_embedder Must not be null. + void AddRenderSurface( + int64_t view_id, + std::unique_ptr external_view_embedder); void RemoveRenderSurface(int64_t view_id); //---------------------------------------------------------------------------- diff --git a/shell/common/shell_test_external_view_embedder.cc b/shell/common/shell_test_external_view_embedder.cc index f9ece8067b3c3..9484c9a607c18 100644 --- a/shell/common/shell_test_external_view_embedder.cc +++ b/shell/common/shell_test_external_view_embedder.cc @@ -89,8 +89,7 @@ DlCanvas* ShellTestExternalViewEmbedder::CompositeEmbeddedView( // |ExternalViewEmbedder| void ShellTestExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - std::unique_ptr frame, - int64_t view_id) { + std::unique_ptr frame) { if (!frame) { return; } diff --git a/shell/common/shell_test_external_view_embedder.h b/shell/common/shell_test_external_view_embedder.h index cd5c7481b40bf..414d3ff2f2f2e 100644 --- a/shell/common/shell_test_external_view_embedder.h +++ b/shell/common/shell_test_external_view_embedder.h @@ -74,8 +74,7 @@ class ShellTestExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame, - int64_t view_id) override; + std::unique_ptr frame) override; // |ExternalViewEmbedder| void EndFrame( 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 cf846608196ef..0bc41ed13d723 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.cc +++ b/shell/platform/android/external_view_embedder/external_view_embedder.cc @@ -66,8 +66,7 @@ SkRect AndroidExternalViewEmbedder::GetViewRect(int64_t view_id) const { // |ExternalViewEmbedder| void AndroidExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) { + std::unique_ptr frame) { TRACE_EVENT0("flutter", "AndroidExternalViewEmbedder::SubmitFrame"); if (!FrameHasPlatformLayers()) { 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 7cd72ca3d8173..42aa48235a909 100644 --- a/shell/platform/android/external_view_embedder/external_view_embedder.h +++ b/shell/platform/android/external_view_embedder/external_view_embedder.h @@ -46,8 +46,7 @@ class AndroidExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame, - int64_t view_id) override; + std::unique_ptr frame) override; // |ExternalViewEmbedder| PostPrerollResult PostPrerollAction( 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 ac3148eba8770..1d38f73069874 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 @@ -308,8 +308,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), - kDefaultViewId); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); // Submits frame if no Android view in the current frame. EXPECT_TRUE(did_submit_frame); // Doesn't resubmit frame. @@ -377,8 +376,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), - kDefaultViewId); + embedder->SubmitFrame(gr_context.get(), 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. @@ -443,8 +441,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrame) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), - kDefaultViewId); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); // Submits frame if there are Android views in the previous frame. EXPECT_TRUE(did_submit_frame); // Doesn't resubmit frame. @@ -551,8 +548,7 @@ TEST(AndroidExternalViewEmbedder, OverlayCoverTwoPlatformViews) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), - kDefaultViewId); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -655,8 +651,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFrameOverlayComposition) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), - kDefaultViewId); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -724,8 +719,7 @@ TEST(AndroidExternalViewEmbedder, SubmitFramePlatformViewWithoutAnyOverlay) { }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), - kDefaultViewId); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -826,8 +820,7 @@ TEST(AndroidExternalViewEmbedder, DestroyOverlayLayersOnSizeChange) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), - kDefaultViewId); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -914,8 +907,7 @@ TEST(AndroidExternalViewEmbedder, DoesNotDestroyOverlayLayersOnSizeChange) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - embedder->SubmitFrame(gr_context.get(), std::move(surface_frame), - kDefaultViewId); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); EXPECT_CALL(*jni_mock, FlutterViewEndFrame()); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); @@ -1028,8 +1020,7 @@ 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(), std::move(surface_frame), - kDefaultViewId); + embedder->SubmitFrame(gr_context.get(), std::move(surface_frame)); embedder->EndFrame(/*should_resubmit_frame=*/false, raster_thread_merger); diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm index 5ac65ae7607b7..784045f1b6be9 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews.mm @@ -653,7 +653,6 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, bool FlutterPlatformViewsController::SubmitFrame(GrDirectContext* gr_context, const std::shared_ptr& ios_context, - int64_t render_view_id, std::unique_ptr frame) { TRACE_EVENT0("flutter", "FlutterPlatformViewsController::SubmitFrame"); @@ -728,7 +727,6 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, // Get a new host layer. std::shared_ptr layer = GetLayer(gr_context, // ios_context, // - render_view_id, // slice, // joined_rect, // current_platform_view_id, // @@ -800,7 +798,6 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, std::shared_ptr FlutterPlatformViewsController::GetLayer( GrDirectContext* gr_context, const std::shared_ptr& ios_context, - int64_t render_view_id, EmbedderViewSlice* slice, SkRect rect, int64_t view_id, @@ -827,7 +824,7 @@ static bool ClipRRectContainsPlatformViewBoundingRect(const SkRRect& clip_rrect, overlay_view.accessibilityIdentifier = [NSString stringWithFormat:@"platform_view[%lld].overlay_view[%lld]", view_id, overlay_id]; - std::unique_ptr frame = layer->surface->AcquireFrame(render_view_id, frame_size_); + std::unique_ptr frame = layer->surface->AcquireFrame(frame_size_); // If frame is null, AcquireFrame already printed out an error message. if (!frame) { return layer; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm index cc573a574a5dc..4ce072477d475 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViewsTest.mm @@ -2272,8 +2272,8 @@ - (void)testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashin nullptr, framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return false; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertFalse(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, - std::move(mock_surface))); + XCTAssertFalse( + flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); auto embeddedViewParams_2 = std::make_unique(finalMatrix, SkSize::Make(300, 300), stack); @@ -2283,7 +2283,7 @@ - (void)testFlutterPlatformViewControllerSubmitFrameWithoutFlutterViewNotCrashin nullptr, framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, + XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface_submit_true))); } @@ -2457,8 +2457,8 @@ - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, - std::move(mock_surface))); + XCTAssertTrue( + flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); // platform view is wrapped by touch interceptor, which itself is wrapped by clipping view. UIView* clippingView1 = view1.superview.superview; UIView* clippingView2 = view2.superview.superview; @@ -2484,8 +2484,8 @@ - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder { std::move(mock_sk_surface), framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, - std::move(mock_surface))); + XCTAssertTrue( + flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] > [flutterView.subviews indexOfObject:clippingView2], @"The first clipping view should be added after the second clipping view."); @@ -2555,8 +2555,8 @@ - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, - std::move(mock_surface))); + XCTAssertTrue( + flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); // platform view is wrapped by touch interceptor, which itself is wrapped by clipping view. UIView* clippingView1 = view1.superview.superview; UIView* clippingView2 = view2.superview.superview; @@ -2582,8 +2582,8 @@ - (void)testFlutterPlatformViewControllerBeginFrameShouldResetCompisitionOrder { std::move(mock_sk_surface), framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, - std::move(mock_surface))); + XCTAssertTrue( + flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); XCTAssertTrue([flutterView.subviews indexOfObject:clippingView1] < [flutterView.subviews indexOfObject:clippingView2], @"The first clipping view should be added before the second clipping view."); @@ -2921,8 +2921,8 @@ - (void)testDisposingViewInCompositionOrderDoNotCrash { std::move(mock_sk_surface), framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, - std::move(mock_surface))); + XCTAssertTrue( + flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); // Disposing won't remove embedded views until the view is removed from the composition_order_ XCTAssertEqual(flutterPlatformViewsController->EmbeddedViewCount(), 2UL); @@ -2948,8 +2948,8 @@ - (void)testDisposingViewInCompositionOrderDoNotCrash { std::move(mock_sk_surface), framebuffer_info, [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - XCTAssertTrue(flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, - std::move(mock_surface))); + XCTAssertTrue( + flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface))); // Disposing won't remove embedded views until the view is removed from the composition_order_ XCTAssertEqual(flutterPlatformViewsController->EmbeddedViewCount(), 1UL); @@ -3015,8 +3015,7 @@ - (void)testOnlyPlatformViewsAreRemovedWhenReset { [](const flutter::SurfaceFrame& surface_frame, flutter::DlCanvas* canvas) { return true; }, /*frame_size=*/SkISize::Make(800, 600)); - flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, kDefaultViewId, - std::move(mock_surface)); + flutterPlatformViewsController->SubmitFrame(nullptr, nullptr, std::move(mock_surface)); UIView* someView = [[[UIView alloc] init] autorelease]; [mockFlutterView addSubview:someView]; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h index 7315f828f3038..80d3c92dfe612 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h +++ b/shell/platform/darwin/ios/framework/Source/FlutterPlatformViews_Internal.h @@ -253,7 +253,6 @@ class FlutterPlatformViewsController { bool SubmitFrame(GrDirectContext* gr_context, const std::shared_ptr& ios_context, - int64_t render_view_id, std::unique_ptr frame); void OnMethodCall(FlutterMethodCall* call, FlutterResult& result); diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.h b/shell/platform/darwin/ios/ios_external_view_embedder.h index 1192dba92d02e..b785d18103faf 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.h +++ b/shell/platform/darwin/ios/ios_external_view_embedder.h @@ -51,8 +51,7 @@ class IOSExternalViewEmbedder : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) override; + std::unique_ptr frame) override; // |ExternalViewEmbedder| void EndFrame( diff --git a/shell/platform/darwin/ios/ios_external_view_embedder.mm b/shell/platform/darwin/ios/ios_external_view_embedder.mm index 98713d914e1a7..8aded863ae4ab 100644 --- a/shell/platform/darwin/ios/ios_external_view_embedder.mm +++ b/shell/platform/darwin/ios/ios_external_view_embedder.mm @@ -67,11 +67,10 @@ // |ExternalViewEmbedder| void IOSExternalViewEmbedder::SubmitFrame(GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) { + std::unique_ptr frame) { TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::SubmitFrame"); FML_CHECK(platform_views_controller_); - platform_views_controller_->SubmitFrame(context, ios_context_, window_view_id, std::move(frame)); + platform_views_controller_->SubmitFrame(context, ios_context_, std::move(frame)); TRACE_EVENT0("flutter", "IOSExternalViewEmbedder::DidSubmitFrame"); } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h index ce22bb9f54916..fd96194b94ad1 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h @@ -27,8 +27,9 @@ class FlutterCompositor { // The view_provider is used to query FlutterViews from view IDs, // which are used for presenting and creating backing stores. // It must not be null, and is typically FlutterViewEngineProvider. - explicit FlutterCompositor(id view_provider, - FlutterPlatformViewController* platform_views_controller); + FlutterCompositor(id view_provider, + int64_t view_id, + FlutterPlatformViewController* platform_views_controller); ~FlutterCompositor() = default; @@ -47,9 +48,9 @@ class FlutterCompositor { bool CreateBackingStore(const FlutterBackingStoreConfig* config, FlutterBackingStore* backing_store_out); - // Presents the FlutterLayers by updating the FlutterView specified by - // `view_id` using the layer content. Sets frame_started_ to false. - bool Present(FlutterViewId view_id, const FlutterLayer** layers, size_t layers_count); + // Presents the FlutterLayers by updating the FlutterView. Sets frame_started_ + // to false. + bool Present(const FlutterLayer** layers, size_t layers_count); private: void PresentPlatformViews(FlutterView* default_base_view, @@ -63,8 +64,8 @@ class FlutterCompositor { const FlutterLayer* layer, size_t layer_position); - // Where the compositor can query FlutterViews. Must not be null. id const view_provider_; + int64_t view_id_; // The controller used to manage creation and deletion of platform views. const FlutterPlatformViewController* platform_view_controller_; diff --git a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm index 79ff85b4adb4e..38e4219aa67cb 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterCompositor.mm @@ -10,16 +10,18 @@ namespace flutter { FlutterCompositor::FlutterCompositor(id view_provider, + int64_t view_id, FlutterPlatformViewController* platform_view_controller) : view_provider_(view_provider), + view_id_(view_id), platform_view_controller_(platform_view_controller), mutator_views_([NSMapTable strongToStrongObjectsMapTable]) { - FML_CHECK(view_provider != nullptr) << "view_provider cannot be nullptr"; + FML_CHECK(view_provider_ != nullptr) << "view provider cannot be nullptr"; } bool FlutterCompositor::CreateBackingStore(const FlutterBackingStoreConfig* config, FlutterBackingStore* backing_store_out) { - FlutterView* view = [view_provider_ viewForId:config->view_id]; + FlutterView* view = [view_provider_ viewForId:view_id_]; if (!view) { return false; } @@ -34,10 +36,8 @@ return true; } -bool FlutterCompositor::Present(FlutterViewId view_id, - const FlutterLayer** layers, - size_t layers_count) { - FlutterView* view = [view_provider_ viewForId:view_id]; +bool FlutterCompositor::Present(const FlutterLayer** layers, size_t layers_count) { + FlutterView* view = [view_provider_ viewForId:view_id_]; if (!view) { return false; } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm index e8903c1667c79..60d82d065591e 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterCompositorTest.mm @@ -87,7 +87,7 @@ - (nullable FlutterView*)viewForId:(FlutterViewId)viewId { TEST(FlutterCompositorTest, TestCreate) { std::unique_ptr macos_compositor = - std::make_unique(MockViewProvider(), + std::make_unique(MockViewProvider(), kFlutterDefaultViewId, /*platform_view_controller*/ nullptr); FlutterBackingStore backing_store; @@ -95,7 +95,6 @@ - (nullable FlutterView*)viewForId:(FlutterViewId)viewId { config.struct_size = sizeof(FlutterBackingStoreConfig); config.size.width = 800; config.size.height = 600; - config.view_id = 0; ASSERT_TRUE(macos_compositor->CreateBackingStore(&config, &backing_store)); ASSERT_EQ(backing_store.type, kFlutterBackingStoreTypeMetal); @@ -113,7 +112,7 @@ - (nullable FlutterView*)viewForId:(FlutterViewId)viewId { }; std::unique_ptr macos_compositor = - std::make_unique(MockViewProvider(onPresent), + std::make_unique(MockViewProvider(onPresent), kFlutterDefaultViewId, /*platform_view_controller*/ nullptr); FlutterBackingStore backing_store; @@ -121,7 +120,6 @@ - (nullable FlutterView*)viewForId:(FlutterViewId)viewId { config.struct_size = sizeof(FlutterBackingStoreConfig); config.size.width = 800; config.size.height = 600; - config.view_id = 0; macos_compositor->CreateBackingStore(&config, &backing_store); FlutterLayer layers[] = {{ @@ -133,7 +131,7 @@ - (nullable FlutterView*)viewForId:(FlutterViewId)viewId { }}; const FlutterLayer* layers_ptr = layers; - macos_compositor->Present(kFlutterDefaultViewId, &layers_ptr, 1); + macos_compositor->Present(&layers_ptr, 1); ASSERT_EQ(presentedSurfaces.count, 1ul); } diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index 79133a59f4a7a..e608b4ef121b7 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -47,6 +47,36 @@ static FlutterLocale FlutterLocaleFromNSLocale(NSLocale* locale) { @"NSApplicationDidChangeAccessibilityEnhancedUserInterfaceNotification"; static NSString* const kEnhancedUserInterfaceKey = @"AXEnhancedUserInterface"; +static FlutterCompositor createFlutterCompositorFor(flutter::FlutterCompositor* macOSCompositor) { + FlutterCompositor compositor; + compositor = {}; + compositor.struct_size = sizeof(FlutterCompositor); + compositor.user_data = macOSCompositor; + + compositor.create_backing_store_callback = [](const FlutterBackingStoreConfig* config, // + FlutterBackingStore* backing_store_out, // + void* user_data // + ) { + return reinterpret_cast(user_data)->CreateBackingStore( + config, backing_store_out); + }; + + compositor.collect_backing_store_callback = [](const FlutterBackingStore* backing_store, // + void* user_data // + ) { return true; }; + + compositor.present_layers_callback = [](const FlutterLayer** layers, // + size_t layers_count, // + void* user_data // + ) { + return reinterpret_cast(user_data)->Present(layers, layers_count); + }; + + compositor.avoid_backing_store_cache = true; + + return compositor; +} + /// Clipboard plain text format. constexpr char kTextPlainFormat[] = "text/plain"; @@ -79,7 +109,10 @@ - (instancetype)initWithConnection:(NSNumber*)connection @interface FlutterEngineViewRecord : NSObject -- (instancetype)initWithViewController:(nonnull FlutterViewController*)controller; +- (nullable instancetype)initWithViewController:(nonnull FlutterViewController*)controller + macOSCompositor: + (std::shared_ptr)macOSCompositor + compositor:(FlutterCompositor)compositor; @property(nonatomic, weak) FlutterViewController* controller; @@ -87,14 +120,25 @@ - (instancetype)initWithViewController:(nonnull FlutterViewController*)controlle @implementation FlutterEngineViewRecord { __weak FlutterViewController* _controller; + + // _macOSCompositor is created when the engine is created and its destruction is handled by ARC + // when the engine is destroyed. + std::shared_ptr _macOSCompositor; + + // FlutterCompositor is copied and used in embedder.cc. + FlutterCompositor _compositor; } @synthesize controller = _controller; -- (instancetype)initWithViewController:(FlutterViewController*)controller { +- (instancetype)initWithViewController:(FlutterViewController*)controller + macOSCompositor:(std::shared_ptr)macOSCompositor + compositor:(FlutterCompositor)compositor { self = [super init]; NSAssert(self, @"Super init cannot be nil"); _controller = controller; + _macOSCompositor = macOSCompositor; + _compositor = compositor; return self; } @end @@ -385,15 +429,15 @@ @implementation FlutterEngine { // Pointer to the Dart AOT snapshot and instruction data. _FlutterEngineAOTData* _aotData; - // _macOSCompositor is created when the engine is created and its destruction is handled by ARC - // when the engine is destroyed. - std::unique_ptr _macOSCompositor; - // The information of all views attached to this engine mapped from IDs. NSMutableDictionary* _viewRecords; + // _macOSCompositor is created when the engine is created and its destruction is handled by ARC + // when the engine is destroyed. + std::shared_ptr _implicitMacOSCompositor; + // FlutterCompositor is copied and used in embedder.cc. - FlutterCompositor _compositor; + FlutterCompositor _implicitCompositor; // Method channel for platform view functions. These functions include creating, disposing and // mutating a platform view. @@ -564,7 +608,11 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { flutterArguments.aot_data = _aotData; } - flutterArguments.compositor = [self createFlutterCompositor]; + _implicitMacOSCompositor = std::make_shared( + [[FlutterViewEngineProvider alloc] initWithEngine:self], kFlutterDefaultViewId, + _platformViewController); + _implicitCompositor = createFlutterCompositorFor(_implicitMacOSCompositor.get()); + flutterArguments.compositor = &_implicitCompositor; flutterArguments.on_pre_engine_restart_callback = [](void* user_data) { FlutterEngine* engine = (__bridge FlutterEngine*)user_data; @@ -632,7 +680,17 @@ - (void)registerViewController:(FlutterViewController*)controller forId:(Flutter NSAssert(_viewRecords[@(viewId)] == nil, @"The requested view ID is occupied."); [controller setUpWithEngine:self viewId:viewId threadSynchronizer:_threadSynchronizer]; NSAssert(controller.viewId == viewId, @"Failed to assign view ID."); - _viewRecords[@(viewId)] = [[FlutterEngineViewRecord alloc] initWithViewController:controller]; + const bool isImplicitView = viewId == kFlutterDefaultViewId; + auto macOSCompositor = isImplicitView + ? _implicitMacOSCompositor + : std::make_shared( + [[FlutterViewEngineProvider alloc] initWithEngine:self], viewId, + _platformViewController); + auto compositor = + isImplicitView ? _implicitCompositor : createFlutterCompositorFor(macOSCompositor.get()); + _viewRecords[@(viewId)] = [[FlutterEngineViewRecord alloc] initWithViewController:controller + macOSCompositor:macOSCompositor + compositor:compositor]; } - (void)deregisterViewControllerForId:(FlutterViewId)viewId { @@ -693,40 +751,6 @@ - (FlutterViewController*)viewController { return [self viewControllerForId:kFlutterDefaultViewId]; } -- (FlutterCompositor*)createFlutterCompositor { - _macOSCompositor = std::make_unique( - [[FlutterViewEngineProvider alloc] initWithEngine:self], _platformViewController); - - _compositor = {}; - _compositor.struct_size = sizeof(FlutterCompositor); - _compositor.user_data = _macOSCompositor.get(); - - _compositor.create_backing_store_callback = [](const FlutterBackingStoreConfig* config, // - FlutterBackingStore* backing_store_out, // - void* user_data // - ) { - return reinterpret_cast(user_data)->CreateBackingStore( - config, backing_store_out); - }; - - _compositor.collect_backing_store_callback = [](const FlutterBackingStore* backing_store, // - void* user_data // - ) { return true; }; - - _compositor.present_layers_callback = [](const FlutterLayer** layers, // - size_t layers_count, // - int64_t view_id, // - void* user_data // - ) { - return reinterpret_cast(user_data)->Present(view_id, layers, - layers_count); - }; - - _compositor.avoid_backing_store_cache = true; - - return &_compositor; -} - - (id)binaryMessenger { // TODO(stuartmorgan): Switch to FlutterBinaryMessengerRelay to avoid plugins // keeping the engine alive. @@ -1342,7 +1366,7 @@ - (void)postMainThreadTask:(FlutterTask)task targetTimeInNanoseconds:(uint64_t)t // Getter used by test harness, only exposed through the FlutterEngine(Test) category - (flutter::FlutterCompositor*)macOSCompositor { - return _macOSCompositor.get(); + return _implicitMacOSCompositor.get(); } @end diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm index 60e8bc363f8df..10abab8a52a94 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngineTest.mm @@ -15,6 +15,7 @@ #include "flutter/shell/platform/common/accessibility_bridge.h" #import "flutter/shell/platform/darwin/common/framework/Headers/FlutterChannels.h" #import "flutter/shell/platform/darwin/macos/framework/Headers/FlutterAppDelegate.h" +#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterEngineTestUtils.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterViewControllerTestUtils.h" #include "flutter/shell/platform/embedder/embedder.h" diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h b/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h index 9e003988ed41e..947c54d7a2ce1 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine_Internal.h @@ -11,7 +11,6 @@ #include "flutter/shell/platform/common/app_lifecycle_state.h" #import "flutter/shell/platform/darwin/macos/framework/Source/AccessibilityBridgeMac.h" -#import "flutter/shell/platform/darwin/macos/framework/Source/FlutterCompositor.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterPlatformViewController.h" #import "flutter/shell/platform/darwin/macos/framework/Source/FlutterRenderer.h" diff --git a/shell/platform/embedder/embedder.cc b/shell/platform/embedder/embedder.cc index 8725a724cce65..817cb3788b18a 100644 --- a/shell/platform/embedder/embedder.cc +++ b/shell/platform/embedder/embedder.cc @@ -485,7 +485,6 @@ InferMetalPlatformViewCreationCallback( frame_info.struct_size = sizeof(FlutterFrameInfo); frame_info.size = {static_cast(frame_size.width()), static_cast(frame_size.height())}; - frame_info.view_id = view_id; flutter::GPUMTLTextureInfo texture_info; FlutterMetalTexture metal_texture = ptr(user_data, &frame_info); @@ -1070,12 +1069,12 @@ InferExternalViewEmbedderFromArgs(const FlutterCompositor* compositor) { }; flutter::EmbedderExternalViewEmbedder::PresentCallback present_callback = - [c_present_callback, user_data = compositor->user_data]( - const auto& layers, int64_t window_view_id) { + [c_present_callback, + user_data = compositor->user_data](const auto& layers) { TRACE_EVENT0("flutter", "FlutterCompositorPresentLayers"); return c_present_callback( const_cast(layers.data()), layers.size(), - window_view_id, user_data); + user_data); }; return {std::make_unique( @@ -2052,14 +2051,20 @@ FlutterEngineResult FlutterEngineShutdown(FLUTTER_API_SYMBOL(FlutterEngine) FLUTTER_EXPORT FlutterEngineResult FlutterEngineAddRenderSurface( FLUTTER_API_SYMBOL(FlutterEngine) engine, - void* user_data, - int64_t view_id) { + FlutterRenderSurfaceConfig* config) { if (engine == nullptr) { return LOG_EMBEDDER_ERROR(kInvalidArguments, "Engine handle was invalid."); } + auto external_view_embedder_result = + InferExternalViewEmbedderFromArgs(config->compositor); + if (external_view_embedder_result.second) { + return LOG_EMBEDDER_ERROR(kInvalidArguments, + "Compositor arguments were invalid."); + } flutter::EmbedderEngine* embedder_engine = reinterpret_cast(engine); - embedder_engine->GetShell().AddRenderSurface(view_id); + embedder_engine->GetShell().AddRenderSurface( + config->view_id, std::move(external_view_embedder_result.first)); return kSuccess; } diff --git a/shell/platform/embedder/embedder.h b/shell/platform/embedder/embedder.h index db03e7985c9f7..2a54931713f49 100644 --- a/shell/platform/embedder/embedder.h +++ b/shell/platform/embedder/embedder.h @@ -464,7 +464,6 @@ typedef struct { size_t struct_size; /// The size of the surface that will be backed by the fbo. FlutterUIntSize size; - int64_t view_id; } FlutterFrameInfo; /// Callback for when a frame buffer object is requested. @@ -654,7 +653,6 @@ typedef struct { /// The callback invoked by the engine when it no longer needs this backing /// store. VoidCallback destruction_callback; - int64_t view_id; } FlutterMetalTexture; /// Callback for when a metal texture is requested. @@ -1560,7 +1558,6 @@ typedef struct { size_t struct_size; /// The size of the render target the engine expects to render into. FlutterSize size; - int64_t view_id; } FlutterBackingStoreConfig; typedef enum { @@ -1603,16 +1600,15 @@ typedef bool (*FlutterBackingStoreCollectCallback)( typedef bool (*FlutterLayersPresentCallback)(const FlutterLayer** layers, size_t layers_count, - int64_t view_id, void* user_data); typedef struct { /// This size of this struct. Must be sizeof(FlutterCompositor). size_t struct_size; - /// A baton that in not interpreted by the engine in any way. If it passed + /// A baton that in not interpreted by the engine in any way. It is passed /// back to the embedder in `FlutterCompositor.create_backing_store_callback`, /// `FlutterCompositor.collect_backing_store_callback` and - /// `FlutterCompositor.present_layers_callback` + /// `FlutterCompositor.present_layers_callback`. void* user_data; /// A callback invoked by the engine to obtain a backing store for a specific /// `FlutterLayer`. @@ -1625,13 +1621,17 @@ typedef struct { /// A callback invoked by the engine to release the backing store. The /// embedder may collect any resources associated with the backing store. FlutterBackingStoreCollectCallback collect_backing_store_callback; - /// Callback invoked by the engine to composite the contents of each layer /// onto the screen. FlutterLayersPresentCallback present_layers_callback; /// Avoid caching backing stores provided by this compositor. bool avoid_backing_store_cache; } FlutterCompositor; +typedef struct { + int64_t view_id; + FlutterCompositor* compositor; +} FlutterRenderSurfaceConfig; + typedef struct { /// This size of this struct. Must be sizeof(FlutterLocale). size_t struct_size; @@ -2265,7 +2265,11 @@ FlutterEngineResult FlutterEngineRunInitialized( FLUTTER_EXPORT FlutterEngineResult FlutterEngineAddRenderSurface( FLUTTER_API_SYMBOL(FlutterEngine) engine, - void* user_data, + FlutterRenderSurfaceConfig* config); + +FLUTTER_EXPORT +FlutterEngineResult FlutterEngineRemoveRenderSurface( + FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t view_id); FLUTTER_EXPORT @@ -2845,7 +2849,9 @@ typedef FlutterEngineResult (*FlutterEngineRunInitializedFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine); typedef FlutterEngineResult (*FlutterEngineAddRenderSurfaceFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine, - void* user_data, + FlutterRenderSurfaceConfig* config); +typedef FlutterEngineResult (*FlutterEngineRemoveRenderSurfaceFnPtr)( + FLUTTER_API_SYMBOL(FlutterEngine) engine, int64_t view_id); typedef FlutterEngineResult (*FlutterEngineSendWindowMetricsEventFnPtr)( FLUTTER_API_SYMBOL(FlutterEngine) engine, diff --git a/shell/platform/embedder/embedder_external_view_embedder.cc b/shell/platform/embedder/embedder_external_view_embedder.cc index 985d0ba3ddcd8..e4870090c6c9f 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.cc +++ b/shell/platform/embedder/embedder_external_view_embedder.cc @@ -111,15 +111,13 @@ DlCanvas* EmbedderExternalViewEmbedder::CompositeEmbeddedView(int64_t view_id) { } static FlutterBackingStoreConfig MakeBackingStoreConfig( - const SkISize& backing_store_size, - int64_t window_view_id) { + const SkISize& backing_store_size) { FlutterBackingStoreConfig config = {}; config.struct_size = sizeof(config); config.size.width = backing_store_size.width(); config.size.height = backing_store_size.height(); - config.view_id = window_view_id; return config; } @@ -127,8 +125,7 @@ static FlutterBackingStoreConfig MakeBackingStoreConfig( // |ExternalViewEmbedder| void EmbedderExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) { + std::unique_ptr frame) { auto [matched_render_targets, pending_keys] = render_target_cache_.GetExistingTargetsInCache(pending_views_); @@ -167,7 +164,7 @@ void EmbedderExternalViewEmbedder::SubmitFrame( const auto render_surface_size = external_view->GetRenderSurfaceSize(); const auto backing_store_config = - MakeBackingStoreConfig(render_surface_size, window_view_id); + MakeBackingStoreConfig(render_surface_size); // This is where the embedder will create render targets for us. Control // flow to the embedder makes the engine susceptible to having the embedder @@ -248,7 +245,7 @@ void EmbedderExternalViewEmbedder::SubmitFrame( // Flush the layer description down to the embedder for presentation. // // @warning: Embedder may trample on our OpenGL context here. - presented_layers.InvokePresentCallback(present_callback_, window_view_id); + presented_layers.InvokePresentCallback(present_callback_); } // See why this is necessary in the comment where this collection in realized. diff --git a/shell/platform/embedder/embedder_external_view_embedder.h b/shell/platform/embedder/embedder_external_view_embedder.h index 2118db5e25758..55a08f0627a72 100644 --- a/shell/platform/embedder/embedder_external_view_embedder.h +++ b/shell/platform/embedder/embedder_external_view_embedder.h @@ -33,8 +33,7 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { GrDirectContext* context, const FlutterBackingStoreConfig& config)>; using PresentCallback = - std::function& layers, - int64_t window_view_id)>; + std::function& layers)>; using SurfaceTransformationCallback = std::function; //---------------------------------------------------------------------------- @@ -96,8 +95,7 @@ class EmbedderExternalViewEmbedder final : public ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) override; + std::unique_ptr frame) override; // |ExternalViewEmbedder| DlCanvas* GetRootCanvas() override; diff --git a/shell/platform/embedder/embedder_layers.cc b/shell/platform/embedder/embedder_layers.cc index f5a62b26c4bea..6465293748f9f 100644 --- a/shell/platform/embedder/embedder_layers.cc +++ b/shell/platform/embedder/embedder_layers.cc @@ -199,14 +199,14 @@ void EmbedderLayers::PushPlatformViewLayer( presented_layers_.push_back(layer); } -void EmbedderLayers::InvokePresentCallback(const PresentCallback& callback, - int64_t window_view_id) const { +void EmbedderLayers::InvokePresentCallback( + const PresentCallback& callback) const { std::vector presented_layers_pointers; presented_layers_pointers.reserve(presented_layers_.size()); for (const auto& layer : presented_layers_) { presented_layers_pointers.push_back(&layer); } - callback(presented_layers_pointers, window_view_id); + callback(presented_layers_pointers); } } // namespace flutter diff --git a/shell/platform/embedder/embedder_layers.h b/shell/platform/embedder/embedder_layers.h index 46137f459df99..c1cb2907588c9 100644 --- a/shell/platform/embedder/embedder_layers.h +++ b/shell/platform/embedder/embedder_layers.h @@ -30,10 +30,8 @@ class EmbedderLayers { const EmbeddedViewParams& params); using PresentCallback = - std::function& layers, - int64_t view_id)>; - void InvokePresentCallback(const PresentCallback& callback, - int64_t window_view_id) const; + std::function& layers)>; + void InvokePresentCallback(const PresentCallback& callback) const; private: const SkISize frame_size_; diff --git a/shell/platform/embedder/tests/embedder_config_builder.cc b/shell/platform/embedder/tests/embedder_config_builder.cc index dae2c4dc12110..f12a9e58b130a 100644 --- a/shell/platform/embedder/tests/embedder_config_builder.cc +++ b/shell/platform/embedder/tests/embedder_config_builder.cc @@ -362,7 +362,6 @@ void EmbedderConfigBuilder::SetCompositor(bool avoid_backing_store_cache) { }; compositor_.present_layers_callback = [](const FlutterLayer** layers, // size_t layers_count, // - int64_t view_id, // void* user_data // ) { return reinterpret_cast(user_data)->Present( diff --git a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc index 9d970c6489865..901bd8c078e97 100644 --- a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc +++ b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.cc @@ -132,8 +132,7 @@ void FlatlandExternalViewEmbedder::EndFrame( void FlatlandExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) { + std::unique_ptr frame) { TRACE_EVENT0("flutter", "FlatlandExternalViewEmbedder::SubmitFrame"); std::vector> frame_surfaces; std::unordered_map frame_surface_indices; diff --git a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h index c637aad11d1eb..033efbe6ae62a 100644 --- a/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h +++ b/shell/platform/fuchsia/flutter/flatland_external_view_embedder.h @@ -87,8 +87,7 @@ class FlatlandExternalViewEmbedder final // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) override; + std::unique_ptr frame) override; // |ExternalViewEmbedder| void CancelFrame() override { Reset(); } diff --git a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc index e34dfc5e64bc3..21c6810c4e11b 100644 --- a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc +++ b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.cc @@ -231,8 +231,7 @@ void GfxExternalViewEmbedder::EndFrame( void GfxExternalViewEmbedder::SubmitFrame( GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) { + std::unique_ptr frame) { TRACE_EVENT0("flutter", "GfxExternalViewEmbedder::SubmitFrame"); std::vector> frame_surfaces; std::unordered_map frame_surface_indices; diff --git a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h index 54ed5d6261b43..39e25dc3daeaa 100644 --- a/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h +++ b/shell/platform/fuchsia/flutter/gfx_external_view_embedder.h @@ -110,8 +110,7 @@ class GfxExternalViewEmbedder final : public flutter::ExternalViewEmbedder { // |ExternalViewEmbedder| void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) override; + std::unique_ptr frame) override; // |ExternalViewEmbedder| void CancelFrame() override { Reset(); } diff --git a/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc b/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc index 7d6034cb7ef91..35f734d2044ac 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_external_view_embedder_unittests.cc @@ -53,8 +53,6 @@ using ::testing::VariantWith; namespace flutter_runner::testing { namespace { -constexpr int64_t kDefaultViewId = 0ll; - constexpr static fuchsia::ui::composition::BlendMode kFirstLayerBlendMode{ fuchsia::ui::composition::BlendMode::SRC}; constexpr static fuchsia::ui::composition::BlendMode kUpperLayerBlendMode{ @@ -337,13 +335,11 @@ void DrawSimpleFrame(FlatlandExternalViewEmbedder& external_view_embedder, flutter::SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; external_view_embedder.SubmitFrame( - nullptr, - std::make_unique( - nullptr, std::move(framebuffer_info), - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size), - kDefaultViewId); + nullptr, std::make_unique( + nullptr, std::move(framebuffer_info), + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size)); } void DrawFrameWithView( @@ -369,13 +365,11 @@ void DrawFrameWithView( flutter::SurfaceFrame::FramebufferInfo framebuffer_info; framebuffer_info.supports_readback = true; external_view_embedder.SubmitFrame( - nullptr, - std::make_unique( - nullptr, std::move(framebuffer_info), - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size), - kDefaultViewId); + nullptr, std::make_unique( + nullptr, std::move(framebuffer_info), + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size)); } }; // namespace diff --git a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc index ae595bea88986..f0e3c6553fced 100644 --- a/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc +++ b/shell/platform/fuchsia/flutter/tests/flatland_platform_view_unittest.cc @@ -54,8 +54,7 @@ class MockExternalViewEmbedder : public flutter::ExternalViewEmbedder { fml::RefPtr raster_thread_merger) override {} void SubmitFrame(GrDirectContext* context, - std::unique_ptr frame, - int64_t window_view_id) override {} + std::unique_ptr frame) override {} void PrerollCompositeEmbeddedView( int64_t view_id, diff --git a/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc b/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc index ba4cf9f4c1fbd..77c04bb6ab7ed 100644 --- a/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc +++ b/shell/platform/fuchsia/flutter/tests/gfx_external_view_embedder_unittests.cc @@ -54,8 +54,6 @@ using ::testing::VariantWith; namespace flutter_runner::testing { namespace { -constexpr int64_t kDefaultViewId = 0ll; - class FakeSurfaceProducerSurface : public SurfaceProducerSurface { public: explicit FakeSurfaceProducerSurface(scenic::Session* session, @@ -460,13 +458,11 @@ void DrawSimpleFrame(GfxExternalViewEmbedder& external_view_embedder, external_view_embedder.EndFrame(false, nullptr); flutter::SurfaceFrame::FramebufferInfo framebuffer_info; external_view_embedder.SubmitFrame( - nullptr, - std::make_unique( - nullptr, framebuffer_info, - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size), - kDefaultViewId); + nullptr, std::make_unique( + nullptr, framebuffer_info, + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size)); } void DrawFrameWithView( @@ -491,13 +487,11 @@ void DrawFrameWithView( external_view_embedder.EndFrame(false, nullptr); flutter::SurfaceFrame::FramebufferInfo framebuffer_info; external_view_embedder.SubmitFrame( - nullptr, - std::make_unique( - nullptr, framebuffer_info, - [](const flutter::SurfaceFrame& surface_frame, - flutter::DlCanvas* canvas) { return true; }, - frame_size), - kDefaultViewId); + nullptr, std::make_unique( + nullptr, framebuffer_info, + [](const flutter::SurfaceFrame& surface_frame, + flutter::DlCanvas* canvas) { return true; }, + frame_size)); } FramePresentedInfo MakeFramePresentedInfoForOnePresent( From 5ad2f7d34caea39ad0bdf536a4cb6f076c22ec46 Mon Sep 17 00:00:00 2001 From: Tong Mu Date: Tue, 30 May 2023 23:25:21 -0700 Subject: [PATCH 142/142] Fix bug --- shell/common/shell.cc | 16 ++++++++++------ .../macos/framework/Source/FlutterEngine.mm | 15 ++++++++++----- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/shell/common/shell.cc b/shell/common/shell.cc index 96ed75ad05aef..607c862e53c52 100644 --- a/shell/common/shell.cc +++ b/shell/common/shell.cc @@ -2007,7 +2007,9 @@ void Shell::AddRenderSurface( TRACE_EVENT0("flutter", "Shell::AddRenderSurface"); FML_DCHECK(is_setup_); FML_DCHECK(task_runners_.GetPlatformTaskRunner()->RunsTasksOnCurrentThread()); - FML_DCHECK(view_id != kFlutterDefaultViewId); + if (view_id == kFlutterDefaultViewId) { + return; + } if (!engine_) { return; } @@ -2017,13 +2019,15 @@ void Shell::AddRenderSurface( // TODO(dkwingsmt): platform_view_ is captured illegally here. // We need some mechanism from it being collected. - task_runners_.GetRasterTaskRunner()->PostTask( - fml::MakeCopyable([platform_view = platform_view_.get(), // - rasterizer = rasterizer_->GetWeakPtr(), // - view_id // + task_runners_.GetRasterTaskRunner()->PostTask(fml::MakeCopyable( + [platform_view = platform_view_.get(), // + rasterizer = rasterizer_->GetWeakPtr(), // + view_embedder_ptr = external_view_embedder.release(), // + view_id // ]() mutable { if (platform_view && rasterizer) { - auto view_embedder = platform_view->CreateExternalViewEmbedder(); + std::shared_ptr view_embedder( + view_embedder_ptr); std::unique_ptr surface = platform_view->CreateSurface(view_id); if (surface) { diff --git a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm index e608b4ef121b7..37f11bf25ca45 100644 --- a/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm +++ b/shell/platform/darwin/macos/framework/Source/FlutterEngine.mm @@ -513,6 +513,11 @@ - (instancetype)initWithName:(NSString*)labelPrefix reinterpret_cast([[NSApplication sharedApplication] delegate]); [appDelegate addApplicationLifecycleDelegate:self]; + _implicitMacOSCompositor = std::make_shared( + [[FlutterViewEngineProvider alloc] initWithEngine:self], kFlutterDefaultViewId, + _platformViewController); + _implicitCompositor = createFlutterCompositorFor(_implicitMacOSCompositor.get()); + return self; } @@ -608,10 +613,6 @@ - (BOOL)runWithEntrypoint:(NSString*)entrypoint { flutterArguments.aot_data = _aotData; } - _implicitMacOSCompositor = std::make_shared( - [[FlutterViewEngineProvider alloc] initWithEngine:self], kFlutterDefaultViewId, - _platformViewController); - _implicitCompositor = createFlutterCompositorFor(_implicitMacOSCompositor.get()); flutterArguments.compositor = &_implicitCompositor; flutterArguments.on_pre_engine_restart_callback = [](void* user_data) { @@ -686,8 +687,12 @@ - (void)registerViewController:(FlutterViewController*)controller forId:(Flutter : std::make_shared( [[FlutterViewEngineProvider alloc] initWithEngine:self], viewId, _platformViewController); - auto compositor = + FlutterCompositor compositor = isImplicitView ? _implicitCompositor : createFlutterCompositorFor(macOSCompositor.get()); + NSAssert(macOSCompositor, @"No macOSCompositor"); + ; + NSAssert(compositor.create_backing_store_callback, @"Invalid compositor"); + ; _viewRecords[@(viewId)] = [[FlutterEngineViewRecord alloc] initWithViewController:controller macOSCompositor:macOSCompositor compositor:compositor];