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

Commit f8bae45

Browse files
committed
[DisplayList] Optimize draws of simple shapes expressed as paths
1 parent 2a13c3a commit f8bae45

File tree

3 files changed

+180
-16
lines changed

3 files changed

+180
-16
lines changed

display_list/display_list_unittests.cc

Lines changed: 159 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5094,11 +5094,164 @@ TEST_F(DisplayListTest, DrawRectPathPromoteToDrawRect) {
50945094
expected.DrawRect(rect, DlPaint());
50955095
auto expect_dl = expected.Build();
50965096

5097-
// Support for this will be re-added soon, until then verify that we
5098-
// do not promote.
5097+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
5098+
}
5099+
5100+
TEST_F(DisplayListTest, FillCompleteUnclosedRectPathPromoteToDrawRect) {
5101+
DlPaint paint = DlPaint().setDrawStyle(DlDrawStyle::kFill);
5102+
5103+
SkPath path;
5104+
path.moveTo(10.0f, 10.0f);
5105+
path.lineTo(20.0f, 10.0f);
5106+
path.lineTo(20.0f, 20.0f);
5107+
path.lineTo(10.0f, 20.0f);
5108+
path.lineTo(10.0f, 10.0f);
5109+
// No explicit close
5110+
// path.close();
5111+
5112+
DisplayListBuilder builder;
5113+
builder.DrawPath(path, paint);
5114+
auto dl = builder.Build();
5115+
5116+
DisplayListBuilder expected;
5117+
expected.DrawRect(path.getBounds(), paint);
5118+
auto expect_dl = expected.Build();
5119+
5120+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
5121+
}
5122+
5123+
TEST_F(DisplayListTest, FillIncompleteUnclosedRectPathPromoteToDrawRect) {
5124+
DlPaint paint = DlPaint().setDrawStyle(DlDrawStyle::kFill);
5125+
5126+
SkPath path;
5127+
path.moveTo(10.0f, 10.0f);
5128+
path.lineTo(20.0f, 10.0f);
5129+
path.lineTo(20.0f, 20.0f);
5130+
path.lineTo(10.0f, 20.0f);
5131+
// Leave last segment for fill operation to infer
5132+
// path.lineTo(10.0f, 10.0f);
5133+
// No explicit close
5134+
// path.close();
5135+
5136+
DisplayListBuilder builder;
5137+
builder.DrawPath(path, paint);
5138+
auto dl = builder.Build();
5139+
5140+
DisplayListBuilder expected;
5141+
expected.DrawRect(path.getBounds(), paint);
5142+
auto expect_dl = expected.Build();
5143+
5144+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
5145+
}
5146+
5147+
TEST_F(DisplayListTest, FillBarelyUnclosedRectPathPromoteToDrawPath) {
5148+
DlPaint paint = DlPaint().setDrawStyle(DlDrawStyle::kFill);
5149+
5150+
SkPath path;
5151+
path.moveTo(10.0f, 10.0f);
5152+
path.lineTo(20.0f, 10.0f);
5153+
path.lineTo(20.0f, 20.0f);
5154+
path.lineTo(10.0f, 20.0f);
5155+
path.lineTo(10.0f, 11.0f); // One pixel short of closed
5156+
5157+
DisplayListBuilder builder;
5158+
builder.DrawPath(path, paint);
5159+
auto dl = builder.Build();
5160+
5161+
DisplayListBuilder expected;
5162+
expected.DrawRect(path.getBounds(), paint);
5163+
auto expect_dl = expected.Build();
5164+
5165+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
5166+
}
5167+
5168+
TEST_F(DisplayListTest, StrokeBarelyUnclosedRectPathPromoteToDrawPath) {
5169+
DlPaint paint = DlPaint().setDrawStyle(DlDrawStyle::kStroke);
5170+
5171+
SkPath path;
5172+
path.moveTo(10.0f, 10.0f);
5173+
path.lineTo(20.0f, 10.0f);
5174+
path.lineTo(20.0f, 20.0f);
5175+
path.lineTo(10.0f, 20.0f);
5176+
path.lineTo(10.0f, 11.0f); // One pixel short of closed
5177+
5178+
DisplayListBuilder builder;
5179+
builder.DrawPath(path, paint);
5180+
auto dl = builder.Build();
5181+
5182+
DisplayListBuilder expected;
5183+
expected.DrawRect(path.getBounds(), paint);
5184+
auto expect_dl = expected.Build();
5185+
5186+
ASSERT_TRUE(DisplayListsNE_Verbose(dl, expect_dl));
5187+
}
5188+
5189+
TEST_F(DisplayListTest, StrokeCompleteUnclosedRectPathNotPromoteToDrawPath) {
5190+
DlPaint paint = DlPaint().setDrawStyle(DlDrawStyle::kStroke);
5191+
5192+
SkPath path;
5193+
path.moveTo(10.0f, 10.0f);
5194+
path.lineTo(20.0f, 10.0f);
5195+
path.lineTo(20.0f, 20.0f);
5196+
path.lineTo(10.0f, 20.0f);
5197+
path.lineTo(10.0f, 10.0f);
5198+
5199+
DisplayListBuilder builder;
5200+
builder.DrawPath(path, paint);
5201+
auto dl = builder.Build();
5202+
5203+
DisplayListBuilder expected;
5204+
expected.DrawRect(path.getBounds(), paint);
5205+
auto expect_dl = expected.Build();
5206+
50995207
ASSERT_TRUE(DisplayListsNE_Verbose(dl, expect_dl));
51005208
}
51015209

5210+
TEST_F(DisplayListTest, StrokeIncompleteClosedRectPathPromoteToDrawRect) {
5211+
DlPaint paint = DlPaint().setDrawStyle(DlDrawStyle::kStroke);
5212+
5213+
SkPath path;
5214+
path.moveTo(10.0f, 10.0f);
5215+
path.lineTo(20.0f, 10.0f);
5216+
path.lineTo(20.0f, 20.0f);
5217+
path.lineTo(10.0f, 20.0f);
5218+
// Leave last segment for close to fill in
5219+
// path.lineTo(10.0f, 10.0f);
5220+
path.close();
5221+
5222+
DisplayListBuilder builder;
5223+
builder.DrawPath(path, paint);
5224+
auto dl = builder.Build();
5225+
5226+
DisplayListBuilder expected;
5227+
expected.DrawRect(path.getBounds(), paint);
5228+
auto expect_dl = expected.Build();
5229+
5230+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
5231+
}
5232+
5233+
TEST_F(DisplayListTest, StrokeCompleteClosedRectPathPromoteToDrawRect) {
5234+
DlPaint paint = DlPaint().setDrawStyle(DlDrawStyle::kStroke);
5235+
5236+
SkPath path;
5237+
path.moveTo(10.0f, 10.0f);
5238+
path.lineTo(20.0f, 10.0f);
5239+
path.lineTo(20.0f, 20.0f);
5240+
path.lineTo(10.0f, 20.0f);
5241+
path.lineTo(10.0f, 10.0f);
5242+
path.close();
5243+
5244+
DisplayListBuilder builder;
5245+
builder.DrawPath(path, paint);
5246+
auto dl = builder.Build();
5247+
5248+
DisplayListBuilder expected;
5249+
expected.DrawRect(path.getBounds(), paint);
5250+
auto expect_dl = expected.Build();
5251+
5252+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
5253+
}
5254+
51025255
TEST_F(DisplayListTest, DrawOvalPathPromoteToDrawOval) {
51035256
SkRect rect = SkRect::MakeLTRB(10.0f, 10.0f, 20.0f, 20.0f);
51045257

@@ -5110,9 +5263,7 @@ TEST_F(DisplayListTest, DrawOvalPathPromoteToDrawOval) {
51105263
expected.DrawOval(rect, DlPaint());
51115264
auto expect_dl = expected.Build();
51125265

5113-
// Support for this will be re-added soon, until then verify that we
5114-
// do not promote.
5115-
ASSERT_TRUE(DisplayListsNE_Verbose(dl, expect_dl));
5266+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
51165267
}
51175268

51185269
TEST_F(DisplayListTest, DrawRRectPathPromoteToDrawRRect) {
@@ -5127,9 +5278,7 @@ TEST_F(DisplayListTest, DrawRRectPathPromoteToDrawRRect) {
51275278
expected.DrawRRect(rrect, DlPaint());
51285279
auto expect_dl = expected.Build();
51295280

5130-
// Support for this will be re-added soon, until then verify that we
5131-
// do not promote.
5132-
ASSERT_TRUE(DisplayListsNE_Verbose(dl, expect_dl));
5281+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
51335282
}
51345283

51355284
TEST_F(DisplayListTest, DrawRectRRectPathPromoteToDrawRect) {
@@ -5144,9 +5293,7 @@ TEST_F(DisplayListTest, DrawRectRRectPathPromoteToDrawRect) {
51445293
expected.DrawRect(rect, DlPaint());
51455294
auto expect_dl = expected.Build();
51465295

5147-
// Support for this will be re-added soon, until then verify that we
5148-
// do not promote.
5149-
ASSERT_TRUE(DisplayListsNE_Verbose(dl, expect_dl));
5296+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
51505297
}
51515298

51525299
TEST_F(DisplayListTest, DrawOvalRRectPathPromoteToDrawOval) {
@@ -5161,9 +5308,7 @@ TEST_F(DisplayListTest, DrawOvalRRectPathPromoteToDrawOval) {
51615308
expected.DrawOval(rect, DlPaint());
51625309
auto expect_dl = expected.Build();
51635310

5164-
// Support for this will be re-added soon, until then verify that we
5165-
// do not promote.
5166-
ASSERT_TRUE(DisplayListsNE_Verbose(dl, expect_dl));
5311+
ASSERT_TRUE(DisplayListsEQ_Verbose(dl, expect_dl));
51675312
}
51685313

51695314
TEST_F(DisplayListTest, ClipRectRRectPromoteToClipRect) {

display_list/dl_builder.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,24 @@ void DisplayListBuilder::DrawDRRect(const SkRRect& outer,
12271227
drawDRRect(outer, inner);
12281228
}
12291229
void DisplayListBuilder::drawPath(const DlPath& path) {
1230+
if (!path.IsInverseFillType()) {
1231+
SkRect rect;
1232+
bool is_closed;
1233+
if (path.IsSkRect(&rect, &is_closed) &&
1234+
(is_closed || current_.getDrawStyle() == DlDrawStyle::kFill)) {
1235+
drawRect(ToDlRect(rect));
1236+
return;
1237+
}
1238+
if (path.IsSkOval(&rect)) {
1239+
drawOval(ToDlRect(rect));
1240+
return;
1241+
}
1242+
SkRRect rrect;
1243+
if (path.IsSkRRect(&rrect)) {
1244+
drawRRect(rrect);
1245+
return;
1246+
}
1247+
}
12301248
DisplayListAttributeFlags flags = kDrawPathFlags;
12311249
OpResult result = PaintResult(current_, flags);
12321250
if (result != OpResult::kNoEffect) {

display_list/testing/dl_test_snippets.cc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,10 +700,11 @@ std::vector<DisplayListInvocationGroup> CreateAllRenderingOps() {
700700
{1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath1); }},
701701
{1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath2); }},
702702
{1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPath3); }},
703-
// oval, rect and rrect paths are left as drawPath
703+
// oval and rect paths are redirected to drawRect and drawOval
704704
{1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRect); }},
705705
{1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathOval); }},
706-
{1, 24, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRRect); }},
706+
// rrect path is redirected to drawRRect
707+
{1, 56, 1, [](DlOpReceiver& r) { r.drawPath(kTestPathRRect); }},
707708
}},
708709
{"DrawArc",
709710
{

0 commit comments

Comments
 (0)