From a144fe21bc9917c60f56c65ee14980302dba3583 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 6 Oct 2023 10:59:59 -0700 Subject: [PATCH 1/3] [Impeller] Ensure known geometry has simple bounds computation. --- impeller/aiks/canvas.cc | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) 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 && From 9ebd781c273fb9dcf53f293f1895643c35b60579 Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 6 Oct 2023 11:43:49 -0700 Subject: [PATCH 2/3] Add unittest. --- impeller/display_list/dl_unittests.cc | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/impeller/display_list/dl_unittests.cc b/impeller/display_list/dl_unittests.cc index 896989c34ef3d..02da90244adbd 100644 --- a/impeller/display_list/dl_unittests.cc +++ b/impeller/display_list/dl_unittests.cc @@ -1681,6 +1681,41 @@ TEST_P(DisplayListTest, DrawVerticesBlendModes) { ASSERT_TRUE(OpenPlaygroundHere(callback)); } +TEST(DisplayListTest, RRectBoundsComputation) { + SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 100, 100), 4, 4); + SkPath path = SkPath().addRRect(rrect); + + flutter::DlPaint paint; + paint.setColor(flutter::DlColor::kRed()); + flutter::DisplayListBuilder builder; + + builder.DrawPath(path, paint); + auto display_list = builder.Build(); + + DlDispatcher dispatcher; + display_list->Dispatch(dispatcher); + auto picture = dispatcher.EndRecordingAsPicture(); + + ASSERT_EQ(picture.pass->GetElementCount(), 1u); + + 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; + }); + + // 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)); +} + #ifdef IMPELLER_ENABLE_3D TEST_P(DisplayListTest, SceneColorSource) { // Load up the scene. From b186d025907be8f3de3b448f30424ab02440676b Mon Sep 17 00:00:00 2001 From: jonahwilliams Date: Fri, 6 Oct 2023 12:07:04 -0700 Subject: [PATCH 3/3] ++ --- impeller/display_list/dl_unittests.cc | 53 ++++++++++++++++++++------- 1 file changed, 39 insertions(+), 14 deletions(-) diff --git a/impeller/display_list/dl_unittests.cc b/impeller/display_list/dl_unittests.cc index 02da90244adbd..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,12 +1682,26 @@ 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; - paint.setColor(flutter::DlColor::kRed()); flutter::DisplayListBuilder builder; builder.DrawPath(path, paint); @@ -1696,19 +1711,8 @@ TEST(DisplayListTest, RRectBoundsComputation) { display_list->Dispatch(dispatcher); auto picture = dispatcher.EndRecordingAsPicture(); - ASSERT_EQ(picture.pass->GetElementCount(), 1u); - - 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; - }); + std::optional coverage = + GetCoverageOfFirstEntity(picture); // Validate that the RRect coverage is _exactly_ the same as the input rect. ASSERT_TRUE(coverage.has_value()); @@ -1716,6 +1720,27 @@ TEST(DisplayListTest, RRectBoundsComputation) { 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.