OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 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 "PathOpsExtendedTest.h" | 8 #include "PathOpsExtendedTest.h" |
9 #include "PathOpsThreadedCommon.h" | 9 #include "PathOpsThreadedCommon.h" |
10 #include "SkBitmap.h" | 10 #include "SkBitmap.h" |
11 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
12 #include "SkForceLinking.h" | 12 #include "SkForceLinking.h" |
13 #include "SkMatrix.h" | 13 #include "SkMatrix.h" |
14 #include "SkPaint.h" | 14 #include "SkPaint.h" |
15 #include "SkRTConf.h" | 15 #include "SkRTConf.h" |
16 #include "SkStream.h" | 16 #include "SkStream.h" |
17 #include "SkTaskGroup.h" | 17 #include "SkTaskGroup.h" |
18 #include "SkThread.h" | 18 #include "SkThread.h" |
19 | 19 |
20 #ifdef SK_BUILD_FOR_MAC | 20 #ifdef SK_BUILD_FOR_MAC |
21 #include <sys/sysctl.h> | 21 #include <sys/sysctl.h> |
22 #endif | 22 #endif |
23 | 23 |
24 __SK_FORCE_IMAGE_DECODER_LINKING; | 24 __SK_FORCE_IMAGE_DECODER_LINKING; |
25 | 25 |
26 DEFINE_bool2(runFail, f, false, "run tests known to fail."); | 26 DEFINE_bool2(runFail, f, false, "run tests known to fail."); |
| 27 DEFINE_bool2(runBinary, f, false, "run tests known to fail binary sect."); |
27 | 28 |
28 static const char marker[] = | 29 static const char marker[] = |
29 "</div>\n" | 30 "</div>\n" |
30 "\n" | 31 "\n" |
31 "<script type=\"text/javascript\">\n" | 32 "<script type=\"text/javascript\">\n" |
32 "\n" | 33 "\n" |
33 "var testDivs = [\n"; | 34 "var testDivs = [\n"; |
34 | 35 |
35 static const char* opStrs[] = { | 36 static const char* opStrs[] = { |
36 "kDifference_PathOp", | 37 "kDifference_SkPathOp", |
37 "kIntersect_PathOp", | 38 "kIntersect_SkPathOp", |
38 "kUnion_PathOp", | 39 "kUnion_SkPathOp", |
39 "kXor_PathOp", | 40 "kXor_PathOp", |
40 "kReverseDifference_PathOp", | 41 "kReverseDifference_SkPathOp", |
41 }; | 42 }; |
42 | 43 |
43 static const char* opSuffixes[] = { | 44 static const char* opSuffixes[] = { |
44 "d", | 45 "d", |
45 "i", | 46 "i", |
46 "u", | 47 "u", |
47 "o", | 48 "o", |
48 }; | 49 }; |
49 | 50 |
50 static bool gShowPath = false; | |
51 static bool gComparePathsAssert = true; | |
52 static bool gPathStrAssert = true; | |
53 | |
54 #if DEBUG_SHOW_TEST_NAME | 51 #if DEBUG_SHOW_TEST_NAME |
55 static void showPathData(const SkPath& path) { | 52 static void showPathData(const SkPath& path) { |
56 SkPath::RawIter iter(path); | 53 SkPath::RawIter iter(path); |
57 uint8_t verb; | 54 uint8_t verb; |
58 SkPoint pts[4]; | 55 SkPoint pts[4]; |
59 SkPoint firstPt = {0, 0}, lastPt = {0, 0}; | 56 SkPoint firstPt = {0, 0}, lastPt = {0, 0}; |
60 bool firstPtSet = false; | 57 bool firstPtSet = false; |
61 bool lastPtSet = true; | 58 bool lastPtSet = true; |
62 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { | 59 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
63 switch (verb) { | 60 switch (verb) { |
(...skipping 11 matching lines...) Expand all Loading... |
75 pts[1].fX, pts[1].fY); | 72 pts[1].fX, pts[1].fY); |
76 lastPt = pts[1]; | 73 lastPt = pts[1]; |
77 lastPtSet = true; | 74 lastPtSet = true; |
78 break; | 75 break; |
79 case SkPath::kQuad_Verb: | 76 case SkPath::kQuad_Verb: |
80 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", | 77 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", |
81 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p
ts[2].fY); | 78 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p
ts[2].fY); |
82 lastPt = pts[2]; | 79 lastPt = pts[2]; |
83 lastPtSet = true; | 80 lastPtSet = true; |
84 break; | 81 break; |
| 82 case SkPath::kConic_Verb: |
| 83 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}}, //weig
ht=%1.9g\n", |
| 84 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p
ts[2].fY, |
| 85 iter.conicWeight()); |
| 86 lastPt = pts[2]; |
| 87 lastPtSet = true; |
| 88 break; |
85 case SkPath::kCubic_Verb: | 89 case SkPath::kCubic_Verb: |
86 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%
1.9g}},\n", | 90 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%
1.9g}},\n", |
87 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p
ts[2].fY, | 91 pts[0].fX, pts[0].fY, pts[1].fX, pts[1].fY, pts[2].fX, p
ts[2].fY, |
88 pts[3].fX, pts[3].fY); | 92 pts[3].fX, pts[3].fY); |
89 lastPt = pts[3]; | 93 lastPt = pts[3]; |
90 lastPtSet = true; | 94 lastPtSet = true; |
91 break; | 95 break; |
92 case SkPath::kClose_Verb: | 96 case SkPath::kClose_Verb: |
93 if (firstPtSet && lastPtSet && firstPt != lastPt) { | 97 if (firstPtSet && lastPtSet && firstPt != lastPt) { |
94 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", lastPt.fX, las
tPt.fY, | 98 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", lastPt.fX, las
tPt.fY, |
95 firstPt.fX, firstPt.fY); | 99 firstPt.fX, firstPt.fY); |
96 } | 100 } |
97 firstPtSet = lastPtSet = false; | 101 firstPtSet = lastPtSet = false; |
98 break; | 102 break; |
99 default: | 103 default: |
100 SkDEBUGFAIL("bad verb"); | 104 SkDEBUGFAIL("bad verb"); |
101 return; | 105 return; |
102 } | 106 } |
103 } | 107 } |
104 if (firstPtSet && lastPtSet && firstPt != lastPt) { | 108 if (firstPtSet && lastPtSet && firstPt != lastPt) { |
105 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", lastPt.fX, lastPt.fY, | 109 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", lastPt.fX, lastPt.fY, |
106 firstPt.fX, firstPt.fY); | 110 firstPt.fX, firstPt.fY); |
107 } | 111 } |
108 } | 112 } |
109 #endif | 113 #endif |
110 | 114 |
111 void showOp(const SkPathOp op) { | 115 void showOp(const SkPathOp op) { |
112 switch (op) { | 116 switch (op) { |
113 case kDifference_PathOp: | 117 case kDifference_SkPathOp: |
114 SkDebugf("op difference\n"); | 118 SkDebugf("op difference\n"); |
115 break; | 119 break; |
116 case kIntersect_PathOp: | 120 case kIntersect_SkPathOp: |
117 SkDebugf("op intersect\n"); | 121 SkDebugf("op intersect\n"); |
118 break; | 122 break; |
119 case kUnion_PathOp: | 123 case kUnion_SkPathOp: |
120 SkDebugf("op union\n"); | 124 SkDebugf("op union\n"); |
121 break; | 125 break; |
122 case kXOR_PathOp: | 126 case kXOR_SkPathOp: |
123 SkDebugf("op xor\n"); | 127 SkDebugf("op xor\n"); |
124 break; | 128 break; |
125 case kReverseDifference_PathOp: | 129 case kReverseDifference_SkPathOp: |
126 SkDebugf("op reverse difference\n"); | 130 SkDebugf("op reverse difference\n"); |
127 break; | 131 break; |
128 default: | 132 default: |
129 SkASSERT(0); | 133 SkASSERT(0); |
130 } | 134 } |
131 } | 135 } |
132 | 136 |
133 #if DEBUG_SHOW_TEST_NAME | 137 #if DEBUG_SHOW_TEST_NAME |
134 static char hexorator(int x) { | 138 static char hexorator(int x) { |
135 if (x < 10) { | 139 if (x < 10) { |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 *outPtr++ = '|'; | 270 *outPtr++ = '|'; |
267 for (x = bitWidth; x < bitWidth * 2; ++x) { | 271 for (x = bitWidth; x < bitWidth * 2; ++x) { |
268 *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x'; | 272 *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x'; |
269 } | 273 } |
270 *outPtr++ = '\0'; | 274 *outPtr++ = '\0'; |
271 SkDebugf("%s\n", out); | 275 SkDebugf("%s\n", out); |
272 } | 276 } |
273 return true; | 277 return true; |
274 } | 278 } |
275 | 279 |
276 static int comparePaths(skiatest::Reporter* reporter, const char* filename, cons
t SkPath& one, | 280 int comparePaths(skiatest::Reporter* reporter, const char* filename, const SkPat
h& one, |
277 const SkPath& two, SkBitmap& bitmap) { | 281 const SkPath& two, SkBitmap& bitmap) { |
278 int errors2x2; | 282 int errors2x2; |
279 SkPath scaledOne, scaledTwo; | 283 SkPath scaledOne, scaledTwo; |
280 (void) pathsDrawTheSame(one, two, bitmap, scaledOne, scaledTwo, errors2x2); | 284 (void) pathsDrawTheSame(one, two, bitmap, scaledOne, scaledTwo, errors2x2); |
281 if (errors2x2 == 0) { | 285 if (errors2x2 == 0) { |
282 return 0; | 286 return 0; |
283 } | 287 } |
284 const int MAX_ERRORS = 9; | 288 const int MAX_ERRORS = 9; |
285 REPORTER_ASSERT(reporter, errors2x2 <= MAX_ERRORS || !gComparePathsAssert); | |
286 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; | 289 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; |
287 } | 290 } |
288 | 291 |
289 const int gTestFirst = 4; | 292 const int gTestFirst = 4; |
290 static int gTestNo = gTestFirst; | 293 static int gTestNo = gTestFirst; |
291 static SkTDArray<SkPathOp> gTestOp; | 294 static SkTDArray<SkPathOp> gTestOp; |
292 | 295 |
293 static void showPathOpPath(const char* testName, const SkPath& one, const SkPath
& two, | 296 static void showPathOpPath(const char* testName, const SkPath& one, const SkPath
& two, |
294 const SkPath& a, const SkPath& b, const SkPath& scaledOne, const SkPath&
scaledTwo, | 297 const SkPath& a, const SkPath& b, const SkPath& scaledOne, const SkPath&
scaledTwo, |
295 const SkPathOp shapeOp, const SkMatrix& scale) { | 298 const SkPathOp shapeOp, const SkMatrix& scale) { |
296 SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); | 299 SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); |
297 SkString defaultTestName; | 300 SkString defaultTestName; |
298 if (!testName) { | 301 if (!testName) { |
299 defaultTestName.printf("xOp%d%s", gTestNo, opSuffixes[shapeOp]); | 302 defaultTestName.printf("xOp%d%s", gTestNo, opSuffixes[shapeOp]); |
300 testName = defaultTestName.c_str(); | 303 testName = defaultTestName.c_str(); |
301 } | 304 } |
302 SkDebugf("static void %s(skiatest::Reporter* reporter, const char* filename)
{\n", testName); | 305 SkDebugf("static void %s(skiatest::Reporter* reporter, const char* filename)
{\n", testName); |
303 *gTestOp.append() = shapeOp; | 306 *gTestOp.append() = shapeOp; |
304 ++gTestNo; | 307 ++gTestNo; |
305 SkDebugf(" SkPath path, pathB;\n"); | 308 SkDebugf(" SkPath path, pathB;\n"); |
306 #if DEBUG_SHOW_TEST_NAME | 309 #if 0 && DEBUG_SHOW_TEST_NAME |
307 SkPathOpsDebug::ShowOnePath(a, "path", false); | 310 SkPathOpsDebug::ShowOnePath(a, "path", false); |
308 SkPathOpsDebug::ShowOnePath(b, "pathB", false); | 311 SkPathOpsDebug::ShowOnePath(b, "pathB", false); |
309 #endif | 312 #endif |
310 SkDebugf(" testPathOp(reporter, path, pathB, %s, filename);\n", opStrs[sh
apeOp]); | 313 SkDebugf(" testPathOp(reporter, path, pathB, %s, filename);\n", opStrs[sh
apeOp]); |
311 SkDebugf("}\n"); | 314 SkDebugf("}\n"); |
312 drawAsciiPaths(scaledOne, scaledTwo, true); | 315 drawAsciiPaths(scaledOne, scaledTwo, true); |
313 } | 316 } |
314 | 317 |
315 void ShowTestArray() { | 318 void ShowTestArray() { |
316 for (int x = gTestFirst; x < gTestNo; ++x) { | 319 for (int x = gTestFirst; x < gTestNo; ++x) { |
(...skipping 10 matching lines...) Expand all Loading... |
327 int errors2x2; | 330 int errors2x2; |
328 const int MAX_ERRORS = 8; | 331 const int MAX_ERRORS = 8; |
329 (void) pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); | 332 (void) pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); |
330 if (!expectSuccess) { | 333 if (!expectSuccess) { |
331 if (errors2x2 <= MAX_ERRORS) { | 334 if (errors2x2 <= MAX_ERRORS) { |
332 REPORTER_ASSERT(reporter, 0); | 335 REPORTER_ASSERT(reporter, 0); |
333 } | 336 } |
334 return 0; | 337 return 0; |
335 } | 338 } |
336 if (errors2x2 == 0) { | 339 if (errors2x2 == 0) { |
337 if (gShowPath) { | |
338 showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shape
Op, scale); | |
339 } | |
340 return 0; | 340 return 0; |
341 } | 341 } |
342 if (errors2x2 > MAX_ERRORS && gComparePathsAssert) { | 342 if (errors2x2 > MAX_ERRORS) { |
343 SkAutoMutexAcquire autoM(compareDebugOut3); | 343 SkAutoMutexAcquire autoM(compareDebugOut3); |
344 SkDebugf("\n*** this test fails ***\n"); | 344 SkDebugf("\n*** this test fails ***\n"); |
345 showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp,
scale); | 345 showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp,
scale); |
346 REPORTER_ASSERT(reporter, 0); | 346 REPORTER_ASSERT(reporter, 0); |
347 } else if (gShowPath || errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS -
1) { | 347 } else if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) { |
348 SkAutoMutexAcquire autoM(compareDebugOut4); | 348 SkAutoMutexAcquire autoM(compareDebugOut4); |
349 showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp,
scale); | 349 showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp,
scale); |
350 } | 350 } |
351 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; | 351 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; |
352 } | 352 } |
353 | 353 |
354 // Default values for when reporter->verbose() is false. | 354 // Default values for when reporter->verbose() is false. |
355 static int testNumber = 55; | 355 static int testNumber = 55; |
356 static const char* testName = "pathOpTest"; | 356 static const char* testName = "pathOpTest"; |
357 | 357 |
358 static void writeTestName(const char* nameSuffix, SkMemoryWStream& outFile) { | 358 static void writeTestName(const char* nameSuffix, SkMemoryWStream& outFile) { |
359 outFile.writeText(testName); | 359 outFile.writeText(testName); |
360 outFile.writeDecAsText(testNumber); | 360 outFile.writeDecAsText(testNumber); |
361 ++testNumber; | 361 ++testNumber; |
362 if (nameSuffix) { | 362 if (nameSuffix) { |
363 outFile.writeText(nameSuffix); | 363 outFile.writeText(nameSuffix); |
364 } | 364 } |
365 } | 365 } |
366 | 366 |
367 static void outputToStream(const char* pathStr, const char* pathPrefix, const ch
ar* nameSuffix, | 367 static void outputToStream(const char* pathStr, const char* pathPrefix, const ch
ar* nameSuffix, |
368 const char* testFunction, bool twoPaths, SkMemoryWStream& outFile) { | 368 const char* testFunction, bool twoPaths, SkMemoryWStream& outFile) { |
369 #if 0 | 369 #if 0 |
370 outFile.writeText("<div id=\""); | 370 outFile.writeText("\n<div id=\""); |
371 writeTestName(nameSuffix, outFile); | 371 writeTestName(nameSuffix, outFile); |
372 outFile.writeText("\">\n"); | 372 outFile.writeText("\">\n"); |
373 if (pathPrefix) { | 373 if (pathPrefix) { |
374 outFile.writeText(pathPrefix); | 374 outFile.writeText(pathPrefix); |
375 } | 375 } |
376 outFile.writeText(pathStr); | 376 outFile.writeText(pathStr); |
377 outFile.writeText("</div>\n\n"); | 377 outFile.writeText("</div>\n\n"); |
378 | 378 |
379 outFile.writeText(marker); | 379 outFile.writeText(marker); |
380 outFile.writeText(" "); | 380 outFile.writeText(" "); |
(...skipping 24 matching lines...) Expand all Loading... |
405 outFile.writeText(" const char* str;\n"); | 405 outFile.writeText(" const char* str;\n"); |
406 outFile.writeText("} tests[] = {\n"); | 406 outFile.writeText("} tests[] = {\n"); |
407 outFile.writeText(" TEST("); | 407 outFile.writeText(" TEST("); |
408 writeTestName(nameSuffix, outFile); | 408 writeTestName(nameSuffix, outFile); |
409 outFile.writeText("),\n"); | 409 outFile.writeText("),\n"); |
410 #endif | 410 #endif |
411 outFile.flush(); | 411 outFile.flush(); |
412 } | 412 } |
413 | 413 |
414 SK_DECLARE_STATIC_MUTEX(simplifyDebugOut); | 414 SK_DECLARE_STATIC_MUTEX(simplifyDebugOut); |
| 415 |
415 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st
ate, | 416 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st
ate, |
416 const char* pathStr) { | 417 const char* pathStr) { |
417 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi
nding_FillType; | 418 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi
nding_FillType; |
418 path.setFillType(fillType); | 419 path.setFillType(fillType); |
419 #if DEBUG_SHOW_TEST_NAME | 420 state.fReporter->bumpTestCount(); |
420 if (gShowPath) { | |
421 SkPathOpsDebug::ShowOnePath(path, "path", false); | |
422 } | |
423 #endif | |
424 if (!Simplify(path, &out)) { | 421 if (!Simplify(path, &out)) { |
425 SkDebugf("%s did not expect failure\n", __FUNCTION__); | 422 SkDebugf("%s did not expect failure\n", __FUNCTION__); |
426 REPORTER_ASSERT(state.fReporter, 0); | 423 REPORTER_ASSERT(state.fReporter, 0); |
427 return false; | 424 return false; |
428 } | 425 } |
429 if (!state.fReporter->verbose()) { | 426 if (!state.fReporter->verbose()) { |
430 return true; | 427 return true; |
431 } | 428 } |
432 int result = comparePaths(state.fReporter, NULL, path, out, *state.fBitmap); | 429 int result = comparePaths(state.fReporter, NULL, path, out, *state.fBitmap); |
433 if (result && gPathStrAssert) { | 430 if (result) { |
434 SkAutoMutexAcquire autoM(simplifyDebugOut); | 431 SkAutoMutexAcquire autoM(simplifyDebugOut); |
435 char temp[8192]; | 432 char temp[8192]; |
436 sk_bzero(temp, sizeof(temp)); | 433 sk_bzero(temp, sizeof(temp)); |
437 SkMemoryWStream stream(temp, sizeof(temp)); | 434 SkMemoryWStream stream(temp, sizeof(temp)); |
438 const char* pathPrefix = NULL; | 435 const char* pathPrefix = NULL; |
439 const char* nameSuffix = NULL; | 436 const char* nameSuffix = NULL; |
440 if (fillType == SkPath::kEvenOdd_FillType) { | 437 if (fillType == SkPath::kEvenOdd_FillType) { |
441 pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n"; | 438 pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n"; |
442 nameSuffix = "x"; | 439 nameSuffix = "x"; |
443 } | 440 } |
444 const char testFunction[] = "testSimplify(reporter, path);"; | 441 const char testFunction[] = "testSimplify(reporter, path);"; |
445 outputToStream(pathStr, pathPrefix, nameSuffix, testFunction, false, str
eam); | 442 outputToStream(pathStr, pathPrefix, nameSuffix, testFunction, false, str
eam); |
446 SkDebugf("%s", temp); | 443 SkDebugf("%s", temp); |
447 REPORTER_ASSERT(state.fReporter, 0); | 444 REPORTER_ASSERT(state.fReporter, 0); |
448 } | 445 } |
449 state.fReporter->bumpTestCount(); | 446 state.fReporter->bumpTestCount(); |
450 return result == 0; | 447 return result == 0; |
451 } | 448 } |
452 | 449 |
453 bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char*
filename) { | 450 static bool inner_simplify(skiatest::Reporter* reporter, const SkPath& path, con
st char* filename, |
454 #if DEBUG_SHOW_TEST_NAME | 451 bool checkFail) { |
| 452 #if 0 && DEBUG_SHOW_TEST_NAME |
455 showPathData(path); | 453 showPathData(path); |
456 #endif | 454 #endif |
457 SkPath out; | 455 SkPath out; |
458 if (!Simplify(path, &out)) { | 456 if (!Simplify(path, &out)) { |
459 SkDebugf("%s did not expect failure\n", __FUNCTION__); | 457 SkDebugf("%s did not expect %s failure\n", __FUNCTION__, filename); |
460 REPORTER_ASSERT(reporter, 0); | 458 REPORTER_ASSERT(reporter, 0); |
461 return false; | 459 return false; |
462 } | 460 } |
463 SkBitmap bitmap; | 461 SkBitmap bitmap; |
464 int result = comparePaths(reporter, filename, path, out, bitmap); | 462 int errors = comparePaths(reporter, filename, path, out, bitmap); |
465 if (result && gPathStrAssert) { | 463 if (!checkFail) { |
| 464 if (!errors) { |
| 465 SkDebugf("%s failing test %s now succeeds\n", __FUNCTION__, filename
); |
| 466 REPORTER_ASSERT(reporter, 0); |
| 467 return false; |
| 468 } |
| 469 } else if (errors) { |
466 REPORTER_ASSERT(reporter, 0); | 470 REPORTER_ASSERT(reporter, 0); |
467 } | 471 } |
468 reporter->bumpTestCount(); | 472 reporter->bumpTestCount(); |
469 return result == 0; | 473 return errors == 0; |
| 474 } |
| 475 |
| 476 bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char*
filename) { |
| 477 return inner_simplify(reporter, path, filename, true); |
| 478 } |
| 479 |
| 480 bool testSimplifyCheck(skiatest::Reporter* reporter, const SkPath& path, const c
har* filename, |
| 481 bool checkFail) { |
| 482 return inner_simplify(reporter, path, filename, checkFail); |
470 } | 483 } |
471 | 484 |
472 #if DEBUG_SHOW_TEST_NAME | 485 #if DEBUG_SHOW_TEST_NAME |
473 static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) { | 486 static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) { |
474 SkDebugf("\n"); | 487 SkDebugf("\n"); |
475 showPathData(a); | 488 showPathData(a); |
476 showOp(shapeOp); | 489 showOp(shapeOp); |
477 showPathData(b); | 490 showPathData(b); |
478 } | 491 } |
479 #endif | 492 #endif |
480 | 493 |
481 static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
ath& b, | 494 static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
ath& b, |
482 const SkPathOp shapeOp, const char* testName, bool threaded, bool expect
Success) { | 495 const SkPathOp shapeOp, const char* testName, bool threaded, bool expect
Success) { |
483 #if DEBUG_SHOW_TEST_NAME | 496 #if 0 && DEBUG_SHOW_TEST_NAME |
484 showName(a, b, shapeOp); | 497 showName(a, b, shapeOp); |
485 #endif | 498 #endif |
486 SkPath out; | 499 SkPath out; |
487 if (!Op(a, b, shapeOp, &out) ) { | 500 if (!Op(a, b, shapeOp, &out) ) { |
488 SkDebugf("%s did not expect failure\n", __FUNCTION__); | 501 SkDebugf("%s did not expect failure\n", __FUNCTION__); |
489 REPORTER_ASSERT(reporter, 0); | 502 REPORTER_ASSERT(reporter, 0); |
490 return false; | 503 return false; |
491 } | 504 } |
492 if (threaded && !reporter->verbose()) { | 505 if (!reporter->verbose()) { |
493 return true; | 506 return true; |
494 } | 507 } |
495 SkPath pathOut, scaledPathOut; | 508 SkPath pathOut, scaledPathOut; |
496 SkRegion rgnA, rgnB, openClip, rgnOut; | 509 SkRegion rgnA, rgnB, openClip, rgnOut; |
497 openClip.setRect(-16000, -16000, 16000, 16000); | 510 openClip.setRect(-16000, -16000, 16000, 16000); |
498 rgnA.setPath(a, openClip); | 511 rgnA.setPath(a, openClip); |
499 rgnB.setPath(b, openClip); | 512 rgnB.setPath(b, openClip); |
500 rgnOut.op(rgnA, rgnB, (SkRegion::Op) shapeOp); | 513 rgnOut.op(rgnA, rgnB, (SkRegion::Op) shapeOp); |
501 rgnOut.getBoundaryPath(&pathOut); | 514 rgnOut.getBoundaryPath(&pathOut); |
502 | 515 |
503 SkMatrix scale; | 516 SkMatrix scale; |
504 scaleMatrix(a, b, scale); | 517 scaleMatrix(a, b, scale); |
505 SkRegion scaledRgnA, scaledRgnB, scaledRgnOut; | 518 SkRegion scaledRgnA, scaledRgnB, scaledRgnOut; |
506 SkPath scaledA, scaledB; | 519 SkPath scaledA, scaledB; |
507 scaledA.addPath(a, scale); | 520 scaledA.addPath(a, scale); |
508 scaledA.setFillType(a.getFillType()); | 521 scaledA.setFillType(a.getFillType()); |
509 scaledB.addPath(b, scale); | 522 scaledB.addPath(b, scale); |
510 scaledB.setFillType(b.getFillType()); | 523 scaledB.setFillType(b.getFillType()); |
511 scaledRgnA.setPath(scaledA, openClip); | 524 scaledRgnA.setPath(scaledA, openClip); |
512 scaledRgnB.setPath(scaledB, openClip); | 525 scaledRgnB.setPath(scaledB, openClip); |
513 scaledRgnOut.op(scaledRgnA, scaledRgnB, (SkRegion::Op) shapeOp); | 526 scaledRgnOut.op(scaledRgnA, scaledRgnB, (SkRegion::Op) shapeOp); |
514 scaledRgnOut.getBoundaryPath(&scaledPathOut); | 527 scaledRgnOut.getBoundaryPath(&scaledPathOut); |
515 SkBitmap bitmap; | 528 SkBitmap bitmap; |
516 SkPath scaledOut; | 529 SkPath scaledOut; |
517 scaledOut.addPath(out, scale); | 530 scaledOut.addPath(out, scale); |
518 scaledOut.setFillType(out.getFillType()); | 531 scaledOut.setFillType(out.getFillType()); |
519 int result = comparePaths(reporter, testName, pathOut, scaledPathOut, out, s
caledOut, bitmap, | 532 int result = comparePaths(reporter, testName, pathOut, scaledPathOut, out, s
caledOut, bitmap, |
520 a, b, shapeOp, scale, expectSuccess); | 533 a, b, shapeOp, scale, expectSuccess); |
521 if (result && gPathStrAssert) { | 534 if (result) { |
522 REPORTER_ASSERT(reporter, 0); | 535 REPORTER_ASSERT(reporter, 0); |
523 } | 536 } |
524 reporter->bumpTestCount(); | 537 reporter->bumpTestCount(); |
525 return result == 0; | 538 return result == 0; |
526 } | 539 } |
527 | 540 |
528 bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, | 541 bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, |
529 const SkPathOp shapeOp, const char* testName) { | 542 const SkPathOp shapeOp, const char* testName) { |
530 return innerPathOp(reporter, a, b, shapeOp, testName, false, true); | 543 return innerPathOp(reporter, a, b, shapeOp, testName, false, true); |
531 } | 544 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
597 void outputProgress(char* ramStr, const char* pathStr, SkPathOp op) { | 610 void outputProgress(char* ramStr, const char* pathStr, SkPathOp op) { |
598 const char testFunction[] = "testOp(path);"; | 611 const char testFunction[] = "testOp(path);"; |
599 SkASSERT((size_t) op < SK_ARRAY_COUNT(opSuffixes)); | 612 SkASSERT((size_t) op < SK_ARRAY_COUNT(opSuffixes)); |
600 const char* nameSuffix = opSuffixes[op]; | 613 const char* nameSuffix = opSuffixes[op]; |
601 SkMemoryWStream rRamStream(ramStr, PATH_STR_SIZE); | 614 SkMemoryWStream rRamStream(ramStr, PATH_STR_SIZE); |
602 outputToStream(pathStr, NULL, nameSuffix, testFunction, true, rRamStream); | 615 outputToStream(pathStr, NULL, nameSuffix, testFunction, true, rRamStream); |
603 } | 616 } |
604 | 617 |
605 void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count, | 618 void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count, |
606 void (*firstTest)(skiatest::Reporter* , const char* filename), | 619 void (*firstTest)(skiatest::Reporter* , const char* filename), |
| 620 void (*skipTest)(skiatest::Reporter* , const char* filename), |
607 void (*stopTest)(skiatest::Reporter* , const char* filename), bo
ol reverse) { | 621 void (*stopTest)(skiatest::Reporter* , const char* filename), bo
ol reverse) { |
608 size_t index; | 622 size_t index; |
609 if (firstTest) { | 623 if (firstTest) { |
610 index = count - 1; | 624 index = count - 1; |
611 while (index > 0 && tests[index].fun != firstTest) { | 625 while (index > 0 && tests[index].fun != firstTest) { |
612 --index; | 626 --index; |
613 } | 627 } |
614 #if DEBUG_SHOW_TEST_NAME | 628 #if DEBUG_SHOW_TEST_NAME |
615 SkDebugf("<div id=\"%s\">\n", tests[index].str); | 629 SkDebugf("\n<div id=\"%s\">\n", tests[index].str); |
616 SkDebugf(" %s [%s]\n", __FUNCTION__, tests[index].str); | |
617 #endif | 630 #endif |
618 (*tests[index].fun)(reporter, tests[index].str); | 631 (*tests[index].fun)(reporter, tests[index].str); |
619 if (tests[index].fun == stopTest) { | 632 if (tests[index].fun == stopTest) { |
620 return; | 633 return; |
621 } | 634 } |
622 } | 635 } |
623 index = reverse ? count - 1 : 0; | 636 index = reverse ? count - 1 : 0; |
624 size_t last = reverse ? 0 : count - 1; | 637 size_t last = reverse ? 0 : count - 1; |
| 638 bool foundSkip = !skipTest; |
625 do { | 639 do { |
626 if (tests[index].fun != firstTest) { | 640 if (tests[index].fun == skipTest) { |
| 641 foundSkip = true; |
| 642 } |
| 643 if (foundSkip && tests[index].fun != firstTest) { |
627 #if DEBUG_SHOW_TEST_NAME | 644 #if DEBUG_SHOW_TEST_NAME |
628 SkDebugf("<div id=\"%s\">\n", tests[index].str); | 645 SkDebugf("\n<div id=\"%s\">\n", tests[index].str); |
629 SkDebugf(" %s [%s]\n", __FUNCTION__, tests[index].str); | |
630 #endif | 646 #endif |
631 (*tests[index].fun)(reporter, tests[index].str); | 647 (*tests[index].fun)(reporter, tests[index].str); |
632 } | 648 } |
633 if (tests[index].fun == stopTest) { | 649 if (tests[index].fun == stopTest) { |
634 SkDebugf("lastTest\n"); | 650 SkDebugf("lastTest\n"); |
635 break; | 651 break; |
636 } | 652 } |
637 if (index == last) { | 653 if (index == last) { |
638 break; | 654 break; |
639 } | 655 } |
640 index += reverse ? -1 : 1; | 656 index += reverse ? -1 : 1; |
641 } while (true); | 657 } while (true); |
642 } | 658 } |
OLD | NEW |