diff --git a/impeller/aiks/canvas.cc b/impeller/aiks/canvas.cc index e8271ca6428c0..d4d3829972fea 100644 --- a/impeller/aiks/canvas.cc +++ b/impeller/aiks/canvas.cc @@ -252,6 +252,7 @@ void Canvas::DrawRRect(Rect rect, Scalar corner_radius, const Paint& paint) { auto path = PathBuilder{} .SetConvexity(Convexity::kConvex) .AddRoundedRect(rect, corner_radius) + .SetBounds(rect) .TakePath(); if (paint.style == Paint::Style::kFill) { Entity entity; @@ -273,10 +274,13 @@ void Canvas::DrawCircle(Point center, Scalar radius, const Paint& paint) { paint)) { return; } - auto circle_path = PathBuilder{} - .AddCircle(center, radius) - .SetConvexity(Convexity::kConvex) - .TakePath(); + auto circle_path = + PathBuilder{} + .AddCircle(center, radius) + .SetConvexity(Convexity::kConvex) + .SetBounds(Rect::MakeLTRB(center.x - radius, center.y - radius, + center.x + radius, center.y + radius)) + .TakePath(); DrawPath(circle_path, paint); } @@ -317,6 +321,7 @@ void Canvas::ClipRRect(const Rect& rect, auto path = PathBuilder{} .SetConvexity(Convexity::kConvex) .AddRoundedRect(rect, corner_radius) + .SetBounds(rect) .TakePath(); std::optional inner_rect = (corner_radius * 2 < rect.size.width && diff --git a/impeller/display_list/dl_unittests.cc b/impeller/display_list/dl_unittests.cc index 896989c34ef3d..c59ca6b01056d 100644 --- a/impeller/display_list/dl_unittests.cc +++ b/impeller/display_list/dl_unittests.cc @@ -21,6 +21,7 @@ #include "impeller/display_list/dl_dispatcher.h" #include "impeller/display_list/dl_image_impeller.h" #include "impeller/display_list/dl_playground.h" +#include "impeller/entity/contents/clip_contents.h" #include "impeller/entity/contents/solid_color_contents.h" #include "impeller/entity/contents/solid_rrect_blur_contents.h" #include "impeller/geometry/constants.h" @@ -1681,6 +1682,65 @@ TEST_P(DisplayListTest, DrawVerticesBlendModes) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } +template +static std::optional GetCoverageOfFirstEntity(const Picture& picture) { + std::optional coverage; + picture.pass->IterateAllEntities([&coverage](Entity& entity) { + if (std::static_pointer_cast(entity.GetContents())) { + auto contents = std::static_pointer_cast(entity.GetContents()); + Entity entity; + coverage = contents->GetCoverage(entity); + return false; + } + return true; + }); + return coverage; +} + +TEST(DisplayListTest, RRectBoundsComputation) { + SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 100, 100), 4, 4); + SkPath path = SkPath().addRRect(rrect); + + flutter::DlPaint paint; + flutter::DisplayListBuilder builder; + + builder.DrawPath(path, paint); + auto display_list = builder.Build(); + + DlDispatcher dispatcher; + display_list->Dispatch(dispatcher); + auto picture = dispatcher.EndRecordingAsPicture(); + + std::optional coverage = + GetCoverageOfFirstEntity(picture); + + // Validate that the RRect coverage is _exactly_ the same as the input rect. + ASSERT_TRUE(coverage.has_value()); + ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()), + Rect::MakeLTRB(0, 0, 100, 100)); +} + +TEST(DisplayListTest, CircleBoundsComputation) { + SkPath path = SkPath().addCircle(0, 0, 5); + + flutter::DlPaint paint; + flutter::DisplayListBuilder builder; + + builder.DrawPath(path, paint); + auto display_list = builder.Build(); + + DlDispatcher dispatcher; + display_list->Dispatch(dispatcher); + auto picture = dispatcher.EndRecordingAsPicture(); + + std::optional coverage = + GetCoverageOfFirstEntity(picture); + + ASSERT_TRUE(coverage.has_value()); + ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()), + Rect::MakeLTRB(-5, -5, 5, 5)); +} + #ifdef IMPELLER_ENABLE_3D TEST_P(DisplayListTest, SceneColorSource) { // Load up the scene.