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 /* | 8 /* |
9 * Code for the "gm" (Golden Master) rendering comparison tool. | 9 * Code for the "gm" (Golden Master) rendering comparison tool. |
10 * | 10 * |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 #include "SkXPSDevice.h" | 73 #include "SkXPSDevice.h" |
74 #endif | 74 #endif |
75 | 75 |
76 #ifdef SK_BUILD_FOR_MAC | 76 #ifdef SK_BUILD_FOR_MAC |
77 #include "SkCGUtils.h" | 77 #include "SkCGUtils.h" |
78 #define CAN_IMAGE_PDF 1 | 78 #define CAN_IMAGE_PDF 1 |
79 #else | 79 #else |
80 #define CAN_IMAGE_PDF 0 | 80 #define CAN_IMAGE_PDF 0 |
81 #endif | 81 #endif |
82 | 82 |
83 // TODO(epoger): We created this ErrorBitfield so that we could record | |
84 // multiple error types for the same comparison. But in practice, we | |
85 // process its final value in switch() statements, which inherently | |
86 // assume that only one error type will be set. | |
87 // I think we should probably change this to be an enum, and thus | |
88 // constrain ourselves to a single error type per comparison. | |
89 typedef int ErrorBitfield; | 83 typedef int ErrorBitfield; |
90 const static ErrorBitfield ERROR_NONE = 0x00; | 84 // an empty bitfield means no errors: |
91 const static ErrorBitfield ERROR_NO_GPU_CONTEXT = 0x01; | 85 const static ErrorBitfield kEmptyErrorBitfield = 0x00; |
92 const static ErrorBitfield ERROR_IMAGE_MISMATCH = 0x02; | 86 // individual error types: |
93 // const static ErrorBitfield ERROR_DIMENSION_MISMATCH = 0x04; DEPRECATED i
n https://codereview.appspot.com/7064047 | 87 const static ErrorBitfield kNoGpuContext_ErrorBitmask = 0x01; |
94 const static ErrorBitfield ERROR_READING_REFERENCE_IMAGE = 0x08; | 88 const static ErrorBitfield kImageMismatch_ErrorBitmask = 0x02; |
95 const static ErrorBitfield ERROR_WRITING_REFERENCE_IMAGE = 0x10; | 89 const static ErrorBitfield kMissingExpectations_ErrorBitmask = 0x04; |
| 90 const static ErrorBitfield kWritingReferenceImage_ErrorBitmask = 0x08; |
| 91 // we typically ignore any errors matching this bitmask: |
| 92 const static ErrorBitfield kIgnorable_ErrorBitmask = kMissingExpectations_ErrorB
itmask; |
96 | 93 |
97 using namespace skiagm; | 94 using namespace skiagm; |
98 | 95 |
99 struct FailRec { | 96 struct FailRec { |
100 SkString fName; | 97 SkString fName; |
101 bool fIsPixelError; | 98 bool fIsPixelError; |
102 | 99 |
103 FailRec() : fIsPixelError(false) {} | 100 FailRec() : fIsPixelError(false) {} |
104 FailRec(const SkString& name) : fName(name), fIsPixelError(false) {} | 101 FailRec(const SkString& name) : fName(name), fIsPixelError(false) {} |
105 }; | 102 }; |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 SkBitmap copy; | 244 SkBitmap copy; |
248 bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); | 245 bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); |
249 return SkImageEncoder::EncodeFile(path.c_str(), copy, | 246 return SkImageEncoder::EncodeFile(path.c_str(), copy, |
250 SkImageEncoder::kPNG_Type, 100); | 247 SkImageEncoder::kPNG_Type, 100); |
251 } | 248 } |
252 | 249 |
253 // Records an error in fFailedTests, if we want to record errors | 250 // Records an error in fFailedTests, if we want to record errors |
254 // of this type. | 251 // of this type. |
255 void RecordError(ErrorBitfield errorType, const SkString& name, | 252 void RecordError(ErrorBitfield errorType, const SkString& name, |
256 const char renderModeDescriptor []) { | 253 const char renderModeDescriptor []) { |
257 bool isPixelError; | 254 // The common case: no error means nothing to record. |
258 switch (errorType) { | 255 if (kEmptyErrorBitfield == errorType) { |
259 case ERROR_NONE: | |
260 return; | 256 return; |
261 case ERROR_READING_REFERENCE_IMAGE: | 257 } |
| 258 |
| 259 // If only certain error type(s) were reported, we know we can ignore th
em. |
| 260 if (errorType == (errorType & kIgnorable_ErrorBitmask)) { |
262 return; | 261 return; |
263 case ERROR_IMAGE_MISMATCH: | |
264 isPixelError = true; | |
265 break; | |
266 default: | |
267 isPixelError = false; | |
268 break; | |
269 } | 262 } |
270 | 263 |
271 FailRec& rec = fFailedTests.push_back(make_name( | 264 FailRec& rec = fFailedTests.push_back(make_name( |
272 name.c_str(), renderModeDescriptor)); | 265 name.c_str(), renderModeDescriptor)); |
273 rec.fIsPixelError = isPixelError; | 266 rec.fIsPixelError = |
| 267 (kEmptyErrorBitfield != (errorType & kImageMismatch_ErrorBitmask)); |
274 } | 268 } |
275 | 269 |
276 // List contents of fFailedTests via SkDebug. | 270 // List contents of fFailedTests via SkDebug. |
277 void ListErrors() { | 271 void ListErrors() { |
278 for (int i = 0; i < fFailedTests.count(); ++i) { | 272 for (int i = 0; i < fFailedTests.count(); ++i) { |
279 if (fFailedTests[i].fIsPixelError) { | 273 if (fFailedTests[i].fIsPixelError) { |
280 SkDebugf("\t\t%s pixel_error\n", fFailedTests[i].fName.c_str()); | 274 SkDebugf("\t\t%s pixel_error\n", fFailedTests[i].fName.c_str()); |
281 } else { | 275 } else { |
282 SkDebugf("\t\t%s\n", fFailedTests[i].fName.c_str()); | 276 SkDebugf("\t\t%s\n", fFailedTests[i].fName.c_str()); |
283 } | 277 } |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 canvas.reset(new SkDeferredCanvas(device)); | 397 canvas.reset(new SkDeferredCanvas(device)); |
404 } else { | 398 } else { |
405 canvas.reset(new SkCanvas(device)); | 399 canvas.reset(new SkCanvas(device)); |
406 } | 400 } |
407 invokeGM(gm, canvas, false, deferred); | 401 invokeGM(gm, canvas, false, deferred); |
408 canvas->flush(); | 402 canvas->flush(); |
409 } | 403 } |
410 #if SK_SUPPORT_GPU | 404 #if SK_SUPPORT_GPU |
411 else { // GPU | 405 else { // GPU |
412 if (NULL == context) { | 406 if (NULL == context) { |
413 return ERROR_NO_GPU_CONTEXT; | 407 return kNoGpuContext_ErrorBitmask; |
414 } | 408 } |
415 SkAutoTUnref<SkDevice> device(new SkGpuDevice(context, rt)); | 409 SkAutoTUnref<SkDevice> device(new SkGpuDevice(context, rt)); |
416 if (deferred) { | 410 if (deferred) { |
417 canvas.reset(new SkDeferredCanvas(device)); | 411 canvas.reset(new SkDeferredCanvas(device)); |
418 } else { | 412 } else { |
419 canvas.reset(new SkCanvas(device)); | 413 canvas.reset(new SkCanvas(device)); |
420 } | 414 } |
421 invokeGM(gm, canvas, false, deferred); | 415 invokeGM(gm, canvas, false, deferred); |
422 // the device is as large as the current rendertarget, so | 416 // the device is as large as the current rendertarget, so |
423 // we explicitly only readback the amount we expect (in | 417 // we explicitly only readback the amount we expect (in |
424 // size) overwrite our previous allocation | 418 // size) overwrite our previous allocation |
425 bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth, | 419 bitmap->setConfig(SkBitmap::kARGB_8888_Config, size.fWidth, |
426 size.fHeight); | 420 size.fHeight); |
427 canvas->readPixels(bitmap, 0, 0); | 421 canvas->readPixels(bitmap, 0, 0); |
428 } | 422 } |
429 #endif | 423 #endif |
430 complete_bitmap(bitmap); | 424 complete_bitmap(bitmap); |
431 return ERROR_NONE; | 425 return kEmptyErrorBitfield; |
432 } | 426 } |
433 | 427 |
434 static void generate_image_from_picture(GM* gm, const ConfigData& gRec, | 428 static void generate_image_from_picture(GM* gm, const ConfigData& gRec, |
435 SkPicture* pict, SkBitmap* bitmap, | 429 SkPicture* pict, SkBitmap* bitmap, |
436 SkScalar scale = SK_Scalar1) { | 430 SkScalar scale = SK_Scalar1) { |
437 SkISize size = gm->getISize(); | 431 SkISize size = gm->getISize(); |
438 setup_bitmap(gRec, size, bitmap); | 432 setup_bitmap(gRec, size, bitmap); |
439 SkCanvas canvas(*bitmap); | 433 SkCanvas canvas(*bitmap); |
440 installFilter(&canvas); | 434 installFilter(&canvas); |
441 canvas.scale(scale, scale); | 435 canvas.scale(scale, scale); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
515 path = make_filename(writePath, renderModeDescriptor, name.c_str(), | 509 path = make_filename(writePath, renderModeDescriptor, name.c_str(), |
516 "pdf"); | 510 "pdf"); |
517 success = write_document(path, *document); | 511 success = write_document(path, *document); |
518 } | 512 } |
519 if (kXPS_Backend == gRec.fBackend) { | 513 if (kXPS_Backend == gRec.fBackend) { |
520 path = make_filename(writePath, renderModeDescriptor, name.c_str(), | 514 path = make_filename(writePath, renderModeDescriptor, name.c_str(), |
521 "xps"); | 515 "xps"); |
522 success = write_document(path, *document); | 516 success = write_document(path, *document); |
523 } | 517 } |
524 if (success) { | 518 if (success) { |
525 return ERROR_NONE; | 519 return kEmptyErrorBitfield; |
526 } else { | 520 } else { |
527 fprintf(stderr, "FAILED to write %s\n", path.c_str()); | 521 fprintf(stderr, "FAILED to write %s\n", path.c_str()); |
528 RecordError(ERROR_WRITING_REFERENCE_IMAGE, name, | 522 RecordError(kWritingReferenceImage_ErrorBitmask, name, |
529 renderModeDescriptor); | 523 renderModeDescriptor); |
530 return ERROR_WRITING_REFERENCE_IMAGE; | 524 return kWritingReferenceImage_ErrorBitmask; |
531 } | 525 } |
532 } | 526 } |
533 | 527 |
534 /** | 528 /** |
535 * Log more detail about the mistmatch between expectedBitmap and | 529 * Log more detail about the mistmatch between expectedBitmap and |
536 * actualBitmap. | 530 * actualBitmap. |
537 */ | 531 */ |
538 void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act
ualBitmap, | 532 void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act
ualBitmap, |
539 const char *testName) { | 533 const char *testName) { |
540 const int expectedWidth = expectedBitmap.width(); | 534 const int expectedWidth = expectedBitmap.width(); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
580 (int)SkGetPackedA32(actualPixel
))); | 574 (int)SkGetPackedA32(actualPixel
))); |
581 } | 575 } |
582 } | 576 } |
583 } | 577 } |
584 SkDebugf("---- %s: %d (of %d) differing pixels, max per-channel mismatch
" | 578 SkDebugf("---- %s: %d (of %d) differing pixels, max per-channel mismatch
" |
585 " R=%d G=%d B=%d A=%d\n", | 579 " R=%d G=%d B=%d A=%d\n", |
586 testName, differingPixels, width*height, errR, errG, errB, errA
); | 580 testName, differingPixels, width*height, errR, errG, errB, errA
); |
587 } | 581 } |
588 | 582 |
589 /** | 583 /** |
590 * Compares actual checksum to expectations. | 584 * Compares actual checksum to expectations. Returns |
591 * Returns ERROR_NONE if they match, or some particular error code otherwise | 585 * kEmptyErrorBitfield if they match, or some combination of |
| 586 * _ErrorBitmask values otherwise. |
592 * | 587 * |
593 * If fMismatchPath has been set, and there are pixel diffs, then the | 588 * If fMismatchPath has been set, and there are pixel diffs, then the |
594 * actual bitmap will be written out to a file within fMismatchPath. | 589 * actual bitmap will be written out to a file within fMismatchPath. |
595 * | 590 * |
596 * @param expectations what expectations to compare actualBitmap against | 591 * @param expectations what expectations to compare actualBitmap against |
597 * @param actualBitmap the image we actually generated | 592 * @param actualBitmap the image we actually generated |
598 * @param baseNameString name of test without renderModeDescriptor added | 593 * @param baseNameString name of test without renderModeDescriptor added |
599 * @param renderModeDescriptor e.g., "-rtree", "-deferred" | 594 * @param renderModeDescriptor e.g., "-rtree", "-deferred" |
600 * @param addToJsonSummary whether to add these results (both actual and | 595 * @param addToJsonSummary whether to add these results (both actual and |
601 * expected) to the JSON summary | 596 * expected) to the JSON summary |
602 * | 597 * |
603 * TODO: For now, addToJsonSummary is only set to true within | 598 * TODO: For now, addToJsonSummary is only set to true within |
604 * compare_test_results_to_stored_expectations(), so results of our | 599 * compare_test_results_to_stored_expectations(), so results of our |
605 * in-memory comparisons (Rtree vs regular, etc.) are not written to the | 600 * in-memory comparisons (Rtree vs regular, etc.) are not written to the |
606 * JSON summary. We may wish to change that. | 601 * JSON summary. We may wish to change that. |
607 */ | 602 */ |
608 ErrorBitfield compare_to_expectations(Expectations expectations, | 603 ErrorBitfield compare_to_expectations(Expectations expectations, |
609 const SkBitmap& actualBitmap, | 604 const SkBitmap& actualBitmap, |
610 const SkString& baseNameString, | 605 const SkString& baseNameString, |
611 const char renderModeDescriptor[], | 606 const char renderModeDescriptor[], |
612 bool addToJsonSummary=false) { | 607 bool addToJsonSummary=false) { |
613 ErrorBitfield retval; | 608 ErrorBitfield retval; |
614 Checksum actualChecksum = SkBitmapChecksummer::Compute64(actualBitmap); | 609 Checksum actualChecksum = SkBitmapChecksummer::Compute64(actualBitmap); |
615 SkString completeNameString = baseNameString; | 610 SkString completeNameString = baseNameString; |
616 completeNameString.append(renderModeDescriptor); | 611 completeNameString.append(renderModeDescriptor); |
617 const char* completeName = completeNameString.c_str(); | 612 const char* completeName = completeNameString.c_str(); |
618 | 613 |
619 if (expectations.empty()) { | 614 if (expectations.empty()) { |
620 retval = ERROR_READING_REFERENCE_IMAGE; | 615 retval = kMissingExpectations_ErrorBitmask; |
621 } else if (expectations.match(actualChecksum)) { | 616 } else if (expectations.match(actualChecksum)) { |
622 retval = ERROR_NONE; | 617 retval = kEmptyErrorBitfield; |
623 } else { | 618 } else { |
624 retval = ERROR_IMAGE_MISMATCH; | 619 retval = kImageMismatch_ErrorBitmask; |
625 | 620 |
626 // Write out the "actuals" for any mismatches, if we have | 621 // Write out the "actuals" for any mismatches, if we have |
627 // been directed to do so. | 622 // been directed to do so. |
628 if (fMismatchPath) { | 623 if (fMismatchPath) { |
629 SkString path = | 624 SkString path = |
630 make_filename(fMismatchPath, renderModeDescriptor, | 625 make_filename(fMismatchPath, renderModeDescriptor, |
631 baseNameString.c_str(), "png"); | 626 baseNameString.c_str(), "png"); |
632 write_bitmap(path, actualBitmap); | 627 write_bitmap(path, actualBitmap); |
633 } | 628 } |
634 | 629 |
(...skipping 20 matching lines...) Expand all Loading... |
655 * Add this result to the appropriate JSON collection of actual results, | 650 * Add this result to the appropriate JSON collection of actual results, |
656 * depending on status. | 651 * depending on status. |
657 */ | 652 */ |
658 void add_actual_results_to_json_summary(const char testName[], | 653 void add_actual_results_to_json_summary(const char testName[], |
659 Checksum actualChecksum, | 654 Checksum actualChecksum, |
660 ErrorBitfield result, | 655 ErrorBitfield result, |
661 bool ignoreFailure) { | 656 bool ignoreFailure) { |
662 Json::Value actualResults; | 657 Json::Value actualResults; |
663 actualResults[kJsonKey_ActualResults_AnyStatus_Checksum] = | 658 actualResults[kJsonKey_ActualResults_AnyStatus_Checksum] = |
664 asJsonValue(actualChecksum); | 659 asJsonValue(actualChecksum); |
665 if (ERROR_NONE == result) { | 660 if (kEmptyErrorBitfield == result) { |
666 this->fJsonActualResults_Succeeded[testName] = actualResults; | 661 this->fJsonActualResults_Succeeded[testName] = actualResults; |
667 } else { | 662 } else { |
668 if (ignoreFailure) { | 663 if (ignoreFailure) { |
669 // TODO: Once we have added the ability to compare | 664 // TODO: Once we have added the ability to compare |
670 // actual results against expectations in a JSON file | 665 // actual results against expectations in a JSON file |
671 // (where we can set ignore-failure to either true or | 666 // (where we can set ignore-failure to either true or |
672 // false), add test cases that exercise ignored | 667 // false), add test cases that exercise ignored |
673 // failures (both for ERROR_READING_REFERENCE_IMAGE | 668 // failures (both for kMissingExpectations_ErrorBitmask |
674 // and ERROR_IMAGE_MISMATCH). | 669 // and kImageMismatch_ErrorBitmask). |
675 this->fJsonActualResults_FailureIgnored[testName] = | 670 this->fJsonActualResults_FailureIgnored[testName] = |
676 actualResults; | 671 actualResults; |
677 } else { | 672 } else { |
678 switch(result) { | 673 if (kEmptyErrorBitfield != (result & kMissingExpectations_ErrorB
itmask)) { |
679 case ERROR_READING_REFERENCE_IMAGE: | |
680 // TODO: What about the case where there IS an | 674 // TODO: What about the case where there IS an |
681 // expected image checksum, but that gm test | 675 // expected image checksum, but that gm test |
682 // doesn't actually run? For now, those cases | 676 // doesn't actually run? For now, those cases |
683 // will always be ignored, because gm only looks | 677 // will always be ignored, because gm only looks |
684 // at expectations that correspond to gm tests | 678 // at expectations that correspond to gm tests |
685 // that were actually run. | 679 // that were actually run. |
686 // | 680 // |
687 // Once we have the ability to express | 681 // Once we have the ability to express |
688 // expectations as a JSON file, we should fix this | 682 // expectations as a JSON file, we should fix this |
689 // (and add a test case for which an expectation | 683 // (and add a test case for which an expectation |
690 // is given but the test is never run). | 684 // is given but the test is never run). |
691 this->fJsonActualResults_NoComparison[testName] = | 685 this->fJsonActualResults_NoComparison[testName] = |
692 actualResults; | 686 actualResults; |
693 break; | 687 } |
694 case ERROR_IMAGE_MISMATCH: | 688 if (kEmptyErrorBitfield != (result & kImageMismatch_ErrorBitmask
)) { |
695 this->fJsonActualResults_Failed[testName] = actualResults; | 689 this->fJsonActualResults_Failed[testName] = actualResults; |
696 break; | |
697 default: | |
698 fprintf(stderr, "encountered unexpected result %d\n", | |
699 result); | |
700 SkDEBUGFAIL("encountered unexpected result"); | |
701 break; | |
702 } | 690 } |
703 } | 691 } |
704 } | 692 } |
705 } | 693 } |
706 | 694 |
707 /** | 695 /** |
708 * Add this test to the JSON collection of expected results. | 696 * Add this test to the JSON collection of expected results. |
709 */ | 697 */ |
710 void add_expected_results_to_json_summary(const char testName[], | 698 void add_expected_results_to_json_summary(const char testName[], |
711 Expectations expectations) { | 699 Expectations expectations) { |
(...skipping 16 matching lines...) Expand all Loading... |
728 * @param writePath unless this is NULL, write out actual images into this | 716 * @param writePath unless this is NULL, write out actual images into this |
729 * directory | 717 * directory |
730 * @param actualBitmap bitmap generated by this run | 718 * @param actualBitmap bitmap generated by this run |
731 * @param pdf | 719 * @param pdf |
732 */ | 720 */ |
733 ErrorBitfield compare_test_results_to_stored_expectations( | 721 ErrorBitfield compare_test_results_to_stored_expectations( |
734 GM* gm, const ConfigData& gRec, const char writePath[], | 722 GM* gm, const ConfigData& gRec, const char writePath[], |
735 SkBitmap& actualBitmap, SkDynamicMemoryWStream* pdf) { | 723 SkBitmap& actualBitmap, SkDynamicMemoryWStream* pdf) { |
736 | 724 |
737 SkString name = make_name(gm->shortName(), gRec.fName); | 725 SkString name = make_name(gm->shortName(), gRec.fName); |
738 ErrorBitfield retval = ERROR_NONE; | 726 ErrorBitfield retval = kEmptyErrorBitfield; |
739 | 727 |
740 ExpectationsSource *expectationsSource = | 728 ExpectationsSource *expectationsSource = |
741 this->fExpectationsSource.get(); | 729 this->fExpectationsSource.get(); |
742 if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) { | 730 if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) { |
743 /* | 731 /* |
744 * Get the expected results for this test, as one or more allowed | 732 * Get the expected results for this test, as one or more allowed |
745 * checksums. The current implementation of expectationsSource | 733 * checksums. The current implementation of expectationsSource |
746 * get this by computing the checksum of a single PNG file on disk. | 734 * get this by computing the checksum of a single PNG file on disk. |
747 * | 735 * |
748 * TODO(epoger): This relies on the fact that | 736 * TODO(epoger): This relies on the fact that |
749 * force_all_opaque() was called on the bitmap before it | 737 * force_all_opaque() was called on the bitmap before it |
750 * was written to disk as a PNG in the first place. If | 738 * was written to disk as a PNG in the first place. If |
751 * not, the checksum returned here may not match the | 739 * not, the checksum returned here may not match the |
752 * checksum of actualBitmap, which *has* been run through | 740 * checksum of actualBitmap, which *has* been run through |
753 * force_all_opaque(). | 741 * force_all_opaque(). |
754 * See comments above complete_bitmap() for more detail. | 742 * See comments above complete_bitmap() for more detail. |
755 */ | 743 */ |
756 Expectations expectations = expectationsSource->get(name.c_str()); | 744 Expectations expectations = expectationsSource->get(name.c_str()); |
757 retval |= compare_to_expectations(expectations, actualBitmap, | 745 retval |= compare_to_expectations(expectations, actualBitmap, |
758 name, "", true); | 746 name, "", true); |
759 } else { | 747 } else { |
760 // If we are running without expectations, we still want to | 748 // If we are running without expectations, we still want to |
761 // record the actual results. | 749 // record the actual results. |
762 Checksum actualChecksum = | 750 Checksum actualChecksum = |
763 SkBitmapChecksummer::Compute64(actualBitmap); | 751 SkBitmapChecksummer::Compute64(actualBitmap); |
764 add_actual_results_to_json_summary(name.c_str(), actualChecksum, | 752 add_actual_results_to_json_summary(name.c_str(), actualChecksum, |
765 ERROR_READING_REFERENCE_IMAGE, | 753 kMissingExpectations_ErrorBitmask
, |
766 false); | 754 false); |
767 } | 755 } |
768 | 756 |
769 // TODO: Consider moving this into compare_to_expectations(), | 757 // TODO: Consider moving this into compare_to_expectations(), |
770 // similar to fMismatchPath... for now, we don't do that, because | 758 // similar to fMismatchPath... for now, we don't do that, because |
771 // we don't want to write out the actual bitmaps for all | 759 // we don't want to write out the actual bitmaps for all |
772 // renderModes of all tests! That would be a lot of files. | 760 // renderModes of all tests! That would be a lot of files. |
773 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { | 761 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { |
774 retval |= write_reference_image(gRec, writePath, "", | 762 retval |= write_reference_image(gRec, writePath, "", |
775 name, actualBitmap, pdf); | 763 name, actualBitmap, pdf); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
855 GrContext* context, | 843 GrContext* context, |
856 GrRenderTarget* rt, | 844 GrRenderTarget* rt, |
857 SkBitmap* bitmap) { | 845 SkBitmap* bitmap) { |
858 SkDynamicMemoryWStream document; | 846 SkDynamicMemoryWStream document; |
859 | 847 |
860 if (gRec.fBackend == kRaster_Backend || | 848 if (gRec.fBackend == kRaster_Backend || |
861 gRec.fBackend == kGPU_Backend) { | 849 gRec.fBackend == kGPU_Backend) { |
862 // Early exit if we can't generate the image. | 850 // Early exit if we can't generate the image. |
863 ErrorBitfield errors = generate_image(gm, gRec, context, rt, bitmap, | 851 ErrorBitfield errors = generate_image(gm, gRec, context, rt, bitmap, |
864 false); | 852 false); |
865 if (ERROR_NONE != errors) { | 853 if (kEmptyErrorBitfield != errors) { |
866 // TODO: Add a test to exercise what the stdout and | 854 // TODO: Add a test to exercise what the stdout and |
867 // JSON look like if we get an "early error" while | 855 // JSON look like if we get an "early error" while |
868 // trying to generate the image. | 856 // trying to generate the image. |
869 return errors; | 857 return errors; |
870 } | 858 } |
871 } else if (gRec.fBackend == kPDF_Backend) { | 859 } else if (gRec.fBackend == kPDF_Backend) { |
872 generate_pdf(gm, document); | 860 generate_pdf(gm, document); |
873 #if CAN_IMAGE_PDF | 861 #if CAN_IMAGE_PDF |
874 SkAutoDataUnref data(document.copyToData()); | 862 SkAutoDataUnref data(document.copyToData()); |
875 SkMemoryStream stream(data->data(), data->size()); | 863 SkMemoryStream stream(data->data(), data->size()); |
(...skipping 12 matching lines...) Expand all Loading... |
888 GrContext* context, | 876 GrContext* context, |
889 GrRenderTarget* rt) { | 877 GrRenderTarget* rt) { |
890 SkDynamicMemoryWStream document; | 878 SkDynamicMemoryWStream document; |
891 | 879 |
892 if (gRec.fBackend == kRaster_Backend || | 880 if (gRec.fBackend == kRaster_Backend || |
893 gRec.fBackend == kGPU_Backend) { | 881 gRec.fBackend == kGPU_Backend) { |
894 SkBitmap bitmap; | 882 SkBitmap bitmap; |
895 // Early exit if we can't generate the image, but this is | 883 // Early exit if we can't generate the image, but this is |
896 // expected in some cases, so don't report a test failure. | 884 // expected in some cases, so don't report a test failure. |
897 if (!generate_image(gm, gRec, context, rt, &bitmap, true)) { | 885 if (!generate_image(gm, gRec, context, rt, &bitmap, true)) { |
898 return ERROR_NONE; | 886 return kEmptyErrorBitfield; |
899 } | 887 } |
900 return compare_test_results_to_reference_bitmap( | 888 return compare_test_results_to_reference_bitmap( |
901 gm, gRec, "-deferred", bitmap, &referenceBitmap); | 889 gm, gRec, "-deferred", bitmap, &referenceBitmap); |
902 } | 890 } |
903 return ERROR_NONE; | 891 return kEmptyErrorBitfield; |
904 } | 892 } |
905 | 893 |
906 ErrorBitfield test_pipe_playback(GM* gm, | 894 ErrorBitfield test_pipe_playback(GM* gm, |
907 const ConfigData& gRec, | 895 const ConfigData& gRec, |
908 const SkBitmap& referenceBitmap) { | 896 const SkBitmap& referenceBitmap) { |
909 ErrorBitfield errors = ERROR_NONE; | 897 ErrorBitfield errors = kEmptyErrorBitfield; |
910 for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) { | 898 for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) { |
911 SkBitmap bitmap; | 899 SkBitmap bitmap; |
912 SkISize size = gm->getISize(); | 900 SkISize size = gm->getISize(); |
913 setup_bitmap(gRec, size, &bitmap); | 901 setup_bitmap(gRec, size, &bitmap); |
914 SkCanvas canvas(bitmap); | 902 SkCanvas canvas(bitmap); |
915 PipeController pipeController(&canvas); | 903 PipeController pipeController(&canvas); |
916 SkGPipeWriter writer; | 904 SkGPipeWriter writer; |
917 SkCanvas* pipeCanvas = writer.startRecording( | 905 SkCanvas* pipeCanvas = writer.startRecording( |
918 &pipeController, gPipeWritingFlagCombos[i].flags); | 906 &pipeController, gPipeWritingFlagCombos[i].flags); |
919 invokeGM(gm, pipeCanvas, false, false); | 907 invokeGM(gm, pipeCanvas, false, false); |
920 complete_bitmap(&bitmap); | 908 complete_bitmap(&bitmap); |
921 writer.endRecording(); | 909 writer.endRecording(); |
922 SkString string("-pipe"); | 910 SkString string("-pipe"); |
923 string.append(gPipeWritingFlagCombos[i].name); | 911 string.append(gPipeWritingFlagCombos[i].name); |
924 errors |= compare_test_results_to_reference_bitmap( | 912 errors |= compare_test_results_to_reference_bitmap( |
925 gm, gRec, string.c_str(), bitmap, &referenceBitmap); | 913 gm, gRec, string.c_str(), bitmap, &referenceBitmap); |
926 if (errors != ERROR_NONE) { | 914 if (errors != kEmptyErrorBitfield) { |
927 break; | 915 break; |
928 } | 916 } |
929 } | 917 } |
930 return errors; | 918 return errors; |
931 } | 919 } |
932 | 920 |
933 ErrorBitfield test_tiled_pipe_playback( | 921 ErrorBitfield test_tiled_pipe_playback( |
934 GM* gm, const ConfigData& gRec, const SkBitmap& referenceBitmap) { | 922 GM* gm, const ConfigData& gRec, const SkBitmap& referenceBitmap) { |
935 ErrorBitfield errors = ERROR_NONE; | 923 ErrorBitfield errors = kEmptyErrorBitfield; |
936 for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) { | 924 for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) { |
937 SkBitmap bitmap; | 925 SkBitmap bitmap; |
938 SkISize size = gm->getISize(); | 926 SkISize size = gm->getISize(); |
939 setup_bitmap(gRec, size, &bitmap); | 927 setup_bitmap(gRec, size, &bitmap); |
940 SkCanvas canvas(bitmap); | 928 SkCanvas canvas(bitmap); |
941 TiledPipeController pipeController(bitmap); | 929 TiledPipeController pipeController(bitmap); |
942 SkGPipeWriter writer; | 930 SkGPipeWriter writer; |
943 SkCanvas* pipeCanvas = writer.startRecording( | 931 SkCanvas* pipeCanvas = writer.startRecording( |
944 &pipeController, gPipeWritingFlagCombos[i].flags); | 932 &pipeController, gPipeWritingFlagCombos[i].flags); |
945 invokeGM(gm, pipeCanvas, false, false); | 933 invokeGM(gm, pipeCanvas, false, false); |
946 complete_bitmap(&bitmap); | 934 complete_bitmap(&bitmap); |
947 writer.endRecording(); | 935 writer.endRecording(); |
948 SkString string("-tiled pipe"); | 936 SkString string("-tiled pipe"); |
949 string.append(gPipeWritingFlagCombos[i].name); | 937 string.append(gPipeWritingFlagCombos[i].name); |
950 errors |= compare_test_results_to_reference_bitmap( | 938 errors |= compare_test_results_to_reference_bitmap( |
951 gm, gRec, string.c_str(), bitmap, &referenceBitmap); | 939 gm, gRec, string.c_str(), bitmap, &referenceBitmap); |
952 if (errors != ERROR_NONE) { | 940 if (errors != kEmptyErrorBitfield) { |
953 break; | 941 break; |
954 } | 942 } |
955 } | 943 } |
956 return errors; | 944 return errors; |
957 } | 945 } |
958 | 946 |
959 // | 947 // |
960 // member variables. | 948 // member variables. |
961 // They are public for now, to allow easier setting by tool_main(). | 949 // They are public for now, to allow easier setting by tool_main(). |
962 // | 950 // |
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1461 const char* shortName = gm->shortName(); | 1449 const char* shortName = gm->shortName(); |
1462 if (skip_name(fMatches, shortName)) { | 1450 if (skip_name(fMatches, shortName)) { |
1463 SkDELETE(gm); | 1451 SkDELETE(gm); |
1464 continue; | 1452 continue; |
1465 } | 1453 } |
1466 | 1454 |
1467 SkISize size = gm->getISize(); | 1455 SkISize size = gm->getISize(); |
1468 SkDebugf("%sdrawing... %s [%d %d]\n", moduloStr.c_str(), shortName, | 1456 SkDebugf("%sdrawing... %s [%d %d]\n", moduloStr.c_str(), shortName, |
1469 size.width(), size.height()); | 1457 size.width(), size.height()); |
1470 | 1458 |
1471 ErrorBitfield testErrors = ERROR_NONE; | 1459 ErrorBitfield testErrors = kEmptyErrorBitfield; |
1472 uint32_t gmFlags = gm->getFlags(); | 1460 uint32_t gmFlags = gm->getFlags(); |
1473 | 1461 |
1474 for (int i = 0; i < configs.count(); i++) { | 1462 for (int i = 0; i < configs.count(); i++) { |
1475 ConfigData config = gRec[configs[i]]; | 1463 ConfigData config = gRec[configs[i]]; |
1476 | 1464 |
1477 // Skip any tests that we don't even need to try. | 1465 // Skip any tests that we don't even need to try. |
1478 if ((kPDF_Backend == config.fBackend) && | 1466 if ((kPDF_Backend == config.fBackend) && |
1479 (!doPDF || (gmFlags & GM::kSkipPDF_Flag))) | 1467 (!doPDF || (gmFlags & GM::kSkipPDF_Flag))) |
1480 { | 1468 { |
1481 continue; | 1469 continue; |
1482 } | 1470 } |
1483 if ((gmFlags & GM::kSkip565_Flag) && | 1471 if ((gmFlags & GM::kSkip565_Flag) && |
1484 (kRaster_Backend == config.fBackend) && | 1472 (kRaster_Backend == config.fBackend) && |
1485 (SkBitmap::kRGB_565_Config == config.fConfig)) { | 1473 (SkBitmap::kRGB_565_Config == config.fConfig)) { |
1486 continue; | 1474 continue; |
1487 } | 1475 } |
1488 | 1476 |
1489 // Now we know that we want to run this test and record its | 1477 // Now we know that we want to run this test and record its |
1490 // success or failure. | 1478 // success or failure. |
1491 ErrorBitfield renderErrors = ERROR_NONE; | 1479 ErrorBitfield renderErrors = kEmptyErrorBitfield; |
1492 GrRenderTarget* renderTarget = NULL; | 1480 GrRenderTarget* renderTarget = NULL; |
1493 #if SK_SUPPORT_GPU | 1481 #if SK_SUPPORT_GPU |
1494 SkAutoTUnref<GrRenderTarget> rt; | 1482 SkAutoTUnref<GrRenderTarget> rt; |
1495 AutoResetGr autogr; | 1483 AutoResetGr autogr; |
1496 if ((ERROR_NONE == renderErrors) && | 1484 if ((kEmptyErrorBitfield == renderErrors) && |
1497 kGPU_Backend == config.fBackend) { | 1485 kGPU_Backend == config.fBackend) { |
1498 GrContext* gr = grFactory->get(config.fGLContextType); | 1486 GrContext* gr = grFactory->get(config.fGLContextType); |
1499 bool grSuccess = false; | 1487 bool grSuccess = false; |
1500 if (gr) { | 1488 if (gr) { |
1501 // create a render target to back the device | 1489 // create a render target to back the device |
1502 GrTextureDesc desc; | 1490 GrTextureDesc desc; |
1503 desc.fConfig = kSkia8888_GrPixelConfig; | 1491 desc.fConfig = kSkia8888_GrPixelConfig; |
1504 desc.fFlags = kRenderTarget_GrTextureFlagBit; | 1492 desc.fFlags = kRenderTarget_GrTextureFlagBit; |
1505 desc.fWidth = gm->getISize().width(); | 1493 desc.fWidth = gm->getISize().width(); |
1506 desc.fHeight = gm->getISize().height(); | 1494 desc.fHeight = gm->getISize().height(); |
1507 desc.fSampleCnt = config.fSampleCnt; | 1495 desc.fSampleCnt = config.fSampleCnt; |
1508 GrTexture* tex = gr->createUncachedTexture(desc, NULL, 0); | 1496 GrTexture* tex = gr->createUncachedTexture(desc, NULL, 0); |
1509 if (tex) { | 1497 if (tex) { |
1510 rt.reset(tex->asRenderTarget()); | 1498 rt.reset(tex->asRenderTarget()); |
1511 rt.get()->ref(); | 1499 rt.get()->ref(); |
1512 tex->unref(); | 1500 tex->unref(); |
1513 autogr.set(gr); | 1501 autogr.set(gr); |
1514 renderTarget = rt.get(); | 1502 renderTarget = rt.get(); |
1515 grSuccess = NULL != renderTarget; | 1503 grSuccess = NULL != renderTarget; |
1516 } | 1504 } |
1517 } | 1505 } |
1518 if (!grSuccess) { | 1506 if (!grSuccess) { |
1519 renderErrors |= ERROR_NO_GPU_CONTEXT; | 1507 renderErrors |= kNoGpuContext_ErrorBitmask; |
1520 } | 1508 } |
1521 } | 1509 } |
1522 #endif | 1510 #endif |
1523 | 1511 |
1524 SkBitmap comparisonBitmap; | 1512 SkBitmap comparisonBitmap; |
1525 | 1513 |
1526 if (ERROR_NONE == renderErrors) { | 1514 if (kEmptyErrorBitfield == renderErrors) { |
1527 renderErrors |= gmmain.test_drawing(gm, config, writePath, | 1515 renderErrors |= gmmain.test_drawing(gm, config, writePath, |
1528 GetGr(), | 1516 GetGr(), |
1529 renderTarget, | 1517 renderTarget, |
1530 &comparisonBitmap); | 1518 &comparisonBitmap); |
1531 } | 1519 } |
1532 | 1520 |
1533 if (doDeferred && !renderErrors && | 1521 if (doDeferred && !renderErrors && |
1534 (kGPU_Backend == config.fBackend || | 1522 (kGPU_Backend == config.fBackend || |
1535 kRaster_Backend == config.fBackend)) { | 1523 kRaster_Backend == config.fBackend)) { |
1536 renderErrors |= gmmain.test_deferred_drawing(gm, config, | 1524 renderErrors |= gmmain.test_deferred_drawing(gm, config, |
1537 comparisonBitmap, | 1525 comparisonBitmap, |
1538 GetGr(), | 1526 GetGr(), |
1539 renderTarget); | 1527 renderTarget); |
1540 } | 1528 } |
1541 | 1529 |
1542 testErrors |= renderErrors; | 1530 testErrors |= renderErrors; |
1543 } | 1531 } |
1544 | 1532 |
1545 SkBitmap comparisonBitmap; | 1533 SkBitmap comparisonBitmap; |
1546 const ConfigData compareConfig = | 1534 const ConfigData compareConfig = |
1547 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
ype, 0, kRW_ConfigFlag, "comparison" }; | 1535 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
ype, 0, kRW_ConfigFlag, "comparison" }; |
1548 testErrors |= gmmain.generate_image(gm, compareConfig, NULL, NULL, &comp
arisonBitmap, false); | 1536 testErrors |= gmmain.generate_image(gm, compareConfig, NULL, NULL, &comp
arisonBitmap, false); |
1549 | 1537 |
1550 // run the picture centric GM steps | 1538 // run the picture centric GM steps |
1551 if (!(gmFlags & GM::kSkipPicture_Flag)) { | 1539 if (!(gmFlags & GM::kSkipPicture_Flag)) { |
1552 | 1540 |
1553 ErrorBitfield pictErrors = ERROR_NONE; | 1541 ErrorBitfield pictErrors = kEmptyErrorBitfield; |
1554 | 1542 |
1555 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); | 1543 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); |
1556 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); | 1544 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); |
1557 SkAutoUnref aur(pict); | 1545 SkAutoUnref aur(pict); |
1558 | 1546 |
1559 if ((ERROR_NONE == testErrors) && doReplay) { | 1547 if ((kEmptyErrorBitfield == testErrors) && doReplay) { |
1560 SkBitmap bitmap; | 1548 SkBitmap bitmap; |
1561 gmmain.generate_image_from_picture(gm, compareConfig, pict, | 1549 gmmain.generate_image_from_picture(gm, compareConfig, pict, |
1562 &bitmap); | 1550 &bitmap); |
1563 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | 1551 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( |
1564 gm, compareConfig, "-replay", bitmap, &comparisonBitmap); | 1552 gm, compareConfig, "-replay", bitmap, &comparisonBitmap); |
1565 } | 1553 } |
1566 | 1554 |
1567 if ((ERROR_NONE == testErrors) && | 1555 if ((kEmptyErrorBitfield == testErrors) && |
1568 (ERROR_NONE == pictErrors) && | 1556 (kEmptyErrorBitfield == pictErrors) && |
1569 doSerialize) { | 1557 doSerialize) { |
1570 SkPicture* repict = gmmain.stream_to_new_picture(*pict); | 1558 SkPicture* repict = gmmain.stream_to_new_picture(*pict); |
1571 SkAutoUnref aurr(repict); | 1559 SkAutoUnref aurr(repict); |
1572 | 1560 |
1573 SkBitmap bitmap; | 1561 SkBitmap bitmap; |
1574 gmmain.generate_image_from_picture(gm, compareConfig, repict, | 1562 gmmain.generate_image_from_picture(gm, compareConfig, repict, |
1575 &bitmap); | 1563 &bitmap); |
1576 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | 1564 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( |
1577 gm, compareConfig, "-serialize", bitmap, &comparisonBitmap); | 1565 gm, compareConfig, "-serialize", bitmap, &comparisonBitmap); |
1578 } | 1566 } |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1626 } | 1614 } |
1627 testErrors |= gmmain.compare_test_results_to_reference_bitmap( | 1615 testErrors |= gmmain.compare_test_results_to_reference_bitmap( |
1628 gm, compareConfig, suffix.c_str(), bitmap, | 1616 gm, compareConfig, suffix.c_str(), bitmap, |
1629 &comparisonBitmap); | 1617 &comparisonBitmap); |
1630 } | 1618 } |
1631 } | 1619 } |
1632 | 1620 |
1633 // run the pipe centric GM steps | 1621 // run the pipe centric GM steps |
1634 if (!(gmFlags & GM::kSkipPipe_Flag)) { | 1622 if (!(gmFlags & GM::kSkipPipe_Flag)) { |
1635 | 1623 |
1636 ErrorBitfield pipeErrors = ERROR_NONE; | 1624 ErrorBitfield pipeErrors = kEmptyErrorBitfield; |
1637 | 1625 |
1638 if ((ERROR_NONE == testErrors) && doPipe) { | 1626 if ((kEmptyErrorBitfield == testErrors) && doPipe) { |
1639 pipeErrors |= gmmain.test_pipe_playback(gm, compareConfig, | 1627 pipeErrors |= gmmain.test_pipe_playback(gm, compareConfig, |
1640 comparisonBitmap); | 1628 comparisonBitmap); |
1641 } | 1629 } |
1642 | 1630 |
1643 if ((ERROR_NONE == testErrors) && | 1631 if ((kEmptyErrorBitfield == testErrors) && |
1644 (ERROR_NONE == pipeErrors) && | 1632 (kEmptyErrorBitfield == pipeErrors) && |
1645 doTiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { | 1633 doTiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { |
1646 pipeErrors |= gmmain.test_tiled_pipe_playback(gm, compareConfig, | 1634 pipeErrors |= gmmain.test_tiled_pipe_playback(gm, compareConfig, |
1647 comparisonBitmap); | 1635 comparisonBitmap); |
1648 } | 1636 } |
1649 | 1637 |
1650 testErrors |= pipeErrors; | 1638 testErrors |= pipeErrors; |
1651 } | 1639 } |
1652 | 1640 |
1653 // Update overall results. | 1641 // Update overall results. |
1654 // We only tabulate the particular error types that we currently | 1642 // We only tabulate the particular error types that we currently |
1655 // care about (e.g., missing reference images). Later on, if we | 1643 // care about (e.g., missing reference images). Later on, if we |
1656 // want to also tabulate other error types, we can do so. | 1644 // want to also tabulate other error types, we can do so. |
1657 testsRun++; | 1645 testsRun++; |
1658 if (!gmmain.fExpectationsSource.get() || | 1646 if (!gmmain.fExpectationsSource.get() || |
1659 (ERROR_READING_REFERENCE_IMAGE & testErrors)) { | 1647 (kEmptyErrorBitfield != (kMissingExpectations_ErrorBitmask & testErr
ors))) { |
1660 testsMissingReferenceImages++; | 1648 testsMissingReferenceImages++; |
1661 } | 1649 } |
1662 if (ERROR_NONE == testErrors || ERROR_READING_REFERENCE_IMAGE == testErr
ors) { | 1650 if (testErrors == (testErrors & kIgnorable_ErrorBitmask)) { |
1663 testsPassed++; | 1651 testsPassed++; |
1664 } else { | 1652 } else { |
1665 testsFailed++; | 1653 testsFailed++; |
1666 } | 1654 } |
1667 | 1655 |
1668 SkDELETE(gm); | 1656 SkDELETE(gm); |
1669 } | 1657 } |
1670 SkDebugf("Ran %d tests: %d passed, %d failed, %d missing reference images\n"
, | 1658 SkDebugf("Ran %d tests: %d passed, %d failed, %d missing reference images\n"
, |
1671 testsRun, testsPassed, testsFailed, testsMissingReferenceImages); | 1659 testsRun, testsPassed, testsFailed, testsMissingReferenceImages); |
1672 gmmain.ListErrors(); | 1660 gmmain.ListErrors(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1709 SkGraphics::Term(); | 1697 SkGraphics::Term(); |
1710 | 1698 |
1711 return (0 == testsFailed) ? 0 : -1; | 1699 return (0 == testsFailed) ? 0 : -1; |
1712 } | 1700 } |
1713 | 1701 |
1714 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 1702 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
1715 int main(int argc, char * const argv[]) { | 1703 int main(int argc, char * const argv[]) { |
1716 return tool_main(argc, (char**) argv); | 1704 return tool_main(argc, (char**) argv); |
1717 } | 1705 } |
1718 #endif | 1706 #endif |
OLD | NEW |