From 6934bb59aada74f301491fe4a7d8325bd2688543 Mon Sep 17 00:00:00 2001 From: Jonah Williams Date: Mon, 1 Jul 2024 12:36:58 -0700 Subject: [PATCH] [Impeller][CP] dont segfault when tessellating empty polygons. (#53212) While this is fixed on ToT, the stable channel is far behind so cherry picking all the tessellation changes is infeasible. Instead, we can land a small fix to avoid the segfault. Atttached unit test crashes without patch. Fixes https://github.com/flutter/flutter/issues/149646 Fixes https://github.com/flutter/flutter/issues/149309 --- impeller/tessellator/tessellator.cc | 29 ++++++++++--------- impeller/tessellator/tessellator_unittests.cc | 11 +++++++ 2 files changed, 26 insertions(+), 14 deletions(-) diff --git a/impeller/tessellator/tessellator.cc b/impeller/tessellator/tessellator.cc index afbf01da90f83..11dbb2882609d 100644 --- a/impeller/tessellator/tessellator.cc +++ b/impeller/tessellator/tessellator.cc @@ -197,7 +197,6 @@ std::vector Tessellator::TessellateConvex(const Path& path, for (auto j = 0u; j < polyline.contours.size(); j++) { auto [start, end] = polyline.GetContourPointBounds(j); auto first_point = polyline.GetPoint(start); - // Some polygons will not self close and an additional triangle // must be inserted, others will self close and we need to avoid // inserting an extra triangle. @@ -221,19 +220,21 @@ std::vector Tessellator::TessellateConvex(const Path& path, output.emplace_back(first_point); } - size_t a = start + 1; - size_t b = end - 1; - while (a < b) { - output.emplace_back(polyline.GetPoint(a)); - output.emplace_back(polyline.GetPoint(b)); - a++; - b--; - } - if (a == b) { - previous_contour_odd_points = false; - output.emplace_back(polyline.GetPoint(a)); - } else { - previous_contour_odd_points = true; + if (start != end) { + size_t a = start + 1; + size_t b = end - 1; + while (a < b) { + output.emplace_back(polyline.GetPoint(a)); + output.emplace_back(polyline.GetPoint(b)); + a++; + b--; + } + if (a == b) { + previous_contour_odd_points = false; + output.emplace_back(polyline.GetPoint(a)); + } else { + previous_contour_odd_points = true; + } } } return output; diff --git a/impeller/tessellator/tessellator_unittests.cc b/impeller/tessellator/tessellator_unittests.cc index fcc2849571571..70b1674295267 100644 --- a/impeller/tessellator/tessellator_unittests.cc +++ b/impeller/tessellator/tessellator_unittests.cc @@ -128,6 +128,17 @@ TEST(TessellatorTest, TessellateConvex) { {20, 30}, {30, 30}}; EXPECT_EQ(pts, expected); } + + { + Tessellator t; + PathBuilder builder{}; + auto path = builder.MoveTo({10, 10}) + .Close() + .AddRect(Rect::MakeLTRB(0, 0, 100, 100)) + .TakePath(); + // Verify no crash. + t.TessellateConvex(path, 1.0); + } } TEST(TessellatorTest, CircleVertexCounts) {