Started filtering out close line segments in rrect polylines. (flutter/engine#55929)

fixes https://github.com/flutter/flutter/issues/156422

tests: AiksTest.GradientOvalStrokeMaskBlurSigmaZero

This filtering needs to happen somewheres.  I opted for putting it inside of the AddLinearComponent instead of where it was affected me in the test: 45237cc63f/impeller/geometry/path_builder.cc (L180)

This seems preferable.  A tiny line segment should never matter.  The rub is that its only happening here.  We might want to do this in other places as well.  It's equally unimportant to have a tiny curve.

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
gaaclarke 2024-10-18 14:54:04 -07:00 committed by GitHub
parent cf27a7a314
commit 4ffade7c5b
4 changed files with 62 additions and 4 deletions

View File

@ -1534,5 +1534,50 @@ TEST_P(AiksTest, MassiveScalingMatrixImageFilter) {
ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
}
TEST_P(AiksTest, NoDimplesInRRectPath) {
Scalar width = 200.f;
Scalar height = 60.f;
Scalar corner = 1.f;
auto callback = [&]() -> sk_sp<DisplayList> {
if (AiksTest::ImGuiBegin("Controls", nullptr,
ImGuiWindowFlags_AlwaysAutoResize)) {
ImGui::SliderFloat("width", &width, 0, 200);
ImGui::SliderFloat("height", &height, 0, 200);
ImGui::SliderFloat("corner", &corner, 0, 1);
ImGui::End();
}
DisplayListBuilder builder;
builder.Scale(GetContentScale().x, GetContentScale().y);
DlPaint background_paint;
background_paint.setColor(DlColor(1, 0.1, 0.1, 0.1, DlColorSpace::kSRGB));
builder.DrawPaint(background_paint);
std::vector<DlColor> colors = {DlColor::kRed(), DlColor::kBlue()};
std::vector<Scalar> stops = {0.0, 1.0};
DlPaint paint;
auto gradient = DlColorSource::MakeLinear(
{0, 0}, {200, 200}, 2, colors.data(), stops.data(), DlTileMode::kClamp);
paint.setColorSource(gradient);
paint.setColor(DlColor::kWhite());
paint.setDrawStyle(DlDrawStyle::kStroke);
paint.setStrokeWidth(20);
builder.Save();
builder.Translate(100, 100);
Scalar corner_x = ((1 - corner) * 50) + 50;
Scalar corner_y = corner * 50 + 50;
SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeXYWH(0, 0, width, height),
corner_x, corner_y);
builder.DrawRRect(rrect, paint);
builder.Restore();
return builder.Build();
};
ASSERT_TRUE(OpenPlaygroundHere(callback));
}
} // namespace testing
} // namespace impeller

View File

@ -165,7 +165,7 @@ PathBuilder& PathBuilder::AddRoundedRect(Rect rect, RoundingRadii radii) {
//----------------------------------------------------------------------------
// Top line.
//
AddLinearComponent(
AddLinearComponentIfNeeded(
{rect_origin.x + radii.top_left.x, rect_origin.y},
{rect_origin.x + rect_size.width - radii.top_right.x, rect_origin.y});
@ -177,7 +177,7 @@ PathBuilder& PathBuilder::AddRoundedRect(Rect rect, RoundingRadii radii) {
//----------------------------------------------------------------------------
// Right line.
//
AddLinearComponent(
AddLinearComponentIfNeeded(
{rect_origin.x + rect_size.width, rect_origin.y + radii.top_right.y},
{rect_origin.x + rect_size.width,
rect_origin.y + rect_size.height - radii.bottom_right.y});
@ -190,7 +190,7 @@ PathBuilder& PathBuilder::AddRoundedRect(Rect rect, RoundingRadii radii) {
//----------------------------------------------------------------------------
// Bottom line.
//
AddLinearComponent(
AddLinearComponentIfNeeded(
{rect_origin.x + rect_size.width - radii.bottom_right.x,
rect_origin.y + rect_size.height},
{rect_origin.x + radii.bottom_left.x, rect_origin.y + rect_size.height});
@ -203,7 +203,7 @@ PathBuilder& PathBuilder::AddRoundedRect(Rect rect, RoundingRadii radii) {
//----------------------------------------------------------------------------
// Left line.
//
AddLinearComponent(
AddLinearComponentIfNeeded(
{rect_origin.x, rect_origin.y + rect_size.height - radii.bottom_left.y},
{rect_origin.x, rect_origin.y + radii.top_left.y});
@ -283,6 +283,14 @@ void PathBuilder::AddContourComponent(const Point& destination,
prototype_.bounds.reset();
}
void PathBuilder::AddLinearComponentIfNeeded(const Point& p1, const Point& p2) {
if (ScalarNearlyEqual(p1.x, p2.x, 1e-4f) &&
ScalarNearlyEqual(p1.y, p2.y, 1e-4f)) {
return;
}
AddLinearComponent(p1, p2);
}
void PathBuilder::AddLinearComponent(const Point& p1, const Point& p2) {
auto& points = prototype_.points;
points.push_back(p1);

View File

@ -173,6 +173,8 @@ class PathBuilder {
void AddLinearComponent(const Point& p1, const Point& p2);
void AddLinearComponentIfNeeded(const Point& p1, const Point& p2);
void AddQuadraticComponent(const Point& p1, const Point& cp, const Point& p2);
void AddCubicComponent(const Point& p1,

View File

@ -819,6 +819,9 @@ impeller_Play_AiksTest_MatrixSaveLayerFilter_Vulkan.png
impeller_Play_AiksTest_MipmapGenerationWorksCorrectly_Metal.png
impeller_Play_AiksTest_MipmapGenerationWorksCorrectly_OpenGLES.png
impeller_Play_AiksTest_MipmapGenerationWorksCorrectly_Vulkan.png
impeller_Play_AiksTest_NoDimplesInRRectPath_Metal.png
impeller_Play_AiksTest_NoDimplesInRRectPath_OpenGLES.png
impeller_Play_AiksTest_NoDimplesInRRectPath_Vulkan.png
impeller_Play_AiksTest_PaintBlendModeIsRespected_Metal.png
impeller_Play_AiksTest_PaintBlendModeIsRespected_OpenGLES.png
impeller_Play_AiksTest_PaintBlendModeIsRespected_Vulkan.png