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/display_list/geometry/dl_path_builder.h"
13 #include "flutter/testing/testing.h"
14 
15 namespace impeller {
16 namespace testing {
17 
18 using namespace flutter;
19 
20 TEST_P(AiksTest, CanRenderNestedClips) {
21  DisplayListBuilder builder;
22  DlPaint paint;
23  paint.setColor(DlColor::kFuchsia());
24 
25  builder.Save();
26  builder.ClipPath(DlPath::MakeCircle(DlPoint(200, 400), 300));
27  builder.Restore();
28  builder.ClipPath(DlPath::MakeCircle(DlPoint(600, 400), 300));
29  builder.ClipPath(DlPath::MakeCircle(DlPoint(400, 600), 300));
30  builder.DrawRect(DlRect::MakeXYWH(200, 200, 400, 400), paint);
31 
32  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
33 }
34 
35 TEST_P(AiksTest, CanRenderDifferenceClips) {
36  DisplayListBuilder builder;
37  builder.Translate(400, 400);
38 
39  // Limit drawing to face circle with a clip.
40  builder.ClipPath(DlPath::MakeCircle(DlPoint(0, 0), 200));
41  builder.Save();
42 
43  // Cut away eyes/mouth using difference clips.
44  builder.ClipPath(DlPath::MakeCircle(DlPoint(-100, -50), 30),
45  DlClipOp::kDifference);
46  builder.ClipPath(DlPath::MakeCircle(DlPoint(100, -50), 30),
47  DlClipOp::kDifference);
48 
49  DlPathBuilder path_builder;
50  path_builder.MoveTo(DlPoint(-100, 50));
51  path_builder.QuadraticCurveTo(DlPoint(0, 150), DlPoint(100, 50));
52  builder.ClipPath(path_builder.TakePath(), DlClipOp::kDifference);
53 
54  // Draw a huge yellow rectangle to prove the clipping works.
55  DlPaint paint;
56  paint.setColor(DlColor::kYellow());
57  builder.DrawRect(DlRect::MakeXYWH(-1000, -1000, 2000, 2000), paint);
58 
59  // Remove the difference clips and draw hair that partially covers the eyes.
60  builder.Restore();
61  paint.setColor(DlColor::kMaroon());
62  DlPathBuilder path_builder_2;
63  path_builder_2.MoveTo(DlPoint(200, -200));
64  path_builder_2.LineTo(DlPoint(-200, -200));
65  path_builder_2.LineTo(DlPoint(-200, -40));
66  path_builder_2.CubicCurveTo(DlPoint(0, -40), DlPoint(0, -80),
67  DlPoint(200, -80));
68 
69  builder.DrawPath(path_builder_2.TakePath(), paint);
70 
71  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
72 }
73 
74 TEST_P(AiksTest, CanRenderWithContiguousClipRestores) {
75  DisplayListBuilder builder;
76 
77  // Cover the whole canvas with red.
78  DlPaint paint;
79  paint.setColor(DlColor::kRed());
80  builder.DrawPaint(paint);
81 
82  builder.Save();
83 
84  // Append two clips, the second resulting in empty coverage.
85  builder.ClipRect(DlRect::MakeXYWH(100, 100, 100, 100));
86  builder.ClipRect(DlRect::MakeXYWH(300, 300, 100, 100));
87 
88  // Restore to no clips.
89  builder.Restore();
90 
91  // Replace the whole canvas with green.
92  paint.setColor(DlColor::kGreen());
93  builder.DrawPaint(paint);
94 
95  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
96 }
97 
98 TEST_P(AiksTest, ClipsUseCurrentTransform) {
99  std::array<DlColor, 5> colors = {DlColor::kWhite(), DlColor::kBlack(),
100  DlColor::kSkyBlue(), DlColor::kRed(),
101  DlColor::kYellow()};
102  DisplayListBuilder builder;
103  DlPaint paint;
104 
105  builder.Translate(300, 300);
106  for (int i = 0; i < 15; i++) {
107  builder.Scale(0.8, 0.8);
108 
109  paint.setColor(colors[i % colors.size()]);
110  builder.ClipPath(DlPath::MakeCircle(DlPoint(0, 0), 300));
111  builder.DrawRect(DlRect::MakeXYWH(-300, -300, 600, 600), paint);
112  }
113  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
114 }
115 
116 /// If correct, this test should draw a green circle. If any red is visible,
117 /// there is a depth bug.
118 TEST_P(AiksTest, FramebufferBlendsRespectClips) {
119  DisplayListBuilder builder;
120 
121  // Clear the whole canvas with white.
122  DlPaint paint;
123  paint.setColor(DlColor::kWhite());
124  builder.DrawPaint(paint);
125 
126  builder.ClipPath(DlPath::MakeCircle(DlPoint(150, 150), 50),
127  DlClipOp::kIntersect);
128 
129  // Draw a red rectangle that should not show through the circle clip.
130  paint.setColor(DlColor::kRed());
131  paint.setBlendMode(DlBlendMode::kMultiply);
132  builder.DrawRect(DlRect::MakeXYWH(100, 100, 100, 100), paint);
133 
134  // Draw a green circle that shows through the clip.
135  paint.setColor(DlColor::kGreen());
136  paint.setBlendMode(DlBlendMode::kSrcOver);
137  builder.DrawCircle(DlPoint(150, 150), 50, paint);
138 
139  ASSERT_TRUE(OpenPlaygroundHere(builder.Build()));
140 }
141 
142 } // namespace testing
143 } // namespace impeller
TEST_P(AiksTest, DrawAtlasNoColor)
flutter::DlPoint DlPoint
Definition: dl_dispatcher.h:24