diff --git a/engine/src/flutter/shell/gpu/gpu_surface_gl_impeller.cc b/engine/src/flutter/shell/gpu/gpu_surface_gl_impeller.cc index 53c457bdda..2c45762a51 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_gl_impeller.cc +++ b/engine/src/flutter/shell/gpu/gpu_surface_gl_impeller.cc @@ -14,7 +14,8 @@ namespace flutter { GPUSurfaceGLImpeller::GPUSurfaceGLImpeller( GPUSurfaceGLDelegate* delegate, - std::shared_ptr context) + std::shared_ptr context, + bool render_to_surface) : weak_factory_(this) { if (delegate == nullptr) { return; @@ -38,6 +39,7 @@ GPUSurfaceGLImpeller::GPUSurfaceGLImpeller( delegate_ = delegate; impeller_context_ = std::move(context); + render_to_surface_ = render_to_surface; impeller_renderer_ = std::move(renderer); aiks_context_ = std::move(aiks_context); is_valid_ = true; @@ -82,6 +84,15 @@ std::unique_ptr GPUSurfaceGLImpeller::AcquireFrame( return nullptr; } + if (!render_to_surface_) { + return std::make_unique( + nullptr, SurfaceFrame::FramebufferInfo{.supports_readback = true}, + [](const SurfaceFrame& surface_frame, DlCanvas* canvas) { + return true; + }, + size); + } + GLFrameInfo frame_info = {static_cast(size.width()), static_cast(size.height())}; const GLFBOInfo fbo_info = delegate_->GLContextFBO(frame_info); diff --git a/engine/src/flutter/shell/gpu/gpu_surface_gl_impeller.h b/engine/src/flutter/shell/gpu/gpu_surface_gl_impeller.h index adf975fbbd..5b6fbd9c1f 100644 --- a/engine/src/flutter/shell/gpu/gpu_surface_gl_impeller.h +++ b/engine/src/flutter/shell/gpu/gpu_surface_gl_impeller.h @@ -18,7 +18,8 @@ namespace flutter { class GPUSurfaceGLImpeller final : public Surface { public: explicit GPUSurfaceGLImpeller(GPUSurfaceGLDelegate* delegate, - std::shared_ptr context); + std::shared_ptr context, + bool render_to_surface); // |Surface| ~GPUSurfaceGLImpeller() override; @@ -29,6 +30,7 @@ class GPUSurfaceGLImpeller final : public Surface { private: GPUSurfaceGLDelegate* delegate_ = nullptr; std::shared_ptr impeller_context_; + bool render_to_surface_ = true; std::shared_ptr impeller_renderer_; std::shared_ptr aiks_context_; bool is_valid_ = false; diff --git a/engine/src/flutter/shell/platform/android/android_surface_gl_impeller.cc b/engine/src/flutter/shell/platform/android/android_surface_gl_impeller.cc index 662541ab64..b2d0b69d9a 100644 --- a/engine/src/flutter/shell/platform/android/android_surface_gl_impeller.cc +++ b/engine/src/flutter/shell/platform/android/android_surface_gl_impeller.cc @@ -36,8 +36,9 @@ bool AndroidSurfaceGLImpeller::IsValid() const { std::unique_ptr AndroidSurfaceGLImpeller::CreateGPUSurface( GrDirectContext* gr_context) { auto surface = std::make_unique( - this, // delegate - android_context_->GetImpellerContext() // context + this, // delegate + android_context_->GetImpellerContext(), // context + true // render to surface ); if (!surface->IsValid()) { return nullptr; diff --git a/engine/src/flutter/shell/platform/embedder/BUILD.gn b/engine/src/flutter/shell/platform/embedder/BUILD.gn index adc2ad6c69..b83364b8b0 100644 --- a/engine/src/flutter/shell/platform/embedder/BUILD.gn +++ b/engine/src/flutter/shell/platform/embedder/BUILD.gn @@ -242,6 +242,7 @@ test_fixtures("fixtures") { "fixtures/dpr_noxform.png", "fixtures/dpr_xform.png", "fixtures/gradient.png", + "fixtures/impeller_gl_gradient.png", "fixtures/vk_dpr_noxform.png", "fixtures/vk_gradient.png", "fixtures/gradient_metal.png", @@ -250,7 +251,6 @@ test_fixtures("fixtures") { "fixtures/scene_without_custom_compositor.png", "fixtures/scene_without_custom_compositor_with_xform.png", "fixtures/snapshot_large_scene.png", - "fixtures/solid_red.png", "fixtures/verifyb143464703.png", "fixtures/verifyb143464703_soft_noxform.png", ] diff --git a/engine/src/flutter/shell/platform/embedder/embedder_surface_gl_impeller.cc b/engine/src/flutter/shell/platform/embedder/embedder_surface_gl_impeller.cc index e205e8e747..cae8037083 100644 --- a/engine/src/flutter/shell/platform/embedder/embedder_surface_gl_impeller.cc +++ b/engine/src/flutter/shell/platform/embedder/embedder_surface_gl_impeller.cc @@ -179,8 +179,9 @@ EmbedderSurfaceGLImpeller::GLContextFramebufferInfo() const { // |EmbedderSurface| std::unique_ptr EmbedderSurfaceGLImpeller::CreateGPUSurface() { return std::make_unique( - this, // GPU surface GL delegate - impeller_context_ // render to surface + this, // GPU surface GL delegate + impeller_context_, // Impeller context + !external_view_embedder_ // render to surface ); } diff --git a/engine/src/flutter/shell/platform/embedder/fixtures/impeller_gl_gradient.png b/engine/src/flutter/shell/platform/embedder/fixtures/impeller_gl_gradient.png new file mode 100644 index 0000000000..76fd5b12f1 Binary files /dev/null and b/engine/src/flutter/shell/platform/embedder/fixtures/impeller_gl_gradient.png differ diff --git a/engine/src/flutter/shell/platform/embedder/fixtures/solid_red.png b/engine/src/flutter/shell/platform/embedder/fixtures/solid_red.png deleted file mode 100644 index 89f889b95d..0000000000 Binary files a/engine/src/flutter/shell/platform/embedder/fixtures/solid_red.png and /dev/null differ diff --git a/engine/src/flutter/shell/platform/embedder/tests/embedder_gl_unittests.cc b/engine/src/flutter/shell/platform/embedder/tests/embedder_gl_unittests.cc index a8b411bd7b..a050e70f8f 100644 --- a/engine/src/flutter/shell/platform/embedder/tests/embedder_gl_unittests.cc +++ b/engine/src/flutter/shell/platform/embedder/tests/embedder_gl_unittests.cc @@ -4704,8 +4704,14 @@ TEST_F(EmbedderTest, CanRenderWithImpellerOpenGL) { auto& context = GetEmbedderContext(EmbedderTestContextType::kOpenGLContext); EmbedderConfigBuilder builder(context); + bool present_called = false; + static_cast(context).SetGLPresentCallback( + [&present_called](FlutterPresentInfo present_info) { + present_called = true; + }); + builder.AddCommandLineArgument("--enable-impeller"); - builder.SetDartEntrypoint("draw_solid_red"); + builder.SetDartEntrypoint("render_gradient"); builder.SetOpenGLRendererConfig(SkISize::Make(800, 600)); builder.SetCompositor(); builder.SetRenderTargetType( @@ -4727,8 +4733,12 @@ TEST_F(EmbedderTest, CanRenderWithImpellerOpenGL) { ASSERT_TRUE(ImageMatchesFixture( FixtureNameForBackend(EmbedderTestContextType::kOpenGLContext, - "solid_red.png"), + "impeller_gl_gradient.png"), rendered_scene)); + + // The scene will be rendered by the compositor, and the surface present + // callback should not be invoked. + ASSERT_FALSE(present_called); } INSTANTIATE_TEST_SUITE_P(