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 "SkThread.h" |
17 #include "SkThreadPool.h" | 18 #include "SkThreadPool.h" |
18 | 19 |
19 #ifdef SK_BUILD_FOR_MAC | 20 #ifdef SK_BUILD_FOR_MAC |
20 #include <sys/sysctl.h> | 21 #include <sys/sysctl.h> |
21 #endif | 22 #endif |
22 | 23 |
23 __SK_FORCE_IMAGE_DECODER_LINKING; | 24 __SK_FORCE_IMAGE_DECODER_LINKING; |
24 | 25 |
25 static const char marker[] = | 26 static const char marker[] = |
26 "</div>\n" | 27 "</div>\n" |
(...skipping 27 matching lines...) Expand all Loading... |
54 "kInverseWinding_FillType", | 55 "kInverseWinding_FillType", |
55 "kInverseEvenOdd_FillType" | 56 "kInverseEvenOdd_FillType" |
56 }; | 57 }; |
57 | 58 |
58 static void output_scalar(SkScalar num) { | 59 static void output_scalar(SkScalar num) { |
59 if (num == (int) num) { | 60 if (num == (int) num) { |
60 SkDebugf("%d", (int) num); | 61 SkDebugf("%d", (int) num); |
61 } else { | 62 } else { |
62 SkString str; | 63 SkString str; |
63 str.printf("%1.9g", num); | 64 str.printf("%1.9g", num); |
64 int width = str.size(); | 65 int width = (int) str.size(); |
65 const char* cStr = str.c_str(); | 66 const char* cStr = str.c_str(); |
66 while (cStr[width - 1] == '0') { | 67 while (cStr[width - 1] == '0') { |
67 --width; | 68 --width; |
68 } | 69 } |
69 str.resize(width); | 70 str.resize(width); |
70 SkDebugf("%sf", str.c_str()); | 71 SkDebugf("%sf", str.c_str()); |
71 } | 72 } |
72 } | 73 } |
73 | 74 |
74 static void output_points(const SkPoint* pts, int count) { | 75 static void output_points(const SkPoint* pts, int count) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
142 SkDebugf(" %s.setFillType(SkPath::%s);\n", pathName, gFillTypeStr[fillTyp
e]); | 143 SkDebugf(" %s.setFillType(SkPath::%s);\n", pathName, gFillTypeStr[fillTyp
e]); |
143 iter.setPath(path); | 144 iter.setPath(path); |
144 showPathContours(iter, pathName); | 145 showPathContours(iter, pathName); |
145 } | 146 } |
146 | 147 |
147 #if DEBUG_SHOW_TEST_NAME | 148 #if DEBUG_SHOW_TEST_NAME |
148 static void showPathData(const SkPath& path) { | 149 static void showPathData(const SkPath& path) { |
149 SkPath::RawIter iter(path); | 150 SkPath::RawIter iter(path); |
150 uint8_t verb; | 151 uint8_t verb; |
151 SkPoint pts[4]; | 152 SkPoint pts[4]; |
152 SkPoint firstPt, lastPt; | 153 SkPoint firstPt = {0, 0}, lastPt = {0, 0}; |
153 bool firstPtSet = false; | 154 bool firstPtSet = false; |
154 bool lastPtSet = true; | 155 bool lastPtSet = true; |
155 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { | 156 while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { |
156 switch (verb) { | 157 switch (verb) { |
157 case SkPath::kMove_Verb: | 158 case SkPath::kMove_Verb: |
158 firstPt = pts[0]; | 159 firstPt = pts[0]; |
159 firstPtSet = true; | 160 firstPtSet = true; |
160 continue; | 161 continue; |
161 case SkPath::kLine_Verb: | 162 case SkPath::kLine_Verb: |
162 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0].
fY, | 163 SkDebugf("{{%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", pts[0].fX, pts[0].
fY, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
210 SkDebugf("op reverse difference\n"); | 211 SkDebugf("op reverse difference\n"); |
211 break; | 212 break; |
212 default: | 213 default: |
213 SkASSERT(0); | 214 SkASSERT(0); |
214 } | 215 } |
215 } | 216 } |
216 | 217 |
217 #if DEBUG_SHOW_TEST_NAME | 218 #if DEBUG_SHOW_TEST_NAME |
218 | 219 |
219 void ShowFunctionHeader(const char* functionName) { | 220 void ShowFunctionHeader(const char* functionName) { |
220 SkDebugf("\nstatic void %s(skiatest::Reporter* reporter) {\n", functionName)
; | 221 SkDebugf("\nstatic void %s(skiatest::Reporter* reporter, const char* filenam
e) {\n", functionName); |
221 if (strcmp("skphealth_com76", functionName) == 0) { | 222 if (strcmp("skphealth_com76", functionName) == 0) { |
222 SkDebugf("found it\n"); | 223 SkDebugf("found it\n"); |
223 } | 224 } |
224 } | 225 } |
225 | 226 |
226 static const char* gOpStrs[] = { | 227 static const char* gOpStrs[] = { |
227 "kDifference_PathOp", | 228 "kDifference_PathOp", |
228 "kIntersect_PathOp", | 229 "kIntersect_PathOp", |
229 "kUnion_PathOp", | 230 "kUnion_PathOp", |
230 "kXor_PathOp", | 231 "kXor_PathOp", |
231 "kReverseDifference_PathOp", | 232 "kReverseDifference_PathOp", |
232 }; | 233 }; |
233 | 234 |
234 void ShowOp(SkPathOp op, const char* pathOne, const char* pathTwo) { | 235 void ShowOp(SkPathOp op, const char* pathOne, const char* pathTwo) { |
235 SkDebugf(" testPathOp(reporter, %s, %s, %s);\n", pathOne, pathTwo, gOpStr
s[op]); | 236 SkDebugf(" testPathOp(reporter, %s, %s, %s, filename);\n", pathOne, pathT
wo, gOpStrs[op]); |
236 SkDebugf("}\n"); | 237 SkDebugf("}\n"); |
237 } | 238 } |
238 #endif | 239 #endif |
239 | 240 |
240 #if DEBUG_SHOW_TEST_NAME | 241 #if DEBUG_SHOW_TEST_NAME |
241 static char hexorator(int x) { | 242 static char hexorator(int x) { |
242 if (x < 10) { | 243 if (x < 10) { |
243 return x + '0'; | 244 return x + '0'; |
244 } | 245 } |
245 x -= 10; | 246 x -= 10; |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 for (int x = 0; x < bitWidth - 1; ++x) { | 314 for (int x = 0; x < bitWidth - 1; ++x) { |
314 // count 2x2 blocks | 315 // count 2x2 blocks |
315 bool err = addr1[x] != addr3[x]; | 316 bool err = addr1[x] != addr3[x]; |
316 if (err) { | 317 if (err) { |
317 errors2 += addr1[x + 1] != addr3[x + 1] | 318 errors2 += addr1[x + 1] != addr3[x + 1] |
318 && addr2[x] != addr4[x] && addr2[x + 1] != addr4[x + 1]; | 319 && addr2[x] != addr4[x] && addr2[x + 1] != addr4[x + 1]; |
319 errors++; | 320 errors++; |
320 } | 321 } |
321 } | 322 } |
322 } | 323 } |
323 if (errors2 >= 6 || errors > 160) { | |
324 SkDebugf("%s errors2=%d errors=%d\n", __FUNCTION__, errors2, errors); | |
325 } | |
326 error2x2 = errors2; | 324 error2x2 = errors2; |
327 return errors; | 325 return errors; |
328 } | 326 } |
329 | 327 |
330 static int pathsDrawTheSame(const SkPath& one, const SkPath& two, SkBitmap& bits
, SkPath& scaledOne, | 328 static int pathsDrawTheSame(const SkPath& one, const SkPath& two, SkBitmap& bits
, SkPath& scaledOne, |
331 SkPath& scaledTwo, int& error2x2) { | 329 SkPath& scaledTwo, int& error2x2) { |
332 SkMatrix scale; | 330 SkMatrix scale; |
333 scaleMatrix(one, two, scale); | 331 scaleMatrix(one, two, scale); |
334 one.transform(scale, &scaledOne); | 332 one.transform(scale, &scaledOne); |
335 two.transform(scale, &scaledTwo); | 333 two.transform(scale, &scaledTwo); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
376 *outPtr++ = '|'; | 374 *outPtr++ = '|'; |
377 for (x = bitWidth; x < bitWidth * 2; ++x) { | 375 for (x = bitWidth; x < bitWidth * 2; ++x) { |
378 *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x'; | 376 *outPtr++ = addr1[x] == (uint32_t) -1 ? '_' : 'x'; |
379 } | 377 } |
380 *outPtr++ = '\0'; | 378 *outPtr++ = '\0'; |
381 SkDebugf("%s\n", out); | 379 SkDebugf("%s\n", out); |
382 } | 380 } |
383 return true; | 381 return true; |
384 } | 382 } |
385 | 383 |
386 static void showSimplifiedPath(const SkPath& one, const SkPath& two, | 384 static int comparePaths(skiatest::Reporter* reporter, const char* filename, cons
t SkPath& one, |
387 const SkPath& scaledOne, const SkPath& scaledTwo) { | 385 const SkPath& two, SkBitmap& bitmap) { |
388 showPath(one, "path", false); | |
389 drawAsciiPaths(scaledOne, scaledTwo, true); | |
390 } | |
391 | |
392 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S
kPath& two, | |
393 SkBitmap& bitmap) { | |
394 int errors2x2; | 386 int errors2x2; |
395 SkPath scaledOne, scaledTwo; | 387 SkPath scaledOne, scaledTwo; |
396 int errors = pathsDrawTheSame(one, two, bitmap, scaledOne, scaledTwo, errors
2x2); | 388 (void) pathsDrawTheSame(one, two, bitmap, scaledOne, scaledTwo, errors2x2); |
397 if (errors2x2 == 0) { | 389 if (errors2x2 == 0) { |
398 return 0; | 390 return 0; |
399 } | 391 } |
400 const int MAX_ERRORS = 9; | 392 const int MAX_ERRORS = 9; |
401 if (errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) { | 393 REPORTER_ASSERT(reporter, errors2x2 <= MAX_ERRORS || !gComparePathsAssert); |
402 showSimplifiedPath(one, two, scaledOne, scaledTwo); | |
403 } | |
404 if (errors2x2 > MAX_ERRORS && gComparePathsAssert) { | |
405 SkDebugf("%s errors=%d\n", __FUNCTION__, errors); | |
406 showSimplifiedPath(one, two, scaledOne, scaledTwo); | |
407 REPORTER_ASSERT(reporter, 0); | |
408 } | |
409 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; | 394 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; |
410 } | 395 } |
411 | 396 |
412 static void showPathOpPath(const SkPath& one, const SkPath& two, const SkPath& a
, const SkPath& b, | 397 const int gTestFirst = 4; |
413 const SkPath& scaledOne, const SkPath& scaledTwo, const SkPathOp shapeOp
, | 398 static int gTestNo = gTestFirst; |
414 const SkMatrix& scale) { | 399 static SkTDArray<SkPathOp> gTestOp; |
| 400 |
| 401 static void showPathOpPath(const char* testName, const SkPath& one, const SkPath
& two, |
| 402 const SkPath& a, const SkPath& b, const SkPath& scaledOne, const SkPath&
scaledTwo, |
| 403 const SkPathOp shapeOp, const SkMatrix& scale) { |
415 SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); | 404 SkASSERT((unsigned) shapeOp < SK_ARRAY_COUNT(opStrs)); |
416 SkDebugf("static void xOp#%s(skiatest::Reporter* reporter) {\n", opSuffixes[
shapeOp]); | 405 SkString defaultTestName; |
| 406 if (!testName) { |
| 407 defaultTestName.printf("xOp%d%s", gTestNo, opSuffixes[shapeOp]); |
| 408 testName = defaultTestName.c_str(); |
| 409 } |
| 410 SkDebugf("static void %s(skiatest::Reporter* reporter, const char* filename)
{\n", testName); |
| 411 *gTestOp.append() = shapeOp; |
| 412 ++gTestNo; |
417 SkDebugf(" SkPath path, pathB;\n"); | 413 SkDebugf(" SkPath path, pathB;\n"); |
418 showPath(a, "path", false); | 414 showPath(a, "path", false); |
419 showPath(b, "pathB", false); | 415 showPath(b, "pathB", false); |
420 SkDebugf(" testPathOp(reporter, path, pathB, %s);\n", opStrs[shapeOp]); | 416 SkDebugf(" testPathOp(reporter, path, pathB, %s, filename);\n", opStrs[sh
apeOp]); |
421 SkDebugf("}\n"); | 417 SkDebugf("}\n"); |
422 drawAsciiPaths(scaledOne, scaledTwo, true); | 418 drawAsciiPaths(scaledOne, scaledTwo, false); |
423 } | 419 } |
424 | 420 |
425 static int comparePaths(skiatest::Reporter* reporter, const SkPath& one, const S
kPath& scaledOne, | 421 void ShowTestArray() { |
426 const SkPath& two, const SkPath& scaledTwo, SkBitmap& bi
tmap, | 422 for (int x = gTestFirst; x < gTestNo; ++x) { |
427 const SkPath& a, const SkPath& b, const SkPathOp shapeOp
, | 423 SkDebugf(" TEST(xOp%d%s),\n", x, opSuffixes[gTestOp[x - gTestFirst]])
; |
428 const SkMatrix& scale) { | 424 } |
| 425 } |
| 426 |
| 427 static int comparePaths(skiatest::Reporter* reporter, const char* testName, cons
t SkPath& one, |
| 428 const SkPath& scaledOne, const SkPath& two, const SkPath& scaledTwo, SkB
itmap& bitmap, |
| 429 const SkPath& a, const SkPath& b, const SkPathOp shapeOp, const SkMatrix
& scale) { |
429 int errors2x2; | 430 int errors2x2; |
430 int errors = pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); | 431 (void) pathsDrawTheSame(bitmap, scaledOne, scaledTwo, errors2x2); |
431 if (errors2x2 == 0) { | 432 if (errors2x2 == 0) { |
432 if (gShowPath) { | 433 if (gShowPath) { |
433 showPathOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale)
; | 434 showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shape
Op, scale); |
434 } | 435 } |
435 return 0; | 436 return 0; |
436 } | 437 } |
437 const int MAX_ERRORS = 8; | 438 const int MAX_ERRORS = 8; |
438 if (gShowPath || errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS - 1) { | |
439 showPathOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale); | |
440 } | |
441 if (errors2x2 > MAX_ERRORS && gComparePathsAssert) { | 439 if (errors2x2 > MAX_ERRORS && gComparePathsAssert) { |
442 SkDebugf("%s errors=%d\n", __FUNCTION__, errors); | 440 SK_DECLARE_STATIC_MUTEX(compareDebugOut3); |
443 showPathOpPath(one, two, a, b, scaledOne, scaledTwo, shapeOp, scale); | 441 SkAutoMutexAcquire autoM(compareDebugOut3); |
| 442 showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp,
scale); |
444 REPORTER_ASSERT(reporter, 0); | 443 REPORTER_ASSERT(reporter, 0); |
| 444 } else if (gShowPath || errors2x2 == MAX_ERRORS || errors2x2 == MAX_ERRORS -
1) { |
| 445 SK_DECLARE_STATIC_MUTEX(compareDebugOut4); |
| 446 SkAutoMutexAcquire autoM(compareDebugOut4); |
| 447 showPathOpPath(testName, one, two, a, b, scaledOne, scaledTwo, shapeOp,
scale); |
445 } | 448 } |
446 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; | 449 return errors2x2 > MAX_ERRORS ? errors2x2 : 0; |
447 } | 450 } |
448 | 451 |
449 // Default values for when reporter->verbose() is false. | 452 // Default values for when reporter->verbose() is false. |
450 static int testNumber = 1; | 453 static int testNumber = 55; |
451 static const char* testName = "pathOpTest"; | 454 static const char* testName = "pathOpTest"; |
452 | 455 |
453 static void writeTestName(const char* nameSuffix, SkMemoryWStream& outFile) { | 456 static void writeTestName(const char* nameSuffix, SkMemoryWStream& outFile) { |
454 outFile.writeText(testName); | 457 outFile.writeText(testName); |
455 outFile.writeDecAsText(testNumber); | 458 outFile.writeDecAsText(testNumber); |
| 459 ++testNumber; |
456 if (nameSuffix) { | 460 if (nameSuffix) { |
457 outFile.writeText(nameSuffix); | 461 outFile.writeText(nameSuffix); |
458 } | 462 } |
459 } | 463 } |
460 | 464 |
461 static void outputToStream(const char* pathStr, const char* pathPrefix, const ch
ar* nameSuffix, | 465 static void outputToStream(const char* pathStr, const char* pathPrefix, const ch
ar* nameSuffix, |
462 const char* testFunction, bool twoPaths, SkMemoryWStream& outFile) { | 466 const char* testFunction, bool twoPaths, SkMemoryWStream& outFile) { |
| 467 #if 0 |
463 outFile.writeText("<div id=\""); | 468 outFile.writeText("<div id=\""); |
464 writeTestName(nameSuffix, outFile); | 469 writeTestName(nameSuffix, outFile); |
465 outFile.writeText("\">\n"); | 470 outFile.writeText("\">\n"); |
466 if (pathPrefix) { | 471 if (pathPrefix) { |
467 outFile.writeText(pathPrefix); | 472 outFile.writeText(pathPrefix); |
468 } | 473 } |
469 outFile.writeText(pathStr); | 474 outFile.writeText(pathStr); |
470 outFile.writeText("</div>\n\n"); | 475 outFile.writeText("</div>\n\n"); |
471 | 476 |
472 outFile.writeText(marker); | 477 outFile.writeText(marker); |
473 outFile.writeText(" "); | 478 outFile.writeText(" "); |
474 writeTestName(nameSuffix, outFile); | 479 writeTestName(nameSuffix, outFile); |
475 outFile.writeText(",\n\n\n"); | 480 outFile.writeText(",\n\n\n"); |
476 | 481 #endif |
477 outFile.writeText("static void "); | 482 outFile.writeText("static void "); |
478 writeTestName(nameSuffix, outFile); | 483 writeTestName(nameSuffix, outFile); |
479 outFile.writeText("() {\n SkPath path"); | 484 outFile.writeText("(skiatest::Reporter* reporter) {\n SkPath path"); |
480 if (twoPaths) { | 485 if (twoPaths) { |
481 outFile.writeText(", pathB"); | 486 outFile.writeText(", pathB"); |
482 } | 487 } |
483 outFile.writeText(";\n"); | 488 outFile.writeText(";\n"); |
484 if (pathPrefix) { | 489 if (pathPrefix) { |
485 outFile.writeText(pathPrefix); | 490 outFile.writeText(pathPrefix); |
486 } | 491 } |
487 outFile.writeText(pathStr); | 492 outFile.writeText(pathStr); |
488 outFile.writeText(" "); | 493 outFile.writeText(" "); |
489 outFile.writeText(testFunction); | 494 outFile.writeText(testFunction); |
490 outFile.writeText("\n}\n\n"); | 495 outFile.writeText("\n}\n\n"); |
| 496 #if 0 |
491 outFile.writeText("static void (*firstTest)() = "); | 497 outFile.writeText("static void (*firstTest)() = "); |
492 writeTestName(nameSuffix, outFile); | 498 writeTestName(nameSuffix, outFile); |
493 outFile.writeText(";\n\n"); | 499 outFile.writeText(";\n\n"); |
494 | 500 |
495 outFile.writeText("static struct {\n"); | 501 outFile.writeText("static struct {\n"); |
496 outFile.writeText(" void (*fun)();\n"); | 502 outFile.writeText(" void (*fun)();\n"); |
497 outFile.writeText(" const char* str;\n"); | 503 outFile.writeText(" const char* str;\n"); |
498 outFile.writeText("} tests[] = {\n"); | 504 outFile.writeText("} tests[] = {\n"); |
499 outFile.writeText(" TEST("); | 505 outFile.writeText(" TEST("); |
500 writeTestName(nameSuffix, outFile); | 506 writeTestName(nameSuffix, outFile); |
501 outFile.writeText("),\n"); | 507 outFile.writeText("),\n"); |
| 508 #endif |
502 outFile.flush(); | 509 outFile.flush(); |
503 } | 510 } |
504 | 511 |
505 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st
ate, | 512 bool testSimplify(SkPath& path, bool useXor, SkPath& out, PathOpsThreadState& st
ate, |
506 const char* pathStr) { | 513 const char* pathStr) { |
507 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi
nding_FillType; | 514 SkPath::FillType fillType = useXor ? SkPath::kEvenOdd_FillType : SkPath::kWi
nding_FillType; |
508 path.setFillType(fillType); | 515 path.setFillType(fillType); |
509 if (gShowPath) { | 516 if (gShowPath) { |
510 showPath(path, "path", false); | 517 showPath(path, "path", false); |
511 } | 518 } |
512 if (!Simplify(path, &out)) { | 519 if (!Simplify(path, &out)) { |
513 SkDebugf("%s did not expect failure\n", __FUNCTION__); | 520 SkDebugf("%s did not expect failure\n", __FUNCTION__); |
514 REPORTER_ASSERT(state.fReporter, 0); | 521 REPORTER_ASSERT(state.fReporter, 0); |
515 return false; | 522 return false; |
516 } | 523 } |
517 if (!state.fReporter->verbose()) { | 524 if (!state.fReporter->verbose()) { |
518 return true; | 525 return true; |
519 } | 526 } |
520 int result = comparePaths(state.fReporter, path, out, *state.fBitmap); | 527 int result = comparePaths(state.fReporter, NULL, path, out, *state.fBitmap); |
521 if (result && gPathStrAssert) { | 528 if (result && gPathStrAssert) { |
| 529 SK_DECLARE_STATIC_MUTEX(simplifyDebugOut); |
| 530 SkAutoMutexAcquire autoM(simplifyDebugOut); |
522 char temp[8192]; | 531 char temp[8192]; |
523 sk_bzero(temp, sizeof(temp)); | 532 sk_bzero(temp, sizeof(temp)); |
524 SkMemoryWStream stream(temp, sizeof(temp)); | 533 SkMemoryWStream stream(temp, sizeof(temp)); |
525 const char* pathPrefix = NULL; | 534 const char* pathPrefix = NULL; |
526 const char* nameSuffix = NULL; | 535 const char* nameSuffix = NULL; |
527 if (fillType == SkPath::kEvenOdd_FillType) { | 536 if (fillType == SkPath::kEvenOdd_FillType) { |
528 pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n"; | 537 pathPrefix = " path.setFillType(SkPath::kEvenOdd_FillType);\n"; |
529 nameSuffix = "x"; | 538 nameSuffix = "x"; |
530 } | 539 } |
531 const char testFunction[] = "testSimplifyx(path);"; | 540 const char testFunction[] = "testSimplify(reporter, path);"; |
532 outputToStream(pathStr, pathPrefix, nameSuffix, testFunction, false, str
eam); | 541 outputToStream(pathStr, pathPrefix, nameSuffix, testFunction, false, str
eam); |
533 SkDebugf(temp); | 542 SkDebugf(temp); |
534 REPORTER_ASSERT(state.fReporter, 0); | 543 REPORTER_ASSERT(state.fReporter, 0); |
535 } | 544 } |
536 state.fReporter->bumpTestCount(); | 545 state.fReporter->bumpTestCount(); |
537 return result == 0; | 546 return result == 0; |
538 } | 547 } |
539 | 548 |
540 bool testSimplify(skiatest::Reporter* reporter, const SkPath& path) { | 549 bool testSimplify(skiatest::Reporter* reporter, const SkPath& path, const char*
filename) { |
541 #if DEBUG_SHOW_TEST_NAME | 550 #if DEBUG_SHOW_TEST_NAME |
542 showPathData(path); | 551 showPathData(path); |
543 #endif | 552 #endif |
544 SkPath out; | 553 SkPath out; |
545 if (!Simplify(path, &out)) { | 554 if (!Simplify(path, &out)) { |
546 SkDebugf("%s did not expect failure\n", __FUNCTION__); | 555 SkDebugf("%s did not expect failure\n", __FUNCTION__); |
547 REPORTER_ASSERT(reporter, 0); | 556 REPORTER_ASSERT(reporter, 0); |
548 return false; | 557 return false; |
549 } | 558 } |
550 SkBitmap bitmap; | 559 SkBitmap bitmap; |
551 int result = comparePaths(reporter, path, out, bitmap); | 560 int result = comparePaths(reporter, filename, path, out, bitmap); |
552 if (result && gPathStrAssert) { | 561 if (result && gPathStrAssert) { |
553 REPORTER_ASSERT(reporter, 0); | 562 REPORTER_ASSERT(reporter, 0); |
554 } | 563 } |
555 reporter->bumpTestCount(); | 564 reporter->bumpTestCount(); |
556 return result == 0; | 565 return result == 0; |
557 } | 566 } |
558 | 567 |
559 #if DEBUG_SHOW_TEST_NAME | 568 #if DEBUG_SHOW_TEST_NAME |
560 void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp
, | 569 void SkPathOpsDebug::ShowPath(const SkPath& a, const SkPath& b, SkPathOp shapeOp
, |
561 const char* testName) { | 570 const char* testName) { |
562 ShowFunctionHeader(testName); | 571 ShowFunctionHeader(testName); |
563 showPath(a, "path", true); | 572 showPath(a, "path", true); |
564 showPath(b, "pathB", true); | 573 showPath(b, "pathB", true); |
565 ShowOp(shapeOp, "path", "pathB"); | 574 ShowOp(shapeOp, "path", "pathB"); |
566 } | 575 } |
567 #endif | 576 #endif |
568 | 577 |
| 578 #if DEBUG_SHOW_TEST_NAME |
| 579 static void showName(const SkPath& a, const SkPath& b, const SkPathOp shapeOp) { |
| 580 SkDebugf("\n"); |
| 581 showPathData(a); |
| 582 showOp(shapeOp); |
| 583 showPathData(b); |
| 584 } |
| 585 #endif |
| 586 |
569 static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
ath& b, | 587 static bool innerPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
ath& b, |
570 const SkPathOp shapeOp, const char* testName, bool threaded) { | 588 const SkPathOp shapeOp, const char* testName, bool threaded) { |
571 #if DEBUG_SHOW_TEST_NAME | 589 #if DEBUG_SHOW_TEST_NAME |
572 if (testName == NULL) { | 590 showName(a, b, shapeOp); |
573 SkDebugf("\n"); | |
574 showPathData(a); | |
575 showOp(shapeOp); | |
576 showPathData(b); | |
577 } else { | |
578 SkPathOpsDebug::ShowPath(a, b, shapeOp, testName); | |
579 } | |
580 #endif | 591 #endif |
581 SkPath out; | 592 SkPath out; |
582 if (!Op(a, b, shapeOp, &out) ) { | 593 if (!Op(a, b, shapeOp, &out) ) { |
583 SkDebugf("%s did not expect failure\n", __FUNCTION__); | 594 SkDebugf("%s did not expect failure\n", __FUNCTION__); |
584 REPORTER_ASSERT(reporter, 0); | 595 REPORTER_ASSERT(reporter, 0); |
585 return false; | 596 return false; |
586 } | 597 } |
587 if (threaded && !reporter->verbose()) { | 598 if (threaded && !reporter->verbose()) { |
588 return true; | 599 return true; |
589 } | 600 } |
(...skipping 14 matching lines...) Expand all Loading... |
604 scaledB.addPath(b, scale); | 615 scaledB.addPath(b, scale); |
605 scaledB.setFillType(b.getFillType()); | 616 scaledB.setFillType(b.getFillType()); |
606 scaledRgnA.setPath(scaledA, openClip); | 617 scaledRgnA.setPath(scaledA, openClip); |
607 scaledRgnB.setPath(scaledB, openClip); | 618 scaledRgnB.setPath(scaledB, openClip); |
608 scaledRgnOut.op(scaledRgnA, scaledRgnB, (SkRegion::Op) shapeOp); | 619 scaledRgnOut.op(scaledRgnA, scaledRgnB, (SkRegion::Op) shapeOp); |
609 scaledRgnOut.getBoundaryPath(&scaledPathOut); | 620 scaledRgnOut.getBoundaryPath(&scaledPathOut); |
610 SkBitmap bitmap; | 621 SkBitmap bitmap; |
611 SkPath scaledOut; | 622 SkPath scaledOut; |
612 scaledOut.addPath(out, scale); | 623 scaledOut.addPath(out, scale); |
613 scaledOut.setFillType(out.getFillType()); | 624 scaledOut.setFillType(out.getFillType()); |
614 int result = comparePaths(reporter, pathOut, scaledPathOut, out, scaledOut,
bitmap, a, b, | 625 int result = comparePaths(reporter, testName, pathOut, scaledPathOut, out, s
caledOut, bitmap, |
615 shapeOp, scale); | 626 a, b, shapeOp, scale); |
616 if (result && gPathStrAssert) { | 627 if (result && gPathStrAssert) { |
617 REPORTER_ASSERT(reporter, 0); | 628 REPORTER_ASSERT(reporter, 0); |
618 } | 629 } |
619 reporter->bumpTestCount(); | 630 reporter->bumpTestCount(); |
620 return result == 0; | 631 return result == 0; |
621 } | 632 } |
622 | 633 |
623 bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, | 634 bool testPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath& b, |
624 const SkPathOp shapeOp, const char* testName) { | 635 const SkPathOp shapeOp, const char* testName) { |
625 return innerPathOp(reporter, a, b, shapeOp, testName, false); | 636 return innerPathOp(reporter, a, b, shapeOp, testName, false); |
626 } | 637 } |
627 | 638 |
| 639 bool testPathFailOp(skiatest::Reporter* reporter, const SkPath& a, const SkPath&
b, |
| 640 const SkPathOp shapeOp, const char* testName) { |
| 641 #if DEBUG_SHOW_TEST_NAME |
| 642 showName(a, b, shapeOp); |
| 643 #endif |
| 644 SkPath out; |
| 645 if (Op(a, b, shapeOp, &out) ) { |
| 646 SkDebugf("%s test is expected to fail\n", __FUNCTION__); |
| 647 REPORTER_ASSERT(reporter, 0); |
| 648 return false; |
| 649 } |
| 650 return true; |
| 651 } |
| 652 |
628 bool testThreadedPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
ath& b, | 653 bool testThreadedPathOp(skiatest::Reporter* reporter, const SkPath& a, const SkP
ath& b, |
629 const SkPathOp shapeOp, const char* testName) { | 654 const SkPathOp shapeOp, const char* testName) { |
630 return innerPathOp(reporter, a, b, shapeOp, testName, true); | 655 return innerPathOp(reporter, a, b, shapeOp, testName, true); |
631 } | 656 } |
632 | 657 |
633 SK_DECLARE_STATIC_MUTEX(gMutex); | 658 SK_DECLARE_STATIC_MUTEX(gMutex); |
634 | 659 |
635 int initializeTests(skiatest::Reporter* reporter, const char* test) { | 660 int initializeTests(skiatest::Reporter* reporter, const char* test) { |
636 #if 0 // doesn't work yet | 661 #if 0 // doesn't work yet |
637 SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true); | 662 SK_CONF_SET("images.jpeg.suppressDecoderWarnings", true); |
638 SK_CONF_SET("images.png.suppressDecoderWarnings", true); | 663 SK_CONF_SET("images.png.suppressDecoderWarnings", true); |
639 #endif | 664 #endif |
640 #ifdef SK_DEBUG | 665 #ifdef SK_DEBUG |
641 SkPathOpsDebug::gMaxWindSum = 4; | 666 SkPathOpsDebug::gMaxWindSum = 4; |
642 SkPathOpsDebug::gMaxWindValue = 4; | 667 SkPathOpsDebug::gMaxWindValue = 4; |
643 #endif | 668 #endif |
644 if (reporter->verbose()) { | 669 if (reporter->verbose()) { |
645 SkAutoMutexAcquire lock(gMutex); | 670 SkAutoMutexAcquire lock(gMutex); |
646 testName = test; | 671 testName = test; |
647 size_t testNameSize = strlen(test); | 672 size_t testNameSize = strlen(test); |
648 SkFILEStream inFile("../../experimental/Intersection/op.htm"); | 673 SkFILEStream inFile("../../experimental/Intersection/op.htm"); |
649 if (inFile.isValid()) { | 674 if (inFile.isValid()) { |
650 SkTDArray<char> inData; | 675 SkTDArray<char> inData; |
651 inData.setCount(inFile.getLength()); | 676 inData.setCount((int) inFile.getLength()); |
652 size_t inLen = inData.count(); | 677 size_t inLen = inData.count(); |
653 inFile.read(inData.begin(), inLen); | 678 inFile.read(inData.begin(), inLen); |
654 inFile.setPath(NULL); | 679 inFile.setPath(NULL); |
655 char* insert = strstr(inData.begin(), marker); | 680 char* insert = strstr(inData.begin(), marker); |
656 if (insert) { | 681 if (insert) { |
657 insert += sizeof(marker) - 1; | 682 insert += sizeof(marker) - 1; |
658 const char* numLoc = insert + 4 /* indent spaces */ + testNameSi
ze - 1; | 683 const char* numLoc = insert + 4 /* indent spaces */ + testNameSi
ze - 1; |
659 testNumber = atoi(numLoc) + 1; | 684 testNumber = atoi(numLoc) + 1; |
660 } | 685 } |
661 } | 686 } |
(...skipping 15 matching lines...) Expand all Loading... |
677 | 702 |
678 void outputProgress(char* ramStr, const char* pathStr, SkPathOp op) { | 703 void outputProgress(char* ramStr, const char* pathStr, SkPathOp op) { |
679 const char testFunction[] = "testOp(path);"; | 704 const char testFunction[] = "testOp(path);"; |
680 SkASSERT((size_t) op < SK_ARRAY_COUNT(opSuffixes)); | 705 SkASSERT((size_t) op < SK_ARRAY_COUNT(opSuffixes)); |
681 const char* nameSuffix = opSuffixes[op]; | 706 const char* nameSuffix = opSuffixes[op]; |
682 SkMemoryWStream rRamStream(ramStr, PATH_STR_SIZE); | 707 SkMemoryWStream rRamStream(ramStr, PATH_STR_SIZE); |
683 outputToStream(pathStr, NULL, nameSuffix, testFunction, true, rRamStream); | 708 outputToStream(pathStr, NULL, nameSuffix, testFunction, true, rRamStream); |
684 } | 709 } |
685 | 710 |
686 void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count, | 711 void RunTestSet(skiatest::Reporter* reporter, TestDesc tests[], size_t count, |
687 void (*firstTest)(skiatest::Reporter* ), | 712 void (*firstTest)(skiatest::Reporter* , const char* filename), |
688 void (*stopTest)(skiatest::Reporter* ), bool reverse) { | 713 void (*stopTest)(skiatest::Reporter* , const char* filename), bo
ol reverse) { |
689 size_t index; | 714 size_t index; |
690 if (firstTest) { | 715 if (firstTest) { |
691 index = count - 1; | 716 index = count - 1; |
692 while (index > 0 && tests[index].fun != firstTest) { | 717 while (index > 0 && tests[index].fun != firstTest) { |
693 --index; | 718 --index; |
694 } | 719 } |
695 #if DEBUG_SHOW_TEST_NAME | 720 #if DEBUG_SHOW_TEST_NAME |
696 SkDebugf("<div id=\"%s\">\n", tests[index].str); | 721 SkDebugf("<div id=\"%s\">\n", tests[index].str); |
697 SkDebugf(" %s [%s]\n", __FUNCTION__, tests[index].str); | 722 SkDebugf(" %s [%s]\n", __FUNCTION__, tests[index].str); |
698 #endif | 723 #endif |
699 (*tests[index].fun)(reporter); | 724 (*tests[index].fun)(reporter, tests[index].str); |
| 725 if (tests[index].fun == stopTest) { |
| 726 return; |
| 727 } |
700 } | 728 } |
701 index = reverse ? count - 1 : 0; | 729 index = reverse ? count - 1 : 0; |
702 size_t last = reverse ? 0 : count - 1; | 730 size_t last = reverse ? 0 : count - 1; |
703 do { | 731 do { |
704 if (tests[index].fun != firstTest) { | 732 if (tests[index].fun != firstTest) { |
705 #if DEBUG_SHOW_TEST_NAME | 733 #if DEBUG_SHOW_TEST_NAME |
706 SkDebugf("<div id=\"%s\">\n", tests[index].str); | 734 SkDebugf("<div id=\"%s\">\n", tests[index].str); |
707 SkDebugf(" %s [%s]\n", __FUNCTION__, tests[index].str); | 735 SkDebugf(" %s [%s]\n", __FUNCTION__, tests[index].str); |
708 #endif | 736 #endif |
709 (*tests[index].fun)(reporter); | 737 (*tests[index].fun)(reporter, tests[index].str); |
710 } | 738 } |
711 if (tests[index].fun == stopTest) { | 739 if (tests[index].fun == stopTest) { |
712 SkDebugf("lastTest\n"); | 740 SkDebugf("lastTest\n"); |
| 741 break; |
713 } | 742 } |
714 if (index == last) { | 743 if (index == last) { |
715 break; | 744 break; |
716 } | 745 } |
717 index += reverse ? -1 : 1; | 746 index += reverse ? -1 : 1; |
718 } while (true); | 747 } while (true); |
719 } | 748 } |
OLD | NEW |