Flutter Impeller
aiks_dl_clip_unittests.cc
Go to the documentation of this file.
1 // Copyright 2013 The Flutter Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
6 
7 #include "flutter/display_list/dl_blend_mode.h"
8 #include "flutter/display_list/dl_builder.h"
9 #include "flutter/display_list/dl_color.h"
10 #include "flutter/display_list/dl_paint.h"
11 #include "flutter/display_list/effects/dl_color_filter.h"
12 #include "flutter/testing/testing.h"
13 
14 namespace impeller {
15 namespace testing {
16 
17 using namespace flutter;
18 
19 namespace {
20 SkPath CreateCircle(Scalar x, Scalar y, Scalar radius) {
21  SkPath path;
22  path.addCircle(x, y, radius);
23  return path;
24 }
25 } // namespace
26 
27 TEST_P(AiksTest, CanRenderNestedClips) {
28  DisplayListBuilder builder;
29  DlPaint paint;
30  paint.setColor(DlColor::kFuchsia());
31 
32  builder.Save();
33  builder.ClipPath(CreateCircle(200, 400, 300));
34  builder.Restore();
35  builder.ClipPath(CreateCircle(600, 400, 300));
36  builder.ClipPath(CreateCircle(400, 600, 300));
37  builder.DrawRect(SkRect::MakeXYWH(200, 200, 400, 400), paint);
38 
39  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
40 }
41 
42 TEST_P(AiksTest, CanRenderDifferenceClips) {
43  DisplayListBuilder builder;
44  builder.Translate(400, 400);
45 
46  // Limit drawing to face circle with a clip.
47  builder.ClipPath(CreateCircle(0, 0, 200));
48  builder.Save();
49 
50  // Cut away eyes/mouth using difference clips.
51  builder.ClipPath(CreateCircle(-100, -50, 30), DlCanvas::ClipOp::kDifference);
52  builder.ClipPath(CreateCircle(100, -50, 30), DlCanvas::ClipOp::kDifference);
53 
54  SkPath path;
55  path.moveTo(-100, 50);
56  path.quadTo(0, 150, 100, 50);
57  builder.ClipPath(path, DlCanvas::ClipOp::kDifference);
58 
59  // Draw a huge yellow rectangle to prove the clipping works.
60  DlPaint paint;
61  paint.setColor(DlColor::kYellow());
62  builder.DrawRect(SkRect::MakeXYWH(-1000, -1000, 2000, 2000), paint);
63 
64  // Remove the difference clips and draw hair that partially covers the eyes.
65  builder.Restore();
66  paint.setColor(DlColor::kMaroon());
67  SkPath path_2;
68  path_2.moveTo(200, -200);
69  path_2.lineTo(-200, -200);
70  path_2.lineTo(-200, -40);
71  path_2.cubicTo({0, -40}, {0, -80}, {200, -80});
72 
73  builder.DrawPath(path_2, paint);
74 
75  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
76 }
77 
78 TEST_P(AiksTest, CanRenderWithContiguousClipRestores) {
79  DisplayListBuilder builder;
80 
81  // Cover the whole canvas with red.
82  DlPaint paint;
83  paint.setColor(DlColor::kRed());
84  builder.DrawPaint(paint);
85 
86  builder.Save();
87 
88  // Append two clips, the second resulting in empty coverage.
89  builder.ClipRect(SkRect::MakeXYWH(100, 100, 100, 100));
90  builder.ClipRect(SkRect::MakeXYWH(300, 300, 100, 100));
91 
92  // Restore to no clips.
93  builder.Restore();
94 
95  // Replace the whole canvas with green.
96  paint.setColor(DlColor::kGreen());
97  builder.DrawPaint(paint);
98 
99  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
100 }
101 
102 TEST_P(AiksTest, ClipsUseCurrentTransform) {
103  std::array<DlColor, 5> colors = {DlColor::kWhite(), DlColor::kBlack(),
104  DlColor::kSkyBlue(), DlColor::kRed(),
105  DlColor::kYellow()};
106  DisplayListBuilder builder;
107  DlPaint paint;
108 
109  builder.Translate(300, 300);
110  for (int i = 0; i < 15; i++) {
111  builder.Scale(0.8, 0.8);
112 
113  paint.setColor(colors[i % colors.size()]);
114  builder.ClipPath(CreateCircle(0, 0, 300));
115  builder.DrawRect(SkRect::MakeXYWH(-300, -300, 600, 600), paint);
116  }
117  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
118 }
119 
120 /// If correct, this test should draw a green circle. If any red is visible,
121 /// there is a depth bug.
122 TEST_P(AiksTest, FramebufferBlendsRespectClips) {
123  DisplayListBuilder builder;
124 
125  // Clear the whole canvas with white.
126  DlPaint paint;
127  paint.setColor(DlColor::kWhite());
128  builder.DrawPaint(paint);
129 
130  builder.ClipPath(SkPath::Circle(150, 150, 50), DlCanvas::ClipOp::kIntersect);
131 
132  // Draw a red rectangle that should not show through the circle clip.
133  paint.setColor(DlColor::kRed());
134  paint.setBlendMode(DlBlendMode::kMultiply);
135  builder.DrawRect(SkRect::MakeXYWH(100, 100, 100, 100), paint);
136 
137  // Draw a green circle that shows through the clip.
138  paint.setColor(DlColor::kGreen());
139  paint.setBlendMode(DlBlendMode::kSrcOver);
140  builder.DrawCircle(SkPoint::Make(150, 150), 50, paint);
141 
142  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
143 }
144 
145 } // namespace testing
146 } // namespace impeller
impeller::AiksPlayground
Definition: aiks_playground.h:16
impeller::Scalar
float Scalar
Definition: scalar.h:18
aiks_unittests.h
flutter
Definition: dl_golden_blur_unittests.cc:15
impeller::testing::TEST_P
TEST_P(AiksTest, DrawAtlasNoColor)
Definition: aiks_dl_atlas_unittests.cc:78
impeller
Definition: allocation.cc:12