| 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 |