From afccbe9355b6563572272b157c06835def28d9c3 Mon Sep 17 00:00:00 2001 From: Jim Graham Date: Wed, 8 Nov 2023 12:46:50 -0800 Subject: [PATCH] Revert "Reverts "[Impeller] add support for Skia concept of RRect::isSimple needed for DL dispatching" (#47821)" This reverts commit 21f055f7d8d07f723621ff76fb973cb772ea4f1b. --- impeller/aiks/aiks_unittests.cc | 14 ++--- impeller/aiks/canvas.cc | 27 +++++----- impeller/aiks/canvas.h | 4 +- impeller/aiks/canvas_recorder.h | 8 +-- impeller/aiks/canvas_recorder_unittests.cc | 4 +- impeller/aiks/canvas_unittests.cc | 16 +++--- impeller/display_list/dl_dispatcher.cc | 44 ++++++++------- impeller/display_list/dl_dispatcher.h | 4 ++ impeller/display_list/dl_unittests.cc | 62 ++++++++++++++++++++++ impeller/geometry/path_builder.cc | 8 ++- impeller/geometry/path_builder.h | 14 +++++ 11 files changed, 143 insertions(+), 62 deletions(-) diff --git a/impeller/aiks/aiks_unittests.cc b/impeller/aiks/aiks_unittests.cc index 3191257a14d44..3b34d94ce911e 100644 --- a/impeller/aiks/aiks_unittests.cc +++ b/impeller/aiks/aiks_unittests.cc @@ -2407,9 +2407,9 @@ TEST_P(AiksTest, DrawRectAbsorbsClears) { TEST_P(AiksTest, DrawRectAbsorbsClearsNegativeRRect) { Canvas canvas; - canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), 5.0, + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0}, {.color = Color::Red(), .blend_mode = BlendMode::kSource}); - canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), 5.0, + canvas.DrawRRect(Rect::MakeXYWH(0, 0, 300, 300), {5.0, 5.0}, {.color = Color::CornflowerBlue().WithAlpha(0.75), .blend_mode = BlendMode::kSourceOver}); @@ -3077,7 +3077,7 @@ TEST_P(AiksTest, CanRenderBackdropBlurInteractive) { canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()}); canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()}); canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()}); - canvas.ClipRRect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), 20); + canvas.ClipRRect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), {20, 20}); canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt, ImageFilter::MakeBlur(Sigma(20.0), Sigma(20.0), FilterContents::BlurStyle::kNormal, @@ -3096,7 +3096,7 @@ TEST_P(AiksTest, CanRenderBackdropBlur) { canvas.DrawCircle({300, 200}, 100, {.color = Color::GreenYellow()}); canvas.DrawCircle({140, 170}, 75, {.color = Color::DarkMagenta()}); canvas.DrawCircle({180, 120}, 100, {.color = Color::OrangeRed()}); - canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), 20); + canvas.ClipRRect(Rect::MakeLTRB(75, 50, 375, 275), {20, 20}); canvas.SaveLayer({.blend_mode = BlendMode::kSource}, std::nullopt, ImageFilter::MakeBlur(Sigma(30.0), Sigma(30.0), FilterContents::BlurStyle::kNormal, @@ -3202,7 +3202,7 @@ TEST_P(AiksTest, CanRenderClippedRuntimeEffects) { Canvas canvas; canvas.Save(); - canvas.ClipRRect(Rect::MakeXYWH(0, 0, 400, 400), 10.0, + canvas.ClipRRect(Rect::MakeXYWH(0, 0, 400, 400), {10.0, 10.0}, Entity::ClipOperation::kIntersect); canvas.DrawRect(Rect::MakeXYWH(0, 0, 400, 400), paint); canvas.Restore(); @@ -3480,7 +3480,7 @@ TEST_P(AiksTest, DrawPictureWithText) { TEST_P(AiksTest, DrawPictureClipped) { Canvas subcanvas; - subcanvas.ClipRRect(Rect::MakeLTRB(100, 100, 400, 400), 15); + subcanvas.ClipRRect(Rect::MakeLTRB(100, 100, 400, 400), {15, 15}); subcanvas.DrawPaint({.color = Color::Red()}); auto picture = subcanvas.EndRecordingAsPicture(); @@ -3492,7 +3492,7 @@ TEST_P(AiksTest, DrawPictureClipped) { // Draw over the picture with a larger green rectangle, completely covering it // up. - canvas.ClipRRect(Rect::MakeLTRB(100, 100, 400, 400).Expand(20), 15); + canvas.ClipRRect(Rect::MakeLTRB(100, 100, 400, 400).Expand(20), {15, 15}); canvas.DrawPaint({.color = Color::Green()}); ASSERT_TRUE(OpenPlaygroundHere(canvas.EndRecordingAsPicture())); diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index 04852db4071e2..a0823f912de98 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -246,13 +246,14 @@ void Canvas::DrawRect(Rect rect, const Paint& paint) { GetCurrentPass().AddEntity(entity); } -void Canvas::DrawRRect(Rect rect, Scalar corner_radius, const Paint& paint) { - if (AttemptDrawBlurredRRect(rect, corner_radius, paint)) { +void Canvas::DrawRRect(Rect rect, Point corner_radii, const Paint& paint) { + if (corner_radii.x == corner_radii.y && + AttemptDrawBlurredRRect(rect, corner_radii.x, paint)) { return; } auto path = PathBuilder{} .SetConvexity(Convexity::kConvex) - .AddRoundedRect(rect, corner_radius) + .AddRoundedRect(rect, corner_radii) .SetBounds(rect) .TakePath(); if (paint.style == Paint::Style::kFill) { @@ -318,20 +319,20 @@ void Canvas::ClipRect(const Rect& rect, Entity::ClipOperation clip_op) { } void Canvas::ClipRRect(const Rect& rect, - Scalar corner_radius, + Point corner_radii, Entity::ClipOperation clip_op) { auto path = PathBuilder{} .SetConvexity(Convexity::kConvex) - .AddRoundedRect(rect, corner_radius) + .AddRoundedRect(rect, corner_radii) .SetBounds(rect) .TakePath(); auto size = rect.GetSize(); // Does the rounded rect have a flat part on the top/bottom or left/right? - bool flat_on_TB = corner_radius * 2 < size.width; - bool flat_on_LR = corner_radius * 2 < size.height; + bool flat_on_TB = corner_radii.x * 2 < size.width; + bool flat_on_LR = corner_radii.y * 2 < size.height; std::optional inner_rect = (flat_on_LR && flat_on_TB) - ? rect.Expand(-corner_radius) + ? rect.Expand(-corner_radii) : std::make_optional(); auto geometry = Geometry::MakeFillPath(path, inner_rect); auto& cull_rect = xformation_stack_.back().cull_rect; @@ -348,7 +349,7 @@ void Canvas::ClipRRect(const Rect& rect, IntersectCulling(rect); break; case Entity::ClipOperation::kDifference: - if (corner_radius <= 0) { + if (corner_radii.x <= 0.0 || corner_radii.y <= 0) { SubtractCulling(rect); } else { // We subtract the inner "tall" and "wide" rectangle pieces @@ -357,14 +358,10 @@ void Canvas::ClipRRect(const Rect& rect, // Since this is a subtract operation, we can subtract each // rectangle piece individually without fear of interference. if (flat_on_TB) { - SubtractCulling(Rect::MakeLTRB( - rect.GetLeft() + corner_radius, rect.GetTop(), - rect.GetRight() - corner_radius, rect.GetBottom())); + SubtractCulling(rect.Expand({-corner_radii.x, 0.0})); } if (flat_on_LR) { - SubtractCulling(Rect::MakeLTRB( - rect.GetLeft(), rect.GetTop() + corner_radius, // - rect.GetRight(), rect.GetBottom() - corner_radius)); + SubtractCulling(rect.Expand({0.0, -corner_radii.y})); } } break; diff --git a/impeller/aiks/canvas.h b/impeller/aiks/canvas.h index 285b7e4f122b8..61b1be4cc4a7c 100644 --- a/impeller/aiks/canvas.h +++ b/impeller/aiks/canvas.h @@ -105,7 +105,7 @@ class Canvas { void DrawRect(Rect rect, const Paint& paint); - void DrawRRect(Rect rect, Scalar corner_radius, const Paint& paint); + void DrawRRect(Rect rect, Point corner_radii, const Paint& paint); void DrawCircle(Point center, Scalar radius, const Paint& paint); @@ -135,7 +135,7 @@ class Canvas { void ClipRRect( const Rect& rect, - Scalar corner_radius, + Point corner_radii, Entity::ClipOperation clip_op = Entity::ClipOperation::kIntersect); void DrawPicture(const Picture& picture); diff --git a/impeller/aiks/canvas_recorder.h b/impeller/aiks/canvas_recorder.h index 62711c13fcc92..360f39fa39878 100644 --- a/impeller/aiks/canvas_recorder.h +++ b/impeller/aiks/canvas_recorder.h @@ -182,9 +182,9 @@ class CanvasRecorder { paint); } - void DrawRRect(Rect rect, Scalar corner_radius, const Paint& paint) { + void DrawRRect(Rect rect, Point corner_radii, const Paint& paint) { return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(DrawRRect), rect, - corner_radius, paint); + corner_radii, paint); } void DrawCircle(Point center, Scalar radius, const Paint& paint) { @@ -233,10 +233,10 @@ class CanvasRecorder { void ClipRRect( const Rect& rect, - Scalar corner_radius, + Point corner_radii, Entity::ClipOperation clip_op = Entity::ClipOperation::kIntersect) { return ExecuteAndSerialize(FLT_CANVAS_RECORDER_OP_ARG(ClipRRect), rect, - corner_radius, clip_op); + corner_radii, clip_op); } void DrawPicture(const Picture& picture) { diff --git a/impeller/aiks/canvas_recorder_unittests.cc b/impeller/aiks/canvas_recorder_unittests.cc index 041fc185dac23..fe2e457f88d7c 100644 --- a/impeller/aiks/canvas_recorder_unittests.cc +++ b/impeller/aiks/canvas_recorder_unittests.cc @@ -160,7 +160,7 @@ TEST(CanvasRecorder, DrawRect) { TEST(CanvasRecorder, DrawRRect) { CanvasRecorder recorder; - recorder.DrawRRect(Rect(), 0, Paint()); + recorder.DrawRRect(Rect(), {}, Paint()); ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::DrawRRect); } @@ -202,7 +202,7 @@ TEST(CanvasRecorder, ClipRect) { TEST(CanvasRecorder, ClipRRect) { CanvasRecorder recorder; - recorder.ClipRRect({}, 0); + recorder.ClipRRect({}, {}); ASSERT_EQ(recorder.GetSerializer().last_op_, CanvasRecorderOp::ClipRRect); } diff --git a/impeller/aiks/canvas_unittests.cc b/impeller/aiks/canvas_unittests.cc index 1f65bec590e06..30be8f4e0f228 100644 --- a/impeller/aiks/canvas_unittests.cc +++ b/impeller/aiks/canvas_unittests.cc @@ -170,7 +170,7 @@ TEST(AiksCanvasTest, RRectClipIntersectAgainstEmptyCullRect) { Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10); Canvas canvas; - canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kIntersect); + canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kIntersect); ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value()); ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), rect_clip); @@ -180,7 +180,7 @@ TEST(AiksCanvasTest, RRectClipDiffAgainstEmptyCullRect) { Rect rect_clip = Rect::MakeXYWH(5, 5, 10, 10); Canvas canvas; - canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference); + canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference); ASSERT_FALSE(canvas.GetCurrentLocalCullingBounds().has_value()); } @@ -191,7 +191,7 @@ TEST(AiksCanvasTest, RRectClipIntersectAgainstCullRect) { Rect result_cull = Rect::MakeXYWH(5, 5, 5, 5); Canvas canvas(initial_cull); - canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kIntersect); + canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kIntersect); ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value()); ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull); @@ -203,7 +203,7 @@ TEST(AiksCanvasTest, RRectClipDiffAgainstNonCoveredCullRect) { Rect result_cull = Rect::MakeXYWH(0, 0, 10, 10); Canvas canvas(initial_cull); - canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference); + canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference); ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value()); ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull); @@ -215,7 +215,7 @@ TEST(AiksCanvasTest, RRectClipDiffAgainstVPartiallyCoveredCullRect) { Rect result_cull = Rect::MakeXYWH(0, 0, 6, 10); Canvas canvas(initial_cull); - canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference); + canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference); ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value()); ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull); @@ -227,7 +227,7 @@ TEST(AiksCanvasTest, RRectClipDiffAgainstVFullyCoveredCullRect) { Rect result_cull = Rect::MakeXYWH(0, 0, 5, 10); Canvas canvas(initial_cull); - canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference); + canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference); ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value()); ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull); @@ -239,7 +239,7 @@ TEST(AiksCanvasTest, RRectClipDiffAgainstHPartiallyCoveredCullRect) { Rect result_cull = Rect::MakeXYWH(0, 0, 10, 6); Canvas canvas(initial_cull); - canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference); + canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference); ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value()); ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull); @@ -251,7 +251,7 @@ TEST(AiksCanvasTest, RRectClipDiffAgainstHFullyCoveredCullRect) { Rect result_cull = Rect::MakeXYWH(0, 0, 10, 5); Canvas canvas(initial_cull); - canvas.ClipRRect(rect_clip, 1, Entity::ClipOperation::kDifference); + canvas.ClipRRect(rect_clip, {1, 1}, Entity::ClipOperation::kDifference); ASSERT_TRUE(canvas.GetCurrentLocalCullingBounds().has_value()); ASSERT_EQ(canvas.GetCurrentLocalCullingBounds().value(), result_cull); diff --git a/impeller/display_list/dl_dispatcher.cc b/impeller/display_list/dl_dispatcher.cc index cbc4ee6ff5461..2b3e02f513515 100644 --- a/impeller/display_list/dl_dispatcher.cc +++ b/impeller/display_list/dl_dispatcher.cc @@ -726,9 +726,13 @@ void DlDispatcher::clipRect(const SkRect& rect, ClipOp clip_op, bool is_aa) { // |flutter::DlOpReceiver| void DlDispatcher::clipRRect(const SkRRect& rrect, ClipOp clip_op, bool is_aa) { - if (rrect.isSimple()) { + if (rrect.isRect()) { + canvas_.ClipRect(skia_conversions::ToRect(rrect.rect()), + ToClipOperation(clip_op)); + } else if (rrect.isSimple()) { canvas_.ClipRRect(skia_conversions::ToRect(rrect.rect()), - rrect.getSimpleRadii().fX, ToClipOperation(clip_op)); + skia_conversions::ToPoint(rrect.getSimpleRadii()), + ToClipOperation(clip_op)); } else { canvas_.ClipPath(skia_conversions::ToPath(rrect), ToClipOperation(clip_op)); } @@ -793,7 +797,8 @@ void DlDispatcher::drawCircle(const SkPoint& center, SkScalar radius) { void DlDispatcher::drawRRect(const SkRRect& rrect) { if (rrect.isSimple()) { canvas_.DrawRRect(skia_conversions::ToRect(rrect.rect()), - rrect.getSimpleRadii().fX, paint_); + skia_conversions::ToPoint(rrect.getSimpleRadii()), + paint_); } else { canvas_.DrawPath(skia_conversions::ToPath(rrect), paint_); } @@ -809,30 +814,36 @@ void DlDispatcher::drawDRRect(const SkRRect& outer, const SkRRect& inner) { // |flutter::DlOpReceiver| void DlDispatcher::drawPath(const SkPath& path) { + SimplifyOrDrawPath(canvas_, path, paint_); +} + +void DlDispatcher::SimplifyOrDrawPath(CanvasType& canvas, + const SkPath& path, + const Paint& paint) { SkRect rect; // We can't "optimize" a path into a rectangle if it's open. bool closed; if (path.isRect(&rect, &closed) && closed) { - canvas_.DrawRect(skia_conversions::ToRect(rect), paint_); + canvas.DrawRect(skia_conversions::ToRect(rect), paint); return; } SkRRect rrect; if (path.isRRect(&rrect) && rrect.isSimple()) { - canvas_.DrawRRect(skia_conversions::ToRect(rrect.rect()), - rrect.getSimpleRadii().fX, paint_); + canvas.DrawRRect(skia_conversions::ToRect(rrect.rect()), + skia_conversions::ToPoint(rrect.getSimpleRadii()), paint); return; } SkRect oval; if (path.isOval(&oval) && oval.width() == oval.height()) { - canvas_.DrawCircle(skia_conversions::ToPoint(oval.center()), - oval.width() * 0.5, paint_); + canvas.DrawCircle(skia_conversions::ToPoint(oval.center()), + oval.width() * 0.5, paint); return; } - canvas_.DrawPath(skia_conversions::ToPath(path), paint_); + canvas.DrawPath(skia_conversions::ToPath(path), paint); } // |flutter::DlOpReceiver| @@ -1100,20 +1111,7 @@ void DlDispatcher::drawShadow(const SkPath& path, canvas_.PreConcat( Matrix::MakeTranslation(Vector2(0, -occluder_z * light_position.y))); - SkRect rect; - SkRRect rrect; - SkRect oval; - if (path.isRect(&rect)) { - canvas_.DrawRect(skia_conversions::ToRect(rect), paint); - } else if (path.isRRect(&rrect) && rrect.isSimple()) { - canvas_.DrawRRect(skia_conversions::ToRect(rrect.rect()), - rrect.getSimpleRadii().fX, paint); - } else if (path.isOval(&oval) && oval.width() == oval.height()) { - canvas_.DrawCircle(skia_conversions::ToPoint(oval.center()), - oval.width() * 0.5, paint); - } else { - canvas_.DrawPath(skia_conversions::ToPath(path), paint); - } + SimplifyOrDrawPath(canvas_, path, paint); canvas_.Restore(); } diff --git a/impeller/display_list/dl_dispatcher.h b/impeller/display_list/dl_dispatcher.h index 05d40cdbe407b..9e604dd4acf54 100644 --- a/impeller/display_list/dl_dispatcher.h +++ b/impeller/display_list/dl_dispatcher.h @@ -226,6 +226,10 @@ class DlDispatcher final : public flutter::DlOpReceiver { CanvasType canvas_; Matrix initial_matrix_; + static void SimplifyOrDrawPath(CanvasType& canvas, + const SkPath& path, + const Paint& paint); + DlDispatcher(const DlDispatcher&) = delete; DlDispatcher& operator=(const DlDispatcher&) = delete; diff --git a/impeller/display_list/dl_unittests.cc b/impeller/display_list/dl_unittests.cc index 9e0456d50db5d..17e7aca95a8c3 100644 --- a/impeller/display_list/dl_unittests.cc +++ b/impeller/display_list/dl_unittests.cc @@ -1591,6 +1591,68 @@ TEST_P(DisplayListTest, DrawShapes) { ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); } +TEST_P(DisplayListTest, ClipDrawRRectWithNonCircularRadii) { + flutter::DisplayListBuilder builder; + + flutter::DlPaint fill_paint = // + flutter::DlPaint() // + .setColor(flutter::DlColor::kBlue()) // + .setDrawStyle(flutter::DlDrawStyle::kFill) // + .setStrokeWidth(10); + flutter::DlPaint stroke_paint = // + flutter::DlPaint() // + .setColor(flutter::DlColor::kGreen()) // + .setDrawStyle(flutter::DlDrawStyle::kStroke) // + .setStrokeWidth(10); + + builder.DrawRRect( + SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40), + fill_paint); + builder.DrawRRect( + SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 100, 300, 300), 120, 40), + stroke_paint); + + builder.DrawRRect( + SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120), + fill_paint); + builder.DrawRRect( + SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 500, 300, 300), 40, 120), + stroke_paint); + + flutter::DlPaint reference_paint = // + flutter::DlPaint() // + .setColor(flutter::DlColor::kMidGrey()) // + .setDrawStyle(flutter::DlDrawStyle::kFill) // + .setStrokeWidth(10); + + builder.DrawRRect( + SkRRect::MakeRectXY(SkRect::MakeXYWH(500, 500, 300, 300), 40, 40), + reference_paint); + builder.DrawRRect( + SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 100, 300, 300), 120, 120), + reference_paint); + + flutter::DlPaint clip_fill_paint = // + flutter::DlPaint() // + .setColor(flutter::DlColor::kCyan()) // + .setDrawStyle(flutter::DlDrawStyle::kFill) // + .setStrokeWidth(10); + + builder.Save(); + builder.ClipRRect( + SkRRect::MakeRectXY(SkRect::MakeXYWH(900, 100, 300, 300), 120, 40)); + builder.DrawPaint(clip_fill_paint); + builder.Restore(); + + builder.Save(); + builder.ClipRRect( + SkRRect::MakeRectXY(SkRect::MakeXYWH(100, 900, 300, 300), 40, 120)); + builder.DrawPaint(clip_fill_paint); + builder.Restore(); + + ASSERT_TRUE(OpenPlaygroundHere(builder.Build())); +} + TEST_P(DisplayListTest, DrawVerticesBlendModes) { std::vector blend_mode_names; std::vector blend_mode_values; diff --git a/impeller/geometry/path_builder.cc b/impeller/geometry/path_builder.cc index 9495cb5328c5a..bad11f13f4458 100644 --- a/impeller/geometry/path_builder.cc +++ b/impeller/geometry/path_builder.cc @@ -201,7 +201,13 @@ PathBuilder& PathBuilder::AddCircle(const Point& c, Scalar r) { PathBuilder& PathBuilder::AddRoundedRect(Rect rect, Scalar radius) { return radius <= 0.0 ? AddRect(rect) - : AddRoundedRect(rect, {radius, radius, radius, radius}); + : AddRoundedRect(rect, RoundingRadii(radius)); +} + +PathBuilder& PathBuilder::AddRoundedRect(Rect rect, Point radii) { + return radii.x <= 0 || radii.y <= 0 + ? AddRect(rect) + : AddRoundedRect(rect, RoundingRadii(radii)); } PathBuilder& PathBuilder::AddRoundedRect(Rect rect, RoundingRadii radii) { diff --git a/impeller/geometry/path_builder.h b/impeller/geometry/path_builder.h index 342f0912aca46..fc72a502a876f 100644 --- a/impeller/geometry/path_builder.h +++ b/impeller/geometry/path_builder.h @@ -122,6 +122,18 @@ class PathBuilder { top_right(p_top_right, p_top_right), bottom_right(p_bottom_right, p_bottom_right) {} + explicit RoundingRadii(Scalar radius) + : top_left(radius, radius), + bottom_left(radius, radius), + top_right(radius, radius), + bottom_right(radius, radius) {} + + explicit RoundingRadii(Point radii) + : top_left(radii), + bottom_left(radii), + top_right(radii), + bottom_right(radii) {} + bool AreAllZero() const { return top_left.IsZero() && // bottom_left.IsZero() && // @@ -132,6 +144,8 @@ class PathBuilder { PathBuilder& AddRoundedRect(Rect rect, RoundingRadii radii); + PathBuilder& AddRoundedRect(Rect rect, Point radii); + PathBuilder& AddRoundedRect(Rect rect, Scalar radius); PathBuilder& AddPath(const Path& path);