Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 32ecd77

Browse files
authored
[Impeller] Fix convex triangulation winding bug for multi-contour paths. (#51198)
An extra triangle needs to be inserted after bridging the triangle strip to a new contour, otherwise the triangle winding ends up getting inverted for each consecutive contour. Before: <img width="685" alt="image" src="https://github.com/flutter/engine/assets/919017/cef666c1-c188-4c83-ae93-fca117b0bc7f"> After: <img width="685" alt="image" src="https://github.com/flutter/engine/assets/919017/0cf5e994-5366-4e73-8f9c-4fec1128b303">
1 parent fd0ac09 commit 32ecd77

File tree

4 files changed

+38
-2
lines changed

4 files changed

+38
-2
lines changed

impeller/aiks/aiks_path_unittests.cc

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -398,5 +398,37 @@ TEST_P(AiksTest, CanRenderClips) {
398398
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
399399
}
400400

401+
TEST_P(AiksTest, CanRenderOverlappingMultiContourPath) {
402+
Canvas canvas;
403+
404+
Paint paint;
405+
paint.color = Color::Red();
406+
407+
PathBuilder::RoundingRadii radii;
408+
radii.top_left = {50, 50};
409+
radii.top_right = {50, 50};
410+
radii.bottom_right = {50, 50};
411+
radii.bottom_left = {50, 50};
412+
413+
const Scalar kTriangleHeight = 100;
414+
canvas.Translate(Vector2(200, 200));
415+
// Form a path similar to the Material drop slider value indicator.
416+
auto path =
417+
PathBuilder{}
418+
.MoveTo({0, kTriangleHeight})
419+
.LineTo({-kTriangleHeight / 2.0f, 0})
420+
.LineTo({kTriangleHeight / 2.0f, 0})
421+
.Close()
422+
.AddRoundedRect(
423+
Rect::MakeXYWH(-kTriangleHeight / 2.0f, -kTriangleHeight / 2.0f,
424+
kTriangleHeight, kTriangleHeight),
425+
radii)
426+
.TakePath();
427+
428+
canvas.DrawPath(path, paint);
429+
430+
ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture()));
431+
}
432+
401433
} // namespace testing
402434
} // namespace impeller

impeller/tessellator/tessellator.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ std::vector<Point> Tessellator::TessellateConvex(const Path& path,
205205
output.emplace_back(output.back());
206206
output.emplace_back(first_point);
207207
output.emplace_back(first_point);
208+
output.emplace_back(first_point);
208209
} else {
209210
output.emplace_back(first_point);
210211
}

impeller/tessellator/tessellator_unittests.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,8 +126,8 @@ TEST(TessellatorTest, TessellateConvex) {
126126
1.0);
127127

128128
std::vector<Point> expected = {{0, 0}, {10, 0}, {0, 10}, {10, 10},
129-
{10, 10}, {20, 20}, {20, 20}, {30, 20},
130-
{20, 30}, {30, 30}};
129+
{10, 10}, {20, 20}, {20, 20}, {20, 20},
130+
{30, 20}, {20, 30}, {30, 30}};
131131
EXPECT_EQ(pts, expected);
132132
}
133133
}

testing/impeller_golden_tests_output.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,9 @@ impeller_Play_AiksTest_CanRenderNestedClips_Vulkan.png
284284
impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_Metal.png
285285
impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_OpenGLES.png
286286
impeller_Play_AiksTest_CanRenderOffscreenCheckerboard_Vulkan.png
287+
impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_Metal.png
288+
impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_OpenGLES.png
289+
impeller_Play_AiksTest_CanRenderOverlappingMultiContourPath_Vulkan.png
287290
impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Metal.png
288291
impeller_Play_AiksTest_CanRenderRadialGradientManyColors_OpenGLES.png
289292
impeller_Play_AiksTest_CanRenderRadialGradientManyColors_Vulkan.png

0 commit comments

Comments
 (0)