| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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}, ®ion); | 840 set_region_to_stack(stack, {0, 0, 50, 30}, ®ion); |
| 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 Loading... |
| 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 Loading... |
| 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, ®ion); | 1059 set_region_to_stack(stack, ibounds, ®ion); |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |