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

Commit e28f875

Browse files
authored
[DisplayList] Optimize ClipRRect and ClipPath to ClipOval when appropriate (#54088)
Fixes: flutter/flutter#151850 Re-adding an optimization originally included in #53642 that detects when ClipRRect and ClipPath operations are actually ovals and redirects them to the ClipOval path during recording to save space and reduce the need for dispatchers to do the same detections and optimizations.
1 parent 0844c0a commit e28f875

File tree

3 files changed

+16
-22
lines changed

3 files changed

+16
-22
lines changed

display_list/display_list_unittests.cc

Lines changed: 5 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4863,8 +4863,6 @@ TEST_F(DisplayListTest, ClipPathOvalNonCulling) {
48634863
auto non_encompassing_oval = clip.makeOutset(2.071f, 2.071f);
48644864
SkPath path;
48654865
path.addOval(non_encompassing_oval);
4866-
SkRRect rrect;
4867-
rrect.setOval(non_encompassing_oval);
48684866

48694867
DisplayListBuilder cull_builder;
48704868
cull_builder.ClipRect(clip, ClipOp::kIntersect, false);
@@ -4873,9 +4871,8 @@ TEST_F(DisplayListTest, ClipPathOvalNonCulling) {
48734871

48744872
CLIP_EXPECTOR(expector);
48754873
expector.addExpectation(clip, ClipOp::kIntersect, false);
4876-
// Builder will not cull this clip, but it will turn it into a ClipRRect
4877-
// Eventually it should turn it into a ClipOval
4878-
expector.addExpectation(rrect, ClipOp::kIntersect, false);
4874+
// Builder will not cull this clip, but it will turn it into a ClipOval
4875+
expector.addOvalExpectation(non_encompassing_oval, ClipOp::kIntersect, false);
48794876
cull_dl->Dispatch(expector);
48804877
}
48814878

@@ -5088,9 +5085,7 @@ TEST_F(DisplayListTest, ClipOvalRRectPromoteToClipOval) {
50885085
expected.DrawRect(draw_rect, DlPaint());
50895086
auto expect_dl = expected.Build();
50905087

5091-
// Support for this will be re-added soon, until then verify that we
5092-
// do not promote.
5093-
ASSERT_TRUE(DisplayListsNE_Verbose(dl, expect_dl));
5088+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
50945089
}
50955090

50965091
TEST_F(DisplayListTest, ClipRectPathPromoteToClipRect) {
@@ -5132,9 +5127,7 @@ TEST_F(DisplayListTest, ClipOvalPathPromoteToClipOval) {
51325127
expected.DrawRect(draw_rect, DlPaint());
51335128
auto expect_dl = expected.Build();
51345129

5135-
// Support for this will be re-added soon, until then verify that we
5136-
// do not promote.
5137-
ASSERT_TRUE(DisplayListsNE_Verbose(dl, expect_dl));
5130+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
51385131
}
51395132

51405133
TEST_F(DisplayListTest, ClipRRectPathPromoteToClipRRect) {
@@ -5273,9 +5266,7 @@ TEST_F(DisplayListTest, ClipOvalRRectPathPromoteToClipOval) {
52735266
expected.DrawRect(draw_rect, DlPaint());
52745267
auto expect_dl = expected.Build();
52755268

5276-
// Support for this will be re-added soon, until then verify that we
5277-
// do not promote.
5278-
ASSERT_TRUE(DisplayListsNE_Verbose(dl, expect_dl));
5269+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
52795270
}
52805271

52815272
TEST_F(DisplayListTest, BoundedRenderOpsDoNotReportUnbounded) {

display_list/dl_builder.cc

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,11 @@ void DisplayListBuilder::ClipRRect(const SkRRect& rrect,
10051005
ClipOp clip_op,
10061006
bool is_aa) {
10071007
if (rrect.isRect()) {
1008-
clipRect(rrect.rect(), clip_op, is_aa);
1008+
ClipRect(rrect.rect(), clip_op, is_aa);
1009+
return;
1010+
}
1011+
if (rrect.isOval()) {
1012+
ClipOval(rrect.rect(), clip_op, is_aa);
10091013
return;
10101014
}
10111015
if (current_info().is_nop) {
@@ -1043,17 +1047,16 @@ void DisplayListBuilder::ClipPath(const SkPath& path,
10431047
if (!path.isInverseFillType()) {
10441048
SkRect rect;
10451049
if (path.isRect(&rect)) {
1046-
this->clipRect(rect, clip_op, is_aa);
1050+
ClipRect(rect, clip_op, is_aa);
10471051
return;
10481052
}
1049-
SkRRect rrect;
10501053
if (path.isOval(&rect)) {
1051-
rrect.setOval(rect);
1052-
this->clipRRect(rrect, clip_op, is_aa);
1054+
ClipOval(rect, clip_op, is_aa);
10531055
return;
10541056
}
1057+
SkRRect rrect;
10551058
if (path.isRRect(&rrect)) {
1056-
this->clipRRect(rrect, clip_op, is_aa);
1059+
ClipRRect(rrect, clip_op, is_aa);
10571060
return;
10581061
}
10591062
}

display_list/testing/dl_test_snippets.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -503,8 +503,8 @@ std::vector<DisplayListInvocationGroup> CreateAllClipOps() {
503503
[](DlOpReceiver& r) {
504504
r.clipPath(kTestPathRect, DlCanvas::ClipOp::kIntersect, true);
505505
}},
506-
// clipPath(oval) becomes clipRRect
507-
{1, 64, 0,
506+
// clipPath(oval) becomes clipOval
507+
{1, 24, 0,
508508
[](DlOpReceiver& r) {
509509
r.clipPath(kTestPathOval, DlCanvas::ClipOp::kIntersect, true);
510510
}},

0 commit comments

Comments
 (0)