1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci#include "include/core/SkTypes.h"
9cb93a386Sopenharmony_ci
10cb93a386Sopenharmony_ci#if !defined(SK_BUILD_FOR_GOOGLE3)
11cb93a386Sopenharmony_ci
12cb93a386Sopenharmony_ci#include "include/core/SkRect.h"
13cb93a386Sopenharmony_ci#include "include/private/SkTo.h"
14cb93a386Sopenharmony_ci#include "modules/sksg/include/SkSGDraw.h"
15cb93a386Sopenharmony_ci#include "modules/sksg/include/SkSGGroup.h"
16cb93a386Sopenharmony_ci#include "modules/sksg/include/SkSGInvalidationController.h"
17cb93a386Sopenharmony_ci#include "modules/sksg/include/SkSGPaint.h"
18cb93a386Sopenharmony_ci#include "modules/sksg/include/SkSGRect.h"
19cb93a386Sopenharmony_ci#include "modules/sksg/include/SkSGRenderEffect.h"
20cb93a386Sopenharmony_ci#include "modules/sksg/include/SkSGTransform.h"
21cb93a386Sopenharmony_ci#include "src/core/SkRectPriv.h"
22cb93a386Sopenharmony_ci
23cb93a386Sopenharmony_ci#include "tests/Test.h"
24cb93a386Sopenharmony_ci
25cb93a386Sopenharmony_ci#include <vector>
26cb93a386Sopenharmony_ci
27cb93a386Sopenharmony_cistatic void check_inval(skiatest::Reporter* reporter, const sk_sp<sksg::Node>& root,
28cb93a386Sopenharmony_ci                        const SkRect& expected_bounds,
29cb93a386Sopenharmony_ci                        const SkRect& expected_inval_bounds,
30cb93a386Sopenharmony_ci                        const std::vector<SkRect>* expected_damage) {
31cb93a386Sopenharmony_ci    sksg::InvalidationController ic;
32cb93a386Sopenharmony_ci    const auto bbox = root->revalidate(&ic, SkMatrix::I());
33cb93a386Sopenharmony_ci
34cb93a386Sopenharmony_ci    if (0) {
35cb93a386Sopenharmony_ci        SkDebugf("** bbox: [%f %f %f %f], ibbox: [%f %f %f %f]\n",
36cb93a386Sopenharmony_ci                 bbox.fLeft, bbox.fTop, bbox.fRight, bbox.fBottom,
37cb93a386Sopenharmony_ci                 ic.bounds().left(), ic.bounds().top(), ic.bounds().right(), ic.bounds().bottom());
38cb93a386Sopenharmony_ci    }
39cb93a386Sopenharmony_ci
40cb93a386Sopenharmony_ci    REPORTER_ASSERT(reporter, bbox == expected_bounds);
41cb93a386Sopenharmony_ci    REPORTER_ASSERT(reporter, ic.bounds() == expected_inval_bounds);
42cb93a386Sopenharmony_ci
43cb93a386Sopenharmony_ci    if (expected_damage) {
44cb93a386Sopenharmony_ci        const auto damage_count = SkTo<size_t>(ic.end() - ic.begin());
45cb93a386Sopenharmony_ci        REPORTER_ASSERT(reporter, expected_damage->size() == damage_count);
46cb93a386Sopenharmony_ci        for (size_t i = 0; i < std::min(expected_damage->size(), damage_count); ++i) {
47cb93a386Sopenharmony_ci            const auto r1 = (*expected_damage)[i],
48cb93a386Sopenharmony_ci                       r2 = ic.begin()[i];
49cb93a386Sopenharmony_ci            if (0) {
50cb93a386Sopenharmony_ci                SkDebugf("*** expected inval: [%f %f %f %f], actual: [%f %f %f %f]\n",
51cb93a386Sopenharmony_ci                         r1.left(), r1.top(), r1.right(), r1.bottom(),
52cb93a386Sopenharmony_ci                         r2.left(), r2.top(), r2.right(), r2.bottom());
53cb93a386Sopenharmony_ci            }
54cb93a386Sopenharmony_ci            REPORTER_ASSERT(reporter, r1 == r2);
55cb93a386Sopenharmony_ci        }
56cb93a386Sopenharmony_ci    }
57cb93a386Sopenharmony_ci}
58cb93a386Sopenharmony_ci
59cb93a386Sopenharmony_cistruct HitTest {
60cb93a386Sopenharmony_ci    const SkPoint           pt;
61cb93a386Sopenharmony_ci    sk_sp<sksg::RenderNode> node;
62cb93a386Sopenharmony_ci};
63cb93a386Sopenharmony_ci
64cb93a386Sopenharmony_cistatic void check_hittest(skiatest::Reporter* reporter, const sk_sp<sksg::RenderNode>& root,
65cb93a386Sopenharmony_ci                          const std::vector<HitTest>& tests) {
66cb93a386Sopenharmony_ci    for (const auto& tst : tests) {
67cb93a386Sopenharmony_ci        const auto* node = root->nodeAt(tst.pt);
68cb93a386Sopenharmony_ci        if (node != tst.node.get()) {
69cb93a386Sopenharmony_ci            SkDebugf("*** nodeAt(%f, %f) - expected %p, got %p\n",
70cb93a386Sopenharmony_ci                     tst.pt.x(), tst.pt.y(), tst.node.get(), node);
71cb93a386Sopenharmony_ci        }
72cb93a386Sopenharmony_ci        REPORTER_ASSERT(reporter, tst.node.get() == node);
73cb93a386Sopenharmony_ci    }
74cb93a386Sopenharmony_ci}
75cb93a386Sopenharmony_ci
76cb93a386Sopenharmony_cistatic void inval_test1(skiatest::Reporter* reporter) {
77cb93a386Sopenharmony_ci    auto color  = sksg::Color::Make(0xff000000);
78cb93a386Sopenharmony_ci    auto r1     = sksg::Rect::Make(SkRect::MakeWH(100, 100)),
79cb93a386Sopenharmony_ci         r2     = sksg::Rect::Make(SkRect::MakeWH(100, 100));
80cb93a386Sopenharmony_ci    auto grp    = sksg::Group::Make();
81cb93a386Sopenharmony_ci    auto matrix = sksg::Matrix<SkMatrix>::Make(SkMatrix::I());
82cb93a386Sopenharmony_ci    auto root   = sksg::TransformEffect::Make(grp, matrix);
83cb93a386Sopenharmony_ci    auto d1     = sksg::Draw::Make(r1, color),
84cb93a386Sopenharmony_ci         d2     = sksg::Draw::Make(r2, color);
85cb93a386Sopenharmony_ci
86cb93a386Sopenharmony_ci    grp->addChild(d1);
87cb93a386Sopenharmony_ci    grp->addChild(d2);
88cb93a386Sopenharmony_ci
89cb93a386Sopenharmony_ci    {
90cb93a386Sopenharmony_ci        // Initial revalidation.
91cb93a386Sopenharmony_ci        check_inval(reporter, root,
92cb93a386Sopenharmony_ci                    SkRect::MakeWH(100, 100),
93cb93a386Sopenharmony_ci                    SkRectPriv::MakeLargeS32(),
94cb93a386Sopenharmony_ci                    nullptr);
95cb93a386Sopenharmony_ci
96cb93a386Sopenharmony_ci        check_hittest(reporter, root, {
97cb93a386Sopenharmony_ci                          {{  -1,   0 }, nullptr },
98cb93a386Sopenharmony_ci                          {{   0,  -1 }, nullptr },
99cb93a386Sopenharmony_ci                          {{ 100,   0 }, nullptr },
100cb93a386Sopenharmony_ci                          {{   0, 100 }, nullptr },
101cb93a386Sopenharmony_ci                          {{   0,   0 },      d2 },
102cb93a386Sopenharmony_ci                          {{  99,  99 },      d2 },
103cb93a386Sopenharmony_ci                      });
104cb93a386Sopenharmony_ci    }
105cb93a386Sopenharmony_ci
106cb93a386Sopenharmony_ci    {
107cb93a386Sopenharmony_ci        // Move r2 to (200 100).
108cb93a386Sopenharmony_ci        r2->setL(200); r2->setT(100); r2->setR(300); r2->setB(200);
109cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
110cb93a386Sopenharmony_ci        check_inval(reporter, root,
111cb93a386Sopenharmony_ci                    SkRect::MakeWH(300, 200),
112cb93a386Sopenharmony_ci                    SkRect::MakeWH(300, 200),
113cb93a386Sopenharmony_ci                    &damage);
114cb93a386Sopenharmony_ci
115cb93a386Sopenharmony_ci        check_hittest(reporter, root, {
116cb93a386Sopenharmony_ci                          {{  -1,   0 }, nullptr },
117cb93a386Sopenharmony_ci                          {{   0,  -1 }, nullptr },
118cb93a386Sopenharmony_ci                          {{ 100,   0 }, nullptr },
119cb93a386Sopenharmony_ci                          {{   0, 100 }, nullptr },
120cb93a386Sopenharmony_ci                          {{   0,   0 },      d1 },
121cb93a386Sopenharmony_ci                          {{  99,  99 },      d1 },
122cb93a386Sopenharmony_ci
123cb93a386Sopenharmony_ci                          {{ 199, 100 }, nullptr },
124cb93a386Sopenharmony_ci                          {{ 200,  99 }, nullptr },
125cb93a386Sopenharmony_ci                          {{ 300, 100 }, nullptr },
126cb93a386Sopenharmony_ci                          {{ 200, 200 }, nullptr },
127cb93a386Sopenharmony_ci                          {{ 200, 100 },      d2 },
128cb93a386Sopenharmony_ci                          {{ 299, 199 },      d2 },
129cb93a386Sopenharmony_ci                      });
130cb93a386Sopenharmony_ci    }
131cb93a386Sopenharmony_ci
132cb93a386Sopenharmony_ci    {
133cb93a386Sopenharmony_ci        // Update the common color.
134cb93a386Sopenharmony_ci        color->setColor(0xffff0000);
135cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
136cb93a386Sopenharmony_ci        check_inval(reporter, root,
137cb93a386Sopenharmony_ci                    SkRect::MakeWH(300, 200),
138cb93a386Sopenharmony_ci                    SkRect::MakeWH(300, 200),
139cb93a386Sopenharmony_ci                    &damage);
140cb93a386Sopenharmony_ci    }
141cb93a386Sopenharmony_ci
142cb93a386Sopenharmony_ci    {
143cb93a386Sopenharmony_ci        // Shrink r1.
144cb93a386Sopenharmony_ci        r1->setR(50);
145cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 50, 100} };
146cb93a386Sopenharmony_ci        check_inval(reporter, root,
147cb93a386Sopenharmony_ci                    SkRect::MakeWH(300, 200),
148cb93a386Sopenharmony_ci                    SkRect::MakeWH(100, 100),
149cb93a386Sopenharmony_ci                    &damage);
150cb93a386Sopenharmony_ci
151cb93a386Sopenharmony_ci        check_hittest(reporter, root, {
152cb93a386Sopenharmony_ci                          {{  -1,   0 }, nullptr },
153cb93a386Sopenharmony_ci                          {{   0,  -1 }, nullptr },
154cb93a386Sopenharmony_ci                          {{  50,   0 }, nullptr },
155cb93a386Sopenharmony_ci                          {{   0, 100 }, nullptr },
156cb93a386Sopenharmony_ci                          {{   0,   0 },      d1 },
157cb93a386Sopenharmony_ci                          {{  49,  99 },      d1 },
158cb93a386Sopenharmony_ci
159cb93a386Sopenharmony_ci                          {{ 199, 100 }, nullptr },
160cb93a386Sopenharmony_ci                          {{ 200,  99 }, nullptr },
161cb93a386Sopenharmony_ci                          {{ 300, 100 }, nullptr },
162cb93a386Sopenharmony_ci                          {{ 200, 200 }, nullptr },
163cb93a386Sopenharmony_ci                          {{ 200, 100 },      d2 },
164cb93a386Sopenharmony_ci                          {{ 299, 199 },      d2 },
165cb93a386Sopenharmony_ci                      });
166cb93a386Sopenharmony_ci    }
167cb93a386Sopenharmony_ci
168cb93a386Sopenharmony_ci    {
169cb93a386Sopenharmony_ci        // Update transform.
170cb93a386Sopenharmony_ci        matrix->setMatrix(SkMatrix::Scale(2, 2));
171cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { {0, 0, 300, 200}, { 0, 0, 600, 400} };
172cb93a386Sopenharmony_ci        check_inval(reporter, root,
173cb93a386Sopenharmony_ci                    SkRect::MakeWH(600, 400),
174cb93a386Sopenharmony_ci                    SkRect::MakeWH(600, 400),
175cb93a386Sopenharmony_ci                    &damage);
176cb93a386Sopenharmony_ci
177cb93a386Sopenharmony_ci        check_hittest(reporter, root, {
178cb93a386Sopenharmony_ci                          {{  -1,   0 }, nullptr },
179cb93a386Sopenharmony_ci                          {{   0,  -1 }, nullptr },
180cb93a386Sopenharmony_ci                          {{  25,   0 }, nullptr },
181cb93a386Sopenharmony_ci                          {{   0,  50 }, nullptr },
182cb93a386Sopenharmony_ci                          {{   0,   0 },      d1 },
183cb93a386Sopenharmony_ci                          {{  24,  49 },      d1 },
184cb93a386Sopenharmony_ci
185cb93a386Sopenharmony_ci                          {{  99,  50 }, nullptr },
186cb93a386Sopenharmony_ci                          {{ 100,  49 }, nullptr },
187cb93a386Sopenharmony_ci                          {{ 150,  50 }, nullptr },
188cb93a386Sopenharmony_ci                          {{ 100, 100 }, nullptr },
189cb93a386Sopenharmony_ci                          {{ 100,  50 },      d2 },
190cb93a386Sopenharmony_ci                          {{ 149,  99 },      d2 },
191cb93a386Sopenharmony_ci                      });
192cb93a386Sopenharmony_ci    }
193cb93a386Sopenharmony_ci
194cb93a386Sopenharmony_ci    {
195cb93a386Sopenharmony_ci        // Shrink r2 under transform.
196cb93a386Sopenharmony_ci        r2->setR(250);
197cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { {400, 200, 600, 400}, { 400, 200, 500, 400} };
198cb93a386Sopenharmony_ci        check_inval(reporter, root,
199cb93a386Sopenharmony_ci                    SkRect::MakeWH(500, 400),
200cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(400, 200, 600, 400),
201cb93a386Sopenharmony_ci                    &damage);
202cb93a386Sopenharmony_ci
203cb93a386Sopenharmony_ci        check_hittest(reporter, root, {
204cb93a386Sopenharmony_ci                          {{  -1,   0 }, nullptr },
205cb93a386Sopenharmony_ci                          {{   0,  -1 }, nullptr },
206cb93a386Sopenharmony_ci                          {{  25,   0 }, nullptr },
207cb93a386Sopenharmony_ci                          {{   0,  50 }, nullptr },
208cb93a386Sopenharmony_ci                          {{   0,   0 },      d1 },
209cb93a386Sopenharmony_ci                          {{  24,  49 },      d1 },
210cb93a386Sopenharmony_ci
211cb93a386Sopenharmony_ci                          {{  99,  50 }, nullptr },
212cb93a386Sopenharmony_ci                          {{ 100,  49 }, nullptr },
213cb93a386Sopenharmony_ci                          {{ 125,  50 }, nullptr },
214cb93a386Sopenharmony_ci                          {{ 100, 100 }, nullptr },
215cb93a386Sopenharmony_ci                          {{ 100,  50 },      d2 },
216cb93a386Sopenharmony_ci                          {{ 124,  99 },      d2 },
217cb93a386Sopenharmony_ci                      });
218cb93a386Sopenharmony_ci    }
219cb93a386Sopenharmony_ci}
220cb93a386Sopenharmony_ci
221cb93a386Sopenharmony_cistatic void inval_test2(skiatest::Reporter* reporter) {
222cb93a386Sopenharmony_ci    auto color = sksg::Color::Make(0xff000000);
223cb93a386Sopenharmony_ci    auto rect  = sksg::Rect::Make(SkRect::MakeWH(100, 100));
224cb93a386Sopenharmony_ci    auto m1    = sksg::Matrix<SkMatrix>::Make(SkMatrix::I()),
225cb93a386Sopenharmony_ci         m2    = sksg::Matrix<SkMatrix>::Make(SkMatrix::I());
226cb93a386Sopenharmony_ci    auto t1    = sksg::TransformEffect::Make(sksg::Draw::Make(rect, color),
227cb93a386Sopenharmony_ci                                             sksg::Transform::MakeConcat(m1, m2)),
228cb93a386Sopenharmony_ci         t2    = sksg::TransformEffect::Make(sksg::Draw::Make(rect, color), m1);
229cb93a386Sopenharmony_ci    auto root  = sksg::Group::Make();
230cb93a386Sopenharmony_ci    root->addChild(t1);
231cb93a386Sopenharmony_ci    root->addChild(t2);
232cb93a386Sopenharmony_ci
233cb93a386Sopenharmony_ci    {
234cb93a386Sopenharmony_ci        // Initial revalidation.
235cb93a386Sopenharmony_ci        check_inval(reporter, root,
236cb93a386Sopenharmony_ci                    SkRect::MakeWH(100, 100),
237cb93a386Sopenharmony_ci                    SkRectPriv::MakeLargeS32(),
238cb93a386Sopenharmony_ci                    nullptr);
239cb93a386Sopenharmony_ci    }
240cb93a386Sopenharmony_ci
241cb93a386Sopenharmony_ci    {
242cb93a386Sopenharmony_ci        // Update the shared color.
243cb93a386Sopenharmony_ci        color->setColor(0xffff0000);
244cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 100, 100} };
245cb93a386Sopenharmony_ci        check_inval(reporter, root,
246cb93a386Sopenharmony_ci                    SkRect::MakeWH(100, 100),
247cb93a386Sopenharmony_ci                    SkRect::MakeWH(100, 100),
248cb93a386Sopenharmony_ci                    &damage);
249cb93a386Sopenharmony_ci    }
250cb93a386Sopenharmony_ci
251cb93a386Sopenharmony_ci    {
252cb93a386Sopenharmony_ci        // Update m2.
253cb93a386Sopenharmony_ci        m2->setMatrix(SkMatrix::Scale(2, 2));
254cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 200, 200} };
255cb93a386Sopenharmony_ci        check_inval(reporter, root,
256cb93a386Sopenharmony_ci                    SkRect::MakeWH(200, 200),
257cb93a386Sopenharmony_ci                    SkRect::MakeWH(200, 200),
258cb93a386Sopenharmony_ci                    &damage);
259cb93a386Sopenharmony_ci    }
260cb93a386Sopenharmony_ci
261cb93a386Sopenharmony_ci    {
262cb93a386Sopenharmony_ci        // Update shared m1.
263cb93a386Sopenharmony_ci        m1->setMatrix(SkMatrix::Translate(100, 100));
264cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { {   0,   0, 200, 200},   // draw1 prev bounds
265cb93a386Sopenharmony_ci                                       { 100, 100, 300, 300},   // draw1 new bounds
266cb93a386Sopenharmony_ci                                       {   0,   0, 100, 100},   // draw2 prev bounds
267cb93a386Sopenharmony_ci                                       { 100, 100, 200, 200} }; // draw2 new bounds
268cb93a386Sopenharmony_ci        check_inval(reporter, root,
269cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(100, 100, 300, 300),
270cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(  0,   0, 300, 300),
271cb93a386Sopenharmony_ci                    &damage);
272cb93a386Sopenharmony_ci    }
273cb93a386Sopenharmony_ci
274cb93a386Sopenharmony_ci    {
275cb93a386Sopenharmony_ci        // Update shared rect.
276cb93a386Sopenharmony_ci        rect->setR(50);
277cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { { 100, 100, 300, 300},   // draw1 prev bounds
278cb93a386Sopenharmony_ci                                       { 100, 100, 200, 300},   // draw1 new bounds
279cb93a386Sopenharmony_ci                                       { 100, 100, 200, 200},   // draw2 prev bounds
280cb93a386Sopenharmony_ci                                       { 100, 100, 150, 200} }; // draw2 new bounds
281cb93a386Sopenharmony_ci        check_inval(reporter, root,
282cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(100, 100, 200, 300),
283cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(100, 100, 300, 300),
284cb93a386Sopenharmony_ci                    &damage);
285cb93a386Sopenharmony_ci    }
286cb93a386Sopenharmony_ci}
287cb93a386Sopenharmony_ci
288cb93a386Sopenharmony_cistatic void inval_test3(skiatest::Reporter* reporter) {
289cb93a386Sopenharmony_ci    auto color1 = sksg::Color::Make(0xff000000),
290cb93a386Sopenharmony_ci         color2 = sksg::Color::Make(0xff000000);
291cb93a386Sopenharmony_ci    auto group  = sksg::Group::Make();
292cb93a386Sopenharmony_ci
293cb93a386Sopenharmony_ci    group->addChild(sksg::Draw::Make(sksg::Rect::Make(SkRect::MakeWH(100, 100)),
294cb93a386Sopenharmony_ci                                     color1));
295cb93a386Sopenharmony_ci    group->addChild(sksg::Draw::Make(sksg::Rect::Make(SkRect::MakeXYWH(200, 0, 100, 100)),
296cb93a386Sopenharmony_ci                                     color2));
297cb93a386Sopenharmony_ci    auto filter = sksg::DropShadowImageFilter::Make();
298cb93a386Sopenharmony_ci    filter->setOffset({50, 75});
299cb93a386Sopenharmony_ci    auto root = sksg::ImageFilterEffect::Make(group, filter);
300cb93a386Sopenharmony_ci
301cb93a386Sopenharmony_ci    {
302cb93a386Sopenharmony_ci        // Initial revalidation.
303cb93a386Sopenharmony_ci        check_inval(reporter, root,
304cb93a386Sopenharmony_ci                    SkRect::MakeXYWH(0, 0, 350, 175),
305cb93a386Sopenharmony_ci                    SkRectPriv::MakeLargeS32(),
306cb93a386Sopenharmony_ci                    nullptr);
307cb93a386Sopenharmony_ci    }
308cb93a386Sopenharmony_ci
309cb93a386Sopenharmony_ci    {
310cb93a386Sopenharmony_ci        // Shadow-only.
311cb93a386Sopenharmony_ci        filter->setMode(sksg::DropShadowImageFilter::Mode::kShadowOnly);
312cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { {0, 0, 350, 175}, { 50, 75, 350, 175} };
313cb93a386Sopenharmony_ci        check_inval(reporter, root,
314cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(50, 75, 350, 175),
315cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(0, 0, 350, 175),
316cb93a386Sopenharmony_ci                    &damage);
317cb93a386Sopenharmony_ci    }
318cb93a386Sopenharmony_ci
319cb93a386Sopenharmony_ci    {
320cb93a386Sopenharmony_ci        // Content change -> single/full filter bounds inval.
321cb93a386Sopenharmony_ci        color1->setColor(0xffff0000);
322cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { { 50, 75, 350, 175} };
323cb93a386Sopenharmony_ci        check_inval(reporter, root,
324cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(50, 75, 350, 175),
325cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(50, 75, 350, 175),
326cb93a386Sopenharmony_ci                    &damage);
327cb93a386Sopenharmony_ci    }
328cb93a386Sopenharmony_ci
329cb93a386Sopenharmony_ci    {
330cb93a386Sopenharmony_ci        // Visibility change -> full inval.
331cb93a386Sopenharmony_ci        group->setVisible(false);
332cb93a386Sopenharmony_ci        std::vector<SkRect> damage = { { 50, 75, 350, 175} };
333cb93a386Sopenharmony_ci        check_inval(reporter, root,
334cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(50, 75, 350, 175),
335cb93a386Sopenharmony_ci                    SkRect::MakeLTRB(50, 75, 350, 175),
336cb93a386Sopenharmony_ci                    &damage);
337cb93a386Sopenharmony_ci    }
338cb93a386Sopenharmony_ci}
339cb93a386Sopenharmony_ci
340cb93a386Sopenharmony_cistatic void inval_group_remove(skiatest::Reporter* reporter) {
341cb93a386Sopenharmony_ci    auto draw = sksg::Draw::Make(sksg::Rect::Make(SkRect::MakeWH(100, 100)),
342cb93a386Sopenharmony_ci                                 sksg::Color::Make(SK_ColorBLACK));
343cb93a386Sopenharmony_ci    auto grp = sksg::Group::Make();
344cb93a386Sopenharmony_ci
345cb93a386Sopenharmony_ci    // Readding the child should not trigger asserts.
346cb93a386Sopenharmony_ci    grp->addChild(draw);
347cb93a386Sopenharmony_ci    grp->removeChild(draw);
348cb93a386Sopenharmony_ci    grp->addChild(draw);
349cb93a386Sopenharmony_ci}
350cb93a386Sopenharmony_ci
351cb93a386Sopenharmony_ciDEF_TEST(SGInvalidation, reporter) {
352cb93a386Sopenharmony_ci    inval_test1(reporter);
353cb93a386Sopenharmony_ci    inval_test2(reporter);
354cb93a386Sopenharmony_ci    inval_test3(reporter);
355cb93a386Sopenharmony_ci    inval_group_remove(reporter);
356cb93a386Sopenharmony_ci}
357cb93a386Sopenharmony_ci
358cb93a386Sopenharmony_ci#endif // !defined(SK_BUILD_FOR_GOOGLE3)
359