diff --git a/shell/platform/embedder/BUILD.gn b/shell/platform/embedder/BUILD.gn index 39ca8dc757ae7..38c7e2db98e87 100644 --- a/shell/platform/embedder/BUILD.gn +++ b/shell/platform/embedder/BUILD.gn @@ -242,7 +242,8 @@ test_fixtures("fixtures") { "fixtures/dpr_noxform.png", "fixtures/dpr_xform.png", "fixtures/gradient.png", - "fixtures/impeller_gl_test.png", + "fixtures/impeller_test.png", + "fixtures/impeller_text_test.png", "fixtures/vk_dpr_noxform.png", "fixtures/vk_gradient.png", "fixtures/gradient_metal.png", diff --git a/shell/platform/embedder/embedder_external_view.cc b/shell/platform/embedder/embedder_external_view.cc index 8aa524359d08b..1111e8a7a8375 100644 --- a/shell/platform/embedder/embedder_external_view.cc +++ b/shell/platform/embedder/embedder_external_view.cc @@ -137,6 +137,7 @@ bool EmbedderExternalView::Render(const EmbedderRenderTarget& render_target, impeller::TextFrameDispatcher collector(aiks_context->GetContentContext(), impeller::Matrix()); + display_list->Dispatch(collector, sk_cull_rect); impeller::ExperimentalDlDispatcher impeller_dispatcher( aiks_context->GetContentContext(), *impeller_target, diff --git a/shell/platform/embedder/fixtures/README.md b/shell/platform/embedder/fixtures/README.md index b68fc603cd73d..eed3fe6b865a1 100644 --- a/shell/platform/embedder/fixtures/README.md +++ b/shell/platform/embedder/fixtures/README.md @@ -71,9 +71,9 @@ $ $ENGINE/out/$TARGET/embedder_unittests --gtest_filter="EmbedderTest.VerifyB143 # Or, a suite of tests: $ $ENGINE/out/$TARGET/embedder_unittests --gtest_filter="EmbedderTest.*" -# 3. Now, copy the output to the golden file: +# 3. Now, copy the output to the golden file (notice the "actual_" prefix): $ cp \ - $ENGINE/out/$TARGET/gen/flutter/shell/platform/embedder/assets/expectation_verifyb143464703_soft_noxform.png \ + $ENGINE/out/$TARGET/gen/flutter/shell/platform/embedder/assets/actual_verifyb143464703_soft_noxform.png \ $ENGINE/flutter/shell/platform/embedder/fixtures/verifyb143464703_soft_noxform.png ``` diff --git a/shell/platform/embedder/fixtures/impeller_gl_test.png b/shell/platform/embedder/fixtures/impeller_test.png similarity index 100% rename from shell/platform/embedder/fixtures/impeller_gl_test.png rename to shell/platform/embedder/fixtures/impeller_test.png diff --git a/shell/platform/embedder/fixtures/impeller_text_test.png b/shell/platform/embedder/fixtures/impeller_text_test.png new file mode 100644 index 0000000000000..72ee258c101a2 Binary files /dev/null and b/shell/platform/embedder/fixtures/impeller_text_test.png differ diff --git a/shell/platform/embedder/fixtures/main.dart b/shell/platform/embedder/fixtures/main.dart index 6f3986b5eb1b9..adc7bb417b05c 100644 --- a/shell/platform/embedder/fixtures/main.dart +++ b/shell/platform/embedder/fixtures/main.dart @@ -1553,7 +1553,7 @@ void render_gradient_retained() { @pragma('vm:entry-point') // ignore: non_constant_identifier_names -void render_impeller_gl_test() { +void render_impeller_test() { PlatformDispatcher.instance.onBeginFrame = (Duration duration) { final SceneBuilder builder = SceneBuilder(); builder.pushOffset(0.0, 0.0); @@ -1569,3 +1569,29 @@ void render_impeller_gl_test() { }; PlatformDispatcher.instance.scheduleFrame(); } + +@pragma('vm:entry-point') +// ignore: non_constant_identifier_names +void render_impeller_text_test() { + PlatformDispatcher.instance.onBeginFrame = (Duration duration) { + final SceneBuilder builder = SceneBuilder(); + builder.pushOffset(0.0, 0.0); + final Paint paint = Paint(); + paint.color = const Color.fromARGB(255, 0, 0, 255); + final PictureRecorder baseRecorder = PictureRecorder(); + final Canvas canvas = Canvas(baseRecorder); + + final ParagraphBuilder paragraphBuilder = ParagraphBuilder(ParagraphStyle( + fontFamily: 'sans-serif' + )) + ..addText('Flutter is the best!'); + final Paragraph paragraph = paragraphBuilder.build() + ..layout(const ParagraphConstraints(width: 400)); + canvas.drawParagraph(paragraph, const Offset(20, 20)); + + builder.addPicture(Offset.zero, baseRecorder.endRecording()); + builder.pop(); + PlatformDispatcher.instance.views.first.render(builder.build()); + }; + PlatformDispatcher.instance.scheduleFrame(); +} diff --git a/shell/platform/embedder/tests/embedder_gl_unittests.cc b/shell/platform/embedder/tests/embedder_gl_unittests.cc index 54ca779ebfa18..4eccb64b888bb 100644 --- a/shell/platform/embedder/tests/embedder_gl_unittests.cc +++ b/shell/platform/embedder/tests/embedder_gl_unittests.cc @@ -4758,7 +4758,7 @@ TEST_F(EmbedderTest, CanRenderWithImpellerOpenGL) { }); builder.AddCommandLineArgument("--enable-impeller"); - builder.SetDartEntrypoint("render_impeller_gl_test"); + builder.SetDartEntrypoint("render_impeller_test"); builder.SetOpenGLRendererConfig(SkISize::Make(800, 600)); builder.SetCompositor(); builder.SetRenderTargetType( @@ -4798,7 +4798,7 @@ TEST_F(EmbedderTest, CanRenderWithImpellerOpenGL) { ASSERT_TRUE(ImageMatchesFixture( FixtureNameForBackend(EmbedderTestContextType::kOpenGLContext, - "impeller_gl_test.png"), + "impeller_test.png"), rendered_scene)); // The scene will be rendered by the compositor, and the surface present diff --git a/shell/platform/embedder/tests/embedder_metal_unittests.mm b/shell/platform/embedder/tests/embedder_metal_unittests.mm index 6b2bead2aa673..3f5ec9e549daf 100644 --- a/shell/platform/embedder/tests/embedder_metal_unittests.mm +++ b/shell/platform/embedder/tests/embedder_metal_unittests.mm @@ -614,6 +614,84 @@ void Collect() { EXPECT_TRUE(resolve_called); } +TEST_F(EmbedderTest, CanRenderWithImpellerMetal) { + auto& context = GetEmbedderContext(EmbedderTestContextType::kMetalContext); + + EmbedderConfigBuilder builder(context); + + builder.AddCommandLineArgument("--enable-impeller"); + builder.SetDartEntrypoint("render_impeller_test"); + builder.SetMetalRendererConfig(SkISize::Make(800, 600)); + + auto rendered_scene = context.GetNextSceneImage(); + + auto engine = builder.LaunchEngine(); + ASSERT_TRUE(engine.is_valid()); + + // Send a window metrics events so frames may be scheduled. + FlutterWindowMetricsEvent event = {}; + event.struct_size = sizeof(event); + event.width = 800; + event.height = 600; + event.pixel_ratio = 1.0; + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); + + ASSERT_TRUE(ImageMatchesFixture("impeller_test.png", rendered_scene)); +} + +TEST_F(EmbedderTest, CanRenderTextWithImpellerMetal) { + auto& context = GetEmbedderContext(EmbedderTestContextType::kMetalContext); + + EmbedderConfigBuilder builder(context); + + builder.AddCommandLineArgument("--enable-impeller"); + builder.SetDartEntrypoint("render_impeller_text_test"); + builder.SetMetalRendererConfig(SkISize::Make(800, 600)); + + auto rendered_scene = context.GetNextSceneImage(); + + auto engine = builder.LaunchEngine(); + ASSERT_TRUE(engine.is_valid()); + + // Send a window metrics events so frames may be scheduled. + FlutterWindowMetricsEvent event = {}; + event.struct_size = sizeof(event); + event.width = 800; + event.height = 600; + event.pixel_ratio = 1.0; + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); + + ASSERT_TRUE(ImageMatchesFixture("impeller_text_test.png", rendered_scene)); +} + +TEST_F(EmbedderTest, CanRenderTextWithImpellerAndCompositorMetal) { + auto& context = GetEmbedderContext(EmbedderTestContextType::kMetalContext); + + EmbedderConfigBuilder builder(context); + + builder.AddCommandLineArgument("--enable-impeller"); + builder.SetDartEntrypoint("render_impeller_text_test"); + builder.SetMetalRendererConfig(SkISize::Make(800, 600)); + builder.SetCompositor(); + + builder.SetRenderTargetType(EmbedderTestBackingStoreProducer::RenderTargetType::kMetalTexture); + + auto rendered_scene = context.GetNextSceneImage(); + + auto engine = builder.LaunchEngine(); + ASSERT_TRUE(engine.is_valid()); + + // Send a window metrics events so frames may be scheduled. + FlutterWindowMetricsEvent event = {}; + event.struct_size = sizeof(event); + event.width = 800; + event.height = 600; + event.pixel_ratio = 1.0; + ASSERT_EQ(FlutterEngineSendWindowMetricsEvent(engine.get(), &event), kSuccess); + + ASSERT_TRUE(ImageMatchesFixture("impeller_text_test.png", rendered_scene)); +} + } // namespace testing } // namespace flutter