Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1364)

Side by Side Diff: tests/ClipStackTest.cpp

Issue 2355483002: abstract name of clipping ops, to transtion to a more restricted set (Closed)
Patch Set: no need for ifdef for globals Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tests/ClipBoundsTest.cpp ('k') | tests/DrawPathTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "Test.h" 8 #include "Test.h"
9 #include "SkClipStack.h" 9 #include "SkClipStack.h"
10 #include "SkPath.h" 10 #include "SkPath.h"
(...skipping 15 matching lines...) Expand all
26 26
27 // Build up a clip stack with a path, an empty clip, and a rect. 27 // Build up a clip stack with a path, an empty clip, and a rect.
28 s.save(); 28 s.save();
29 REPORTER_ASSERT(reporter, 1 == s.getSaveCount()); 29 REPORTER_ASSERT(reporter, 1 == s.getSaveCount());
30 30
31 SkPath p; 31 SkPath p;
32 p.moveTo(5, 6); 32 p.moveTo(5, 6);
33 p.lineTo(7, 8); 33 p.lineTo(7, 8);
34 p.lineTo(5, 9); 34 p.lineTo(5, 9);
35 p.close(); 35 p.close();
36 s.clipDevPath(p, SkRegion::kIntersect_Op, doAA); 36 s.clipDevPath(p, SkCanvas::kIntersect_Op, doAA);
37 37
38 s.save(); 38 s.save();
39 REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 39 REPORTER_ASSERT(reporter, 2 == s.getSaveCount());
40 40
41 SkRect r = SkRect::MakeLTRB(1, 2, 3, 4); 41 SkRect r = SkRect::MakeLTRB(1, 2, 3, 4);
42 s.clipDevRect(r, SkRegion::kIntersect_Op, doAA); 42 s.clipDevRect(r, SkCanvas::kIntersect_Op, doAA);
43 r = SkRect::MakeLTRB(10, 11, 12, 13); 43 r = SkRect::MakeLTRB(10, 11, 12, 13);
44 s.clipDevRect(r, SkRegion::kIntersect_Op, doAA); 44 s.clipDevRect(r, SkCanvas::kIntersect_Op, doAA);
45 45
46 s.save(); 46 s.save();
47 REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 47 REPORTER_ASSERT(reporter, 3 == s.getSaveCount());
48 48
49 r = SkRect::MakeLTRB(14, 15, 16, 17); 49 r = SkRect::MakeLTRB(14, 15, 16, 17);
50 s.clipDevRect(r, SkRegion::kUnion_Op, doAA); 50 s.clipDevRect(r, SkCanvas::kUnion_Op, doAA);
51 51
52 // Test that assignment works. 52 // Test that assignment works.
53 SkClipStack copy = s; 53 SkClipStack copy = s;
54 REPORTER_ASSERT(reporter, s == copy); 54 REPORTER_ASSERT(reporter, s == copy);
55 55
56 // Test that different save levels triggers not equal. 56 // Test that different save levels triggers not equal.
57 s.restore(); 57 s.restore();
58 REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 58 REPORTER_ASSERT(reporter, 2 == s.getSaveCount());
59 REPORTER_ASSERT(reporter, s != copy); 59 REPORTER_ASSERT(reporter, s != copy);
60 60
61 // Test that an equal, but not copied version is equal. 61 // Test that an equal, but not copied version is equal.
62 s.save(); 62 s.save();
63 REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 63 REPORTER_ASSERT(reporter, 3 == s.getSaveCount());
64 r = SkRect::MakeLTRB(14, 15, 16, 17); 64 r = SkRect::MakeLTRB(14, 15, 16, 17);
65 s.clipDevRect(r, SkRegion::kUnion_Op, doAA); 65 s.clipDevRect(r, SkCanvas::kUnion_Op, doAA);
66 REPORTER_ASSERT(reporter, s == copy); 66 REPORTER_ASSERT(reporter, s == copy);
67 67
68 // Test that a different op on one level triggers not equal. 68 // Test that a different op on one level triggers not equal.
69 s.restore(); 69 s.restore();
70 REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 70 REPORTER_ASSERT(reporter, 2 == s.getSaveCount());
71 s.save(); 71 s.save();
72 REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 72 REPORTER_ASSERT(reporter, 3 == s.getSaveCount());
73 r = SkRect::MakeLTRB(14, 15, 16, 17); 73 r = SkRect::MakeLTRB(14, 15, 16, 17);
74 s.clipDevRect(r, SkRegion::kIntersect_Op, doAA); 74 s.clipDevRect(r, SkCanvas::kIntersect_Op, doAA);
75 REPORTER_ASSERT(reporter, s != copy); 75 REPORTER_ASSERT(reporter, s != copy);
76 76
77 // Test that version constructed with rect-path rather than a rect is still considered equal. 77 // Test that version constructed with rect-path rather than a rect is still considered equal.
78 s.restore(); 78 s.restore();
79 s.save(); 79 s.save();
80 SkPath rp; 80 SkPath rp;
81 rp.addRect(r); 81 rp.addRect(r);
82 s.clipDevPath(rp, SkRegion::kUnion_Op, doAA); 82 s.clipDevPath(rp, SkCanvas::kUnion_Op, doAA);
83 REPORTER_ASSERT(reporter, s == copy); 83 REPORTER_ASSERT(reporter, s == copy);
84 84
85 // Test that different rects triggers not equal. 85 // Test that different rects triggers not equal.
86 s.restore(); 86 s.restore();
87 REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 87 REPORTER_ASSERT(reporter, 2 == s.getSaveCount());
88 s.save(); 88 s.save();
89 REPORTER_ASSERT(reporter, 3 == s.getSaveCount()); 89 REPORTER_ASSERT(reporter, 3 == s.getSaveCount());
90 90
91 r = SkRect::MakeLTRB(24, 25, 26, 27); 91 r = SkRect::MakeLTRB(24, 25, 26, 27);
92 s.clipDevRect(r, SkRegion::kUnion_Op, doAA); 92 s.clipDevRect(r, SkCanvas::kUnion_Op, doAA);
93 REPORTER_ASSERT(reporter, s != copy); 93 REPORTER_ASSERT(reporter, s != copy);
94 94
95 // Sanity check 95 // Sanity check
96 s.restore(); 96 s.restore();
97 REPORTER_ASSERT(reporter, 2 == s.getSaveCount()); 97 REPORTER_ASSERT(reporter, 2 == s.getSaveCount());
98 98
99 copy.restore(); 99 copy.restore();
100 REPORTER_ASSERT(reporter, 2 == copy.getSaveCount()); 100 REPORTER_ASSERT(reporter, 2 == copy.getSaveCount());
101 REPORTER_ASSERT(reporter, s == copy); 101 REPORTER_ASSERT(reporter, s == copy);
102 s.restore(); 102 s.restore();
103 REPORTER_ASSERT(reporter, 1 == s.getSaveCount()); 103 REPORTER_ASSERT(reporter, 1 == s.getSaveCount());
104 copy.restore(); 104 copy.restore();
105 REPORTER_ASSERT(reporter, 1 == copy.getSaveCount()); 105 REPORTER_ASSERT(reporter, 1 == copy.getSaveCount());
106 REPORTER_ASSERT(reporter, s == copy); 106 REPORTER_ASSERT(reporter, s == copy);
107 107
108 // Test that different paths triggers not equal. 108 // Test that different paths triggers not equal.
109 s.restore(); 109 s.restore();
110 REPORTER_ASSERT(reporter, 0 == s.getSaveCount()); 110 REPORTER_ASSERT(reporter, 0 == s.getSaveCount());
111 s.save(); 111 s.save();
112 REPORTER_ASSERT(reporter, 1 == s.getSaveCount()); 112 REPORTER_ASSERT(reporter, 1 == s.getSaveCount());
113 113
114 p.addRect(r); 114 p.addRect(r);
115 s.clipDevPath(p, SkRegion::kIntersect_Op, doAA); 115 s.clipDevPath(p, SkCanvas::kIntersect_Op, doAA);
116 REPORTER_ASSERT(reporter, s != copy); 116 REPORTER_ASSERT(reporter, s != copy);
117 } 117 }
118 118
119 static void assert_count(skiatest::Reporter* reporter, const SkClipStack& stack, 119 static void assert_count(skiatest::Reporter* reporter, const SkClipStack& stack,
120 int count) { 120 int count) {
121 SkClipStack::B2TIter iter(stack); 121 SkClipStack::B2TIter iter(stack);
122 int counter = 0; 122 int counter = 0;
123 while (iter.next()) { 123 while (iter.next()) {
124 counter += 1; 124 counter += 1;
125 } 125 }
126 REPORTER_ASSERT(reporter, count == counter); 126 REPORTER_ASSERT(reporter, count == counter);
127 } 127 }
128 128
129 // Exercise the SkClipStack's bottom to top and bidirectional iterators 129 // Exercise the SkClipStack's bottom to top and bidirectional iterators
130 // (including the skipToTopmost functionality) 130 // (including the skipToTopmost functionality)
131 static void test_iterators(skiatest::Reporter* reporter) { 131 static void test_iterators(skiatest::Reporter* reporter) {
132 SkClipStack stack; 132 SkClipStack stack;
133 133
134 static const SkRect gRects[] = { 134 static const SkRect gRects[] = {
135 { 0, 0, 40, 40 }, 135 { 0, 0, 40, 40 },
136 { 60, 0, 100, 40 }, 136 { 60, 0, 100, 40 },
137 { 0, 60, 40, 100 }, 137 { 0, 60, 40, 100 },
138 { 60, 60, 100, 100 } 138 { 60, 60, 100, 100 }
139 }; 139 };
140 140
141 for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) { 141 for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) {
142 // the union op will prevent these from being fused together 142 // the union op will prevent these from being fused together
143 stack.clipDevRect(gRects[i], SkRegion::kUnion_Op, false); 143 stack.clipDevRect(gRects[i], SkCanvas::kUnion_Op, false);
144 } 144 }
145 145
146 assert_count(reporter, stack, 4); 146 assert_count(reporter, stack, 4);
147 147
148 // bottom to top iteration 148 // bottom to top iteration
149 { 149 {
150 const SkClipStack::Element* element = nullptr; 150 const SkClipStack::Element* element = nullptr;
151 151
152 SkClipStack::B2TIter iter(stack); 152 SkClipStack::B2TIter iter(stack);
153 int i; 153 int i;
(...skipping 20 matching lines...) Expand all
174 174
175 SkASSERT(i == -1); 175 SkASSERT(i == -1);
176 } 176 }
177 177
178 // skipToTopmost 178 // skipToTopmost
179 { 179 {
180 const SkClipStack::Element* element = nullptr; 180 const SkClipStack::Element* element = nullptr;
181 181
182 SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 182 SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
183 183
184 element = iter.skipToTopmost(SkRegion::kUnion_Op); 184 element = iter.skipToTopmost(SkCanvas::kUnion_Op);
185 REPORTER_ASSERT(reporter, SkClipStack::Element::kRect_Type == element->g etType()); 185 REPORTER_ASSERT(reporter, SkClipStack::Element::kRect_Type == element->g etType());
186 REPORTER_ASSERT(reporter, element->getRect() == gRects[3]); 186 REPORTER_ASSERT(reporter, element->getRect() == gRects[3]);
187 } 187 }
188 } 188 }
189 189
190 // Exercise the SkClipStack's getConservativeBounds computation 190 // Exercise the SkClipStack's getConservativeBounds computation
191 static void test_bounds(skiatest::Reporter* reporter, SkClipStack::Element::Type primType) { 191 static void test_bounds(skiatest::Reporter* reporter, SkClipStack::Element::Type primType) {
192 static const int gNumCases = 20; 192 static const int gNumCases = 20;
193 static const SkRect gAnswerRectsBW[gNumCases] = { 193 static const SkRect gAnswerRectsBW[gNumCases] = {
194 // A op B 194 // A op B
(...skipping 18 matching lines...) Expand all
213 { 0, 0, 100, 100 }, 213 { 0, 0, 100, 100 },
214 214
215 // invA op invB 215 // invA op invB
216 { 0, 0, 100, 100 }, 216 { 0, 0, 100, 100 },
217 { 40, 40, 80, 80 }, 217 { 40, 40, 80, 80 },
218 { 0, 0, 100, 100 }, 218 { 0, 0, 100, 100 },
219 { 10, 10, 80, 80 }, 219 { 10, 10, 80, 80 },
220 { 10, 10, 50, 50 }, 220 { 10, 10, 50, 50 },
221 }; 221 };
222 222
223 static const SkRegion::Op gOps[] = { 223 static const SkCanvas::ClipOp gOps[] = {
224 SkRegion::kIntersect_Op, 224 SkCanvas::kIntersect_Op,
225 SkRegion::kDifference_Op, 225 SkCanvas::kDifference_Op,
226 SkRegion::kUnion_Op, 226 SkCanvas::kUnion_Op,
227 SkRegion::kXOR_Op, 227 SkCanvas::kXOR_Op,
228 SkRegion::kReverseDifference_Op 228 SkCanvas::kReverseDifference_Op
229 }; 229 };
230 230
231 SkRect rectA, rectB; 231 SkRect rectA, rectB;
232 232
233 rectA.iset(10, 10, 50, 50); 233 rectA.iset(10, 10, 50, 50);
234 rectB.iset(40, 40, 80, 80); 234 rectB.iset(40, 40, 80, 80);
235 235
236 SkRRect rrectA, rrectB; 236 SkRRect rrectA, rrectB;
237 rrectA.setOval(rectA); 237 rrectA.setOval(rectA);
238 rrectB.setRectXY(rectB, SkIntToScalar(1), SkIntToScalar(2)); 238 rrectB.setRectXY(rectB, SkIntToScalar(1), SkIntToScalar(2));
(...skipping 19 matching lines...) Expand all
258 pathA.setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType : 258 pathA.setFillType(doInvA ? SkPath::kInverseEvenOdd_FillType :
259 SkPath::kEvenOdd_FillType); 259 SkPath::kEvenOdd_FillType);
260 pathB.setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType : 260 pathB.setFillType(doInvB ? SkPath::kInverseEvenOdd_FillType :
261 SkPath::kEvenOdd_FillType); 261 SkPath::kEvenOdd_FillType);
262 262
263 switch (primType) { 263 switch (primType) {
264 case SkClipStack::Element::kEmpty_Type: 264 case SkClipStack::Element::kEmpty_Type:
265 SkDEBUGFAIL("Don't call this with kEmpty."); 265 SkDEBUGFAIL("Don't call this with kEmpty.");
266 break; 266 break;
267 case SkClipStack::Element::kRect_Type: 267 case SkClipStack::Element::kRect_Type:
268 stack.clipDevRect(rectA, SkRegion::kIntersect_Op, false); 268 stack.clipDevRect(rectA, SkCanvas::kIntersect_Op, false);
269 stack.clipDevRect(rectB, gOps[op], false); 269 stack.clipDevRect(rectB, gOps[op], false);
270 break; 270 break;
271 case SkClipStack::Element::kRRect_Type: 271 case SkClipStack::Element::kRRect_Type:
272 stack.clipDevRRect(rrectA, SkRegion::kIntersect_Op, false); 272 stack.clipDevRRect(rrectA, SkCanvas::kIntersect_Op, false);
273 stack.clipDevRRect(rrectB, gOps[op], false); 273 stack.clipDevRRect(rrectB, gOps[op], false);
274 break; 274 break;
275 case SkClipStack::Element::kPath_Type: 275 case SkClipStack::Element::kPath_Type:
276 stack.clipDevPath(pathA, SkRegion::kIntersect_Op, false); 276 stack.clipDevPath(pathA, SkCanvas::kIntersect_Op, false);
277 stack.clipDevPath(pathB, gOps[op], false); 277 stack.clipDevPath(pathB, gOps[op], false);
278 break; 278 break;
279 } 279 }
280 280
281 REPORTER_ASSERT(reporter, !stack.isWideOpen()); 281 REPORTER_ASSERT(reporter, !stack.isWideOpen());
282 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID != stack.getTo pmostGenID()); 282 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID != stack.getTo pmostGenID());
283 283
284 stack.getConservativeBounds(0, 0, 100, 100, &devClipBound, 284 stack.getConservativeBounds(0, 0, 100, 100, &devClipBound,
285 &isIntersectionOfRects); 285 &isIntersectionOfRects);
286 286
287 if (SkClipStack::Element::kRect_Type == primType) { 287 if (SkClipStack::Element::kRect_Type == primType) {
288 REPORTER_ASSERT(reporter, isIntersectionOfRects == 288 REPORTER_ASSERT(reporter, isIntersectionOfRects ==
289 (gOps[op] == SkRegion::kIntersect_Op)); 289 (gOps[op] == SkCanvas::kIntersect_Op));
290 } else { 290 } else {
291 REPORTER_ASSERT(reporter, !isIntersectionOfRects); 291 REPORTER_ASSERT(reporter, !isIntersectionOfRects);
292 } 292 }
293 293
294 SkASSERT(testCase < gNumCases); 294 SkASSERT(testCase < gNumCases);
295 REPORTER_ASSERT(reporter, devClipBound == gAnswerRectsBW[testCase]); 295 REPORTER_ASSERT(reporter, devClipBound == gAnswerRectsBW[testCase]);
296 ++testCase; 296 ++testCase;
297 297
298 stack.restore(); 298 stack.restore();
299 } 299 }
(...skipping 27 matching lines...) Expand all
327 SkClipStack stack; 327 SkClipStack stack;
328 328
329 SkPath clipA, clipB; 329 SkPath clipA, clipB;
330 330
331 clipA.addRoundRect(rectA, SkIntToScalar(5), SkIntToScalar(5)); 331 clipA.addRoundRect(rectA, SkIntToScalar(5), SkIntToScalar(5));
332 clipA.setFillType(SkPath::kInverseEvenOdd_FillType); 332 clipA.setFillType(SkPath::kInverseEvenOdd_FillType);
333 333
334 clipB.addRoundRect(rectB, SkIntToScalar(5), SkIntToScalar(5)); 334 clipB.addRoundRect(rectB, SkIntToScalar(5), SkIntToScalar(5));
335 clipB.setFillType(SkPath::kInverseEvenOdd_FillType); 335 clipB.setFillType(SkPath::kInverseEvenOdd_FillType);
336 336
337 stack.clipDevPath(clipA, SkRegion::kReplace_Op, false); 337 stack.clipDevPath(clipA, SkCanvas::kReplace_Op, false);
338 stack.clipDevPath(clipB, SkRegion::kUnion_Op, false); 338 stack.clipDevPath(clipB, SkCanvas::kUnion_Op, false);
339 339
340 REPORTER_ASSERT(reporter, stack.isWideOpen()); 340 REPORTER_ASSERT(reporter, stack.isWideOpen());
341 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmos tGenID()); 341 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmos tGenID());
342 } 342 }
343 343
344 // Test out union w/ a wide open clip 344 // Test out union w/ a wide open clip
345 { 345 {
346 SkClipStack stack; 346 SkClipStack stack;
347 347
348 stack.clipDevRect(rectA, SkRegion::kUnion_Op, false); 348 stack.clipDevRect(rectA, SkCanvas::kUnion_Op, false);
349 349
350 REPORTER_ASSERT(reporter, stack.isWideOpen()); 350 REPORTER_ASSERT(reporter, stack.isWideOpen());
351 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmos tGenID()); 351 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmos tGenID());
352 } 352 }
353 353
354 // Test out empty difference from a wide open clip 354 // Test out empty difference from a wide open clip
355 { 355 {
356 SkClipStack stack; 356 SkClipStack stack;
357 357
358 SkRect emptyRect; 358 SkRect emptyRect;
359 emptyRect.setEmpty(); 359 emptyRect.setEmpty();
360 360
361 stack.clipDevRect(emptyRect, SkRegion::kDifference_Op, false); 361 stack.clipDevRect(emptyRect, SkCanvas::kDifference_Op, false);
362 362
363 REPORTER_ASSERT(reporter, stack.isWideOpen()); 363 REPORTER_ASSERT(reporter, stack.isWideOpen());
364 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmos tGenID()); 364 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmos tGenID());
365 } 365 }
366 366
367 // Test out return to wide open 367 // Test out return to wide open
368 { 368 {
369 SkClipStack stack; 369 SkClipStack stack;
370 370
371 stack.save(); 371 stack.save();
372 372
373 stack.clipDevRect(rectA, SkRegion::kReplace_Op, false); 373 stack.clipDevRect(rectA, SkCanvas::kReplace_Op, false);
374 374
375 REPORTER_ASSERT(reporter, !stack.isWideOpen()); 375 REPORTER_ASSERT(reporter, !stack.isWideOpen());
376 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID != stack.getTopmos tGenID()); 376 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID != stack.getTopmos tGenID());
377 377
378 stack.restore(); 378 stack.restore();
379 379
380 REPORTER_ASSERT(reporter, stack.isWideOpen()); 380 REPORTER_ASSERT(reporter, stack.isWideOpen());
381 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmos tGenID()); 381 REPORTER_ASSERT(reporter, SkClipStack::kWideOpenGenID == stack.getTopmos tGenID());
382 } 382 }
383 } 383 }
(...skipping 13 matching lines...) Expand all
397 } 397 }
398 398
399 static void test_rect_inverse_fill(skiatest::Reporter* reporter) { 399 static void test_rect_inverse_fill(skiatest::Reporter* reporter) {
400 // non-intersecting rectangles 400 // non-intersecting rectangles
401 SkRect rect = SkRect::MakeLTRB(0, 0, 10, 10); 401 SkRect rect = SkRect::MakeLTRB(0, 0, 10, 10);
402 402
403 SkPath path; 403 SkPath path;
404 path.addRect(rect); 404 path.addRect(rect);
405 path.toggleInverseFillType(); 405 path.toggleInverseFillType();
406 SkClipStack stack; 406 SkClipStack stack;
407 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 407 stack.clipDevPath(path, SkCanvas::kIntersect_Op, false);
408 408
409 SkRect bounds; 409 SkRect bounds;
410 SkClipStack::BoundsType boundsType; 410 SkClipStack::BoundsType boundsType;
411 stack.getBounds(&bounds, &boundsType); 411 stack.getBounds(&bounds, &boundsType);
412 REPORTER_ASSERT(reporter, SkClipStack::kInsideOut_BoundsType == boundsType); 412 REPORTER_ASSERT(reporter, SkClipStack::kInsideOut_BoundsType == boundsType);
413 REPORTER_ASSERT(reporter, bounds == rect); 413 REPORTER_ASSERT(reporter, bounds == rect);
414 } 414 }
415 415
416 static void test_rect_replace(skiatest::Reporter* reporter) { 416 static void test_rect_replace(skiatest::Reporter* reporter) {
417 SkRect rect = SkRect::MakeWH(100, 100); 417 SkRect rect = SkRect::MakeWH(100, 100);
418 SkRect rect2 = SkRect::MakeXYWH(50, 50, 100, 100); 418 SkRect rect2 = SkRect::MakeXYWH(50, 50, 100, 100);
419 419
420 SkRect bound; 420 SkRect bound;
421 SkClipStack::BoundsType type; 421 SkClipStack::BoundsType type;
422 bool isIntersectionOfRects; 422 bool isIntersectionOfRects;
423 423
424 // Adding a new rect with the replace operator should not increase 424 // Adding a new rect with the replace operator should not increase
425 // the stack depth. BW replacing BW. 425 // the stack depth. BW replacing BW.
426 { 426 {
427 SkClipStack stack; 427 SkClipStack stack;
428 REPORTER_ASSERT(reporter, 0 == count(stack)); 428 REPORTER_ASSERT(reporter, 0 == count(stack));
429 stack.clipDevRect(rect, SkRegion::kReplace_Op, false); 429 stack.clipDevRect(rect, SkCanvas::kReplace_Op, false);
430 REPORTER_ASSERT(reporter, 1 == count(stack)); 430 REPORTER_ASSERT(reporter, 1 == count(stack));
431 stack.clipDevRect(rect, SkRegion::kReplace_Op, false); 431 stack.clipDevRect(rect, SkCanvas::kReplace_Op, false);
432 REPORTER_ASSERT(reporter, 1 == count(stack)); 432 REPORTER_ASSERT(reporter, 1 == count(stack));
433 } 433 }
434 434
435 // Adding a new rect with the replace operator should not increase 435 // Adding a new rect with the replace operator should not increase
436 // the stack depth. AA replacing AA. 436 // the stack depth. AA replacing AA.
437 { 437 {
438 SkClipStack stack; 438 SkClipStack stack;
439 REPORTER_ASSERT(reporter, 0 == count(stack)); 439 REPORTER_ASSERT(reporter, 0 == count(stack));
440 stack.clipDevRect(rect, SkRegion::kReplace_Op, true); 440 stack.clipDevRect(rect, SkCanvas::kReplace_Op, true);
441 REPORTER_ASSERT(reporter, 1 == count(stack)); 441 REPORTER_ASSERT(reporter, 1 == count(stack));
442 stack.clipDevRect(rect, SkRegion::kReplace_Op, true); 442 stack.clipDevRect(rect, SkCanvas::kReplace_Op, true);
443 REPORTER_ASSERT(reporter, 1 == count(stack)); 443 REPORTER_ASSERT(reporter, 1 == count(stack));
444 } 444 }
445 445
446 // Adding a new rect with the replace operator should not increase 446 // Adding a new rect with the replace operator should not increase
447 // the stack depth. BW replacing AA replacing BW. 447 // the stack depth. BW replacing AA replacing BW.
448 { 448 {
449 SkClipStack stack; 449 SkClipStack stack;
450 REPORTER_ASSERT(reporter, 0 == count(stack)); 450 REPORTER_ASSERT(reporter, 0 == count(stack));
451 stack.clipDevRect(rect, SkRegion::kReplace_Op, false); 451 stack.clipDevRect(rect, SkCanvas::kReplace_Op, false);
452 REPORTER_ASSERT(reporter, 1 == count(stack)); 452 REPORTER_ASSERT(reporter, 1 == count(stack));
453 stack.clipDevRect(rect, SkRegion::kReplace_Op, true); 453 stack.clipDevRect(rect, SkCanvas::kReplace_Op, true);
454 REPORTER_ASSERT(reporter, 1 == count(stack)); 454 REPORTER_ASSERT(reporter, 1 == count(stack));
455 stack.clipDevRect(rect, SkRegion::kReplace_Op, false); 455 stack.clipDevRect(rect, SkCanvas::kReplace_Op, false);
456 REPORTER_ASSERT(reporter, 1 == count(stack)); 456 REPORTER_ASSERT(reporter, 1 == count(stack));
457 } 457 }
458 458
459 // Make sure replace clip rects don't collapse too much. 459 // Make sure replace clip rects don't collapse too much.
460 { 460 {
461 SkClipStack stack; 461 SkClipStack stack;
462 stack.clipDevRect(rect, SkRegion::kReplace_Op, false); 462 stack.clipDevRect(rect, SkCanvas::kReplace_Op, false);
463 stack.clipDevRect(rect2, SkRegion::kIntersect_Op, false); 463 stack.clipDevRect(rect2, SkCanvas::kIntersect_Op, false);
464 REPORTER_ASSERT(reporter, 1 == count(stack)); 464 REPORTER_ASSERT(reporter, 1 == count(stack));
465 465
466 stack.save(); 466 stack.save();
467 stack.clipDevRect(rect, SkRegion::kReplace_Op, false); 467 stack.clipDevRect(rect, SkCanvas::kReplace_Op, false);
468 REPORTER_ASSERT(reporter, 2 == count(stack)); 468 REPORTER_ASSERT(reporter, 2 == count(stack));
469 stack.getBounds(&bound, &type, &isIntersectionOfRects); 469 stack.getBounds(&bound, &type, &isIntersectionOfRects);
470 REPORTER_ASSERT(reporter, bound == rect); 470 REPORTER_ASSERT(reporter, bound == rect);
471 stack.restore(); 471 stack.restore();
472 REPORTER_ASSERT(reporter, 1 == count(stack)); 472 REPORTER_ASSERT(reporter, 1 == count(stack));
473 473
474 stack.save(); 474 stack.save();
475 stack.clipDevRect(rect, SkRegion::kReplace_Op, false); 475 stack.clipDevRect(rect, SkCanvas::kReplace_Op, false);
476 stack.clipDevRect(rect, SkRegion::kReplace_Op, false); 476 stack.clipDevRect(rect, SkCanvas::kReplace_Op, false);
477 REPORTER_ASSERT(reporter, 2 == count(stack)); 477 REPORTER_ASSERT(reporter, 2 == count(stack));
478 stack.restore(); 478 stack.restore();
479 REPORTER_ASSERT(reporter, 1 == count(stack)); 479 REPORTER_ASSERT(reporter, 1 == count(stack));
480 480
481 stack.save(); 481 stack.save();
482 stack.clipDevRect(rect, SkRegion::kReplace_Op, false); 482 stack.clipDevRect(rect, SkCanvas::kReplace_Op, false);
483 stack.clipDevRect(rect2, SkRegion::kIntersect_Op, false); 483 stack.clipDevRect(rect2, SkCanvas::kIntersect_Op, false);
484 stack.clipDevRect(rect, SkRegion::kReplace_Op, false); 484 stack.clipDevRect(rect, SkCanvas::kReplace_Op, false);
485 REPORTER_ASSERT(reporter, 2 == count(stack)); 485 REPORTER_ASSERT(reporter, 2 == count(stack));
486 stack.restore(); 486 stack.restore();
487 REPORTER_ASSERT(reporter, 1 == count(stack)); 487 REPORTER_ASSERT(reporter, 1 == count(stack));
488 } 488 }
489 } 489 }
490 490
491 // Simplified path-based version of test_rect_replace. 491 // Simplified path-based version of test_rect_replace.
492 static void test_path_replace(skiatest::Reporter* reporter) { 492 static void test_path_replace(skiatest::Reporter* reporter) {
493 SkRect rect = SkRect::MakeWH(100, 100); 493 SkRect rect = SkRect::MakeWH(100, 100);
494 SkPath path; 494 SkPath path;
495 path.addCircle(50, 50, 50); 495 path.addCircle(50, 50, 50);
496 496
497 // Replace operation doesn't grow the stack. 497 // Replace operation doesn't grow the stack.
498 { 498 {
499 SkClipStack stack; 499 SkClipStack stack;
500 REPORTER_ASSERT(reporter, 0 == count(stack)); 500 REPORTER_ASSERT(reporter, 0 == count(stack));
501 stack.clipDevPath(path, SkRegion::kReplace_Op, false); 501 stack.clipDevPath(path, SkCanvas::kReplace_Op, false);
502 REPORTER_ASSERT(reporter, 1 == count(stack)); 502 REPORTER_ASSERT(reporter, 1 == count(stack));
503 stack.clipDevPath(path, SkRegion::kReplace_Op, false); 503 stack.clipDevPath(path, SkCanvas::kReplace_Op, false);
504 REPORTER_ASSERT(reporter, 1 == count(stack)); 504 REPORTER_ASSERT(reporter, 1 == count(stack));
505 } 505 }
506 506
507 // Replacing rect with path. 507 // Replacing rect with path.
508 { 508 {
509 SkClipStack stack; 509 SkClipStack stack;
510 stack.clipDevRect(rect, SkRegion::kReplace_Op, true); 510 stack.clipDevRect(rect, SkCanvas::kReplace_Op, true);
511 REPORTER_ASSERT(reporter, 1 == count(stack)); 511 REPORTER_ASSERT(reporter, 1 == count(stack));
512 stack.clipDevPath(path, SkRegion::kReplace_Op, true); 512 stack.clipDevPath(path, SkCanvas::kReplace_Op, true);
513 REPORTER_ASSERT(reporter, 1 == count(stack)); 513 REPORTER_ASSERT(reporter, 1 == count(stack));
514 } 514 }
515 } 515 }
516 516
517 // Test out SkClipStack's merging of rect clips. In particular exercise 517 // Test out SkClipStack's merging of rect clips. In particular exercise
518 // merging of aa vs. bw rects. 518 // merging of aa vs. bw rects.
519 static void test_rect_merging(skiatest::Reporter* reporter) { 519 static void test_rect_merging(skiatest::Reporter* reporter) {
520 520
521 SkRect overlapLeft = SkRect::MakeLTRB(10, 10, 50, 50); 521 SkRect overlapLeft = SkRect::MakeLTRB(10, 10, 50, 50);
522 SkRect overlapRight = SkRect::MakeLTRB(40, 40, 80, 80); 522 SkRect overlapRight = SkRect::MakeLTRB(40, 40, 80, 80);
523 523
524 SkRect nestedParent = SkRect::MakeLTRB(10, 10, 90, 90); 524 SkRect nestedParent = SkRect::MakeLTRB(10, 10, 90, 90);
525 SkRect nestedChild = SkRect::MakeLTRB(40, 40, 60, 60); 525 SkRect nestedChild = SkRect::MakeLTRB(40, 40, 60, 60);
526 526
527 SkRect bound; 527 SkRect bound;
528 SkClipStack::BoundsType type; 528 SkClipStack::BoundsType type;
529 bool isIntersectionOfRects; 529 bool isIntersectionOfRects;
530 530
531 // all bw overlapping - should merge 531 // all bw overlapping - should merge
532 { 532 {
533 SkClipStack stack; 533 SkClipStack stack;
534 534
535 stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, false); 535 stack.clipDevRect(overlapLeft, SkCanvas::kReplace_Op, false);
536 536
537 stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); 537 stack.clipDevRect(overlapRight, SkCanvas::kIntersect_Op, false);
538 538
539 REPORTER_ASSERT(reporter, 1 == count(stack)); 539 REPORTER_ASSERT(reporter, 1 == count(stack));
540 540
541 stack.getBounds(&bound, &type, &isIntersectionOfRects); 541 stack.getBounds(&bound, &type, &isIntersectionOfRects);
542 542
543 REPORTER_ASSERT(reporter, isIntersectionOfRects); 543 REPORTER_ASSERT(reporter, isIntersectionOfRects);
544 } 544 }
545 545
546 // all aa overlapping - should merge 546 // all aa overlapping - should merge
547 { 547 {
548 SkClipStack stack; 548 SkClipStack stack;
549 549
550 stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, true); 550 stack.clipDevRect(overlapLeft, SkCanvas::kReplace_Op, true);
551 551
552 stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, true); 552 stack.clipDevRect(overlapRight, SkCanvas::kIntersect_Op, true);
553 553
554 REPORTER_ASSERT(reporter, 1 == count(stack)); 554 REPORTER_ASSERT(reporter, 1 == count(stack));
555 555
556 stack.getBounds(&bound, &type, &isIntersectionOfRects); 556 stack.getBounds(&bound, &type, &isIntersectionOfRects);
557 557
558 REPORTER_ASSERT(reporter, isIntersectionOfRects); 558 REPORTER_ASSERT(reporter, isIntersectionOfRects);
559 } 559 }
560 560
561 // mixed overlapping - should _not_ merge 561 // mixed overlapping - should _not_ merge
562 { 562 {
563 SkClipStack stack; 563 SkClipStack stack;
564 564
565 stack.clipDevRect(overlapLeft, SkRegion::kReplace_Op, true); 565 stack.clipDevRect(overlapLeft, SkCanvas::kReplace_Op, true);
566 566
567 stack.clipDevRect(overlapRight, SkRegion::kIntersect_Op, false); 567 stack.clipDevRect(overlapRight, SkCanvas::kIntersect_Op, false);
568 568
569 REPORTER_ASSERT(reporter, 2 == count(stack)); 569 REPORTER_ASSERT(reporter, 2 == count(stack));
570 570
571 stack.getBounds(&bound, &type, &isIntersectionOfRects); 571 stack.getBounds(&bound, &type, &isIntersectionOfRects);
572 572
573 REPORTER_ASSERT(reporter, !isIntersectionOfRects); 573 REPORTER_ASSERT(reporter, !isIntersectionOfRects);
574 } 574 }
575 575
576 // mixed nested (bw inside aa) - should merge 576 // mixed nested (bw inside aa) - should merge
577 { 577 {
578 SkClipStack stack; 578 SkClipStack stack;
579 579
580 stack.clipDevRect(nestedParent, SkRegion::kReplace_Op, true); 580 stack.clipDevRect(nestedParent, SkCanvas::kReplace_Op, true);
581 581
582 stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, false); 582 stack.clipDevRect(nestedChild, SkCanvas::kIntersect_Op, false);
583 583
584 REPORTER_ASSERT(reporter, 1 == count(stack)); 584 REPORTER_ASSERT(reporter, 1 == count(stack));
585 585
586 stack.getBounds(&bound, &type, &isIntersectionOfRects); 586 stack.getBounds(&bound, &type, &isIntersectionOfRects);
587 587
588 REPORTER_ASSERT(reporter, isIntersectionOfRects); 588 REPORTER_ASSERT(reporter, isIntersectionOfRects);
589 } 589 }
590 590
591 // mixed nested (aa inside bw) - should merge 591 // mixed nested (aa inside bw) - should merge
592 { 592 {
593 SkClipStack stack; 593 SkClipStack stack;
594 594
595 stack.clipDevRect(nestedParent, SkRegion::kReplace_Op, false); 595 stack.clipDevRect(nestedParent, SkCanvas::kReplace_Op, false);
596 596
597 stack.clipDevRect(nestedChild, SkRegion::kIntersect_Op, true); 597 stack.clipDevRect(nestedChild, SkCanvas::kIntersect_Op, true);
598 598
599 REPORTER_ASSERT(reporter, 1 == count(stack)); 599 REPORTER_ASSERT(reporter, 1 == count(stack));
600 600
601 stack.getBounds(&bound, &type, &isIntersectionOfRects); 601 stack.getBounds(&bound, &type, &isIntersectionOfRects);
602 602
603 REPORTER_ASSERT(reporter, isIntersectionOfRects); 603 REPORTER_ASSERT(reporter, isIntersectionOfRects);
604 } 604 }
605 605
606 // reverse nested (aa inside bw) - should _not_ merge 606 // reverse nested (aa inside bw) - should _not_ merge
607 { 607 {
608 SkClipStack stack; 608 SkClipStack stack;
609 609
610 stack.clipDevRect(nestedChild, SkRegion::kReplace_Op, false); 610 stack.clipDevRect(nestedChild, SkCanvas::kReplace_Op, false);
611 611
612 stack.clipDevRect(nestedParent, SkRegion::kIntersect_Op, true); 612 stack.clipDevRect(nestedParent, SkCanvas::kIntersect_Op, true);
613 613
614 REPORTER_ASSERT(reporter, 2 == count(stack)); 614 REPORTER_ASSERT(reporter, 2 == count(stack));
615 615
616 stack.getBounds(&bound, &type, &isIntersectionOfRects); 616 stack.getBounds(&bound, &type, &isIntersectionOfRects);
617 617
618 REPORTER_ASSERT(reporter, !isIntersectionOfRects); 618 REPORTER_ASSERT(reporter, !isIntersectionOfRects);
619 } 619 }
620 } 620 }
621 621
622 static void test_quickContains(skiatest::Reporter* reporter) { 622 static void test_quickContains(skiatest::Reporter* reporter) {
623 SkRect testRect = SkRect::MakeLTRB(10, 10, 40, 40); 623 SkRect testRect = SkRect::MakeLTRB(10, 10, 40, 40);
624 SkRect insideRect = SkRect::MakeLTRB(20, 20, 30, 30); 624 SkRect insideRect = SkRect::MakeLTRB(20, 20, 30, 30);
625 SkRect intersectingRect = SkRect::MakeLTRB(25, 25, 50, 50); 625 SkRect intersectingRect = SkRect::MakeLTRB(25, 25, 50, 50);
626 SkRect outsideRect = SkRect::MakeLTRB(0, 0, 50, 50); 626 SkRect outsideRect = SkRect::MakeLTRB(0, 0, 50, 50);
627 SkRect nonIntersectingRect = SkRect::MakeLTRB(100, 100, 110, 110); 627 SkRect nonIntersectingRect = SkRect::MakeLTRB(100, 100, 110, 110);
628 628
629 SkPath insideCircle; 629 SkPath insideCircle;
630 insideCircle.addCircle(25, 25, 5); 630 insideCircle.addCircle(25, 25, 5);
631 SkPath intersectingCircle; 631 SkPath intersectingCircle;
632 intersectingCircle.addCircle(25, 40, 10); 632 intersectingCircle.addCircle(25, 40, 10);
633 SkPath outsideCircle; 633 SkPath outsideCircle;
634 outsideCircle.addCircle(25, 25, 50); 634 outsideCircle.addCircle(25, 25, 50);
635 SkPath nonIntersectingCircle; 635 SkPath nonIntersectingCircle;
636 nonIntersectingCircle.addCircle(100, 100, 5); 636 nonIntersectingCircle.addCircle(100, 100, 5);
637 637
638 { 638 {
639 SkClipStack stack; 639 SkClipStack stack;
640 stack.clipDevRect(outsideRect, SkRegion::kDifference_Op, false); 640 stack.clipDevRect(outsideRect, SkCanvas::kDifference_Op, false);
641 // return false because quickContains currently does not care for kDiffe rence_Op 641 // return false because quickContains currently does not care for kDiffe rence_Op
642 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 642 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
643 } 643 }
644 644
645 // Replace Op tests 645 // Replace Op tests
646 { 646 {
647 SkClipStack stack; 647 SkClipStack stack;
648 stack.clipDevRect(outsideRect, SkRegion::kReplace_Op, false); 648 stack.clipDevRect(outsideRect, SkCanvas::kReplace_Op, false);
649 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 649 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect));
650 } 650 }
651 651
652 { 652 {
653 SkClipStack stack; 653 SkClipStack stack;
654 stack.clipDevRect(insideRect, SkRegion::kIntersect_Op, false); 654 stack.clipDevRect(insideRect, SkCanvas::kIntersect_Op, false);
655 stack.save(); // To prevent in-place substitution by replace OP 655 stack.save(); // To prevent in-place substitution by replace OP
656 stack.clipDevRect(outsideRect, SkRegion::kReplace_Op, false); 656 stack.clipDevRect(outsideRect, SkCanvas::kReplace_Op, false);
657 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 657 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect));
658 stack.restore(); 658 stack.restore();
659 } 659 }
660 660
661 { 661 {
662 SkClipStack stack; 662 SkClipStack stack;
663 stack.clipDevRect(outsideRect, SkRegion::kIntersect_Op, false); 663 stack.clipDevRect(outsideRect, SkCanvas::kIntersect_Op, false);
664 stack.save(); // To prevent in-place substitution by replace OP 664 stack.save(); // To prevent in-place substitution by replace OP
665 stack.clipDevRect(insideRect, SkRegion::kReplace_Op, false); 665 stack.clipDevRect(insideRect, SkCanvas::kReplace_Op, false);
666 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 666 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
667 stack.restore(); 667 stack.restore();
668 } 668 }
669 669
670 // Verify proper traversal of multi-element clip 670 // Verify proper traversal of multi-element clip
671 { 671 {
672 SkClipStack stack; 672 SkClipStack stack;
673 stack.clipDevRect(insideRect, SkRegion::kIntersect_Op, false); 673 stack.clipDevRect(insideRect, SkCanvas::kIntersect_Op, false);
674 // Use a path for second clip to prevent in-place intersection 674 // Use a path for second clip to prevent in-place intersection
675 stack.clipDevPath(outsideCircle, SkRegion::kIntersect_Op, false); 675 stack.clipDevPath(outsideCircle, SkCanvas::kIntersect_Op, false);
676 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 676 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
677 } 677 }
678 678
679 // Intersect Op tests with rectangles 679 // Intersect Op tests with rectangles
680 { 680 {
681 SkClipStack stack; 681 SkClipStack stack;
682 stack.clipDevRect(outsideRect, SkRegion::kIntersect_Op, false); 682 stack.clipDevRect(outsideRect, SkCanvas::kIntersect_Op, false);
683 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 683 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect));
684 } 684 }
685 685
686 { 686 {
687 SkClipStack stack; 687 SkClipStack stack;
688 stack.clipDevRect(insideRect, SkRegion::kIntersect_Op, false); 688 stack.clipDevRect(insideRect, SkCanvas::kIntersect_Op, false);
689 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 689 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
690 } 690 }
691 691
692 { 692 {
693 SkClipStack stack; 693 SkClipStack stack;
694 stack.clipDevRect(intersectingRect, SkRegion::kIntersect_Op, false); 694 stack.clipDevRect(intersectingRect, SkCanvas::kIntersect_Op, false);
695 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 695 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
696 } 696 }
697 697
698 { 698 {
699 SkClipStack stack; 699 SkClipStack stack;
700 stack.clipDevRect(nonIntersectingRect, SkRegion::kIntersect_Op, false); 700 stack.clipDevRect(nonIntersectingRect, SkCanvas::kIntersect_Op, false);
701 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 701 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
702 } 702 }
703 703
704 // Intersect Op tests with circle paths 704 // Intersect Op tests with circle paths
705 { 705 {
706 SkClipStack stack; 706 SkClipStack stack;
707 stack.clipDevPath(outsideCircle, SkRegion::kIntersect_Op, false); 707 stack.clipDevPath(outsideCircle, SkCanvas::kIntersect_Op, false);
708 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 708 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect));
709 } 709 }
710 710
711 { 711 {
712 SkClipStack stack; 712 SkClipStack stack;
713 stack.clipDevPath(insideCircle, SkRegion::kIntersect_Op, false); 713 stack.clipDevPath(insideCircle, SkCanvas::kIntersect_Op, false);
714 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 714 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
715 } 715 }
716 716
717 { 717 {
718 SkClipStack stack; 718 SkClipStack stack;
719 stack.clipDevPath(intersectingCircle, SkRegion::kIntersect_Op, false); 719 stack.clipDevPath(intersectingCircle, SkCanvas::kIntersect_Op, false);
720 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 720 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
721 } 721 }
722 722
723 { 723 {
724 SkClipStack stack; 724 SkClipStack stack;
725 stack.clipDevPath(nonIntersectingCircle, SkRegion::kIntersect_Op, false) ; 725 stack.clipDevPath(nonIntersectingCircle, SkCanvas::kIntersect_Op, false) ;
726 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 726 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
727 } 727 }
728 728
729 // Intersect Op tests with inverse filled rectangles 729 // Intersect Op tests with inverse filled rectangles
730 { 730 {
731 SkClipStack stack; 731 SkClipStack stack;
732 SkPath path; 732 SkPath path;
733 path.addRect(outsideRect); 733 path.addRect(outsideRect);
734 path.toggleInverseFillType(); 734 path.toggleInverseFillType();
735 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 735 stack.clipDevPath(path, SkCanvas::kIntersect_Op, false);
736 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 736 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
737 } 737 }
738 738
739 { 739 {
740 SkClipStack stack; 740 SkClipStack stack;
741 SkPath path; 741 SkPath path;
742 path.addRect(insideRect); 742 path.addRect(insideRect);
743 path.toggleInverseFillType(); 743 path.toggleInverseFillType();
744 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 744 stack.clipDevPath(path, SkCanvas::kIntersect_Op, false);
745 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 745 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
746 } 746 }
747 747
748 { 748 {
749 SkClipStack stack; 749 SkClipStack stack;
750 SkPath path; 750 SkPath path;
751 path.addRect(intersectingRect); 751 path.addRect(intersectingRect);
752 path.toggleInverseFillType(); 752 path.toggleInverseFillType();
753 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 753 stack.clipDevPath(path, SkCanvas::kIntersect_Op, false);
754 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 754 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
755 } 755 }
756 756
757 { 757 {
758 SkClipStack stack; 758 SkClipStack stack;
759 SkPath path; 759 SkPath path;
760 path.addRect(nonIntersectingRect); 760 path.addRect(nonIntersectingRect);
761 path.toggleInverseFillType(); 761 path.toggleInverseFillType();
762 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 762 stack.clipDevPath(path, SkCanvas::kIntersect_Op, false);
763 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 763 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect));
764 } 764 }
765 765
766 // Intersect Op tests with inverse filled circles 766 // Intersect Op tests with inverse filled circles
767 { 767 {
768 SkClipStack stack; 768 SkClipStack stack;
769 SkPath path = outsideCircle; 769 SkPath path = outsideCircle;
770 path.toggleInverseFillType(); 770 path.toggleInverseFillType();
771 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 771 stack.clipDevPath(path, SkCanvas::kIntersect_Op, false);
772 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 772 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
773 } 773 }
774 774
775 { 775 {
776 SkClipStack stack; 776 SkClipStack stack;
777 SkPath path = insideCircle; 777 SkPath path = insideCircle;
778 path.toggleInverseFillType(); 778 path.toggleInverseFillType();
779 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 779 stack.clipDevPath(path, SkCanvas::kIntersect_Op, false);
780 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 780 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
781 } 781 }
782 782
783 { 783 {
784 SkClipStack stack; 784 SkClipStack stack;
785 SkPath path = intersectingCircle; 785 SkPath path = intersectingCircle;
786 path.toggleInverseFillType(); 786 path.toggleInverseFillType();
787 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 787 stack.clipDevPath(path, SkCanvas::kIntersect_Op, false);
788 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect)); 788 REPORTER_ASSERT(reporter, false == stack.quickContains(testRect));
789 } 789 }
790 790
791 { 791 {
792 SkClipStack stack; 792 SkClipStack stack;
793 SkPath path = nonIntersectingCircle; 793 SkPath path = nonIntersectingCircle;
794 path.toggleInverseFillType(); 794 path.toggleInverseFillType();
795 stack.clipDevPath(path, SkRegion::kIntersect_Op, false); 795 stack.clipDevPath(path, SkCanvas::kIntersect_Op, false);
796 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect)); 796 REPORTER_ASSERT(reporter, true == stack.quickContains(testRect));
797 } 797 }
798 } 798 }
799 799
800 static void set_region_to_stack(const SkClipStack& stack, const SkIRect& bounds, SkRegion* region) { 800 static void set_region_to_stack(const SkClipStack& stack, const SkIRect& bounds, SkRegion* region) {
801 region->setRect(bounds); 801 region->setRect(bounds);
802 SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart); 802 SkClipStack::Iter iter(stack, SkClipStack::Iter::kBottom_IterStart);
803 while (const SkClipStack::Element *element = iter.next()) { 803 while (const SkClipStack::Element *element = iter.next()) {
804 SkRegion elemRegion; 804 SkRegion elemRegion;
805 SkRegion boundsRgn(bounds); 805 SkRegion boundsRgn(bounds);
806 SkPath path; 806 SkPath path;
807 807
808 switch (element->getType()) { 808 switch (element->getType()) {
809 case SkClipStack::Element::kEmpty_Type: 809 case SkClipStack::Element::kEmpty_Type:
810 elemRegion.setEmpty(); 810 elemRegion.setEmpty();
811 break; 811 break;
812 default: 812 default:
813 element->asPath(&path); 813 element->asPath(&path);
814 elemRegion.setPath(path, boundsRgn); 814 elemRegion.setPath(path, boundsRgn);
815 break; 815 break;
816 } 816 }
817 region->op(elemRegion, element->getOp()); 817 region->op(elemRegion, (SkRegion::Op)element->getOp());
818 } 818 }
819 } 819 }
820 820
821 static void test_invfill_diff_bug(skiatest::Reporter* reporter) { 821 static void test_invfill_diff_bug(skiatest::Reporter* reporter) {
822 SkClipStack stack; 822 SkClipStack stack;
823 stack.clipDevRect({10, 10, 20, 20}, SkRegion::kIntersect_Op, false); 823 stack.clipDevRect({10, 10, 20, 20}, SkCanvas::kIntersect_Op, false);
824 824
825 SkPath path; 825 SkPath path;
826 path.addRect({30, 10, 40, 20}); 826 path.addRect({30, 10, 40, 20});
827 path.setFillType(SkPath::kInverseWinding_FillType); 827 path.setFillType(SkPath::kInverseWinding_FillType);
828 stack.clipDevPath(path, SkRegion::kDifference_Op, false); 828 stack.clipDevPath(path, SkCanvas::kDifference_Op, false);
829 829
830 REPORTER_ASSERT(reporter, SkClipStack::kEmptyGenID == stack.getTopmostGenID( )); 830 REPORTER_ASSERT(reporter, SkClipStack::kEmptyGenID == stack.getTopmostGenID( ));
831 831
832 SkRect stackBounds; 832 SkRect stackBounds;
833 SkClipStack::BoundsType stackBoundsType; 833 SkClipStack::BoundsType stackBoundsType;
834 stack.getBounds(&stackBounds, &stackBoundsType); 834 stack.getBounds(&stackBounds, &stackBoundsType);
835 835
836 REPORTER_ASSERT(reporter, stackBounds.isEmpty()); 836 REPORTER_ASSERT(reporter, stackBounds.isEmpty());
837 REPORTER_ASSERT(reporter, SkClipStack::kNormal_BoundsType == stackBoundsType ); 837 REPORTER_ASSERT(reporter, SkClipStack::kNormal_BoundsType == stackBoundsType );
838 838
839 SkRegion region; 839 SkRegion region;
840 set_region_to_stack(stack, {0, 0, 50, 30}, &region); 840 set_region_to_stack(stack, {0, 0, 50, 30}, &region);
841 841
842 REPORTER_ASSERT(reporter, region.isEmpty()); 842 REPORTER_ASSERT(reporter, region.isEmpty());
843 } 843 }
844 844
845 //////////////////////////////////////////////////////////////////////////////// /////////////////// 845 //////////////////////////////////////////////////////////////////////////////// ///////////////////
846 846
847 #if SK_SUPPORT_GPU 847 #if SK_SUPPORT_GPU
848 // Functions that add a shape to the clip stack. The shape is computed from a re ctangle. 848 // Functions that add a shape to the clip stack. The shape is computed from a re ctangle.
849 // AA is always disabled since the clip stack reducer can cause changes in aa ra sterization of the 849 // AA is always disabled since the clip stack reducer can cause changes in aa ra sterization of the
850 // stack. A fractional edge repeated in different elements may be rasterized few er times using the 850 // stack. A fractional edge repeated in different elements may be rasterized few er times using the
851 // reduced stack. 851 // reduced stack.
852 typedef void (*AddElementFunc) (const SkRect& rect, 852 typedef void (*AddElementFunc) (const SkRect& rect,
853 bool invert, 853 bool invert,
854 SkRegion::Op op, 854 SkCanvas::ClipOp op,
855 SkClipStack* stack, 855 SkClipStack* stack,
856 bool doAA); 856 bool doAA);
857 857
858 static void add_round_rect(const SkRect& rect, bool invert, SkRegion::Op op, SkC lipStack* stack, 858 static void add_round_rect(const SkRect& rect, bool invert, SkCanvas::ClipOp op, SkClipStack* stack,
859 bool doAA) { 859 bool doAA) {
860 SkScalar rx = rect.width() / 10; 860 SkScalar rx = rect.width() / 10;
861 SkScalar ry = rect.height() / 20; 861 SkScalar ry = rect.height() / 20;
862 if (invert) { 862 if (invert) {
863 SkPath path; 863 SkPath path;
864 path.addRoundRect(rect, rx, ry); 864 path.addRoundRect(rect, rx, ry);
865 path.setFillType(SkPath::kInverseWinding_FillType); 865 path.setFillType(SkPath::kInverseWinding_FillType);
866 stack->clipDevPath(path, op, doAA); 866 stack->clipDevPath(path, op, doAA);
867 } else { 867 } else {
868 SkRRect rrect; 868 SkRRect rrect;
869 rrect.setRectXY(rect, rx, ry); 869 rrect.setRectXY(rect, rx, ry);
870 stack->clipDevRRect(rrect, op, doAA); 870 stack->clipDevRRect(rrect, op, doAA);
871 } 871 }
872 }; 872 };
873 873
874 static void add_rect(const SkRect& rect, bool invert, SkRegion::Op op, SkClipSta ck* stack, 874 static void add_rect(const SkRect& rect, bool invert, SkCanvas::ClipOp op, SkCli pStack* stack,
875 bool doAA) { 875 bool doAA) {
876 if (invert) { 876 if (invert) {
877 SkPath path; 877 SkPath path;
878 path.addRect(rect); 878 path.addRect(rect);
879 path.setFillType(SkPath::kInverseWinding_FillType); 879 path.setFillType(SkPath::kInverseWinding_FillType);
880 stack->clipDevPath(path, op, doAA); 880 stack->clipDevPath(path, op, doAA);
881 } else { 881 } else {
882 stack->clipDevRect(rect, op, doAA); 882 stack->clipDevRect(rect, op, doAA);
883 } 883 }
884 }; 884 };
885 885
886 static void add_oval(const SkRect& rect, bool invert, SkRegion::Op op, SkClipSta ck* stack, 886 static void add_oval(const SkRect& rect, bool invert, SkCanvas::ClipOp op, SkCli pStack* stack,
887 bool doAA) { 887 bool doAA) {
888 SkPath path; 888 SkPath path;
889 path.addOval(rect); 889 path.addOval(rect);
890 if (invert) { 890 if (invert) {
891 path.setFillType(SkPath::kInverseWinding_FillType); 891 path.setFillType(SkPath::kInverseWinding_FillType);
892 } 892 }
893 stack->clipDevPath(path, op, doAA); 893 stack->clipDevPath(path, op, doAA);
894 }; 894 };
895 895
896 static void add_elem_to_stack(const SkClipStack::Element& element, SkClipStack* stack) { 896 static void add_elem_to_stack(const SkClipStack::Element& element, SkClipStack* stack) {
(...skipping 25 matching lines...) Expand all
922 enum { 922 enum {
923 kNumTests = 250, 923 kNumTests = 250,
924 kMinElemsPerTest = 1, 924 kMinElemsPerTest = 1,
925 kMaxElemsPerTest = 50, 925 kMaxElemsPerTest = 50,
926 }; 926 };
927 927
928 // min/max size of a clip element as a fraction of kBounds. 928 // min/max size of a clip element as a fraction of kBounds.
929 static const SkScalar kMinElemSizeFrac = SK_Scalar1 / 5; 929 static const SkScalar kMinElemSizeFrac = SK_Scalar1 / 5;
930 static const SkScalar kMaxElemSizeFrac = SK_Scalar1; 930 static const SkScalar kMaxElemSizeFrac = SK_Scalar1;
931 931
932 static const SkRegion::Op kOps[] = { 932 static const SkCanvas::ClipOp kOps[] = {
933 SkRegion::kDifference_Op, 933 SkCanvas::kDifference_Op,
934 SkRegion::kIntersect_Op, 934 SkCanvas::kIntersect_Op,
935 SkRegion::kUnion_Op, 935 SkCanvas::kUnion_Op,
936 SkRegion::kXOR_Op, 936 SkCanvas::kXOR_Op,
937 SkRegion::kReverseDifference_Op, 937 SkCanvas::kReverseDifference_Op,
938 SkRegion::kReplace_Op, 938 SkCanvas::kReplace_Op,
939 }; 939 };
940 940
941 // Replace operations short-circuit the optimizer. We want to make sure that we test this code 941 // Replace operations short-circuit the optimizer. We want to make sure that we test this code
942 // path a little bit but we don't want it to prevent us from testing many lo nger traversals in 942 // path a little bit but we don't want it to prevent us from testing many lo nger traversals in
943 // the optimizer. 943 // the optimizer.
944 static const int kReplaceDiv = 4 * kMaxElemsPerTest; 944 static const int kReplaceDiv = 4 * kMaxElemsPerTest;
945 945
946 // We want to test inverse fills. However, they are quite rare in practice s o don't over do it. 946 // We want to test inverse fills. However, they are quite rare in practice s o don't over do it.
947 static const SkScalar kFractionInverted = SK_Scalar1 / kMaxElemsPerTest; 947 static const SkScalar kFractionInverted = SK_Scalar1 / kMaxElemsPerTest;
948 948
949 static const SkScalar kFractionAntialiased = 0.25; 949 static const SkScalar kFractionAntialiased = 0.25;
950 950
951 static const AddElementFunc kElementFuncs[] = { 951 static const AddElementFunc kElementFuncs[] = {
952 add_rect, 952 add_rect,
953 add_round_rect, 953 add_round_rect,
954 add_oval, 954 add_oval,
955 }; 955 };
956 956
957 SkRandom r; 957 SkRandom r;
958 958
959 for (int i = 0; i < kNumTests; ++i) { 959 for (int i = 0; i < kNumTests; ++i) {
960 SkString testCase; 960 SkString testCase;
961 testCase.printf("Iteration %d", i); 961 testCase.printf("Iteration %d", i);
962 962
963 // Randomly generate a clip stack. 963 // Randomly generate a clip stack.
964 SkClipStack stack; 964 SkClipStack stack;
965 int numElems = r.nextRangeU(kMinElemsPerTest, kMaxElemsPerTest); 965 int numElems = r.nextRangeU(kMinElemsPerTest, kMaxElemsPerTest);
966 bool doAA = r.nextBiasedBool(kFractionAntialiased); 966 bool doAA = r.nextBiasedBool(kFractionAntialiased);
967 for (int e = 0; e < numElems; ++e) { 967 for (int e = 0; e < numElems; ++e) {
968 SkRegion::Op op = kOps[r.nextULessThan(SK_ARRAY_COUNT(kOps))]; 968 SkCanvas::ClipOp op = kOps[r.nextULessThan(SK_ARRAY_COUNT(kOps))];
969 if (op == SkRegion::kReplace_Op) { 969 if (op == SkCanvas::kReplace_Op) {
970 if (r.nextU() % kReplaceDiv) { 970 if (r.nextU() % kReplaceDiv) {
971 --e; 971 --e;
972 continue; 972 continue;
973 } 973 }
974 } 974 }
975 975
976 // saves can change the clip stack behavior when an element is added . 976 // saves can change the clip stack behavior when an element is added .
977 bool doSave = r.nextBool(); 977 bool doSave = r.nextBool();
978 978
979 SkSize size = SkSize::Make( 979 SkSize size = SkSize::Make(
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1044 // whether the result is bounded or not, the whole plane should star t outside the clip. 1044 // whether the result is bounded or not, the whole plane should star t outside the clip.
1045 reducedStack.clipEmpty(); 1045 reducedStack.clipEmpty();
1046 } 1046 }
1047 for (ElementList::Iter iter(reduced->elements()); iter.get(); iter.next( )) { 1047 for (ElementList::Iter iter(reduced->elements()); iter.get(); iter.next( )) {
1048 add_elem_to_stack(*iter.get(), &reducedStack); 1048 add_elem_to_stack(*iter.get(), &reducedStack);
1049 } 1049 }
1050 1050
1051 SkIRect ibounds = reduced->hasIBounds() ? reduced->ibounds() : kIBounds; 1051 SkIRect ibounds = reduced->hasIBounds() ? reduced->ibounds() : kIBounds;
1052 1052
1053 // GrReducedClipStack assumes that the final result is clipped to the re turned bounds 1053 // GrReducedClipStack assumes that the final result is clipped to the re turned bounds
1054 reducedStack.clipDevRect(ibounds, SkRegion::kIntersect_Op); 1054 reducedStack.clipDevRect(ibounds, SkCanvas::kIntersect_Op);
1055 stack.clipDevRect(ibounds, SkRegion::kIntersect_Op); 1055 stack.clipDevRect(ibounds, SkCanvas::kIntersect_Op);
1056 1056
1057 // convert both the original stack and reduced stack to SkRegions and se e if they're equal 1057 // convert both the original stack and reduced stack to SkRegions and se e if they're equal
1058 SkRegion region; 1058 SkRegion region;
1059 set_region_to_stack(stack, ibounds, &region); 1059 set_region_to_stack(stack, ibounds, &region);
1060 1060
1061 SkRegion reducedRegion; 1061 SkRegion reducedRegion;
1062 set_region_to_stack(reducedStack, ibounds, &reducedRegion); 1062 set_region_to_stack(reducedStack, ibounds, &reducedRegion);
1063 1063
1064 REPORTER_ASSERT_MESSAGE(reporter, region == reducedRegion, testCase.c_st r()); 1064 REPORTER_ASSERT_MESSAGE(reporter, region == reducedRegion, testCase.c_st r());
1065 1065
1066 reduced->~GrReducedClip(); 1066 reduced->~GrReducedClip();
1067 } 1067 }
1068 } 1068 }
1069 1069
1070 #ifdef SK_BUILD_FOR_WIN 1070 #ifdef SK_BUILD_FOR_WIN
1071 #define SUPPRESS_VISIBILITY_WARNING 1071 #define SUPPRESS_VISIBILITY_WARNING
1072 #else 1072 #else
1073 #define SUPPRESS_VISIBILITY_WARNING __attribute__((visibility("hidden"))) 1073 #define SUPPRESS_VISIBILITY_WARNING __attribute__((visibility("hidden")))
1074 #endif 1074 #endif
1075 1075
1076 static void test_reduced_clip_stack_genid(skiatest::Reporter* reporter) { 1076 static void test_reduced_clip_stack_genid(skiatest::Reporter* reporter) {
1077 { 1077 {
1078 SkClipStack stack; 1078 SkClipStack stack;
1079 stack.clipDevRect(SkRect::MakeXYWH(0, 0, 100, 100), SkRegion::kReplace_O p, true); 1079 stack.clipDevRect(SkRect::MakeXYWH(0, 0, 100, 100), SkCanvas::kReplace_O p, true);
1080 stack.clipDevRect(SkRect::MakeXYWH(0, 0, SkScalar(50.3), SkScalar(50.3)) , SkRegion::kReplace_Op, true); 1080 stack.clipDevRect(SkRect::MakeXYWH(0, 0, SkScalar(50.3), SkScalar(50.3)) , SkCanvas::kReplace_Op, true);
1081 SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100); 1081 SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
1082 1082
1083 SkAlignedSTStorage<1, GrReducedClip> storage; 1083 SkAlignedSTStorage<1, GrReducedClip> storage;
1084 memset(storage.get(), 0, sizeof(GrReducedClip)); 1084 memset(storage.get(), 0, sizeof(GrReducedClip));
1085 GR_STATIC_ASSERT(0 == SkClipStack::kInvalidGenID); 1085 GR_STATIC_ASSERT(0 == SkClipStack::kInvalidGenID);
1086 const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, bounds); 1086 const GrReducedClip* reduced = new (storage.get()) GrReducedClip(stack, bounds);
1087 1087
1088 REPORTER_ASSERT(reporter, reduced->elements().count() == 1); 1088 REPORTER_ASSERT(reporter, reduced->elements().count() == 1);
1089 // Clips will be cached based on the generation id. Make sure the gen id is valid. 1089 // Clips will be cached based on the generation id. Make sure the gen id is valid.
1090 REPORTER_ASSERT(reporter, SkClipStack::kInvalidGenID != reduced->element sGenID()); 1090 REPORTER_ASSERT(reporter, SkClipStack::kInvalidGenID != reduced->element sGenID());
1091 1091
1092 reduced->~GrReducedClip(); 1092 reduced->~GrReducedClip();
1093 } 1093 }
1094 { 1094 {
1095 SkClipStack stack; 1095 SkClipStack stack;
1096 1096
1097 // Create a clip with following 25.3, 25.3 boxes which are 25 apart: 1097 // Create a clip with following 25.3, 25.3 boxes which are 25 apart:
1098 // A B 1098 // A B
1099 // C D 1099 // C D
1100 1100
1101 stack.clipDevRect(SkRect::MakeXYWH(0, 0, SkScalar(25.3), SkScalar(25.3)) , SkRegion::kReplace_Op, true); 1101 stack.clipDevRect(SkRect::MakeXYWH(0, 0, SkScalar(25.3), SkScalar(25.3)) , SkCanvas::kReplace_Op, true);
1102 int32_t genIDA = stack.getTopmostGenID(); 1102 int32_t genIDA = stack.getTopmostGenID();
1103 stack.clipDevRect(SkRect::MakeXYWH(50, 0, SkScalar(25.3), SkScalar(25.3) ), SkRegion::kUnion_Op, true); 1103 stack.clipDevRect(SkRect::MakeXYWH(50, 0, SkScalar(25.3), SkScalar(25.3) ), SkCanvas::kUnion_Op, true);
1104 int32_t genIDB = stack.getTopmostGenID(); 1104 int32_t genIDB = stack.getTopmostGenID();
1105 stack.clipDevRect(SkRect::MakeXYWH(0, 50, SkScalar(25.3), SkScalar(25.3) ), SkRegion::kUnion_Op, true); 1105 stack.clipDevRect(SkRect::MakeXYWH(0, 50, SkScalar(25.3), SkScalar(25.3) ), SkCanvas::kUnion_Op, true);
1106 int32_t genIDC = stack.getTopmostGenID(); 1106 int32_t genIDC = stack.getTopmostGenID();
1107 stack.clipDevRect(SkRect::MakeXYWH(50, 50, SkScalar(25.3), SkScalar(25.3 )), SkRegion::kUnion_Op, true); 1107 stack.clipDevRect(SkRect::MakeXYWH(50, 50, SkScalar(25.3), SkScalar(25.3 )), SkCanvas::kUnion_Op, true);
1108 int32_t genIDD = stack.getTopmostGenID(); 1108 int32_t genIDD = stack.getTopmostGenID();
1109 1109
1110 1110
1111 #define IXYWH SkIRect::MakeXYWH 1111 #define IXYWH SkIRect::MakeXYWH
1112 #define XYWH SkRect::MakeXYWH 1112 #define XYWH SkRect::MakeXYWH
1113 1113
1114 SkIRect stackBounds = IXYWH(0, 0, 76, 76); 1114 SkIRect stackBounds = IXYWH(0, 0, 76, 76);
1115 1115
1116 // The base test is to test each rect in two ways: 1116 // The base test is to test each rect in two ways:
1117 // 1) The box dimensions. (Should reduce to "all in", no elements). 1117 // 1) The box dimensions. (Should reduce to "all in", no elements).
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1176 REPORTER_ASSERT(reporter, reduced.hasIBounds()); 1176 REPORTER_ASSERT(reporter, reduced.hasIBounds());
1177 SkASSERT(reduced.hasIBounds()); 1177 SkASSERT(reduced.hasIBounds());
1178 REPORTER_ASSERT(reporter, reduced.ibounds() == testCases[i].clipIRec t); 1178 REPORTER_ASSERT(reporter, reduced.ibounds() == testCases[i].clipIRec t);
1179 SkASSERT(reduced.ibounds() == testCases[i].clipIRect); 1179 SkASSERT(reduced.ibounds() == testCases[i].clipIRect);
1180 } 1180 }
1181 } 1181 }
1182 } 1182 }
1183 1183
1184 static void test_reduced_clip_stack_no_aa_crash(skiatest::Reporter* reporter) { 1184 static void test_reduced_clip_stack_no_aa_crash(skiatest::Reporter* reporter) {
1185 SkClipStack stack; 1185 SkClipStack stack;
1186 stack.clipDevRect(SkIRect::MakeXYWH(0, 0, 100, 100), SkRegion::kReplace_Op); 1186 stack.clipDevRect(SkIRect::MakeXYWH(0, 0, 100, 100), SkCanvas::kReplace_Op);
1187 stack.clipDevRect(SkIRect::MakeXYWH(0, 0, 50, 50), SkRegion::kReplace_Op); 1187 stack.clipDevRect(SkIRect::MakeXYWH(0, 0, 50, 50), SkCanvas::kReplace_Op);
1188 SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100); 1188 SkRect bounds = SkRect::MakeXYWH(0, 0, 100, 100);
1189 1189
1190 // At the time, this would crash. 1190 // At the time, this would crash.
1191 const GrReducedClip reduced(stack, bounds); 1191 const GrReducedClip reduced(stack, bounds);
1192 REPORTER_ASSERT(reporter, reduced.elements().isEmpty()); 1192 REPORTER_ASSERT(reporter, reduced.elements().isEmpty());
1193 } 1193 }
1194 1194
1195 enum class ClipMethod { 1195 enum class ClipMethod {
1196 kSkipDraw, 1196 kSkipDraw,
1197 kIgnoreClip, 1197 kIgnoreClip,
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 constexpr SkScalar kMaxScale = 3; 1277 constexpr SkScalar kMaxScale = 3;
1278 constexpr int kNumIters = 8; 1278 constexpr int kNumIters = 8;
1279 1279
1280 SkString name; 1280 SkString name;
1281 SkRandom rand; 1281 SkRandom rand;
1282 1282
1283 for (int i = 0; i < kNumIters; ++i) { 1283 for (int i = 0; i < kNumIters; ++i) {
1284 // Pixel-aligned rect (iior=true). 1284 // Pixel-aligned rect (iior=true).
1285 name.printf("Pixel-aligned rect test, iter %i", i); 1285 name.printf("Pixel-aligned rect test, iter %i", i);
1286 SkClipStack stack; 1286 SkClipStack stack;
1287 stack.clipDevRect(alignedRect, SkRegion::kIntersect_Op, true); 1287 stack.clipDevRect(alignedRect, SkCanvas::kIntersect_Op, true);
1288 test_aa_query(reporter, name, stack, m, {IL, IT, IR, IB}, ClipMethod::kI gnoreClip); 1288 test_aa_query(reporter, name, stack, m, {IL, IT, IR, IB}, ClipMethod::kI gnoreClip);
1289 test_aa_query(reporter, name, stack, m, {IL, IT-1, IR, IT}, ClipMethod:: kSkipDraw); 1289 test_aa_query(reporter, name, stack, m, {IL, IT-1, IR, IT}, ClipMethod:: kSkipDraw);
1290 test_aa_query(reporter, name, stack, m, {IL, IT-2, IR, IB}, ClipMethod:: kScissor); 1290 test_aa_query(reporter, name, stack, m, {IL, IT-2, IR, IB}, ClipMethod:: kScissor);
1291 1291
1292 // Rect (iior=true). 1292 // Rect (iior=true).
1293 name.printf("Rect test, iter %i", i); 1293 name.printf("Rect test, iter %i", i);
1294 stack.reset(); 1294 stack.reset();
1295 stack.clipDevRect(rect, SkRegion::kIntersect_Op, true); 1295 stack.clipDevRect(rect, SkCanvas::kIntersect_Op, true);
1296 test_aa_query(reporter, name, stack, m, {L, T, R, B}, ClipMethod::kIgno reClip); 1296 test_aa_query(reporter, name, stack, m, {L, T, R, B}, ClipMethod::kIgno reClip);
1297 test_aa_query(reporter, name, stack, m, {L-.1f, T, L, B}, ClipMethod::kS kipDraw); 1297 test_aa_query(reporter, name, stack, m, {L-.1f, T, L, B}, ClipMethod::kS kipDraw);
1298 test_aa_query(reporter, name, stack, m, {L-.1f, T, L+.1f, B}, ClipMethod ::kAAElements, 1); 1298 test_aa_query(reporter, name, stack, m, {L-.1f, T, L+.1f, B}, ClipMethod ::kAAElements, 1);
1299 1299
1300 // Difference rect (iior=false, inside-out bounds). 1300 // Difference rect (iior=false, inside-out bounds).
1301 name.printf("Difference rect test, iter %i", i); 1301 name.printf("Difference rect test, iter %i", i);
1302 stack.reset(); 1302 stack.reset();
1303 stack.clipDevRect(rect, SkRegion::kDifference_Op, true); 1303 stack.clipDevRect(rect, SkCanvas::kDifference_Op, true);
1304 test_aa_query(reporter, name, stack, m, {L, T, R, B}, ClipMethod::kSkipD raw); 1304 test_aa_query(reporter, name, stack, m, {L, T, R, B}, ClipMethod::kSkipD raw);
1305 test_aa_query(reporter, name, stack, m, {L, T-.1f, R, T}, ClipMethod::kI gnoreClip); 1305 test_aa_query(reporter, name, stack, m, {L, T-.1f, R, T}, ClipMethod::kI gnoreClip);
1306 test_aa_query(reporter, name, stack, m, {L, T-.1f, R, T+.1f}, ClipMethod ::kAAElements, 1); 1306 test_aa_query(reporter, name, stack, m, {L, T-.1f, R, T+.1f}, ClipMethod ::kAAElements, 1);
1307 1307
1308 // Complex clip (iior=false, normal bounds). 1308 // Complex clip (iior=false, normal bounds).
1309 name.printf("Complex clip test, iter %i", i); 1309 name.printf("Complex clip test, iter %i", i);
1310 stack.reset(); 1310 stack.reset();
1311 stack.clipDevRect(rect, SkRegion::kIntersect_Op, true); 1311 stack.clipDevRect(rect, SkCanvas::kIntersect_Op, true);
1312 stack.clipDevRect(innerRect, SkRegion::kXOR_Op, true); 1312 stack.clipDevRect(innerRect, SkCanvas::kXOR_Op, true);
1313 test_aa_query(reporter, name, stack, m, {l, t, r, b}, ClipMethod::kSkipD raw); 1313 test_aa_query(reporter, name, stack, m, {l, t, r, b}, ClipMethod::kSkipD raw);
1314 test_aa_query(reporter, name, stack, m, {r-.1f, t, R, b}, ClipMethod::kA AElements, 1); 1314 test_aa_query(reporter, name, stack, m, {r-.1f, t, R, b}, ClipMethod::kA AElements, 1);
1315 test_aa_query(reporter, name, stack, m, {r-.1f, t, R+.1f, b}, ClipMethod ::kAAElements, 2); 1315 test_aa_query(reporter, name, stack, m, {r-.1f, t, R+.1f, b}, ClipMethod ::kAAElements, 2);
1316 test_aa_query(reporter, name, stack, m, {r, t, R+.1f, b}, ClipMethod::kA AElements, 1); 1316 test_aa_query(reporter, name, stack, m, {r, t, R+.1f, b}, ClipMethod::kA AElements, 1);
1317 test_aa_query(reporter, name, stack, m, {r, t, R, b}, ClipMethod::kIgnor eClip); 1317 test_aa_query(reporter, name, stack, m, {r, t, R, b}, ClipMethod::kIgnor eClip);
1318 test_aa_query(reporter, name, stack, m, {R, T, R+.1f, B}, ClipMethod::kS kipDraw); 1318 test_aa_query(reporter, name, stack, m, {R, T, R+.1f, B}, ClipMethod::kS kipDraw);
1319 1319
1320 // Complex clip where outer rect is pixel aligned (iior=false, normal bo unds). 1320 // Complex clip where outer rect is pixel aligned (iior=false, normal bo unds).
1321 name.printf("Aligned Complex clip test, iter %i", i); 1321 name.printf("Aligned Complex clip test, iter %i", i);
1322 stack.reset(); 1322 stack.reset();
1323 stack.clipDevRect(alignedRect, SkRegion::kIntersect_Op, true); 1323 stack.clipDevRect(alignedRect, SkCanvas::kIntersect_Op, true);
1324 stack.clipDevRect(innerRect, SkRegion::kXOR_Op, true); 1324 stack.clipDevRect(innerRect, SkCanvas::kXOR_Op, true);
1325 test_aa_query(reporter, name, stack, m, {l, t, r, b}, ClipMethod::kSkipD raw); 1325 test_aa_query(reporter, name, stack, m, {l, t, r, b}, ClipMethod::kSkipD raw);
1326 test_aa_query(reporter, name, stack, m, {l, b-.1f, r, IB}, ClipMethod::k AAElements, 1); 1326 test_aa_query(reporter, name, stack, m, {l, b-.1f, r, IB}, ClipMethod::k AAElements, 1);
1327 test_aa_query(reporter, name, stack, m, {l, b-.1f, r, IB+.1f}, ClipMetho d::kAAElements, 1); 1327 test_aa_query(reporter, name, stack, m, {l, b-.1f, r, IB+.1f}, ClipMetho d::kAAElements, 1);
1328 test_aa_query(reporter, name, stack, m, {l, b, r, IB+.1f}, ClipMethod::k AAElements, 0); 1328 test_aa_query(reporter, name, stack, m, {l, b, r, IB+.1f}, ClipMethod::k AAElements, 0);
1329 test_aa_query(reporter, name, stack, m, {l, b, r, IB}, ClipMethod::kIgno reClip); 1329 test_aa_query(reporter, name, stack, m, {l, b, r, IB}, ClipMethod::kIgno reClip);
1330 test_aa_query(reporter, name, stack, m, {IL, IB, IR, IB+.1f}, ClipMethod ::kSkipDraw); 1330 test_aa_query(reporter, name, stack, m, {IL, IB, IR, IB+.1f}, ClipMethod ::kSkipDraw);
1331 1331
1332 // Apply random transforms and try again. This ensures the clip stack re duction is hardened 1332 // Apply random transforms and try again. This ensures the clip stack re duction is hardened
1333 // against FP rounding error. 1333 // against FP rounding error.
1334 SkScalar sx = rand.nextRangeScalar(kMinScale, kMaxScale); 1334 SkScalar sx = rand.nextRangeScalar(kMinScale, kMaxScale);
(...skipping 20 matching lines...) Expand all
1355 REPORTER_ASSERT(reporter, 0 == stack.getSaveCount()); 1355 REPORTER_ASSERT(reporter, 0 == stack.getSaveCount());
1356 assert_count(reporter, stack, 0); 1356 assert_count(reporter, stack, 0);
1357 1357
1358 static const SkIRect gRects[] = { 1358 static const SkIRect gRects[] = {
1359 { 0, 0, 100, 100 }, 1359 { 0, 0, 100, 100 },
1360 { 25, 25, 125, 125 }, 1360 { 25, 25, 125, 125 },
1361 { 0, 0, 1000, 1000 }, 1361 { 0, 0, 1000, 1000 },
1362 { 0, 0, 75, 75 } 1362 { 0, 0, 75, 75 }
1363 }; 1363 };
1364 for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) { 1364 for (size_t i = 0; i < SK_ARRAY_COUNT(gRects); i++) {
1365 stack.clipDevRect(gRects[i], SkRegion::kIntersect_Op); 1365 stack.clipDevRect(gRects[i], SkCanvas::kIntersect_Op);
1366 } 1366 }
1367 1367
1368 // all of the above rects should have been intersected, leaving only 1 rect 1368 // all of the above rects should have been intersected, leaving only 1 rect
1369 SkClipStack::B2TIter iter(stack); 1369 SkClipStack::B2TIter iter(stack);
1370 const SkClipStack::Element* element = iter.next(); 1370 const SkClipStack::Element* element = iter.next();
1371 SkRect answer; 1371 SkRect answer;
1372 answer.iset(25, 25, 75, 75); 1372 answer.iset(25, 25, 75, 75);
1373 1373
1374 REPORTER_ASSERT(reporter, element); 1374 REPORTER_ASSERT(reporter, element);
1375 REPORTER_ASSERT(reporter, SkClipStack::Element::kRect_Type == element->getTy pe()); 1375 REPORTER_ASSERT(reporter, SkClipStack::Element::kRect_Type == element->getTy pe());
1376 REPORTER_ASSERT(reporter, SkRegion::kIntersect_Op == element->getOp()); 1376 REPORTER_ASSERT(reporter, SkCanvas::kIntersect_Op == element->getOp());
1377 REPORTER_ASSERT(reporter, element->getRect() == answer); 1377 REPORTER_ASSERT(reporter, element->getRect() == answer);
1378 // now check that we only had one in our iterator 1378 // now check that we only had one in our iterator
1379 REPORTER_ASSERT(reporter, !iter.next()); 1379 REPORTER_ASSERT(reporter, !iter.next());
1380 1380
1381 stack.reset(); 1381 stack.reset();
1382 REPORTER_ASSERT(reporter, 0 == stack.getSaveCount()); 1382 REPORTER_ASSERT(reporter, 0 == stack.getSaveCount());
1383 assert_count(reporter, stack, 0); 1383 assert_count(reporter, stack, 0);
1384 1384
1385 test_assign_and_comparison(reporter); 1385 test_assign_and_comparison(reporter);
1386 test_iterators(reporter); 1386 test_iterators(reporter);
1387 test_bounds(reporter, SkClipStack::Element::kRect_Type); 1387 test_bounds(reporter, SkClipStack::Element::kRect_Type);
1388 test_bounds(reporter, SkClipStack::Element::kRRect_Type); 1388 test_bounds(reporter, SkClipStack::Element::kRRect_Type);
1389 test_bounds(reporter, SkClipStack::Element::kPath_Type); 1389 test_bounds(reporter, SkClipStack::Element::kPath_Type);
1390 test_isWideOpen(reporter); 1390 test_isWideOpen(reporter);
1391 test_rect_merging(reporter); 1391 test_rect_merging(reporter);
1392 test_rect_replace(reporter); 1392 test_rect_replace(reporter);
1393 test_rect_inverse_fill(reporter); 1393 test_rect_inverse_fill(reporter);
1394 test_path_replace(reporter); 1394 test_path_replace(reporter);
1395 test_quickContains(reporter); 1395 test_quickContains(reporter);
1396 test_invfill_diff_bug(reporter); 1396 test_invfill_diff_bug(reporter);
1397 #if SK_SUPPORT_GPU 1397 #if SK_SUPPORT_GPU
1398 test_reduced_clip_stack(reporter); 1398 test_reduced_clip_stack(reporter);
1399 test_reduced_clip_stack_genid(reporter); 1399 test_reduced_clip_stack_genid(reporter);
1400 test_reduced_clip_stack_no_aa_crash(reporter); 1400 test_reduced_clip_stack_no_aa_crash(reporter);
1401 test_reduced_clip_stack_aa(reporter); 1401 test_reduced_clip_stack_aa(reporter);
1402 #endif 1402 #endif
1403 } 1403 }
OLDNEW
« no previous file with comments | « tests/ClipBoundsTest.cpp ('k') | tests/DrawPathTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698