From 85ffa59762dd07fb5a651e3a79fde8d55473cce5 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 1 Aug 2024 14:06:52 -0700 Subject: [PATCH 01/10] [Impeller] move aiks text tests to DL. --- impeller/aiks/aiks_unittests.cc | 396 ---------------- impeller/display_list/BUILD.gn | 1 + .../display_list/aiks_dl_basic_unittests.cc | 34 ++ .../display_list/aiks_dl_text_unittests.cc | 447 ++++++++++++++++++ 4 files changed, 482 insertions(+), 396 deletions(-) create mode 100644 impeller/display_list/aiks_dl_text_unittests.cc diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 52ae55bb5c00f..fc8683507183a 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -33,9 +33,6 @@ #include "impeller/renderer/command_buffer.h" #include "impeller/renderer/snapshot.h" #include "impeller/typographer/backends/skia/text_frame_skia.h" -#include "impeller/typographer/backends/stb/text_frame_stb.h" -#include "impeller/typographer/backends/stb/typeface_stb.h" -#include "impeller/typographer/backends/stb/typographer_context_stb.h" #include "third_party/imgui/imgui.h" #include "third_party/skia/include/core/SkFontMgr.h" #include "txt/platform.h" @@ -205,352 +202,6 @@ TEST_P(AiksTest, CanPerformSaveLayerWithBounds) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } -TEST_P(AiksTest, - CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated) { - Canvas canvas; - - Paint red; - red.color = Color::Red(); - - Paint green; - green.color = Color::Green(); - - Paint blue; - blue.color = Color::Blue(); - - Paint save; - save.color = Color::Black().WithAlpha(0.5); - - canvas.SaveLayer(save, Rect::MakeXYWH(0, 0, 100000, 100000)); - - canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red); - canvas.DrawRect(Rect::MakeXYWH(10, 10, 100, 100), green); - canvas.DrawRect(Rect::MakeXYWH(20, 20, 100, 100), blue); - - canvas.Restore(); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -struct TextRenderOptions { - bool stroke = false; - Scalar font_size = 50; - Color color = Color::Yellow(); - Point position = Vector2(100, 200); - std::optional mask_blur_descriptor; -}; - -bool RenderTextInCanvasSkia(const std::shared_ptr& context, - Canvas& canvas, - const std::string& text, - const std::string_view& font_fixture, - TextRenderOptions options = {}) { - // Draw the baseline. - canvas.DrawRect( - Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10), - Paint{.color = Color::Aqua().WithAlpha(0.25)}); - - // Mark the point at which the text is drawn. - canvas.DrawCircle(options.position, 5.0, - Paint{.color = Color::Red().WithAlpha(0.25)}); - - // Construct the text blob. - auto c_font_fixture = std::string(font_fixture); - auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str()); - if (!mapping) { - return false; - } - sk_sp font_mgr = txt::GetDefaultFontManager(); - SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size); - auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font); - if (!blob) { - return false; - } - - // Create the Impeller text frame and draw it at the designated baseline. - auto frame = MakeTextFrameFromTextBlobSkia(blob); - - Paint text_paint; - text_paint.color = options.color; - text_paint.mask_blur_descriptor = options.mask_blur_descriptor; - text_paint.stroke_width = 1; - text_paint.style = - options.stroke ? Paint::Style::kStroke : Paint::Style::kFill; - canvas.DrawTextFrame(frame, options.position, text_paint); - return true; -} - -bool RenderTextInCanvasSTB(const std::shared_ptr& context, - Canvas& canvas, - const std::string& text, - const std::string& font_fixture, - TextRenderOptions options = {}) { - // Draw the baseline. - canvas.DrawRect( - Rect::MakeXYWH(options.position.x - 50, options.position.y, 900, 10), - Paint{.color = Color::Aqua().WithAlpha(0.25)}); - - // Mark the point at which the text is drawn. - canvas.DrawCircle(options.position, 5.0, - Paint{.color = Color::Red().WithAlpha(0.25)}); - - // Construct the text blob. - auto mapping = flutter::testing::OpenFixtureAsMapping(font_fixture.c_str()); - if (!mapping) { - return false; - } - auto typeface_stb = std::make_shared(std::move(mapping)); - - auto frame = MakeTextFrameSTB( - typeface_stb, Font::Metrics{.point_size = options.font_size}, text); - - Paint text_paint; - text_paint.color = options.color; - canvas.DrawTextFrame(frame, options.position, text_paint); - return true; -} - -TEST_P(AiksTest, CanRenderTextFrame) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?", - "Roboto-Regular.ttf")); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderTextFrameWithInvertedTransform) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - canvas.Translate({1000, 0, 0}); - canvas.Scale({-1, 1, 1}); - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?", - "Roboto-Regular.ttf")); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderStrokedTextFrame) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?", - "Roboto-Regular.ttf", - { - .stroke = true, - })); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderTextFrameWithHalfScaling) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - canvas.Scale({0.5, 0.5, 1}); - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?", - "Roboto-Regular.ttf")); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderTextFrameWithFractionScaling) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - canvas.Scale({2.625, 2.625, 1}); - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?", - "Roboto-Regular.ttf")); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderTextFrameSTB) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - ASSERT_TRUE(RenderTextInCanvasSTB( - GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?", - "Roboto-Regular.ttf")); - - SetTypographerContext(TypographerContextSTB::Make()); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, TextFrameSubpixelAlignment) { - // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens. - std::array phase_offsets = { - 7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767, - 0.218959, 0.0470446, 0.678865, 0.679296, 0.934693, - 0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616, - 0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422}; - auto callback = [&](AiksContext& renderer) -> std::optional { - static float font_size = 20; - static float phase_variation = 0.2; - static float speed = 0.5; - static float magnitude = 100; - if (AiksTest::ImGuiBegin("Controls", nullptr, - ImGuiWindowFlags_AlwaysAutoResize)) { - ImGui::SliderFloat("Font size", &font_size, 5, 50); - ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1); - ImGui::SliderFloat("Oscillation speed", &speed, 0, 2); - ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300); - ImGui::End(); - } - - Canvas canvas; - canvas.Scale(GetContentScale()); - - for (size_t i = 0; i < phase_offsets.size(); i++) { - auto position = - Point(200 + magnitude * - std::sin((-phase_offsets[i] * k2Pi * phase_variation + - GetSecondsElapsed() * speed)), // - 200 + i * font_size * 1.1 // - ); - if (!RenderTextInCanvasSkia( - GetContext(), canvas, - "the quick brown fox jumped over " - "the lazy dog!.?", - "Roboto-Regular.ttf", - {.font_size = font_size, .position = position})) { - return std::nullopt; - } - } - return canvas.EndRecordingAsPicture(); - }; - - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - -TEST_P(AiksTest, CanRenderItalicizedText) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?", - "HomemadeApple.ttf")); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -static constexpr std::string_view kFontFixture = -#if FML_OS_MACOSX - "Apple Color Emoji.ttc"; -#else - "NotoColorEmoji.ttf"; -#endif - -TEST_P(AiksTest, CanRenderEmojiTextFrame) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture)); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderEmojiTextFrameWithBlur) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture, - TextRenderOptions{.color = Color::Blue(), - .mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Sigma(4)}})); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderEmojiTextFrameWithAlpha) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture, - {.color = Color::Black().WithAlpha(0.5)})); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderTextInSaveLayer) { - Canvas canvas; - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - canvas.Translate({100, 100}); - canvas.Scale(Vector2{0.5, 0.5}); - - // Blend the layer with the parent pass using kClear to expose the coverage. - canvas.SaveLayer({.blend_mode = BlendMode::kClear}); - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?", - "Roboto-Regular.ttf")); - canvas.Restore(); - - // Render the text again over the cleared coverage rect. - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?", - "Roboto-Regular.ttf")); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderTextOutsideBoundaries) { - Canvas canvas; - canvas.Translate({200, 150}); - - // Construct the text blob. - auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf"); - ASSERT_NE(mapping, nullptr); - - Scalar font_size = 80; - sk_sp font_mgr = txt::GetDefaultFontManager(); - SkFont sk_font(font_mgr->makeFromData(mapping), font_size); - - Paint text_paint; - text_paint.color = Color::Blue().WithAlpha(0.8); - - struct { - Point position; - const char* text; - } text[] = {{Point(0, 0), "0F0F0F0"}, - {Point(1, 2), "789"}, - {Point(1, 3), "456"}, - {Point(1, 4), "123"}, - {Point(0, 6), "0F0F0F0"}}; - for (auto& t : text) { - canvas.Save(); - canvas.Translate(t.position * Point(font_size * 2, font_size * 1.1)); - { - auto blob = SkTextBlob::MakeFromString(t.text, sk_font); - ASSERT_NE(blob, nullptr); - auto frame = MakeTextFrameFromTextBlobSkia(blob); - canvas.DrawTextFrame(frame, Point(), text_paint); - } - canvas.Restore(); - } - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, TextRotated) { - Canvas canvas; - canvas.Scale(GetContentScale()); - canvas.DrawPaint({.color = Color(0.1, 0.1, 0.1, 1.0)}); - - canvas.Transform(Matrix(0.25, -0.3, 0, -0.002, // - 0, 0.5, 0, 0, // - 0, 0, 0.3, 0, // - 100, 100, 0, 1.3)); - ASSERT_TRUE(RenderTextInCanvasSkia( - GetContext(), canvas, "the quick brown fox jumped over the lazy dog!.?", - "Roboto-Regular.ttf")); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -// This makes sure the WideGamut named tests use 16bit float pixel format. -TEST_P(AiksTest, FormatWideGamut) { - EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), - PixelFormat::kB10G10R10A10XR); -} - TEST_P(AiksTest, FormatSRGB) { PixelFormat pixel_format = GetContext()->GetCapabilities()->GetDefaultColorFormat(); @@ -1326,35 +977,6 @@ TEST_P(AiksTest, SolidColorApplyColorFilter) { Color(0.424452, 0.828743, 0.79105, 0.9375)); } -TEST_P(AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer) { - Canvas canvas; - canvas.Transform(Matrix(1.0, 0.0, 0.0, 0.0, // - 0.0, 1.0, 0.0, 0.0, // - 0.0, 0.0, 1.0, 0.01, // - 0.0, 0.0, 0.0, 1.0) * // - Matrix::MakeRotationY({Degrees{10}})); - - ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world", - "Roboto-Regular.ttf")); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, DrawScaledTextWithPerspectiveSaveLayer) { - Canvas canvas; - Paint save_paint; - canvas.SaveLayer(save_paint); - canvas.Transform(Matrix(1.0, 0.0, 0.0, 0.0, // - 0.0, 1.0, 0.0, 0.0, // - 0.0, 0.0, 1.0, 0.01, // - 0.0, 0.0, 0.0, 1.0) * // - Matrix::MakeRotationY({Degrees{10}})); - - ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world", - "Roboto-Regular.ttf")); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - TEST_P(AiksTest, PipelineBlendSingleParameter) { Canvas canvas; @@ -1559,24 +1181,6 @@ TEST_P(AiksTest, StrokedPathWithMoveToThenCloseDrawnCorrectly) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } -TEST_P(AiksTest, CanRenderTextWithLargePerspectiveTransform) { - // Verifies that text scales are clamped to work around - // https://github.com/flutter/flutter/issues/136112 . - - Canvas canvas; - Paint save_paint; - canvas.SaveLayer(save_paint); - canvas.Transform(Matrix(2000, 0, 0, 0, // - 0, 2000, 0, 0, // - 0, 0, -1, 9000, // - 0, 0, -1, 7000 // - )); - - ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), canvas, "Hello world", - "Roboto-Regular.ttf")); - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - TEST_P(AiksTest, SetContentsWithRegion) { auto bridge = CreateTextureForFixture("bay_bridge.jpg"); diff --git a/impeller/display_list/BUILD.gn b/impeller/display_list/BUILD.gn index 879800eefea08..8fee973e31b63 100644 --- a/impeller/display_list/BUILD.gn +++ b/impeller/display_list/BUILD.gn @@ -59,6 +59,7 @@ template("display_list_unittests_component") { "aiks_dl_opacity_unittests.cc", "aiks_dl_path_unittests.cc", "aiks_dl_runtime_effect_unittests.cc", + "aiks_dl_text_unittests.cc", "aiks_dl_unittests.cc", "aiks_dl_vertices_unittests.cc", "dl_golden_blur_unittests.cc", diff --git a/impeller/display_list/aiks_dl_basic_unittests.cc b/impeller/display_list/aiks_dl_basic_unittests.cc index 078276dc829d3..d20e854fd760b 100644 --- a/impeller/display_list/aiks_dl_basic_unittests.cc +++ b/impeller/display_list/aiks_dl_basic_unittests.cc @@ -1067,5 +1067,39 @@ TEST_P(AiksTest, EmptySaveLayerRendersWithClear) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +TEST_P(AiksTest, + CanPerformSaveLayerWithBoundsAndLargerIntermediateIsNotAllocated) { + DisplayListBuilder builder; + + DlPaint red; + red.setColor(DlColor::kRed()); + + DlPaint green; + green.setColor(DlColor::kGreen()); + + DlPaint blue; + blue.setColor(DlColor::kBlue()); + + DlPaint save; + save.setColor(DlColor::kBlack().modulateOpacity(0.5)); + + SkRect huge_bounds = SkRect::MakeXYWH(0, 0, 100000, 100000); + builder.SaveLayer(&huge_bounds, &save); + + builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), red); + builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100), green); + builder.DrawRect(SkRect::MakeXYWH(20, 20, 100, 100), blue); + + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +// This makes sure the WideGamut named tests use 16bit float pixel format. +TEST_P(AiksTest, FormatWideGamut) { + EXPECT_EQ(GetContext()->GetCapabilities()->GetDefaultColorFormat(), + PixelFormat::kB10G10R10A10XR); +} + } // namespace testing } // namespace impeller diff --git a/impeller/display_list/aiks_dl_text_unittests.cc b/impeller/display_list/aiks_dl_text_unittests.cc new file mode 100644 index 0000000000000..296bbbbe651f1 --- /dev/null +++ b/impeller/display_list/aiks_dl_text_unittests.cc @@ -0,0 +1,447 @@ +// 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 "display_list/display_list.h" +#include "display_list/dl_blend_mode.h" +#include "display_list/effects/dl_mask_filter.h" +#include "flutter/impeller/aiks/aiks_unittests.h" + +#include "flutter/display_list/dl_builder.h" +#include "flutter/display_list/dl_color.h" +#include "flutter/display_list/dl_paint.h" +#include "flutter/testing/testing.h" +#include "impeller/geometry/matrix.h" +#include "impeller/typographer/backends/skia/text_frame_skia.h" +#include "impeller/typographer/backends/stb/text_frame_stb.h" +#include "impeller/typographer/backends/stb/typeface_stb.h" +#include "impeller/typographer/backends/stb/typographer_context_stb.h" +#include "include/core/SkRect.h" + +#include "txt/platform.h" + +using namespace flutter; +///////////////////////////////////////////////////// + +namespace impeller { +namespace testing { + +struct TextRenderOptions { + bool stroke = false; + Scalar font_size = 50; + DlColor color = DlColor::kYellow(); + SkPoint position = SkPoint::Make(100, 200); + std::shared_ptr filter; +}; + +bool RenderTextInCanvasSkia(const std::shared_ptr& context, + DisplayListBuilder& canvas, + const std::string& text, + const std::string_view& font_fixture, + const TextRenderOptions& options = {}) { + // Draw the baseline. + DlPaint paint; + paint.setColor(DlColor::kBlue().modulateOpacity(0.25)); + canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50, + options.position.y(), 900, 10), + paint); + + // Mark the point at which the text is drawn. + paint.setColor(DlColor::kRed().modulateOpacity(0.25)); + canvas.DrawCircle(options.position, 5.0, paint); + + // Construct the text blob. + auto c_font_fixture = std::string(font_fixture); + auto mapping = flutter::testing::OpenFixtureAsSkData(c_font_fixture.c_str()); + if (!mapping) { + return false; + } + sk_sp font_mgr = txt::GetDefaultFontManager(); + SkFont sk_font(font_mgr->makeFromData(mapping), options.font_size); + auto blob = SkTextBlob::MakeFromString(text.c_str(), sk_font); + if (!blob) { + return false; + } + + // Create the Impeller text frame and draw it at the designated baseline. + auto frame = MakeTextFrameFromTextBlobSkia(blob); + + DlPaint text_paint; + text_paint.setColor(options.color); + text_paint.setMaskFilter(options.filter); + text_paint.setStrokeWidth(1); + text_paint.setDrawStyle(options.stroke ? DlDrawStyle::kStroke + : DlDrawStyle::kFill); + canvas.DrawTextFrame(frame, options.position.x(), options.position.y(), + text_paint); + return true; +} + +bool RenderTextInCanvasSTB(const std::shared_ptr& context, + DisplayListBuilder& canvas, + const std::string& text, + const std::string& font_fixture, + const TextRenderOptions& options = {}) { + // Draw the baseline. + DlPaint paint; + paint.setColor(DlColor::kBlue().modulateOpacity(0.25)); + canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50, + options.position.y(), 900, 10), + paint); + + // Mark the point at which the text is drawn. + paint.setColor(DlColor::kRed().modulateOpacity(0.25)); + canvas.DrawCircle(options.position, 5.0, paint); + + // Construct the text blob. + auto mapping = flutter::testing::OpenFixtureAsMapping(font_fixture.c_str()); + if (!mapping) { + return false; + } + auto typeface_stb = std::make_shared(std::move(mapping)); + + auto frame = MakeTextFrameSTB( + typeface_stb, Font::Metrics{.point_size = options.font_size}, text); + + DlPaint text_paint; + text_paint.setColor(options.color); + canvas.DrawTextFrame(frame, options.position.x(), options.position.y(), + text_paint); + return true; +} + +TEST_P(AiksTest, CanRenderTextFrame) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "Roboto-Regular.ttf")); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderTextFrameWithInvertedTransform) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + builder.Translate(1000, 0); + builder.Scale(-1, 1); + + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "Roboto-Regular.ttf")); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderStrokedTextFrame) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "Roboto-Regular.ttf", + { + .stroke = true, + })); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderTextFrameWithHalfScaling) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + builder.Scale(0.5, 0.5); + + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "Roboto-Regular.ttf")); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderTextFrameWithFractionScaling) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + builder.Scale(2.625, 2.625); + + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "Roboto-Regular.ttf")); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderTextFrameSTB) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + + ASSERT_TRUE(RenderTextInCanvasSTB( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "Roboto-Regular.ttf")); + + SetTypographerContext(TypographerContextSTB::Make()); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, TextFrameSubpixelAlignment) { + // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens. + std::array phase_offsets = { + 7.82637e-06, 0.131538, 0.755605, 0.45865, 0.532767, + 0.218959, 0.0470446, 0.678865, 0.679296, 0.934693, + 0.383502, 0.519416, 0.830965, 0.0345721, 0.0534616, + 0.5297, 0.671149, 0.00769819, 0.383416, 0.0668422}; + auto callback = [&]() -> sk_sp { + static float font_size = 20; + static float phase_variation = 0.2; + static float speed = 0.5; + static float magnitude = 100; + if (AiksTest::ImGuiBegin("Controls", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SliderFloat("Font size", &font_size, 5, 50); + ImGui::SliderFloat("Phase variation", &phase_variation, 0, 1); + ImGui::SliderFloat("Oscillation speed", &speed, 0, 2); + ImGui::SliderFloat("Oscillation magnitude", &magnitude, 0, 300); + ImGui::End(); + } + + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + for (size_t i = 0; i < phase_offsets.size(); i++) { + SkPoint position = SkPoint::Make( + 200 + + magnitude * std::sin((-phase_offsets[i] * k2Pi * phase_variation + + GetSecondsElapsed() * speed)), // + 200 + i * font_size * 1.1 // + ); + if (!RenderTextInCanvasSkia( + GetContext(), builder, + "the quick brown fox jumped over " + "the lazy dog!.?", + "Roboto-Regular.ttf", + {.font_size = font_size, .position = position})) { + return nullptr; + } + } + return builder.Build(); + }; + + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + +TEST_P(AiksTest, CanRenderItalicizedText) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "HomemadeApple.ttf")); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +static constexpr std::string_view kFontFixture = +#if FML_OS_MACOSX + "Apple Color Emoji.ttc"; +#else + "NotoColorEmoji.ttf"; +#endif + +TEST_P(AiksTest, CanRenderEmojiTextFrame) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture)); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderEmojiTextFrameWithBlur) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture, + TextRenderOptions{ + .color = DlColor::kBlue(), + .filter = DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 4)})); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderEmojiTextFrameWithAlpha) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "😀 😃 😄 😁 😆 😅 😂 🤣 🥲 😊", kFontFixture, + {.color = DlColor::kBlack().modulateOpacity(0.5)})); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderTextInSaveLayer) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); + + builder.Translate(100, 100); + builder.Scale(0.5, 0.5); + + // Blend the layer with the parent pass using kClear to expose the coverage. + paint.setBlendMode(DlBlendMode::kClear); + builder.SaveLayer(nullptr, &paint); + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "Roboto-Regular.ttf")); + builder.Restore(); + + // Render the text again over the cleared coverage rect. + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "Roboto-Regular.ttf")); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderTextOutsideBoundaries) { + DisplayListBuilder builder; + builder.Translate(200, 150); + + // Construct the text blob. + auto mapping = flutter::testing::OpenFixtureAsSkData("wtf.otf"); + ASSERT_NE(mapping, nullptr); + + Scalar font_size = 80; + sk_sp font_mgr = txt::GetDefaultFontManager(); + SkFont sk_font(font_mgr->makeFromData(mapping), font_size); + + DlPaint text_paint; + text_paint.setColor(DlColor::kBlue().modulateOpacity(0.8)); + + struct { + SkPoint position; + const char* text; + } text[] = {{SkPoint::Make(0, 0), "0F0F0F0"}, + {SkPoint::Make(1, 2), "789"}, + {SkPoint::Make(1, 3), "456"}, + {SkPoint::Make(1, 4), "123"}, + {SkPoint::Make(0, 6), "0F0F0F0"}}; + for (auto& t : text) { + builder.Save(); + builder.Translate(t.position.x() * font_size * 2, + t.position.y() * font_size * 1.1); + { + auto blob = SkTextBlob::MakeFromString(t.text, sk_font); + ASSERT_NE(blob, nullptr); + auto frame = MakeTextFrameFromTextBlobSkia(blob); + builder.DrawTextFrame(frame, 0, 0, text_paint); + } + builder.Restore(); + } + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, TextRotated) { + DisplayListBuilder builder; + + builder.Scale(GetContentScale().x, GetContentScale().y); + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 1.0)); + builder.DrawPaint(paint); + + builder.Transform(SkM44::ColMajor(Matrix(0.25, -0.3, 0, -0.002, // + 0, 0.5, 0, 0, // + 0, 0, 0.3, 0, // + 100, 100, 0, 1.3) + .m)); + ASSERT_TRUE(RenderTextInCanvasSkia( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "Roboto-Regular.ttf")); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, DrawScaledTextWithPerspectiveNoSaveLayer) { + DisplayListBuilder builder; + + Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, // + 0.0, 1.0, 0.0, 0.0, // + 0.0, 0.0, 1.0, 0.01, // + 0.0, 0.0, 0.0, 1.0) * // + Matrix::MakeRotationY({Degrees{10}}); + + builder.Transform(SkM44::ColMajor(matrix.m)); + + ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world", + "Roboto-Regular.ttf")); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, DrawScaledTextWithPerspectiveSaveLayer) { + DisplayListBuilder builder; + + Matrix matrix = Matrix(1.0, 0.0, 0.0, 0.0, // + 0.0, 1.0, 0.0, 0.0, // + 0.0, 0.0, 1.0, 0.01, // + 0.0, 0.0, 0.0, 1.0) * // + Matrix::MakeRotationY({Degrees{10}}); + + DlPaint save_paint; + builder.SaveLayer(nullptr, &save_paint); + builder.Transform(SkM44::ColMajor(matrix.m)); + + ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world", + "Roboto-Regular.ttf")); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderTextWithLargePerspectiveTransform) { + // Verifies that text scales are clamped to work around + // https://github.com/flutter/flutter/issues/136112 . + + DisplayListBuilder builder; + + DlPaint save_paint; + builder.SaveLayer(nullptr, &save_paint); + builder.Transform(SkM44::ColMajor(Matrix(2000, 0, 0, 0, // + 0, 2000, 0, 0, // + 0, 0, -1, 9000, // + 0, 0, -1, 7000 // + ) + .m)); + + ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world", + "Roboto-Regular.ttf")); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +} // namespace testing +} // namespace impeller From 92c1bdd7de6dc99ed270cb757d3d1d6e47e7954b Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 1 Aug 2024 16:54:36 -0700 Subject: [PATCH 02/10] ++ --- ci/licenses_golden/excluded_files | 1 + .../display_list/aiks_dl_text_unittests.cc | 23 ++++++++++--------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/ci/licenses_golden/excluded_files b/ci/licenses_golden/excluded_files index 987b99fea8b69..25ea67ef6d288 100644 --- a/ci/licenses_golden/excluded_files +++ b/ci/licenses_golden/excluded_files @@ -149,6 +149,7 @@ ../../../flutter/impeller/display_list/aiks_dl_opacity_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_path_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_runtime_effect_unittests.cc +../../../flutter/impeller/display_list/aiks_dl_text_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_unittests.cc ../../../flutter/impeller/display_list/aiks_dl_vertices_unittests.cc ../../../flutter/impeller/display_list/dl_golden_blur_unittests.cc diff --git a/impeller/display_list/aiks_dl_text_unittests.cc b/impeller/display_list/aiks_dl_text_unittests.cc index 296bbbbe651f1..8494f4f8e638e 100644 --- a/impeller/display_list/aiks_dl_text_unittests.cc +++ b/impeller/display_list/aiks_dl_text_unittests.cc @@ -105,6 +105,7 @@ bool RenderTextInCanvasSTB(const std::shared_ptr& context, DlPaint text_paint; text_paint.setColor(options.color); + canvas.DrawTextFrame(frame, options.position.x(), options.position.y(), text_paint); return true; @@ -183,20 +184,20 @@ TEST_P(AiksTest, CanRenderTextFrameWithFractionScaling) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } -TEST_P(AiksTest, CanRenderTextFrameSTB) { - DisplayListBuilder builder; +// TEST_P(AiksTest, CanRenderTextFrameSTB) { +// DisplayListBuilder builder; - DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); - builder.DrawPaint(paint); +// DlPaint paint; +// paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); +// builder.DrawPaint(paint); - ASSERT_TRUE(RenderTextInCanvasSTB( - GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", - "Roboto-Regular.ttf")); +// ASSERT_TRUE(RenderTextInCanvasSTB( +// GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", +// "Roboto-Regular.ttf")); - SetTypographerContext(TypographerContextSTB::Make()); - ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); -} +// SetTypographerContext(TypographerContextSTB::Make()); +// ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +// } TEST_P(AiksTest, TextFrameSubpixelAlignment) { // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens. From ceb8bdd1009fe065347d2dfbe137237148afc5a6 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Thu, 1 Aug 2024 16:55:49 -0700 Subject: [PATCH 03/10] ++ --- .../display_list/aiks_dl_text_unittests.cc | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/impeller/display_list/aiks_dl_text_unittests.cc b/impeller/display_list/aiks_dl_text_unittests.cc index 8494f4f8e638e..5ac13a4b96add 100644 --- a/impeller/display_list/aiks_dl_text_unittests.cc +++ b/impeller/display_list/aiks_dl_text_unittests.cc @@ -184,20 +184,20 @@ TEST_P(AiksTest, CanRenderTextFrameWithFractionScaling) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } -// TEST_P(AiksTest, CanRenderTextFrameSTB) { -// DisplayListBuilder builder; +TEST_P(AiksTest, CanRenderTextFrameSTB) { + DisplayListBuilder builder; -// DlPaint paint; -// paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); -// builder.DrawPaint(paint); + DlPaint paint; + paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + builder.DrawPaint(paint); -// ASSERT_TRUE(RenderTextInCanvasSTB( -// GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", -// "Roboto-Regular.ttf")); + ASSERT_TRUE(RenderTextInCanvasSTB( + GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", + "Roboto-Regular.ttf")); -// SetTypographerContext(TypographerContextSTB::Make()); -// ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); -// } + // SetTypographerContext(TypographerContextSTB::Make()); + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} TEST_P(AiksTest, TextFrameSubpixelAlignment) { // "Random" numbers between 0 and 1. Hardcoded to avoid flakiness in goldens. From 028d04de765320d81e277229d95b34d59e8e4b08 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sat, 3 Aug 2024 12:32:22 -0700 Subject: [PATCH 04/10] stb fixes. --- impeller/display_list/aiks_dl_text_unittests.cc | 2 +- .../backends/stb/typographer_context_stb.cc | 15 ++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/impeller/display_list/aiks_dl_text_unittests.cc b/impeller/display_list/aiks_dl_text_unittests.cc index 5ac13a4b96add..d49b21af7076d 100644 --- a/impeller/display_list/aiks_dl_text_unittests.cc +++ b/impeller/display_list/aiks_dl_text_unittests.cc @@ -195,7 +195,7 @@ TEST_P(AiksTest, CanRenderTextFrameSTB) { GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", "Roboto-Regular.ttf")); - // SetTypographerContext(TypographerContextSTB::Make()); + SetTypographerContext(TypographerContextSTB::Make()); ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } diff --git a/impeller/typographer/backends/stb/typographer_context_stb.cc b/impeller/typographer/backends/stb/typographer_context_stb.cc index c73cd471482c2..2c8fa2dcc68b5 100644 --- a/impeller/typographer/backends/stb/typographer_context_stb.cc +++ b/impeller/typographer/backends/stb/typographer_context_stb.cc @@ -413,13 +413,6 @@ std::shared_ptr TypographerContextSTB::CreateGlyphAtlas( return last_atlas; } - std::shared_ptr cmd_buffer = context.CreateCommandBuffer(); - std::shared_ptr blit_pass = cmd_buffer->CreateBlitPass(); - - fml::ScopedCleanupClosure closure([&cmd_buffer, &context]() { - context.GetCommandQueue()->Submit({std::move(cmd_buffer)}); - }); - // --------------------------------------------------------------------------- // Step 1: Determine if the atlas type and font glyph pairs are compatible // with the current atlas and reuse if possible. @@ -444,10 +437,18 @@ std::shared_ptr TypographerContextSTB::CreateGlyphAtlas( } } } + if (last_atlas->GetType() == type && new_glyphs.size() == 0) { return last_atlas; } + std::shared_ptr cmd_buffer = context.CreateCommandBuffer(); + std::shared_ptr blit_pass = cmd_buffer->CreateBlitPass(); + + fml::ScopedCleanupClosure closure([&cmd_buffer, &context]() { + context.GetCommandQueue()->Submit({std::move(cmd_buffer)}); + }); + // --------------------------------------------------------------------------- // Step 2: Determine if the additional missing glyphs can be appended to the // existing bitmap without recreating the atlas. This requires that From f9fbf49f0134a3ec7d9580562f759d557ebd9812 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sat, 3 Aug 2024 12:38:05 -0700 Subject: [PATCH 05/10] ++ --- impeller/aiks/aiks_unittests.cc | 39 ----------------- .../display_list/aiks_dl_text_unittests.cc | 43 +++++++++++++++++++ 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index fc8683507183a..2344f49d61bbc 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -32,10 +32,7 @@ #include "impeller/playground/widgets.h" #include "impeller/renderer/command_buffer.h" #include "impeller/renderer/snapshot.h" -#include "impeller/typographer/backends/skia/text_frame_skia.h" #include "third_party/imgui/imgui.h" -#include "third_party/skia/include/core/SkFontMgr.h" -#include "txt/platform.h" namespace impeller { namespace testing { @@ -879,42 +876,6 @@ TEST_P(AiksTest, OpaqueEntitiesGetCoercedToSource) { ASSERT_EQ(entity[0].GetBlendMode(), BlendMode::kSource); } -// This currently renders solid blue, as the support for text color sources was -// moved into DLDispatching. Path data requires the SkTextBlobs which are not -// used in impeller::TextFrames. -TEST_P(AiksTest, TextForegroundShaderWithTransform) { - auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf"); - ASSERT_NE(mapping, nullptr); - - Scalar font_size = 100; - sk_sp font_mgr = txt::GetDefaultFontManager(); - SkFont sk_font(font_mgr->makeFromData(mapping), font_size); - - Paint text_paint; - text_paint.color = Color::Blue(); - - std::vector colors = {Color{0.9568, 0.2627, 0.2118, 1.0}, - Color{0.1294, 0.5882, 0.9529, 1.0}}; - std::vector stops = { - 0.0, - 1.0, - }; - text_paint.color_source = ColorSource::MakeLinearGradient( - {0, 0}, {100, 100}, std::move(colors), std::move(stops), - Entity::TileMode::kRepeat, {}); - - Canvas canvas; - canvas.Translate({100, 100}); - canvas.Rotate(Radians(kPi / 4)); - - auto blob = SkTextBlob::MakeFromString("Hello", sk_font); - ASSERT_NE(blob, nullptr); - auto frame = MakeTextFrameFromTextBlobSkia(blob); - canvas.DrawTextFrame(frame, Point(), text_paint); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - TEST_P(AiksTest, MatrixSaveLayerFilter) { Canvas canvas; canvas.DrawPaint({.color = Color::Black()}); diff --git a/impeller/display_list/aiks_dl_text_unittests.cc b/impeller/display_list/aiks_dl_text_unittests.cc index d49b21af7076d..8f976e8861014 100644 --- a/impeller/display_list/aiks_dl_text_unittests.cc +++ b/impeller/display_list/aiks_dl_text_unittests.cc @@ -4,6 +4,8 @@ #include "display_list/display_list.h" #include "display_list/dl_blend_mode.h" +#include "display_list/dl_tile_mode.h" +#include "display_list/effects/dl_color_source.h" #include "display_list/effects/dl_mask_filter.h" #include "flutter/impeller/aiks/aiks_unittests.h" @@ -444,5 +446,46 @@ TEST_P(AiksTest, CanRenderTextWithLargePerspectiveTransform) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +// This currently renders solid blue, as the support for text color sources was +// moved into DLDispatching. Path data requires the SkTextBlobs which are not +// used in impeller::TextFrames. +TEST_P(AiksTest, TextForegroundShaderWithTransform) { + auto mapping = flutter::testing::OpenFixtureAsSkData("Roboto-Regular.ttf"); + ASSERT_NE(mapping, nullptr); + + Scalar font_size = 100; + sk_sp font_mgr = txt::GetDefaultFontManager(); + SkFont sk_font(font_mgr->makeFromData(mapping), font_size); + + DlPaint text_paint; + text_paint.setColor(DlColor::kBlue()); + + std::vector colors = {DlColor::RGBA(0.9568, 0.2627, 0.2118, 1.0), + DlColor::RGBA(0.1294, 0.5882, 0.9529, 1.0)}; + std::vector stops = { + 0.0, + 1.0, + }; + text_paint.setColorSource(DlColorSource::MakeLinear( + /*start_point=*/{0, 0}, // + /*end_point=*/{100, 100}, // + /*stop_count=*/2, // + /*colors=*/colors.data(), // + /*stops=*/stops.data(), // + /*tile_mode=*/DlTileMode::kRepeat // + )); + + DisplayListBuilder builder; + builder.Translate(100, 100); + builder.Rotate(45); + + auto blob = SkTextBlob::MakeFromString("Hello", sk_font); + ASSERT_NE(blob, nullptr); + auto frame = MakeTextFrameFromTextBlobSkia(blob); + builder.DrawTextFrame(frame, 0, 0, text_paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + } // namespace testing } // namespace impeller From b091bfbb7adb1c359a90668566eee04a737c1a5f Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Sun, 4 Aug 2024 12:17:59 -0700 Subject: [PATCH 06/10] add bounds. --- display_list/dl_color.h | 1 + impeller/aiks/aiks_unittests.cc | 382 ---------------- .../display_list/aiks_dl_basic_unittests.cc | 408 ++++++++++++++++++ .../display_list/aiks_dl_text_unittests.cc | 8 +- 4 files changed, 416 insertions(+), 383 deletions(-) diff --git a/display_list/dl_color.h b/display_list/dl_color.h index 9a823f813894b..ac324fec51ec9 100644 --- a/display_list/dl_color.h +++ b/display_list/dl_color.h @@ -56,6 +56,7 @@ struct DlColor { static constexpr DlColor kMaroon() {return DlColor(0xFF800000);}; static constexpr DlColor kSkyBlue() {return DlColor(0xFF87CEEB);}; static constexpr DlColor kCornflowerBlue() {return DlColor(0xFF6495ED);}; + static constexpr DlColor kCrimson() {return DlColor(0xFFFF5733);}; // clang-format on constexpr bool isOpaque() const { return getAlpha() == 0xFF; } diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 2344f49d61bbc..88efdf1c28617 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -109,104 +109,6 @@ TEST_P(AiksTest, CanEmptyPictureConvertToImage) { ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); } -TEST_P(AiksTest, CoordinateConversionsAreCorrect) { - Canvas canvas; - - // Render a texture directly. - { - Paint paint; - auto image = - std::make_shared(CreateTextureForFixture("kalimba.jpg")); - paint.color = Color::Red(); - - canvas.Save(); - canvas.Translate({100, 200, 0}); - canvas.Scale(Vector2{0.5, 0.5}); - canvas.DrawImage(image, Point::MakeXY(100.0, 100.0), paint); - canvas.Restore(); - } - - // Render an offscreen rendered texture. - { - Paint red; - red.color = Color::Red(); - Paint green; - green.color = Color::Green(); - Paint blue; - blue.color = Color::Blue(); - - Paint alpha; - alpha.color = Color::Red().WithAlpha(0.5); - - canvas.SaveLayer(alpha); - - canvas.DrawRect(Rect::MakeXYWH(000, 000, 100, 100), red); - canvas.DrawRect(Rect::MakeXYWH(020, 020, 100, 100), green); - canvas.DrawRect(Rect::MakeXYWH(040, 040, 100, 100), blue); - - canvas.Restore(); - } - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanPerformFullScreenMSAA) { - Canvas canvas; - - Paint red; - red.color = Color::Red(); - - canvas.DrawCircle({250, 250}, 125, red); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanPerformSkew) { - Canvas canvas; - - Paint red; - red.color = Color::Red(); - - canvas.Skew(2, 5); - canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanPerformSaveLayerWithBounds) { - Canvas canvas; - - Paint red; - red.color = Color::Red(); - - Paint green; - green.color = Color::Green(); - - Paint blue; - blue.color = Color::Blue(); - - Paint save; - save.color = Color::Black(); - - canvas.SaveLayer(save, Rect::MakeXYWH(0, 0, 50, 50)); - - canvas.DrawRect(Rect::MakeXYWH(0, 0, 100, 100), red); - canvas.DrawRect(Rect::MakeXYWH(10, 10, 100, 100), green); - canvas.DrawRect(Rect::MakeXYWH(20, 20, 100, 100), blue); - - canvas.Restore(); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, FormatSRGB) { - PixelFormat pixel_format = - GetContext()->GetCapabilities()->GetDefaultColorFormat(); - EXPECT_TRUE(pixel_format == PixelFormat::kR8G8B8A8UNormInt || - pixel_format == PixelFormat::kB8G8R8A8UNormInt) - << "pixel format: " << PixelFormatToString(pixel_format); -} - TEST_P(AiksTest, TransformMultipliesCorrectly) { Canvas canvas; ASSERT_MATRIX_NEAR(canvas.GetCurrentTransform(), Matrix()); @@ -246,267 +148,6 @@ TEST_P(AiksTest, TransformMultipliesCorrectly) { // clang-format on } -TEST_P(AiksTest, FastEllipticalRRectMaskBlursRenderCorrectly) { - Canvas canvas; - canvas.Scale(GetContentScale()); - Paint paint; - paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Sigma{1}, - }; - - canvas.DrawPaint({.color = Color::White()}); - - paint.color = Color::Blue(); - for (int i = 0; i < 5; i++) { - Scalar y = i * 125; - Scalar y_radius = i * 15; - for (int j = 0; j < 5; j++) { - Scalar x = j * 125; - Scalar x_radius = j * 15; - canvas.DrawRRect(Rect::MakeXYWH(x + 50, y + 50, 100.0f, 100.0f), - {x_radius, y_radius}, paint); - } - } - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, FilledRoundRectPathsRenderCorrectly) { - Canvas canvas; - canvas.Scale(GetContentScale()); - Paint paint; - const int color_count = 3; - Color colors[color_count] = { - Color::Blue(), - Color::Green(), - Color::Crimson(), - }; - - paint.color = Color::White(); - canvas.DrawPaint(paint); - - auto draw_rrect_as_path = [&canvas](const Rect& rect, const Size& radii, - const Paint& paint) { - PathBuilder builder = PathBuilder(); - builder.AddRoundedRect(rect, radii); - canvas.DrawPath(builder.TakePath(), paint); - }; - - int c_index = 0; - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 4; j++) { - paint.color = colors[(c_index++) % color_count]; - draw_rrect_as_path(Rect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80), - Size(i * 5 + 10, j * 5 + 10), paint); - } - } - paint.color = colors[(c_index++) % color_count]; - draw_rrect_as_path(Rect::MakeXYWH(10, 420, 380, 80), Size(40, 40), paint); - paint.color = colors[(c_index++) % color_count]; - draw_rrect_as_path(Rect::MakeXYWH(410, 20, 80, 380), Size(40, 40), paint); - - std::vector gradient_colors = { - Color{0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0}, - Color{0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0}, - Color{0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0}, - Color{0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0}, - Color{0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0}, - Color{0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0}, - Color{0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0}}; - std::vector stops = { - 0.0, - (1.0 / 6.0) * 1, - (1.0 / 6.0) * 2, - (1.0 / 6.0) * 3, - (1.0 / 6.0) * 4, - (1.0 / 6.0) * 5, - 1.0, - }; - auto texture = CreateTextureForFixture("airplane.jpg", - /*enable_mipmapping=*/true); - - paint.color = Color::White().WithAlpha(0.1); - paint.color_source = ColorSource::MakeRadialGradient( - {550, 550}, 75, gradient_colors, stops, Entity::TileMode::kMirror, {}); - for (int i = 1; i <= 10; i++) { - int j = 11 - i; - draw_rrect_as_path(Rect::MakeLTRB(550 - i * 20, 550 - j * 20, // - 550 + i * 20, 550 + j * 20), - Size(i * 10, j * 10), paint); - } - paint.color = Color::White().WithAlpha(0.5); - paint.color_source = ColorSource::MakeRadialGradient( - {200, 650}, 75, std::move(gradient_colors), std::move(stops), - Entity::TileMode::kMirror, {}); - draw_rrect_as_path(Rect::MakeLTRB(100, 610, 300, 690), Size(40, 40), paint); - draw_rrect_as_path(Rect::MakeLTRB(160, 550, 240, 750), Size(40, 40), paint); - - paint.color = Color::White().WithAlpha(0.1); - paint.color_source = ColorSource::MakeImage( - texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, - Matrix::MakeTranslation({520, 20})); - for (int i = 1; i <= 10; i++) { - int j = 11 - i; - draw_rrect_as_path(Rect::MakeLTRB(720 - i * 20, 220 - j * 20, // - 720 + i * 20, 220 + j * 20), - Size(i * 10, j * 10), paint); - } - paint.color = Color::White().WithAlpha(0.5); - paint.color_source = ColorSource::MakeImage( - texture, Entity::TileMode::kRepeat, Entity::TileMode::kRepeat, {}, - Matrix::MakeTranslation({800, 300})); - draw_rrect_as_path(Rect::MakeLTRB(800, 410, 1000, 490), Size(40, 40), paint); - draw_rrect_as_path(Rect::MakeLTRB(860, 350, 940, 550), Size(40, 40), paint); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CoverageOriginShouldBeAccountedForInSubpasses) { - auto callback = [&](AiksContext& renderer) -> std::optional { - Canvas canvas; - canvas.Scale(GetContentScale()); - - Paint alpha; - alpha.color = Color::Red().WithAlpha(0.5); - - auto current = Point{25, 25}; - const auto offset = Point{25, 25}; - const auto size = Size(100, 100); - - static PlaygroundPoint point_a(Point(40, 40), 10, Color::White()); - static PlaygroundPoint point_b(Point(160, 160), 10, Color::White()); - auto [b0, b1] = DrawPlaygroundLine(point_a, point_b); - auto bounds = Rect::MakeLTRB(b0.x, b0.y, b1.x, b1.y); - - canvas.DrawRect(bounds, Paint{.color = Color::Yellow(), - .stroke_width = 5.0f, - .style = Paint::Style::kStroke}); - - canvas.SaveLayer(alpha, bounds); - - canvas.DrawRect(Rect::MakeOriginSize(current, size), - Paint{.color = Color::Red()}); - canvas.DrawRect(Rect::MakeOriginSize(current += offset, size), - Paint{.color = Color::Green()}); - canvas.DrawRect(Rect::MakeOriginSize(current += offset, size), - Paint{.color = Color::Blue()}); - - canvas.Restore(); - - return canvas.EndRecordingAsPicture(); - }; - - ASSERT_TRUE(OpenPlaygroundHere(callback)); -} - -TEST_P(AiksTest, SaveLayerDrawsBehindSubsequentEntities) { - // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636 - Canvas canvas; - Paint paint; - - paint.color = Color::Black(); - Rect rect = Rect::MakeXYWH(25, 25, 25, 25); - canvas.DrawRect(rect, paint); - - canvas.Translate({10, 10}); - canvas.SaveLayer({}); - - paint.color = Color::Green(); - canvas.DrawRect(rect, paint); - - canvas.Restore(); - - canvas.Translate({10, 10}); - paint.color = Color::Red(); - canvas.DrawRect(rect, paint); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, SiblingSaveLayerBoundsAreRespected) { - Canvas canvas; - Paint paint; - Rect rect = Rect::MakeXYWH(0, 0, 1000, 1000); - - // Black, green, and red squares offset by [10, 10]. - { - canvas.SaveLayer({}, Rect::MakeXYWH(25, 25, 25, 25)); - paint.color = Color::Black(); - canvas.DrawRect(rect, paint); - canvas.Restore(); - } - - { - canvas.SaveLayer({}, Rect::MakeXYWH(35, 35, 25, 25)); - paint.color = Color::Green(); - canvas.DrawRect(rect, paint); - canvas.Restore(); - } - - { - canvas.SaveLayer({}, Rect::MakeXYWH(45, 45, 25, 25)); - paint.color = Color::Red(); - canvas.DrawRect(rect, paint); - canvas.Restore(); - } - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, CanRenderClippedLayers) { - Canvas canvas; - - canvas.DrawPaint({.color = Color::White()}); - - // Draw a green circle on the screen. - { - // Increase the clip depth for the savelayer to contend with. - canvas.ClipPath(PathBuilder{}.AddCircle({100, 100}, 50).TakePath()); - - canvas.SaveLayer({}, Rect::MakeXYWH(50, 50, 100, 100)); - - // Fill the layer with white. - canvas.DrawRect(Rect::MakeSize(Size{400, 400}), {.color = Color::White()}); - // Fill the layer with green, but do so with a color blend that can't be - // collapsed into the parent pass. - // TODO(jonahwilliams): this blend mode was changed from color burn to - // hardlight to work around https://github.com/flutter/flutter/issues/136554 - // . - canvas.DrawRect( - Rect::MakeSize(Size{400, 400}), - {.color = Color::Green(), .blend_mode = BlendMode::kHardLight}); - } - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - -TEST_P(AiksTest, SaveLayerFiltersScaleWithTransform) { - Canvas canvas; - canvas.Scale(GetContentScale()); - canvas.Translate(Vector2(100, 100)); - - auto texture = std::make_shared(CreateTextureForFixture("boston.jpg")); - auto draw_image_layer = [&canvas, &texture](const Paint& paint) { - canvas.SaveLayer(paint); - canvas.DrawImage(texture, {}, Paint{}); - canvas.Restore(); - }; - - Paint effect_paint; - effect_paint.mask_blur_descriptor = Paint::MaskBlurDescriptor{ - .style = FilterContents::BlurStyle::kNormal, - .sigma = Sigma{6}, - }; - draw_image_layer(effect_paint); - - canvas.Translate(Vector2(300, 300)); - canvas.Scale(Vector2(3, 3)); - draw_image_layer(effect_paint); - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - #if IMPELLER_ENABLE_3D TEST_P(AiksTest, SceneColorSource) { // Load up the scene. @@ -938,29 +579,6 @@ TEST_P(AiksTest, SolidColorApplyColorFilter) { Color(0.424452, 0.828743, 0.79105, 0.9375)); } -TEST_P(AiksTest, PipelineBlendSingleParameter) { - Canvas canvas; - - // Should render a green square in the middle of a blue circle. - canvas.SaveLayer({}); - { - canvas.Translate(Point(100, 100)); - canvas.DrawCircle(Point(200, 200), 200, {.color = Color::Blue()}); - canvas.ClipRect(Rect::MakeXYWH(100, 100, 200, 200)); - canvas.DrawCircle(Point(200, 200), 200, - { - .color = Color::Green(), - .blend_mode = BlendMode::kSourceOver, - .image_filter = ImageFilter::MakeFromColorFilter( - *ColorFilter::MakeBlend(BlendMode::kDestination, - Color::White())), - }); - canvas.Restore(); - } - - ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); -} - // Regression test for https://github.com/flutter/flutter/issues/134678. TEST_P(AiksTest, ReleasesTextureOnTeardown) { auto context = MakeContext(); diff --git a/impeller/display_list/aiks_dl_basic_unittests.cc b/impeller/display_list/aiks_dl_basic_unittests.cc index d20e854fd760b..b84c19da1e3b2 100644 --- a/impeller/display_list/aiks_dl_basic_unittests.cc +++ b/impeller/display_list/aiks_dl_basic_unittests.cc @@ -8,6 +8,7 @@ #include "display_list/effects/dl_color_filter.h" #include "display_list/effects/dl_color_source.h" #include "display_list/effects/dl_image_filter.h" +#include "display_list/effects/dl_mask_filter.h" #include "flutter/impeller/aiks/aiks_unittests.h" #include "flutter/display_list/dl_blend_mode.h" @@ -18,6 +19,7 @@ #include "flutter/impeller/geometry/scalar.h" #include "flutter/testing/display_list_testing.h" #include "flutter/testing/testing.h" +#include "impeller/playground/widgets.h" #include "include/core/SkMatrix.h" namespace impeller { @@ -1101,5 +1103,411 @@ TEST_P(AiksTest, FormatWideGamut) { PixelFormat::kB10G10R10A10XR); } +TEST_P(AiksTest, FormatSRGB) { + PixelFormat pixel_format = + GetContext()->GetCapabilities()->GetDefaultColorFormat(); + EXPECT_TRUE(pixel_format == PixelFormat::kR8G8B8A8UNormInt || + pixel_format == PixelFormat::kB8G8R8A8UNormInt) + << "pixel format: " << PixelFormatToString(pixel_format); +} + +TEST_P(AiksTest, CoordinateConversionsAreCorrect) { + DisplayListBuilder builder; + + // Render a texture directly. + { + auto image = DlImageImpeller::Make(CreateTextureForFixture("kalimba.jpg")); + + builder.Save(); + builder.Translate(100, 200); + builder.Scale(0.5, 0.5); + builder.DrawImage(image, SkPoint::Make(100.0, 100.0), + DlImageSampling::kLinear); + builder.Restore(); + } + + // Render an offscreen rendered texture. + { + DlPaint alpha; + alpha.setColor(DlColor::kRed().modulateOpacity(0.5)); + + builder.SaveLayer(nullptr, &alpha); + + DlPaint paint; + paint.setColor(DlColor::kRed()); + builder.DrawRect(SkRect::MakeXYWH(000, 000, 100, 100), paint); + paint.setColor(DlColor::kGreen()); + builder.DrawRect(SkRect::MakeXYWH(020, 020, 100, 100), paint); + paint.setColor(DlColor::kBlue()); + builder.DrawRect(SkRect::MakeXYWH(040, 040, 100, 100), paint); + + builder.Restore(); + } + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanPerformFullScreenMSAA) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::kRed()); + builder.DrawCircle(SkPoint::Make(250, 250), 125, paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanPerformSkew) { + DisplayListBuilder builder; + + DlPaint red; + red.setColor(DlColor::kRed()); + builder.Skew(2, 5); + builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), red); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanPerformSaveLayerWithBounds) { + DisplayListBuilder builder; + + DlPaint save; + save.setColor(DlColor::kBlack()); + + SkRect save_bounds = SkRect::MakeXYWH(0, 0, 50, 50); + builder.SaveLayer(&save_bounds, &save); + + DlPaint paint; + paint.setColor(DlColor::kRed()); + builder.DrawRect(SkRect::MakeXYWH(0, 0, 100, 100), paint); + paint.setColor(DlColor::kGreen()); + builder.DrawRect(SkRect::MakeXYWH(10, 10, 100, 100), paint); + paint.setColor(DlColor::kBlue()); + builder.DrawRect(SkRect::MakeXYWH(20, 20, 100, 100), paint); + + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, FilledRoundRectPathsRenderCorrectly) { + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint paint; + const int color_count = 3; + DlColor colors[color_count] = { + DlColor::kBlue(), + DlColor::kGreen(), + DlColor::kCrimson(), + }; + + paint.setColor(DlColor::kWhite()); + builder.DrawPaint(paint); + + auto draw_rrect_as_path = [&builder](const SkRect& rect, Scalar x, Scalar y, + const DlPaint& paint) { + SkPath path; + path.addRoundRect(rect, x, y); + builder.DrawPath(path, paint); + }; + + int c_index = 0; + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + paint.setColor(colors[(c_index++) % color_count]); + draw_rrect_as_path(SkRect::MakeXYWH(i * 100 + 10, j * 100 + 20, 80, 80), + i * 5 + 10, j * 5 + 10, paint); + } + } + paint.setColor(colors[(c_index++) % color_count]); + draw_rrect_as_path(SkRect::MakeXYWH(10, 420, 380, 80), 40, 40, paint); + paint.setColor(colors[(c_index++) % color_count]); + draw_rrect_as_path(SkRect::MakeXYWH(410, 20, 80, 380), 40, 40, paint); + + std::vector gradient_colors = { + DlColor::RGBA(0x1f / 255.0, 0.0, 0x5c / 255.0, 1.0), + DlColor::RGBA(0x5b / 255.0, 0.0, 0x60 / 255.0, 1.0), + DlColor::RGBA(0x87 / 255.0, 0x01 / 255.0, 0x60 / 255.0, 1.0), + DlColor::RGBA(0xac / 255.0, 0x25 / 255.0, 0x53 / 255.0, 1.0), + DlColor::RGBA(0xe1 / 255.0, 0x6b / 255.0, 0x5c / 255.0, 1.0), + DlColor::RGBA(0xf3 / 255.0, 0x90 / 255.0, 0x60 / 255.0, 1.0), + DlColor::RGBA(0xff / 255.0, 0xb5 / 255.0, 0x6b / 250.0, 1.0)}; + std::vector stops = { + 0.0, + (1.0 / 6.0) * 1, + (1.0 / 6.0) * 2, + (1.0 / 6.0) * 3, + (1.0 / 6.0) * 4, + (1.0 / 6.0) * 5, + 1.0, + }; + auto texture = DlImageImpeller::Make( + CreateTextureForFixture("airplane.jpg", + /*enable_mipmapping=*/true)); + + paint.setColor(DlColor::kWhite().modulateOpacity(0.1)); + paint.setColorSource(DlColorSource::MakeRadial( + /*center=*/{550, 550}, + /*radius=*/75, + /*stop_count=*/gradient_colors.size(), + /*colors=*/gradient_colors.data(), + /*stops=*/stops.data(), + /*tile_mode=*/DlTileMode::kMirror)); + for (int i = 1; i <= 10; i++) { + int j = 11 - i; + draw_rrect_as_path(SkRect::MakeLTRB(550 - i * 20, 550 - j * 20, // + 550 + i * 20, 550 + j * 20), + i * 10, j * 10, paint); + } + paint.setColor(DlColor::kWhite().modulateOpacity(0.5)); + paint.setColorSource(DlColorSource::MakeRadial( + /*center=*/{200, 650}, + /*radius=*/75, + /*stop_count=*/gradient_colors.size(), + /*colors=*/gradient_colors.data(), + /*stops=*/stops.data(), + /*tile_mode=*/DlTileMode::kMirror)); + draw_rrect_as_path(SkRect::MakeLTRB(100, 610, 300, 690), 40, 40, paint); + draw_rrect_as_path(SkRect::MakeLTRB(160, 550, 240, 750), 40, 40, paint); + + auto matrix = SkMatrix::Translate(520, 20); + paint.setColor(DlColor::kWhite().modulateOpacity(0.1)); + paint.setColorSource(std::make_shared( + texture, DlTileMode::kRepeat, DlTileMode::kRepeat, + DlImageSampling::kLinear, &matrix)); + for (int i = 1; i <= 10; i++) { + int j = 11 - i; + draw_rrect_as_path(SkRect::MakeLTRB(720 - i * 20, 220 - j * 20, // + 720 + i * 20, 220 + j * 20), + i * 10, j * 10, paint); + } + matrix = SkMatrix::Translate(800, 300); + paint.setColor(DlColor::kWhite().modulateOpacity(0.5)); + paint.setColorSource(std::make_shared( + texture, DlTileMode::kRepeat, DlTileMode::kRepeat, + DlImageSampling::kLinear, &matrix)); + + draw_rrect_as_path(SkRect::MakeLTRB(800, 410, 1000, 490), 40, 40, paint); + draw_rrect_as_path(SkRect::MakeLTRB(860, 350, 940, 550), 40, 40, paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CoverageOriginShouldBeAccountedForInSubpasses) { + auto callback = [&]() -> sk_sp { + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint alpha; + alpha.setColor(DlColor::kRed().modulateOpacity(0.5)); + + auto current = Point{25, 25}; + const auto offset = Point{25, 25}; + const auto size = Size(100, 100); + + static PlaygroundPoint point_a(Point(40, 40), 10, Color::White()); + static PlaygroundPoint point_b(Point(160, 160), 10, Color::White()); + auto [b0, b1] = DrawPlaygroundLine(point_a, point_b); + SkRect bounds = SkRect::MakeLTRB(b0.x, b0.y, b1.x, b1.y); + + DlPaint stroke_paint; + stroke_paint.setColor(DlColor::kYellow()); + stroke_paint.setStrokeWidth(5); + stroke_paint.setDrawStyle(DlDrawStyle::kStroke); + builder.DrawRect(bounds, stroke_paint); + + builder.SaveLayer(&bounds, &alpha); + + DlPaint paint; + paint.setColor(DlColor::kRed()); + builder.DrawRect( + SkRect::MakeXYWH(current.x, current.y, size.width, size.height), paint); + + paint.setColor(DlColor::kGreen()); + current += offset; + builder.DrawRect( + SkRect::MakeXYWH(current.x, current.y, size.width, size.height), paint); + + paint.setColor(DlColor::kBlue()); + current += offset; + builder.DrawRect( + SkRect::MakeXYWH(current.x, current.y, size.width, size.height), paint); + + builder.Restore(); + + return builder.Build(); + }; + + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + +TEST_P(AiksTest, SaveLayerDrawsBehindSubsequentEntities) { + // Compare with https://fiddle.skia.org/c/9e03de8567ffb49e7e83f53b64bcf636 + DisplayListBuilder builder; + DlPaint paint; + + paint.setColor(DlColor::kBlack()); + SkRect rect = SkRect::MakeXYWH(25, 25, 25, 25); + builder.DrawRect(rect, paint); + + builder.Translate(10, 10); + + DlPaint save_paint; + builder.SaveLayer(nullptr, &save_paint); + + paint.setColor(DlColor::kGreen()); + builder.DrawRect(rect, paint); + + builder.Restore(); + + builder.Translate(10, 10); + paint.setColor(DlColor::kRed()); + builder.DrawRect(rect, paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, SiblingSaveLayerBoundsAreRespected) { + DisplayListBuilder builder; + DlPaint paint; + SkRect rect = SkRect::MakeXYWH(0, 0, 1000, 1000); + + // Black, green, and red squares offset by [10, 10]. + { + DlPaint save_paint; + SkRect bounds = SkRect::MakeXYWH(25, 25, 25, 25); + builder.SaveLayer(&bounds, &save_paint); + paint.setColor(DlColor::kBlack()); + builder.DrawRect(rect, paint); + builder.Restore(); + } + + { + DlPaint save_paint; + SkRect bounds = SkRect::MakeXYWH(35, 35, 25, 25); + builder.SaveLayer(&bounds, &save_paint); + paint.setColor(DlColor::kGreen()); + builder.DrawRect(rect, paint); + builder.Restore(); + } + + { + DlPaint save_paint; + SkRect bounds = SkRect::MakeXYWH(45, 45, 25, 25); + builder.SaveLayer(&bounds, &save_paint); + paint.setColor(DlColor::kRed()); + builder.DrawRect(rect, paint); + builder.Restore(); + } + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, CanRenderClippedLayers) { + DisplayListBuilder builder; + + DlPaint paint; + paint.setColor(DlColor::kWhite()); + builder.DrawPaint(paint); + + // Draw a green circle on the screen. + { + // Increase the clip depth for the savelayer to contend with. + SkPath path = SkPath::Circle(100, 100, 50); + builder.ClipPath(path); + + SkRect bounds = SkRect::MakeXYWH(50, 50, 100, 100); + DlPaint save_paint; + builder.SaveLayer(&bounds, &save_paint); + + // Fill the layer with white. + paint.setColor(DlColor::kWhite()); + builder.DrawRect(SkRect::MakeSize(SkSize{400, 400}), paint); + // Fill the layer with green, but do so with a color blend that can't be + // collapsed into the parent pass. + paint.setColor(DlColor::kGreen()); + paint.setBlendMode(DlBlendMode::kHardLight); + builder.DrawRect(SkRect::MakeSize(SkSize{400, 400}), paint); + } + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, SaveLayerFiltersScaleWithTransform) { + DisplayListBuilder builder; + + builder.Scale(GetContentScale().x, GetContentScale().y); + builder.Translate(100, 100); + + auto texture = DlImageImpeller::Make(CreateTextureForFixture("boston.jpg")); + auto draw_image_layer = [&builder, &texture](const DlPaint& paint) { + builder.SaveLayer(nullptr, &paint); + builder.DrawImage(texture, {}, DlImageSampling::kLinear); + builder.Restore(); + }; + + DlPaint effect_paint; + effect_paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 6)); + draw_image_layer(effect_paint); + + builder.Translate(300, 300); + builder.Scale(3, 3); + draw_image_layer(effect_paint); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, FastEllipticalRRectMaskBlursRenderCorrectly) { + DisplayListBuilder builder; + + builder.Scale(GetContentScale().x, GetContentScale().y); + DlPaint paint; + paint.setMaskFilter(DlBlurMaskFilter::Make(DlBlurStyle::kNormal, 1)); + + DlPaint save_paint; + save_paint.setColor(DlColor::kWhite()); + builder.DrawPaint(save_paint); + + paint.setColor(DlColor::kBlue()); + for (int i = 0; i < 5; i++) { + Scalar y = i * 125; + Scalar y_radius = i * 15; + for (int j = 0; j < 5; j++) { + Scalar x = j * 125; + Scalar x_radius = j * 15; + builder.DrawRRect( + SkRRect::MakeRectXY(SkRect::MakeXYWH(x + 50, y + 50, 100.0f, 100.0f), + x_radius, y_radius), + paint); + } + } + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + +TEST_P(AiksTest, PipelineBlendSingleParameter) { + DisplayListBuilder builder; + + // Should render a green square in the middle of a blue circle. + DlPaint paint; + builder.SaveLayer(nullptr, &paint); + { + builder.Translate(100, 100); + paint.setColor(DlColor::kBlue()); + builder.DrawCircle(SkPoint::Make(200, 200), 200, paint); + builder.ClipRect(SkRect::MakeXYWH(100, 100, 200, 200)); + + paint.setColor(DlColor::kGreen()); + paint.setBlendMode(DlBlendMode::kSrcOver); + paint.setImageFilter(DlColorFilterImageFilter::Make( + DlBlendColorFilter::Make(DlColor::kWhite(), DlBlendMode::kDst))); + builder.DrawCircle(SkPoint::Make(200, 200), 200, paint); + builder.Restore(); + } + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + } // namespace testing } // namespace impeller diff --git a/impeller/display_list/aiks_dl_text_unittests.cc b/impeller/display_list/aiks_dl_text_unittests.cc index 8f976e8861014..e542ed6c05505 100644 --- a/impeller/display_list/aiks_dl_text_unittests.cc +++ b/impeller/display_list/aiks_dl_text_unittests.cc @@ -18,6 +18,7 @@ #include "impeller/typographer/backends/stb/text_frame_stb.h" #include "impeller/typographer/backends/stb/typeface_stb.h" #include "impeller/typographer/backends/stb/typographer_context_stb.h" +#include "include/core/SkMatrix.h" #include "include/core/SkRect.h" #include "txt/platform.h" @@ -418,11 +419,16 @@ TEST_P(AiksTest, DrawScaledTextWithPerspectiveSaveLayer) { Matrix::MakeRotationY({Degrees{10}}); DlPaint save_paint; - builder.SaveLayer(nullptr, &save_paint); + SkRect window_bounds = + SkRect::MakeXYWH(0, 0, GetWindowSize().width, GetWindowSize().height); + // Note: bounds were not needed by the AIKS version, which may indicate a bug. + builder.SaveLayer(&window_bounds, &save_paint); builder.Transform(SkM44::ColMajor(matrix.m)); ASSERT_TRUE(RenderTextInCanvasSkia(GetContext(), builder, "Hello world", "Roboto-Regular.ttf")); + + builder.Restore(); ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } From 8019b835a74cc201b1aae9d092849cf3a338b32b Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 6 Aug 2024 09:49:12 -0700 Subject: [PATCH 07/10] ++ --- display_list/dl_color.h | 1 + impeller/display_list/aiks_dl_basic_unittests.cc | 2 +- impeller/display_list/aiks_dl_text_unittests.cc | 16 ++++++++-------- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/display_list/dl_color.h b/display_list/dl_color.h index ac324fec51ec9..c7fd49b0857ac 100644 --- a/display_list/dl_color.h +++ b/display_list/dl_color.h @@ -57,6 +57,7 @@ struct DlColor { static constexpr DlColor kSkyBlue() {return DlColor(0xFF87CEEB);}; static constexpr DlColor kCornflowerBlue() {return DlColor(0xFF6495ED);}; static constexpr DlColor kCrimson() {return DlColor(0xFFFF5733);}; + static constexpr DlColor kAqua() {return DlColor(0xFF00FFFF);}; // clang-format on constexpr bool isOpaque() const { return getAlpha() == 0xFF; } diff --git a/impeller/display_list/aiks_dl_basic_unittests.cc b/impeller/display_list/aiks_dl_basic_unittests.cc index b84c19da1e3b2..992e5541ff36f 100644 --- a/impeller/display_list/aiks_dl_basic_unittests.cc +++ b/impeller/display_list/aiks_dl_basic_unittests.cc @@ -1122,7 +1122,7 @@ TEST_P(AiksTest, CoordinateConversionsAreCorrect) { builder.Translate(100, 200); builder.Scale(0.5, 0.5); builder.DrawImage(image, SkPoint::Make(100.0, 100.0), - DlImageSampling::kLinear); + DlImageSampling::kNearestNeighbor); builder.Restore(); } diff --git a/impeller/display_list/aiks_dl_text_unittests.cc b/impeller/display_list/aiks_dl_text_unittests.cc index e542ed6c05505..83240a5da8169 100644 --- a/impeller/display_list/aiks_dl_text_unittests.cc +++ b/impeller/display_list/aiks_dl_text_unittests.cc @@ -44,7 +44,7 @@ bool RenderTextInCanvasSkia(const std::shared_ptr& context, const TextRenderOptions& options = {}) { // Draw the baseline. DlPaint paint; - paint.setColor(DlColor::kBlue().modulateOpacity(0.25)); + paint.setColor(DlColor::kAqua().modulateOpacity(0.25)); canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50, options.position.y(), 900, 10), paint); @@ -87,7 +87,7 @@ bool RenderTextInCanvasSTB(const std::shared_ptr& context, const TextRenderOptions& options = {}) { // Draw the baseline. DlPaint paint; - paint.setColor(DlColor::kBlue().modulateOpacity(0.25)); + paint.setColor(DlColor::kAqua().modulateOpacity(0.25)); canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50, options.position.y(), 900, 10), paint); @@ -118,7 +118,7 @@ TEST_P(AiksTest, CanRenderTextFrame) { DisplayListBuilder builder; DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1)); builder.DrawPaint(paint); ASSERT_TRUE(RenderTextInCanvasSkia( GetContext(), builder, "the quick brown fox jumped over the lazy dog!.?", @@ -131,7 +131,7 @@ TEST_P(AiksTest, CanRenderTextFrameWithInvertedTransform) { DisplayListBuilder builder; DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1)); builder.DrawPaint(paint); builder.Translate(1000, 0); builder.Scale(-1, 1); @@ -147,7 +147,7 @@ TEST_P(AiksTest, CanRenderStrokedTextFrame) { DisplayListBuilder builder; DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1)); builder.DrawPaint(paint); ASSERT_TRUE(RenderTextInCanvasSkia( @@ -163,7 +163,7 @@ TEST_P(AiksTest, CanRenderTextFrameWithHalfScaling) { DisplayListBuilder builder; DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1)); builder.DrawPaint(paint); builder.Scale(0.5, 0.5); @@ -177,7 +177,7 @@ TEST_P(AiksTest, CanRenderTextFrameWithFractionScaling) { DisplayListBuilder builder; DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1)); builder.DrawPaint(paint); builder.Scale(2.625, 2.625); @@ -191,7 +191,7 @@ TEST_P(AiksTest, CanRenderTextFrameSTB) { DisplayListBuilder builder; DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1)); builder.DrawPaint(paint); ASSERT_TRUE(RenderTextInCanvasSTB( From 030afbe7fd810840f1cb8a1508140f816ed250ed Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 6 Aug 2024 10:58:20 -0700 Subject: [PATCH 08/10] ++ --- impeller/display_list/aiks_dl_basic_unittests.cc | 4 ++-- impeller/display_list/aiks_dl_text_unittests.cc | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/impeller/display_list/aiks_dl_basic_unittests.cc b/impeller/display_list/aiks_dl_basic_unittests.cc index 992e5541ff36f..4a1665c49f8ab 100644 --- a/impeller/display_list/aiks_dl_basic_unittests.cc +++ b/impeller/display_list/aiks_dl_basic_unittests.cc @@ -1275,7 +1275,7 @@ TEST_P(AiksTest, FilledRoundRectPathsRenderCorrectly) { paint.setColor(DlColor::kWhite().modulateOpacity(0.1)); paint.setColorSource(std::make_shared( texture, DlTileMode::kRepeat, DlTileMode::kRepeat, - DlImageSampling::kLinear, &matrix)); + DlImageSampling::kNearestNeighbor, &matrix)); for (int i = 1; i <= 10; i++) { int j = 11 - i; draw_rrect_as_path(SkRect::MakeLTRB(720 - i * 20, 220 - j * 20, // @@ -1286,7 +1286,7 @@ TEST_P(AiksTest, FilledRoundRectPathsRenderCorrectly) { paint.setColor(DlColor::kWhite().modulateOpacity(0.5)); paint.setColorSource(std::make_shared( texture, DlTileMode::kRepeat, DlTileMode::kRepeat, - DlImageSampling::kLinear, &matrix)); + DlImageSampling::kNearestNeighbor, &matrix)); draw_rrect_as_path(SkRect::MakeLTRB(800, 410, 1000, 490), 40, 40, paint); draw_rrect_as_path(SkRect::MakeLTRB(860, 350, 940, 550), 40, 40, paint); diff --git a/impeller/display_list/aiks_dl_text_unittests.cc b/impeller/display_list/aiks_dl_text_unittests.cc index 83240a5da8169..99542db9dc5f9 100644 --- a/impeller/display_list/aiks_dl_text_unittests.cc +++ b/impeller/display_list/aiks_dl_text_unittests.cc @@ -252,7 +252,7 @@ TEST_P(AiksTest, CanRenderItalicizedText) { DisplayListBuilder builder; DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1)); builder.DrawPaint(paint); ASSERT_TRUE(RenderTextInCanvasSkia( @@ -284,7 +284,7 @@ TEST_P(AiksTest, CanRenderEmojiTextFrameWithBlur) { DisplayListBuilder builder; DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1)); builder.DrawPaint(paint); ASSERT_TRUE(RenderTextInCanvasSkia( @@ -299,7 +299,7 @@ TEST_P(AiksTest, CanRenderEmojiTextFrameWithAlpha) { DisplayListBuilder builder; DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1)); builder.DrawPaint(paint); ASSERT_TRUE(RenderTextInCanvasSkia( From 397ca9b5849906c5a20d4c9bee8d0503f7d23de6 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 6 Aug 2024 12:15:22 -0700 Subject: [PATCH 09/10] ++ --- impeller/display_list/aiks_dl_basic_unittests.cc | 6 +++--- impeller/display_list/aiks_dl_text_unittests.cc | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/impeller/display_list/aiks_dl_basic_unittests.cc b/impeller/display_list/aiks_dl_basic_unittests.cc index 4a1665c49f8ab..0f89a4acfafed 100644 --- a/impeller/display_list/aiks_dl_basic_unittests.cc +++ b/impeller/display_list/aiks_dl_basic_unittests.cc @@ -1199,7 +1199,7 @@ TEST_P(AiksTest, FilledRoundRectPathsRenderCorrectly) { DlColor colors[color_count] = { DlColor::kBlue(), DlColor::kGreen(), - DlColor::kCrimson(), + DlColor::ARGB(1.0, 220.0f / 255.0f, 20.0f / 255.0f, 60.0f / 255.0f), }; paint.setColor(DlColor::kWhite()); @@ -1275,7 +1275,7 @@ TEST_P(AiksTest, FilledRoundRectPathsRenderCorrectly) { paint.setColor(DlColor::kWhite().modulateOpacity(0.1)); paint.setColorSource(std::make_shared( texture, DlTileMode::kRepeat, DlTileMode::kRepeat, - DlImageSampling::kNearestNeighbor, &matrix)); + DlImageSampling::kMipmapLinear, &matrix)); for (int i = 1; i <= 10; i++) { int j = 11 - i; draw_rrect_as_path(SkRect::MakeLTRB(720 - i * 20, 220 - j * 20, // @@ -1286,7 +1286,7 @@ TEST_P(AiksTest, FilledRoundRectPathsRenderCorrectly) { paint.setColor(DlColor::kWhite().modulateOpacity(0.5)); paint.setColorSource(std::make_shared( texture, DlTileMode::kRepeat, DlTileMode::kRepeat, - DlImageSampling::kNearestNeighbor, &matrix)); + DlImageSampling::kMipmapLinear, &matrix)); draw_rrect_as_path(SkRect::MakeLTRB(800, 410, 1000, 490), 40, 40, paint); draw_rrect_as_path(SkRect::MakeLTRB(860, 350, 940, 550), 40, 40, paint); diff --git a/impeller/display_list/aiks_dl_text_unittests.cc b/impeller/display_list/aiks_dl_text_unittests.cc index 99542db9dc5f9..539e8bbefc3af 100644 --- a/impeller/display_list/aiks_dl_text_unittests.cc +++ b/impeller/display_list/aiks_dl_text_unittests.cc @@ -44,13 +44,13 @@ bool RenderTextInCanvasSkia(const std::shared_ptr& context, const TextRenderOptions& options = {}) { // Draw the baseline. DlPaint paint; - paint.setColor(DlColor::kAqua().modulateOpacity(0.25)); + paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25)); canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50, options.position.y(), 900, 10), paint); // Mark the point at which the text is drawn. - paint.setColor(DlColor::kRed().modulateOpacity(0.25)); + paint.setColor(DlColor::kRed().withAlpha(255 * 0.25)); canvas.DrawCircle(options.position, 5.0, paint); // Construct the text blob. @@ -87,13 +87,13 @@ bool RenderTextInCanvasSTB(const std::shared_ptr& context, const TextRenderOptions& options = {}) { // Draw the baseline. DlPaint paint; - paint.setColor(DlColor::kAqua().modulateOpacity(0.25)); + paint.setColor(DlColor::kAqua().withAlpha(255 * 0.25)); canvas.DrawRect(SkRect::MakeXYWH(options.position.x() - 50, options.position.y(), 900, 10), paint); // Mark the point at which the text is drawn. - paint.setColor(DlColor::kRed().modulateOpacity(0.25)); + paint.setColor(DlColor::kRed().withAlpha(255 * 0.25)); canvas.DrawCircle(options.position, 5.0, paint); // Construct the text blob. @@ -272,7 +272,7 @@ TEST_P(AiksTest, CanRenderEmojiTextFrame) { DisplayListBuilder builder; DlPaint paint; - paint.setColor(DlColor::ARGB(0.1, 0.1, 0.1, 0.1)); + paint.setColor(DlColor::ARGB(1, 0.1, 0.1, 0.1)); builder.DrawPaint(paint); ASSERT_TRUE(RenderTextInCanvasSkia( @@ -347,7 +347,7 @@ TEST_P(AiksTest, CanRenderTextOutsideBoundaries) { SkFont sk_font(font_mgr->makeFromData(mapping), font_size); DlPaint text_paint; - text_paint.setColor(DlColor::kBlue().modulateOpacity(0.8)); + text_paint.setColor(DlColor::kBlue().withAlpha(255 * 0.8)); struct { SkPoint position; From 776dc122837402e4c83a53ac5ea033e5cdc28f2e Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Tue, 6 Aug 2024 15:08:35 -0700 Subject: [PATCH 10/10] dont peephole on clipped bounds. --- impeller/aiks/canvas.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 917df48bd3a82..a1a5704736260 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -815,7 +815,8 @@ void Canvas::SaveLayer(const Paint& paint, uint32_t total_content_depth, bool can_distribute_opacity) { if (can_distribute_opacity && !backdrop_filter && - Paint::CanApplyOpacityPeephole(paint)) { + Paint::CanApplyOpacityPeephole(paint) && + bounds_promise != ContentBoundsPromise::kMayClipContents) { Save(false, total_content_depth, paint.blend_mode, backdrop_filter); transform_stack_.back().distributed_opacity *= paint.color.alpha; return;