| 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
5 #include "flutter/impeller/display_list/aiks_unittests.h"
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
aiks_unittests.h
impeller::AiksPlayground
Definition: aiks_playground.h:16
x
int32_t x
Definition: dl_golden_unittests.cc:443
flutter
Definition: dl_golden_blur_unittests.cc:16
impeller::testing::TEST_P
TEST_P(AiksTest, DrawAtlasNoColor)
Definition: aiks_dl_atlas_unittests.cc:57
impeller
Definition: allocation.cc:12
impeller::Scalar
float Scalar
Definition: scalar.h:18