blob: 873cd9a1c177a5ffcd7c0d976b1d2dbf31c76cec [file] [log] [blame]
Florin Malitac75e2402018-01-03 16:17:29 -05001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Hal Canaryc640d0d2018-06-13 09:59:02 -04008#include "SkTypes.h"
Florin Malitaf4f3f0f2018-01-03 23:53:37 -05009
10#if !defined(SK_BUILD_FOR_GOOGLE3)
11
Hal Canaryc640d0d2018-06-13 09:59:02 -040012#include "SkRect.h"
13#include "SkRectPriv.h"
Florin Malitac75e2402018-01-03 16:17:29 -050014#include "SkSGColor.h"
15#include "SkSGDraw.h"
16#include "SkSGGroup.h"
17#include "SkSGInvalidationController.h"
18#include "SkSGRect.h"
Florin Malitaef26fcb2019-02-10 12:54:20 -050019#include "SkSGRenderEffect.h"
Florin Malitac75e2402018-01-03 16:17:29 -050020#include "SkSGTransform.h"
Hal Canaryc640d0d2018-06-13 09:59:02 -040021#include "SkTo.h"
Florin Malitac75e2402018-01-03 16:17:29 -050022
23#include "Test.h"
24
25#include <vector>
26
27static void check_inval(skiatest::Reporter* reporter, const sk_sp<sksg::Node>& root,
28 const SkRect& expected_bounds,
29 const SkRect& expected_inval_bounds,
30 const std::vector<SkRect>* expected_damage) {
31 sksg::InvalidationController ic;
32 const auto bbox = root->revalidate(&ic, SkMatrix::I());
33
34 if (0) {
Florin Malita67cd9b22018-01-03 20:13:34 -050035 SkDebugf("** bbox: [%f %f %f %f], ibbox: [%f %f %f %f]\n",
36 bbox.fLeft, bbox.fTop, bbox.fRight, bbox.fBottom,
37 ic.bounds().left(), ic.bounds().top(), ic.bounds().right(), ic.bounds().bottom());
Florin Malitac75e2402018-01-03 16:17:29 -050038 }
39
40 REPORTER_ASSERT(reporter, bbox == expected_bounds);
41 REPORTER_ASSERT(reporter, ic.bounds() == expected_inval_bounds);
42
43 if (expected_damage) {
Florin Malitac14f1442018-01-05 11:32:31 -050044 const auto damage_count = SkTo<size_t>(ic.end() - ic.begin());
45 REPORTER_ASSERT(reporter, expected_damage->size() == damage_count);
46 for (size_t i = 0; i < std::min(expected_damage->size(), damage_count); ++i) {
Florin Malitac75e2402018-01-03 16:17:29 -050047 const auto r1 = (*expected_damage)[i],
48 r2 = ic.begin()[i];
49 if (0) {
Florin Malita67cd9b22018-01-03 20:13:34 -050050 SkDebugf("*** expected inval: [%f %f %f %f], actual: [%f %f %f %f]\n",
51 r1.left(), r1.top(), r1.right(), r1.bottom(),
52 r2.left(), r2.top(), r2.right(), r2.bottom());
Florin Malitac75e2402018-01-03 16:17:29 -050053 }
54 REPORTER_ASSERT(reporter, r1 == r2);
55 }
56 }
57}
58
Florin Malitac14f1442018-01-05 11:32:31 -050059static void inval_test1(skiatest::Reporter* reporter) {
Florin Malita18eafd92018-01-04 21:11:55 -050060 auto color = sksg::Color::Make(0xff000000);
61 auto r1 = sksg::Rect::Make(SkRect::MakeWH(100, 100)),
62 r2 = sksg::Rect::Make(SkRect::MakeWH(100, 100));
63 auto grp = sksg::Group::Make();
Florin Malita760a0522019-01-10 15:24:15 -050064 auto matrix = sksg::Matrix<SkMatrix>::Make(SkMatrix::I());
Florin Malita919e2092019-01-09 15:37:57 -050065 auto root = sksg::TransformEffect::Make(grp, matrix);
Florin Malitac75e2402018-01-03 16:17:29 -050066
67 grp->addChild(sksg::Draw::Make(r1, color));
68 grp->addChild(sksg::Draw::Make(r2, color));
69
70 {
71 // Initial revalidation.
Florin Malita18eafd92018-01-04 21:11:55 -050072 check_inval(reporter, root,
Florin Malitac75e2402018-01-03 16:17:29 -050073 SkRect::MakeWH(100, 100),
Mike Reed8008df12018-01-17 12:20:04 -050074 SkRectPriv::MakeLargeS32(),
Florin Malitac75e2402018-01-03 16:17:29 -050075 nullptr);
76 }
77
78 {
79 // Move r2 to (200 100).
80 r2->setL(200); r2->setT(100); r2->setR(300); r2->setB(200);
81 std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
Florin Malita18eafd92018-01-04 21:11:55 -050082 check_inval(reporter, root,
Florin Malitac75e2402018-01-03 16:17:29 -050083 SkRect::MakeWH(300, 200),
84 SkRect::MakeWH(300, 200),
85 &damage);
86 }
87
88 {
89 // Update the common color.
Florin Malita0ebf4192018-01-04 19:21:58 -050090 color->setColor(0xffff0000);
91 std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
Florin Malita18eafd92018-01-04 21:11:55 -050092 check_inval(reporter, root,
Florin Malita0ebf4192018-01-04 19:21:58 -050093 SkRect::MakeWH(300, 200),
94 SkRect::MakeWH(300, 200),
95 &damage);
Florin Malitac75e2402018-01-03 16:17:29 -050096 }
97
98 {
99 // Shrink r1.
100 r1->setR(50);
101 std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 50, 100} };
Florin Malita18eafd92018-01-04 21:11:55 -0500102 check_inval(reporter, root,
Florin Malitac75e2402018-01-03 16:17:29 -0500103 SkRect::MakeWH(300, 200),
104 SkRect::MakeWH(100, 100),
105 &damage);
106 }
107
108 {
109 // Update transform.
Florin Malita18eafd92018-01-04 21:11:55 -0500110 matrix->setMatrix(SkMatrix::MakeScale(2, 2));
Florin Malitac75e2402018-01-03 16:17:29 -0500111 std::vector<SkRect> damage = { {0, 0, 300, 200}, { 0, 0, 600, 400} };
Florin Malita18eafd92018-01-04 21:11:55 -0500112 check_inval(reporter, root,
Florin Malitac75e2402018-01-03 16:17:29 -0500113 SkRect::MakeWH(600, 400),
114 SkRect::MakeWH(600, 400),
115 &damage);
116 }
117
118 {
119 // Shrink r2 under transform.
120 r2->setR(250);
121 std::vector<SkRect> damage = { {400, 200, 600, 400}, { 400, 200, 500, 400} };
Florin Malita18eafd92018-01-04 21:11:55 -0500122 check_inval(reporter, root,
Florin Malitac75e2402018-01-03 16:17:29 -0500123 SkRect::MakeWH(500, 400),
124 SkRect::MakeLTRB(400, 200, 600, 400),
125 &damage);
126 }
127}
Florin Malitaf4f3f0f2018-01-03 23:53:37 -0500128
Florin Malitac14f1442018-01-05 11:32:31 -0500129static void inval_test2(skiatest::Reporter* reporter) {
130 auto color = sksg::Color::Make(0xff000000);
131 auto rect = sksg::Rect::Make(SkRect::MakeWH(100, 100));
Florin Malita760a0522019-01-10 15:24:15 -0500132 auto m1 = sksg::Matrix<SkMatrix>::Make(SkMatrix::I()),
133 m2 = sksg::Matrix<SkMatrix>::Make(SkMatrix::I());
Florin Malita919e2092019-01-09 15:37:57 -0500134 auto t1 = sksg::TransformEffect::Make(sksg::Draw::Make(rect, color),
135 sksg::Transform::MakeConcat(m1, m2)),
136 t2 = sksg::TransformEffect::Make(sksg::Draw::Make(rect, color), m1);
Florin Malitac14f1442018-01-05 11:32:31 -0500137 auto root = sksg::Group::Make();
138 root->addChild(t1);
139 root->addChild(t2);
140
141 {
142 // Initial revalidation.
143 check_inval(reporter, root,
144 SkRect::MakeWH(100, 100),
Mike Reed8008df12018-01-17 12:20:04 -0500145 SkRectPriv::MakeLargeS32(),
Florin Malitac14f1442018-01-05 11:32:31 -0500146 nullptr);
147 }
148
149 {
150 // Update the shared color.
151 color->setColor(0xffff0000);
152 std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 100, 100} };
153 check_inval(reporter, root,
154 SkRect::MakeWH(100, 100),
155 SkRect::MakeWH(100, 100),
156 &damage);
157 }
158
159 {
160 // Update m2.
161 m2->setMatrix(SkMatrix::MakeScale(2, 2));
162 std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 200, 200} };
163 check_inval(reporter, root,
164 SkRect::MakeWH(200, 200),
165 SkRect::MakeWH(200, 200),
166 &damage);
167 }
168
169 {
170 // Update shared m1.
171 m1->setMatrix(SkMatrix::MakeTrans(100, 100));
172 std::vector<SkRect> damage = { { 0, 0, 200, 200}, // draw1 prev bounds
173 { 100, 100, 300, 300}, // draw1 new bounds
174 { 0, 0, 100, 100}, // draw2 prev bounds
175 { 100, 100, 200, 200} }; // draw2 new bounds
176 check_inval(reporter, root,
177 SkRect::MakeLTRB(100, 100, 300, 300),
178 SkRect::MakeLTRB( 0, 0, 300, 300),
179 &damage);
180 }
181
182 {
183 // Update shared rect.
184 rect->setR(50);
185 std::vector<SkRect> damage = { { 100, 100, 300, 300}, // draw1 prev bounds
186 { 100, 100, 200, 300}, // draw1 new bounds
187 { 100, 100, 200, 200}, // draw2 prev bounds
188 { 100, 100, 150, 200} }; // draw2 new bounds
189 check_inval(reporter, root,
190 SkRect::MakeLTRB(100, 100, 200, 300),
191 SkRect::MakeLTRB(100, 100, 300, 300),
192 &damage);
193 }
194}
195
Florin Malitaef26fcb2019-02-10 12:54:20 -0500196static void inval_test3(skiatest::Reporter* reporter) {
197 auto color1 = sksg::Color::Make(0xff000000),
198 color2 = sksg::Color::Make(0xff000000);
199 auto group = sksg::Group::Make();
200
201 group->addChild(sksg::Draw::Make(sksg::Rect::Make(SkRect::MakeWH(100, 100)),
202 color1));
203 group->addChild(sksg::Draw::Make(sksg::Rect::Make(SkRect::MakeXYWH(200, 0, 100, 100)),
204 color2));
205 auto filter = sksg::DropShadowImageFilter::Make();
206 filter->setOffset({50, 75});
207 auto root = sksg::ImageFilterEffect::Make(group, filter);
208
209 {
210 // Initial revalidation.
211 check_inval(reporter, root,
212 SkRect::MakeXYWH(0, 0, 350, 175),
213 SkRectPriv::MakeLargeS32(),
214 nullptr);
215 }
216
217 {
218 // Shadow-only.
219 filter->setMode(sksg::DropShadowImageFilter::Mode::kShadowOnly);
220 std::vector<SkRect> damage = { {0, 0, 350, 175}, { 50, 75, 350, 175} };
221 check_inval(reporter, root,
222 SkRect::MakeLTRB(50, 75, 350, 175),
223 SkRect::MakeLTRB(0, 0, 350, 175),
224 &damage);
225 }
226
227 {
228 // Content change -> single/full filter bounds inval.
229 color1->setColor(0xffff0000);
230 std::vector<SkRect> damage = { { 50, 75, 350, 175} };
231 check_inval(reporter, root,
232 SkRect::MakeLTRB(50, 75, 350, 175),
233 SkRect::MakeLTRB(50, 75, 350, 175),
234 &damage);
235 }
236
237}
238
Florin Malitabee88d42018-10-02 13:05:39 -0400239static void inval_group_remove(skiatest::Reporter* reporter) {
240 auto draw = sksg::Draw::Make(sksg::Rect::Make(SkRect::MakeWH(100, 100)),
241 sksg::Color::Make(SK_ColorBLACK));
242 auto grp = sksg::Group::Make();
243
244 // Readding the child should not trigger asserts.
245 grp->addChild(draw);
246 grp->removeChild(draw);
247 grp->addChild(draw);
248}
249
Florin Malitac14f1442018-01-05 11:32:31 -0500250DEF_TEST(SGInvalidation, reporter) {
251 inval_test1(reporter);
252 inval_test2(reporter);
Florin Malitaef26fcb2019-02-10 12:54:20 -0500253 inval_test3(reporter);
Florin Malitabee88d42018-10-02 13:05:39 -0400254 inval_group_remove(reporter);
Florin Malitac14f1442018-01-05 11:32:31 -0500255}
256
Florin Malitaf4f3f0f2018-01-03 23:53:37 -0500257#endif // !defined(SK_BUILD_FOR_GOOGLE3)