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.
## 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