• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
8 #include "SkRect.h"
9 #include "SkRectPriv.h"
10 
11 #if !defined(SK_BUILD_FOR_GOOGLE3)
12 
13 #include "SkSGColor.h"
14 #include "SkSGDraw.h"
15 #include "SkSGGroup.h"
16 #include "SkSGInvalidationController.h"
17 #include "SkSGRect.h"
18 #include "SkSGTransform.h"
19 
20 #include "Test.h"
21 
22 #include <vector>
23 
check_inval(skiatest::Reporter * reporter,const sk_sp<sksg::Node> & root,const SkRect & expected_bounds,const SkRect & expected_inval_bounds,const std::vector<SkRect> * expected_damage)24 static void check_inval(skiatest::Reporter* reporter, const sk_sp<sksg::Node>& root,
25                         const SkRect& expected_bounds,
26                         const SkRect& expected_inval_bounds,
27                         const std::vector<SkRect>* expected_damage) {
28     sksg::InvalidationController ic;
29     const auto bbox = root->revalidate(&ic, SkMatrix::I());
30 
31     if (0) {
32         SkDebugf("** bbox: [%f %f %f %f], ibbox: [%f %f %f %f]\n",
33                  bbox.fLeft, bbox.fTop, bbox.fRight, bbox.fBottom,
34                  ic.bounds().left(), ic.bounds().top(), ic.bounds().right(), ic.bounds().bottom());
35     }
36 
37     REPORTER_ASSERT(reporter, bbox == expected_bounds);
38     REPORTER_ASSERT(reporter, ic.bounds() == expected_inval_bounds);
39 
40     if (expected_damage) {
41         const auto damage_count = SkTo<size_t>(ic.end() - ic.begin());
42         REPORTER_ASSERT(reporter, expected_damage->size() == damage_count);
43         for (size_t i = 0; i < std::min(expected_damage->size(), damage_count); ++i) {
44             const auto r1 = (*expected_damage)[i],
45                        r2 = ic.begin()[i];
46             if (0) {
47                 SkDebugf("*** expected inval: [%f %f %f %f], actual: [%f %f %f %f]\n",
48                          r1.left(), r1.top(), r1.right(), r1.bottom(),
49                          r2.left(), r2.top(), r2.right(), r2.bottom());
50             }
51             REPORTER_ASSERT(reporter, r1 == r2);
52         }
53     }
54 }
55 
inval_test1(skiatest::Reporter * reporter)56 static void inval_test1(skiatest::Reporter* reporter) {
57     auto color  = sksg::Color::Make(0xff000000);
58     auto r1     = sksg::Rect::Make(SkRect::MakeWH(100, 100)),
59          r2     = sksg::Rect::Make(SkRect::MakeWH(100, 100));
60     auto grp    = sksg::Group::Make();
61     auto matrix = sksg::Matrix::Make(SkMatrix::I());
62     auto root   = sksg::Transform::Make(grp, matrix);
63 
64     grp->addChild(sksg::Draw::Make(r1, color));
65     grp->addChild(sksg::Draw::Make(r2, color));
66 
67     {
68         // Initial revalidation.
69         check_inval(reporter, root,
70                     SkRect::MakeWH(100, 100),
71                     SkRectPriv::MakeLargeS32(),
72                     nullptr);
73     }
74 
75     {
76         // Move r2 to (200 100).
77         r2->setL(200); r2->setT(100); r2->setR(300); r2->setB(200);
78         std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
79         check_inval(reporter, root,
80                     SkRect::MakeWH(300, 200),
81                     SkRect::MakeWH(300, 200),
82                     &damage);
83     }
84 
85     {
86         // Update the common color.
87         color->setColor(0xffff0000);
88         std::vector<SkRect> damage = { {0, 0, 100, 100}, { 200, 100, 300, 200} };
89         check_inval(reporter, root,
90                     SkRect::MakeWH(300, 200),
91                     SkRect::MakeWH(300, 200),
92                     &damage);
93     }
94 
95     {
96         // Shrink r1.
97         r1->setR(50);
98         std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 50, 100} };
99         check_inval(reporter, root,
100                     SkRect::MakeWH(300, 200),
101                     SkRect::MakeWH(100, 100),
102                     &damage);
103     }
104 
105     {
106         // Update transform.
107         matrix->setMatrix(SkMatrix::MakeScale(2, 2));
108         std::vector<SkRect> damage = { {0, 0, 300, 200}, { 0, 0, 600, 400} };
109         check_inval(reporter, root,
110                     SkRect::MakeWH(600, 400),
111                     SkRect::MakeWH(600, 400),
112                     &damage);
113     }
114 
115     {
116         // Shrink r2 under transform.
117         r2->setR(250);
118         std::vector<SkRect> damage = { {400, 200, 600, 400}, { 400, 200, 500, 400} };
119         check_inval(reporter, root,
120                     SkRect::MakeWH(500, 400),
121                     SkRect::MakeLTRB(400, 200, 600, 400),
122                     &damage);
123     }
124 }
125 
inval_test2(skiatest::Reporter * reporter)126 static void inval_test2(skiatest::Reporter* reporter) {
127     auto color = sksg::Color::Make(0xff000000);
128     auto rect  = sksg::Rect::Make(SkRect::MakeWH(100, 100));
129     auto m1    = sksg::Matrix::Make(SkMatrix::I()),
130          m2    = sksg::Matrix::Make(SkMatrix::I(), m1);
131     auto t1    = sksg::Transform::Make(sksg::Draw::Make(rect, color), m2),
132          t2    = sksg::Transform::Make(sksg::Draw::Make(rect, color), m1);
133     auto root  = sksg::Group::Make();
134     root->addChild(t1);
135     root->addChild(t2);
136 
137     {
138         // Initial revalidation.
139         check_inval(reporter, root,
140                     SkRect::MakeWH(100, 100),
141                     SkRectPriv::MakeLargeS32(),
142                     nullptr);
143     }
144 
145     {
146         // Update the shared color.
147         color->setColor(0xffff0000);
148         std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 100, 100} };
149         check_inval(reporter, root,
150                     SkRect::MakeWH(100, 100),
151                     SkRect::MakeWH(100, 100),
152                     &damage);
153     }
154 
155     {
156         // Update m2.
157         m2->setMatrix(SkMatrix::MakeScale(2, 2));
158         std::vector<SkRect> damage = { {0, 0, 100, 100}, { 0, 0, 200, 200} };
159         check_inval(reporter, root,
160                     SkRect::MakeWH(200, 200),
161                     SkRect::MakeWH(200, 200),
162                     &damage);
163     }
164 
165     {
166         // Update shared m1.
167         m1->setMatrix(SkMatrix::MakeTrans(100, 100));
168         std::vector<SkRect> damage = { {   0,   0, 200, 200},   // draw1 prev bounds
169                                        { 100, 100, 300, 300},   // draw1 new bounds
170                                        {   0,   0, 100, 100},   // draw2 prev bounds
171                                        { 100, 100, 200, 200} }; // draw2 new bounds
172         check_inval(reporter, root,
173                     SkRect::MakeLTRB(100, 100, 300, 300),
174                     SkRect::MakeLTRB(  0,   0, 300, 300),
175                     &damage);
176     }
177 
178     {
179         // Update shared rect.
180         rect->setR(50);
181         std::vector<SkRect> damage = { { 100, 100, 300, 300},   // draw1 prev bounds
182                                        { 100, 100, 200, 300},   // draw1 new bounds
183                                        { 100, 100, 200, 200},   // draw2 prev bounds
184                                        { 100, 100, 150, 200} }; // draw2 new bounds
185         check_inval(reporter, root,
186                     SkRect::MakeLTRB(100, 100, 200, 300),
187                     SkRect::MakeLTRB(100, 100, 300, 300),
188                     &damage);
189     }
190 }
191 
DEF_TEST(SGInvalidation,reporter)192 DEF_TEST(SGInvalidation, reporter) {
193     inval_test1(reporter);
194     inval_test2(reporter);
195 }
196 
197 #endif // !defined(SK_BUILD_FOR_GOOGLE3)
198