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

Commit 1dc9674

Browse files
Jonah Williamsharryterkelsen
authored andcommitted
[Impeller] Ensure known geometry has simple bounds computation. (#46623)
Computing the bounds of an RRect can be really slow if you don't actually know that it is an RRect, and shows up in the traces for flutter gallery on wembly. This change should be semantically equivalent and is only an optimization to avoid recomputing the same value we already know.
1 parent a933ef8 commit 1dc9674

File tree

2 files changed

+69
-4
lines changed

2 files changed

+69
-4
lines changed

impeller/aiks/canvas.cc

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ void Canvas::DrawRRect(Rect rect, Scalar corner_radius, const Paint& paint) {
252252
auto path = PathBuilder{}
253253
.SetConvexity(Convexity::kConvex)
254254
.AddRoundedRect(rect, corner_radius)
255+
.SetBounds(rect)
255256
.TakePath();
256257
if (paint.style == Paint::Style::kFill) {
257258
Entity entity;
@@ -273,10 +274,13 @@ void Canvas::DrawCircle(Point center, Scalar radius, const Paint& paint) {
273274
paint)) {
274275
return;
275276
}
276-
auto circle_path = PathBuilder{}
277-
.AddCircle(center, radius)
278-
.SetConvexity(Convexity::kConvex)
279-
.TakePath();
277+
auto circle_path =
278+
PathBuilder{}
279+
.AddCircle(center, radius)
280+
.SetConvexity(Convexity::kConvex)
281+
.SetBounds(Rect::MakeLTRB(center.x - radius, center.y - radius,
282+
center.x + radius, center.y + radius))
283+
.TakePath();
280284
DrawPath(circle_path, paint);
281285
}
282286

@@ -317,6 +321,7 @@ void Canvas::ClipRRect(const Rect& rect,
317321
auto path = PathBuilder{}
318322
.SetConvexity(Convexity::kConvex)
319323
.AddRoundedRect(rect, corner_radius)
324+
.SetBounds(rect)
320325
.TakePath();
321326

322327
std::optional<Rect> inner_rect = (corner_radius * 2 < rect.size.width &&

impeller/display_list/dl_unittests.cc

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "impeller/display_list/dl_dispatcher.h"
2222
#include "impeller/display_list/dl_image_impeller.h"
2323
#include "impeller/display_list/dl_playground.h"
24+
#include "impeller/entity/contents/clip_contents.h"
2425
#include "impeller/entity/contents/solid_color_contents.h"
2526
#include "impeller/entity/contents/solid_rrect_blur_contents.h"
2627
#include "impeller/geometry/constants.h"
@@ -1681,6 +1682,65 @@ TEST_P(DisplayListTest, DrawVerticesBlendModes) {
16811682
ASSERT_TRUE(OpenPlaygroundHere(callback));
16821683
}
16831684

1685+
template <typename Contents>
1686+
static std::optional<Rect> GetCoverageOfFirstEntity(const Picture& picture) {
1687+
std::optional<Rect> coverage;
1688+
picture.pass->IterateAllEntities([&coverage](Entity& entity) {
1689+
if (std::static_pointer_cast<Contents>(entity.GetContents())) {
1690+
auto contents = std::static_pointer_cast<Contents>(entity.GetContents());
1691+
Entity entity;
1692+
coverage = contents->GetCoverage(entity);
1693+
return false;
1694+
}
1695+
return true;
1696+
});
1697+
return coverage;
1698+
}
1699+
1700+
TEST(DisplayListTest, RRectBoundsComputation) {
1701+
SkRRect rrect = SkRRect::MakeRectXY(SkRect::MakeLTRB(0, 0, 100, 100), 4, 4);
1702+
SkPath path = SkPath().addRRect(rrect);
1703+
1704+
flutter::DlPaint paint;
1705+
flutter::DisplayListBuilder builder;
1706+
1707+
builder.DrawPath(path, paint);
1708+
auto display_list = builder.Build();
1709+
1710+
DlDispatcher dispatcher;
1711+
display_list->Dispatch(dispatcher);
1712+
auto picture = dispatcher.EndRecordingAsPicture();
1713+
1714+
std::optional<Rect> coverage =
1715+
GetCoverageOfFirstEntity<SolidColorContents>(picture);
1716+
1717+
// Validate that the RRect coverage is _exactly_ the same as the input rect.
1718+
ASSERT_TRUE(coverage.has_value());
1719+
ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()),
1720+
Rect::MakeLTRB(0, 0, 100, 100));
1721+
}
1722+
1723+
TEST(DisplayListTest, CircleBoundsComputation) {
1724+
SkPath path = SkPath().addCircle(0, 0, 5);
1725+
1726+
flutter::DlPaint paint;
1727+
flutter::DisplayListBuilder builder;
1728+
1729+
builder.DrawPath(path, paint);
1730+
auto display_list = builder.Build();
1731+
1732+
DlDispatcher dispatcher;
1733+
display_list->Dispatch(dispatcher);
1734+
auto picture = dispatcher.EndRecordingAsPicture();
1735+
1736+
std::optional<Rect> coverage =
1737+
GetCoverageOfFirstEntity<SolidColorContents>(picture);
1738+
1739+
ASSERT_TRUE(coverage.has_value());
1740+
ASSERT_EQ(coverage.value_or(Rect::MakeMaximum()),
1741+
Rect::MakeLTRB(-5, -5, 5, 5));
1742+
}
1743+
16841744
#ifdef IMPELLER_ENABLE_3D
16851745
TEST_P(DisplayListTest, SceneColorSource) {
16861746
// Load up the scene.

0 commit comments

Comments
 (0)