From 31ed3b7b83b48420feb496601ff0b69f20f8c529 Mon Sep 17 00:00:00 2001 From: gaaclarke <30870216+gaaclarke@users.noreply.github.com> Date: Thu, 27 Mar 2025 08:23:26 -0700 Subject: [PATCH] Scale aa lines (#165917) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fixes https://github.com/flutter/flutter/issues/165905 Notice that the horizontal lines both have about 1 pixel of blurring for both scales. Screenshot 2025-03-25 at 1 09 16 PM ## Pre-launch Checklist - [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs. - [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities. - [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement]. - [x] I signed the [CLA]. - [x] I listed at least one issue that this PR fixes in the description above. - [x] I updated/added relevant documentation (doc comments with `///`). - [x] I added new tests to check the change I am making, or this PR is [test-exempt]. - [x] I followed the [breaking change policy] and added [Data Driven Fixes] where supported. - [x] All existing and new tests are passing. If you need help, consider asking for advice on the #hackers-new channel on [Discord]. [Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview [Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md [test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests [Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md [Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement [CLA]: https://cla.developers.google.com/ [flutter/tests]: https://github.com/flutter/tests [breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes [Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md [Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md --- .../display_list/aiks_dl_path_unittests.cc | 35 +++++++++++++++++++ .../impeller/entity/contents/line_contents.cc | 15 ++++---- .../testing/impeller_golden_tests_output.txt | 1 + 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc b/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc index 0f4729c7ea..dc0ee7de24 100644 --- a/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc +++ b/engine/src/flutter/impeller/display_list/aiks_dl_path_unittests.cc @@ -382,6 +382,41 @@ TEST_P(AiksTest, DrawLinesRenderCorrectly) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +// The goal of this test is to show that scaling the lines doesn't also scale +// the antialiasing. The amount of blurring should be the same for both +// horizontal lines. +TEST_P(AiksTest, ScaleExperimentAntialiasLines) { + Scalar scale = 5.0; + Scalar line_width = 10.f; + auto callback = [&]() -> sk_sp { + if (AiksTest::ImGuiBegin("Controls", nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) { + ImGui::SliderFloat("Scale", &scale, 0.001, 5); + ImGui::SliderFloat("Width", &line_width, 1, 20); + + ImGui::End(); + } + DisplayListBuilder builder; + builder.Scale(GetContentScale().x, GetContentScale().y); + + DlPaint paint; + paint.setColor(DlColor::kGreenYellow()); + paint.setStrokeWidth(line_width); + + builder.DrawLine(DlPoint(100, 100), DlPoint(350, 100), paint); + builder.DrawLine(DlPoint(100, 100), DlPoint(350, 150), paint); + + builder.Translate(100, 300); + builder.Scale(scale, scale); + builder.Translate(-100, -300); + builder.DrawLine(DlPoint(100, 300), DlPoint(350, 300), paint); + builder.DrawLine(DlPoint(100, 300), DlPoint(350, 450), paint); + + return builder.Build(); + }; + ASSERT_TRUE(OpenPlaygroundHere(callback)); +} + TEST_P(AiksTest, SimpleExperimentAntialiasLines) { DisplayListBuilder builder; builder.Scale(GetContentScale().x, GetContentScale().y); diff --git a/engine/src/flutter/impeller/entity/contents/line_contents.cc b/engine/src/flutter/impeller/entity/contents/line_contents.cc index 4c20026c41..2c74dabd17 100644 --- a/engine/src/flutter/impeller/entity/contents/line_contents.cc +++ b/engine/src/flutter/impeller/entity/contents/line_contents.cc @@ -24,7 +24,7 @@ using CreateGeometryCallback = const Geometry* geometry)>; const int32_t kCurveResolution = 32; -const Scalar kSampleRadius = 0.5f; +const float kSampleRadius = 1.f; struct LineInfo { Vector3 e0; @@ -62,6 +62,8 @@ uint8_t DoubleToUint8(double x) { /// See also: CreateGradientTexture std::shared_ptr CreateCurveTexture( Scalar width, + Scalar radius, + Scalar scale, const std::shared_ptr& context) { // impeller::TextureDescriptor texture_descriptor; @@ -73,8 +75,8 @@ std::shared_ptr CreateCurveTexture( curve_data.reserve(kCurveResolution); for (int i = 0; i < kCurveResolution; ++i) { double norm = (static_cast(i) + 1.0) / 32.0; - double loc = norm * (kSampleRadius + width / 2.0); - double den = kSampleRadius * 2.0 + 1.0; + double loc = scale * norm * (radius + width / 2.0); + double den = radius * 2.0 + 1.0; curve_data.push_back(DoubleToUint8(loc / den)); } @@ -96,13 +98,14 @@ GeometryResult CreateGeometry(const ContentContext& renderer, corners, transform, /*extend_endpoints=*/line_geometry->GetCap() != Cap::kButt, line_geometry->GetP0(), line_geometry->GetP1(), - line_geometry->GetWidth() + kSampleRadius)) { + line_geometry->GetWidth() + kSampleRadius * 2.0)) { return kEmptyResult; } auto& host_buffer = renderer.GetTransientsBuffer(); size_t count = 4; + Scalar scale = entity.GetTransform().GetMaxBasisLengthXY(); LineInfo line_info = CalculateLineInfo(line_geometry->GetP0(), line_geometry->GetP1(), line_geometry->GetWidth(), kSampleRadius); @@ -121,8 +124,8 @@ GeometryResult CreateGeometry(const ContentContext& renderer, } }); - std::shared_ptr curve_texture = - CreateCurveTexture(line_geometry->GetWidth(), renderer.GetContext()); + std::shared_ptr curve_texture = CreateCurveTexture( + line_geometry->GetWidth(), kSampleRadius, scale, renderer.GetContext()); SamplerDescriptor sampler_desc; sampler_desc.min_filter = MinMagFilter::kLinear; diff --git a/engine/src/flutter/testing/impeller_golden_tests_output.txt b/engine/src/flutter/testing/impeller_golden_tests_output.txt index 8d3f2b1b07..1a54e9d1f6 100644 --- a/engine/src/flutter/testing/impeller_golden_tests_output.txt +++ b/engine/src/flutter/testing/impeller_golden_tests_output.txt @@ -886,6 +886,7 @@ impeller_Play_AiksTest_SaveLayerDrawsBehindSubsequentEntities_Vulkan.png impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_Metal.png impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_OpenGLES.png impeller_Play_AiksTest_SaveLayerFiltersScaleWithTransform_Vulkan.png +impeller_Play_AiksTest_ScaleExperimentAntialiasLines_Metal.png impeller_Play_AiksTest_ScaledK_Metal.png impeller_Play_AiksTest_ScaledK_OpenGLES.png impeller_Play_AiksTest_ScaledK_Vulkan.png