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 12 matching lines...) Expand all Loading... |
23 #include "SkData.h" | 23 #include "SkData.h" |
24 #include "SkDeferredCanvas.h" | 24 #include "SkDeferredCanvas.h" |
25 #include "SkDevice.h" | 25 #include "SkDevice.h" |
26 #include "SkDrawFilter.h" | 26 #include "SkDrawFilter.h" |
27 #include "SkForceLinking.h" | 27 #include "SkForceLinking.h" |
28 #include "SkGPipe.h" | 28 #include "SkGPipe.h" |
29 #include "SkGraphics.h" | 29 #include "SkGraphics.h" |
30 #include "SkImageDecoder.h" | 30 #include "SkImageDecoder.h" |
31 #include "SkImageEncoder.h" | 31 #include "SkImageEncoder.h" |
32 #include "SkOSFile.h" | 32 #include "SkOSFile.h" |
| 33 #include "SkPDFRasterizer.h" |
33 #include "SkPicture.h" | 34 #include "SkPicture.h" |
34 #include "SkRefCnt.h" | 35 #include "SkRefCnt.h" |
35 #include "SkStream.h" | 36 #include "SkStream.h" |
36 #include "SkTArray.h" | 37 #include "SkTArray.h" |
37 #include "SkTDict.h" | 38 #include "SkTDict.h" |
38 #include "SkTileGridPicture.h" | 39 #include "SkTileGridPicture.h" |
39 #include "SamplePipeControllers.h" | 40 #include "SamplePipeControllers.h" |
40 | 41 |
41 __SK_FORCE_IMAGE_DECODER_LINKING; | 42 __SK_FORCE_IMAGE_DECODER_LINKING; |
42 | 43 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 | 77 |
77 // Until we resolve http://code.google.com/p/skia/issues/detail?id=455 , | 78 // Until we resolve http://code.google.com/p/skia/issues/detail?id=455 , |
78 // stop writing out XPS-format image baselines in gm. | 79 // stop writing out XPS-format image baselines in gm. |
79 #undef SK_SUPPORT_XPS | 80 #undef SK_SUPPORT_XPS |
80 #ifdef SK_SUPPORT_XPS | 81 #ifdef SK_SUPPORT_XPS |
81 #include "SkXPSDevice.h" | 82 #include "SkXPSDevice.h" |
82 #endif | 83 #endif |
83 | 84 |
84 #ifdef SK_BUILD_FOR_MAC | 85 #ifdef SK_BUILD_FOR_MAC |
85 #include "SkCGUtils.h" | 86 #include "SkCGUtils.h" |
86 #define CAN_IMAGE_PDF 1 | |
87 #else | |
88 #define CAN_IMAGE_PDF 0 | |
89 #endif | 87 #endif |
90 | 88 |
91 using namespace skiagm; | 89 using namespace skiagm; |
92 | 90 |
93 class Iter { | 91 class Iter { |
94 public: | 92 public: |
95 Iter() { | 93 Iter() { |
96 this->reset(); | 94 this->reset(); |
97 } | 95 } |
98 | 96 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 struct ConfigData { | 151 struct ConfigData { |
154 SkBitmap::Config fConfig; | 152 SkBitmap::Config fConfig; |
155 Backend fBackend; | 153 Backend fBackend; |
156 GLContextType fGLContextType; // GPU backend only | 154 GLContextType fGLContextType; // GPU backend only |
157 int fSampleCnt; // GPU backend only | 155 int fSampleCnt; // GPU backend only |
158 ConfigFlags fFlags; | 156 ConfigFlags fFlags; |
159 const char* fName; | 157 const char* fName; |
160 bool fRunByDefault; | 158 bool fRunByDefault; |
161 }; | 159 }; |
162 | 160 |
| 161 struct PDFRasterizerData { |
| 162 bool (*fRasterizerFunction)(SkStream*, SkBitmap*); |
| 163 const char* fName; |
| 164 bool fRunByDefault; |
| 165 }; |
| 166 |
163 class BWTextDrawFilter : public SkDrawFilter { | 167 class BWTextDrawFilter : public SkDrawFilter { |
164 public: | 168 public: |
165 virtual bool filter(SkPaint*, Type) SK_OVERRIDE; | 169 virtual bool filter(SkPaint*, Type) SK_OVERRIDE; |
166 }; | 170 }; |
167 bool BWTextDrawFilter::filter(SkPaint* p, Type t) { | 171 bool BWTextDrawFilter::filter(SkPaint* p, Type t) { |
168 if (kText_Type == t) { | 172 if (kText_Type == t) { |
169 p->setAntiAlias(false); | 173 p->setAntiAlias(false); |
170 } | 174 } |
171 return true; | 175 return true; |
172 } | 176 } |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
275 | 279 |
276 static void force_all_opaque_8888(const SkBitmap& bitmap) { | 280 static void force_all_opaque_8888(const SkBitmap& bitmap) { |
277 SkAutoLockPixels lock(bitmap); | 281 SkAutoLockPixels lock(bitmap); |
278 for (int y = 0; y < bitmap.height(); y++) { | 282 for (int y = 0; y < bitmap.height(); y++) { |
279 for (int x = 0; x < bitmap.width(); x++) { | 283 for (int x = 0; x < bitmap.width(); x++) { |
280 *bitmap.getAddr32(x, y) |= (SK_A32_MASK << SK_A32_SHIFT); | 284 *bitmap.getAddr32(x, y) |= (SK_A32_MASK << SK_A32_SHIFT); |
281 } | 285 } |
282 } | 286 } |
283 } | 287 } |
284 | 288 |
285 static bool write_bitmap(const SkString& path, const SkBitmap& bitmap) { | 289 static ErrorCombination write_bitmap(const SkString& path, const SkBitmap& b
itmap) { |
286 // TODO(epoger): Now that we have removed force_all_opaque() | 290 // TODO(epoger): Now that we have removed force_all_opaque() |
287 // from this method, we should be able to get rid of the | 291 // from this method, we should be able to get rid of the |
288 // transformation to 8888 format also. | 292 // transformation to 8888 format also. |
289 SkBitmap copy; | 293 SkBitmap copy; |
290 bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); | 294 bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); |
291 return SkImageEncoder::EncodeFile(path.c_str(), copy, | 295 if (!SkImageEncoder::EncodeFile(path.c_str(), copy, |
292 SkImageEncoder::kPNG_Type, 100); | 296 SkImageEncoder::kPNG_Type, |
| 297 100)) { |
| 298 gm_fprintf(stderr, "FAILED to write bitmap: %s\n", path.c_str()); |
| 299 return ErrorCombination(kWritingReferenceImage_ErrorType); |
| 300 } |
| 301 return kEmpty_ErrorCombination; |
293 } | 302 } |
294 | 303 |
295 /** | 304 /** |
296 * Add all render modes encountered thus far to the "modes" array. | 305 * Add all render modes encountered thus far to the "modes" array. |
297 */ | 306 */ |
298 void GetRenderModesEncountered(SkTArray<SkString> &modes) { | 307 void GetRenderModesEncountered(SkTArray<SkString> &modes) { |
299 SkTDict<int>::Iter iter(this->fRenderModesEncountered); | 308 SkTDict<int>::Iter iter(this->fRenderModesEncountered); |
300 const char* mode; | 309 const char* mode; |
301 while ((mode = iter.next(NULL)) != NULL) { | 310 while ((mode = iter.next(NULL)) != NULL) { |
302 SkString modeAsString = SkString(mode); | 311 SkString modeAsString = SkString(mode); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 } | 412 } |
404 gm_fprintf(stdout, "%s\n", summary.c_str()); | 413 gm_fprintf(stdout, "%s\n", summary.c_str()); |
405 | 414 |
406 // Now, for each failure type, list the tests that failed that way. | 415 // Now, for each failure type, list the tests that failed that way. |
407 for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) { | 416 for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) { |
408 this->DisplayResultTypeSummary(static_cast<ErrorType>(typeInt), verb
ose); | 417 this->DisplayResultTypeSummary(static_cast<ErrorType>(typeInt), verb
ose); |
409 } | 418 } |
410 gm_fprintf(stdout, "(results marked with [*] will cause nonzero return v
alue)\n"); | 419 gm_fprintf(stdout, "(results marked with [*] will cause nonzero return v
alue)\n"); |
411 } | 420 } |
412 | 421 |
413 static bool write_document(const SkString& path, SkStreamAsset* asset) { | 422 static ErrorCombination write_document(const SkString& path, SkStreamAsset*
asset) { |
414 SkFILEWStream stream(path.c_str()); | 423 SkFILEWStream stream(path.c_str()); |
415 return stream.writeStream(asset, asset->getLength()); | 424 if (!stream.writeStream(asset, asset->getLength())) { |
| 425 gm_fprintf(stderr, "FAILED to write document: %s\n", path.c_str()); |
| 426 return ErrorCombination(kWritingReferenceImage_ErrorType); |
| 427 } |
| 428 return kEmpty_ErrorCombination; |
416 } | 429 } |
417 | 430 |
418 /** | 431 /** |
419 * Prepare an SkBitmap to render a GM into. | 432 * Prepare an SkBitmap to render a GM into. |
420 * | 433 * |
421 * After you've rendered the GM into the SkBitmap, you must call | 434 * After you've rendered the GM into the SkBitmap, you must call |
422 * complete_bitmap()! | 435 * complete_bitmap()! |
423 * | 436 * |
424 * @todo thudson 22 April 2011 - could refactor this to take in | 437 * @todo thudson 22 April 2011 - could refactor this to take in |
425 * a factory to generate the context, always call readPixels() | 438 * a factory to generate the context, always call readPixels() |
(...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
652 SkCanvas c(dev); | 665 SkCanvas c(dev); |
653 dev->beginPortfolio(&xps); | 666 dev->beginPortfolio(&xps); |
654 dev->beginSheet(unitsPerMeter, pixelsPerMeter, trimSize); | 667 dev->beginSheet(unitsPerMeter, pixelsPerMeter, trimSize); |
655 invokeGM(gm, &c, false, false); | 668 invokeGM(gm, &c, false, false); |
656 dev->endSheet(); | 669 dev->endSheet(); |
657 dev->endPortfolio(); | 670 dev->endPortfolio(); |
658 | 671 |
659 #endif | 672 #endif |
660 } | 673 } |
661 | 674 |
662 ErrorCombination write_reference_image(const ConfigData& gRec, const char wr
itePath [], | |
663 const char renderModeDescriptor [], | |
664 const char *shortName, | |
665 const BitmapAndDigest* bitmapAndDiges
t, | |
666 SkStreamAsset* document) { | |
667 SkString path; | |
668 bool success = false; | |
669 if (gRec.fBackend == kRaster_Backend || | |
670 gRec.fBackend == kGPU_Backend || | |
671 (gRec.fBackend == kPDF_Backend && CAN_IMAGE_PDF)) { | |
672 | |
673 path = make_bitmap_filename(writePath, shortName, gRec.fName, render
ModeDescriptor, | |
674 bitmapAndDigest->fDigest); | |
675 success = write_bitmap(path, bitmapAndDigest->fBitmap); | |
676 } | |
677 if (kPDF_Backend == gRec.fBackend) { | |
678 path = make_filename(writePath, shortName, gRec.fName, renderModeDes
criptor, | |
679 "pdf"); | |
680 success = write_document(path, document); | |
681 } | |
682 if (kXPS_Backend == gRec.fBackend) { | |
683 path = make_filename(writePath, shortName, gRec.fName, renderModeDes
criptor, | |
684 "xps"); | |
685 success = write_document(path, document); | |
686 } | |
687 if (success) { | |
688 return kEmpty_ErrorCombination; | |
689 } else { | |
690 gm_fprintf(stderr, "FAILED to write %s\n", path.c_str()); | |
691 ErrorCombination errors(kWritingReferenceImage_ErrorType); | |
692 // TODO(epoger): Don't call RecordTestResults() here... | |
693 // Instead, we should make sure to call RecordTestResults | |
694 // exactly ONCE per test. (Otherwise, gmmain.fTestsRun | |
695 // will be incremented twice for this test: once in | |
696 // compare_test_results_to_stored_expectations() before | |
697 // that method calls this one, and again here.) | |
698 // | |
699 // When we make that change, we should probably add a | |
700 // WritingReferenceImage test to the gm self-tests.) | |
701 RecordTestResults(errors, make_shortname_plus_config(shortName, gRec
.fName), | |
702 renderModeDescriptor); | |
703 return errors; | |
704 } | |
705 } | |
706 | |
707 /** | 675 /** |
708 * Log more detail about the mistmatch between expectedBitmap and | 676 * Log more detail about the mistmatch between expectedBitmap and |
709 * actualBitmap. | 677 * actualBitmap. |
710 */ | 678 */ |
711 void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act
ualBitmap, | 679 void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act
ualBitmap, |
712 const char *testName) { | 680 const char *testName) { |
713 const int expectedWidth = expectedBitmap.width(); | 681 const int expectedWidth = expectedBitmap.width(); |
714 const int expectedHeight = expectedBitmap.height(); | 682 const int expectedHeight = expectedBitmap.height(); |
715 const int width = actualBitmap.width(); | 683 const int width = actualBitmap.width(); |
716 const int height = actualBitmap.height(); | 684 const int height = actualBitmap.height(); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
825 } | 793 } |
826 | 794 |
827 // If we have access to a single expected bitmap, log more | 795 // If we have access to a single expected bitmap, log more |
828 // detail about the mismatch. | 796 // detail about the mismatch. |
829 const SkBitmap *expectedBitmapPtr = expectations.asBitmap(); | 797 const SkBitmap *expectedBitmapPtr = expectations.asBitmap(); |
830 if (NULL != expectedBitmapPtr) { | 798 if (NULL != expectedBitmapPtr) { |
831 report_bitmap_diffs(*expectedBitmapPtr, actualBitmapAndDigest.fB
itmap, | 799 report_bitmap_diffs(*expectedBitmapPtr, actualBitmapAndDigest.fB
itmap, |
832 completeName); | 800 completeName); |
833 } | 801 } |
834 } | 802 } |
835 RecordTestResults(errors, shortNamePlusConfig, renderModeDescriptor); | |
836 | 803 |
837 if (addToJsonSummary) { | 804 if (addToJsonSummary) { |
838 add_actual_results_to_json_summary(completeName, actualBitmapAndDige
st.fDigest, errors, | 805 add_actual_results_to_json_summary(completeName, actualBitmapAndDige
st.fDigest, errors, |
839 expectations.ignoreFailure()); | 806 expectations.ignoreFailure()); |
840 add_expected_results_to_json_summary(completeName, expectations); | 807 add_expected_results_to_json_summary(completeName, expectations); |
841 } | 808 } |
842 | 809 |
843 return errors; | 810 return errors; |
844 } | 811 } |
845 | 812 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
894 void add_expected_results_to_json_summary(const char testName[], | 861 void add_expected_results_to_json_summary(const char testName[], |
895 Expectations expectations) { | 862 Expectations expectations) { |
896 this->fJsonExpectedResults[testName] = expectations.asJsonValue(); | 863 this->fJsonExpectedResults[testName] = expectations.asJsonValue(); |
897 } | 864 } |
898 | 865 |
899 /** | 866 /** |
900 * Compare actualBitmap to expectations stored in this->fExpectationsSource. | 867 * Compare actualBitmap to expectations stored in this->fExpectationsSource. |
901 * | 868 * |
902 * @param gm which test generated the actualBitmap | 869 * @param gm which test generated the actualBitmap |
903 * @param gRec | 870 * @param gRec |
904 * @param writePath unless this is NULL, write out actual images into this | |
905 * directory | |
906 * @param actualBitmapAndDigest ptr to bitmap generated by this run, or NULL | 871 * @param actualBitmapAndDigest ptr to bitmap generated by this run, or NULL |
907 * if we don't have a usable bitmap representation | 872 * if we don't have a usable bitmap representation |
908 * @param document pdf or xps representation, if appropriate | |
909 */ | 873 */ |
910 ErrorCombination compare_test_results_to_stored_expectations( | 874 ErrorCombination compare_test_results_to_stored_expectations( |
911 GM* gm, const ConfigData& gRec, const char writePath[], | 875 GM* gm, const ConfigData& gRec, |
912 const BitmapAndDigest* actualBitmapAndDigest, SkStreamAsset* document) { | 876 const BitmapAndDigest* actualBitmapAndDigest) { |
913 | 877 |
914 SkString shortNamePlusConfig = make_shortname_plus_config(gm->shortName(
), gRec.fName); | 878 SkString shortNamePlusConfig = make_shortname_plus_config(gm->shortName(
), gRec.fName); |
915 SkString nameWithExtension(shortNamePlusConfig); | |
916 nameWithExtension.append("."); | |
917 nameWithExtension.append(kPNG_FileExtension); | |
918 | 879 |
919 ErrorCombination errors; | 880 ErrorCombination errors; |
920 | 881 |
921 if (NULL == actualBitmapAndDigest) { | 882 if (NULL == actualBitmapAndDigest) { |
922 // Note that we intentionally skipped validating the results for | 883 // Note that we intentionally skipped validating the results for |
923 // this test, because we don't know how to generate an SkBitmap | 884 // this test, because we don't know how to generate an SkBitmap |
924 // version of the output. | 885 // version of the output. |
925 RecordTestResults(ErrorCombination(kIntentionallySkipped_ErrorType), | 886 errors.add(ErrorCombination(kIntentionallySkipped_ErrorType)); |
926 shortNamePlusConfig, ""); | |
927 } else if (!(gRec.fFlags & kWrite_ConfigFlag)) { | 887 } else if (!(gRec.fFlags & kWrite_ConfigFlag)) { |
928 // We don't record the results for this test or compare them | 888 // We don't record the results for this test or compare them |
929 // against any expectations, because the output image isn't | 889 // against any expectations, because the output image isn't |
930 // meaningful. | 890 // meaningful. |
931 // See https://code.google.com/p/skia/issues/detail?id=1410 ('some | 891 // See https://code.google.com/p/skia/issues/detail?id=1410 ('some |
932 // GM result images not available for download from Google Storage') | 892 // GM result images not available for download from Google Storage') |
933 RecordTestResults(ErrorCombination(kIntentionallySkipped_ErrorType), | 893 errors.add(ErrorCombination(kIntentionallySkipped_ErrorType)); |
934 shortNamePlusConfig, ""); | |
935 } else { | 894 } else { |
936 ExpectationsSource *expectationsSource = this->fExpectationsSource.g
et(); | 895 ExpectationsSource *expectationsSource = this->fExpectationsSource.g
et(); |
| 896 SkString nameWithExtension(shortNamePlusConfig); |
| 897 nameWithExtension.append("."); |
| 898 nameWithExtension.append(kPNG_FileExtension); |
| 899 |
937 if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) { | 900 if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) { |
938 /* | 901 /* |
939 * Get the expected results for this test, as one or more allowe
d | 902 * Get the expected results for this test, as one or more allowe
d |
940 * hash digests. The current implementation of expectationsSourc
e | 903 * hash digests. The current implementation of expectationsSourc
e |
941 * get this by computing the hash digest of a single PNG file on
disk. | 904 * get this by computing the hash digest of a single PNG file on
disk. |
942 * | 905 * |
943 * TODO(epoger): This relies on the fact that | 906 * TODO(epoger): This relies on the fact that |
944 * force_all_opaque() was called on the bitmap before it | 907 * force_all_opaque() was called on the bitmap before it |
945 * was written to disk as a PNG in the first place. If | 908 * was written to disk as a PNG in the first place. If |
946 * not, the hash digest returned here may not match the | 909 * not, the hash digest returned here may not match the |
947 * hash digest of actualBitmap, which *has* been run through | 910 * hash digest of actualBitmap, which *has* been run through |
948 * force_all_opaque(). | 911 * force_all_opaque(). |
949 * See comments above complete_bitmap() for more detail. | 912 * See comments above complete_bitmap() for more detail. |
950 */ | 913 */ |
951 Expectations expectations = expectationsSource->get(nameWithExte
nsion.c_str()); | 914 Expectations expectations = expectationsSource->get(nameWithExte
nsion.c_str()); |
952 errors.add(compare_to_expectations(expectations, *actualBitmapAn
dDigest, | 915 errors.add(compare_to_expectations(expectations, *actualBitmapAn
dDigest, |
953 gm->shortName(), gRec.fName,
"", true)); | 916 gm->shortName(), gRec.fName,
"", true)); |
954 } else { | 917 } else { |
955 // If we are running without expectations, we still want to | 918 // If we are running without expectations, we still want to |
956 // record the actual results. | 919 // record the actual results. |
957 add_actual_results_to_json_summary(nameWithExtension.c_str(), | 920 add_actual_results_to_json_summary(nameWithExtension.c_str(), |
958 actualBitmapAndDigest->fDiges
t, | 921 actualBitmapAndDigest->fDiges
t, |
959 ErrorCombination(kMissingExpe
ctations_ErrorType), | 922 ErrorCombination(kMissingExpe
ctations_ErrorType), |
960 false); | 923 false); |
961 RecordTestResults(ErrorCombination(kMissingExpectations_ErrorTyp
e), | 924 errors.add(ErrorCombination(kMissingExpectations_ErrorType)); |
962 shortNamePlusConfig, ""); | |
963 } | 925 } |
964 } | 926 } |
965 | |
966 // TODO: Consider moving this into compare_to_expectations(), | |
967 // similar to fMismatchPath... for now, we don't do that, because | |
968 // we don't want to write out the actual bitmaps for all | |
969 // renderModes of all tests! That would be a lot of files. | |
970 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { | |
971 errors.add(write_reference_image(gRec, writePath, "", gm->shortName(
), | |
972 actualBitmapAndDigest, document)); | |
973 } | |
974 | |
975 return errors; | 927 return errors; |
976 } | 928 } |
977 | 929 |
978 /** | 930 /** |
979 * Compare actualBitmap to referenceBitmap. | 931 * Compare actualBitmap to referenceBitmap. |
980 * | 932 * |
981 * @param shortName test name, e.g. "selftest1" | 933 * @param shortName test name, e.g. "selftest1" |
982 * @param configName configuration name, e.g. "8888" | 934 * @param configName configuration name, e.g. "8888" |
983 * @param renderModeDescriptor | 935 * @param renderModeDescriptor |
984 * @param actualBitmap actual bitmap generated by this run | 936 * @param actualBitmap actual bitmap generated by this run |
985 * @param referenceBitmap bitmap we expected to be generated | 937 * @param referenceBitmap bitmap we expected to be generated |
986 */ | 938 */ |
987 ErrorCombination compare_test_results_to_reference_bitmap( | 939 ErrorCombination compare_test_results_to_reference_bitmap( |
988 const char *shortName, const char *configName, const char *renderModeDes
criptor, | 940 const char *shortName, const char *configName, const char *renderModeDes
criptor, |
989 SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) { | 941 SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) { |
990 | |
991 SkASSERT(referenceBitmap); | 942 SkASSERT(referenceBitmap); |
992 Expectations expectations(*referenceBitmap); | 943 Expectations expectations(*referenceBitmap); |
993 BitmapAndDigest actualBitmapAndDigest(actualBitmap); | 944 BitmapAndDigest actualBitmapAndDigest(actualBitmap); |
994 return compare_to_expectations(expectations, actualBitmapAndDigest, shor
tName, | 945 |
995 configName, renderModeDescriptor, false); | 946 // TODO: Error reporting code is here to maintain consistent behavior, n
ow that |
| 947 // compare_to_expectations has been refactored to pass up ErrorCombinati
ons |
| 948 // instead of reporting it there. While the test_drawing path has been |
| 949 // refactored to the new style, the test_deferred_drawing path has not. |
| 950 // Once the other path follows the new style, these following few lines
can |
| 951 // be replaced with simply returning the errors from compare_to_expectat
ions. |
| 952 ErrorCombination errors; |
| 953 errors.add(compare_to_expectations(expectations, actualBitmapAndDigest,
shortName, |
| 954 configName, renderModeDescriptor, fal
se)); |
| 955 SkString shortNamePlusConfig = make_shortname_plus_config(shortName, con
figName); |
| 956 RecordTestResults(errors, shortNamePlusConfig, renderModeDescriptor); |
| 957 |
| 958 return errors; |
996 } | 959 } |
997 | 960 |
998 static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t rec
ordFlags, | 961 static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t rec
ordFlags, |
999 SkScalar scale = SK_Scalar1) { | 962 SkScalar scale = SK_Scalar1) { |
1000 // Pictures are refcounted so must be on heap | 963 // Pictures are refcounted so must be on heap |
1001 SkPicture* pict; | 964 SkPicture* pict; |
1002 int width = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().w
idth()), scale)); | 965 int width = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().w
idth()), scale)); |
1003 int height = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().
height()), scale)); | 966 int height = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().
height()), scale)); |
1004 | 967 |
1005 if (kTileGrid_BbhType == bbhType) { | 968 if (kTileGrid_BbhType == bbhType) { |
(...skipping 19 matching lines...) Expand all Loading... |
1025 static SkPicture* stream_to_new_picture(const SkPicture& src) { | 988 static SkPicture* stream_to_new_picture(const SkPicture& src) { |
1026 SkDynamicMemoryWStream storage; | 989 SkDynamicMemoryWStream storage; |
1027 src.serialize(&storage); | 990 src.serialize(&storage); |
1028 SkAutoTUnref<SkStreamAsset> pictReadback(storage.detachAsStream()); | 991 SkAutoTUnref<SkStreamAsset> pictReadback(storage.detachAsStream()); |
1029 SkPicture* retval = SkPicture::CreateFromStream(pictReadback); | 992 SkPicture* retval = SkPicture::CreateFromStream(pictReadback); |
1030 return retval; | 993 return retval; |
1031 } | 994 } |
1032 | 995 |
1033 // Test: draw into a bitmap or pdf. | 996 // Test: draw into a bitmap or pdf. |
1034 // Depending on flags, possibly compare to an expected image. | 997 // Depending on flags, possibly compare to an expected image. |
1035 ErrorCombination test_drawing(GM* gm, | 998 // If writePath is not NULL, also write images (or documents) to the |
1036 const ConfigData& gRec, | 999 // specified path. |
| 1000 ErrorCombination test_drawing(GM* gm, const ConfigData& gRec, |
| 1001 const SkTDArray<const PDFRasterizerData*> &pdf
Rasterizers, |
1037 const char writePath [], | 1002 const char writePath [], |
1038 GrSurface* gpuTarget, | 1003 GrSurface* gpuTarget, |
1039 SkBitmap* bitmap) { | 1004 SkBitmap* bitmap) { |
| 1005 ErrorCombination errors; |
1040 SkDynamicMemoryWStream document; | 1006 SkDynamicMemoryWStream document; |
| 1007 SkString path; |
1041 | 1008 |
1042 if (gRec.fBackend == kRaster_Backend || | 1009 if (gRec.fBackend == kRaster_Backend || |
1043 gRec.fBackend == kGPU_Backend) { | 1010 gRec.fBackend == kGPU_Backend) { |
1044 // Early exit if we can't generate the image. | 1011 // Early exit if we can't generate the image. |
1045 ErrorCombination errors = generate_image(gm, gRec, gpuTarget, bitmap
, false); | 1012 errors.add(generate_image(gm, gRec, gpuTarget, bitmap, false)); |
1046 if (!errors.isEmpty()) { | 1013 if (!errors.isEmpty()) { |
1047 // TODO: Add a test to exercise what the stdout and | 1014 // TODO: Add a test to exercise what the stdout and |
1048 // JSON look like if we get an "early error" while | 1015 // JSON look like if we get an "early error" while |
1049 // trying to generate the image. | 1016 // trying to generate the image. |
1050 return errors; | 1017 return errors; |
1051 } | 1018 } |
| 1019 BitmapAndDigest bitmapAndDigest(*bitmap); |
| 1020 errors.add(compare_test_results_to_stored_expectations( |
| 1021 gm, gRec, &bitmapAndDigest)); |
| 1022 |
| 1023 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { |
| 1024 path = make_bitmap_filename(writePath, gm->shortName(), gRec.fNa
me, |
| 1025 "", bitmapAndDigest.fDigest); |
| 1026 errors.add(write_bitmap(path, bitmapAndDigest.fBitmap)); |
| 1027 } |
1052 } else if (gRec.fBackend == kPDF_Backend) { | 1028 } else if (gRec.fBackend == kPDF_Backend) { |
1053 generate_pdf(gm, document); | 1029 generate_pdf(gm, document); |
1054 #if CAN_IMAGE_PDF | 1030 |
1055 SkAutoDataUnref data(document.copyToData()); | 1031 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream()
); |
1056 SkMemoryStream stream(data->data(), data->size()); | 1032 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { |
1057 SkPDFDocumentToBitmap(&stream, bitmap); | 1033 path = make_filename(writePath, gm->shortName(), gRec.fName, "",
"pdf"); |
1058 #else | 1034 errors.add(write_document(path, documentStream)); |
1059 bitmap = NULL; // we don't generate a bitmap rendering of the PDF f
ile | 1035 } |
1060 #endif | 1036 |
| 1037 for (int i = 0; i < pdfRasterizers.count(); i++) { |
| 1038 SkBitmap pdfBitmap; |
| 1039 SkASSERT(documentStream->rewind()); |
| 1040 bool success = (*pdfRasterizers[i]->fRasterizerFunction)( |
| 1041 documentStream.get(), &pdfBitmap); |
| 1042 if (!success) { |
| 1043 gm_fprintf(stderr, "FAILED to render PDF for %s using render
er %s\n", |
| 1044 gm->shortName(), |
| 1045 pdfRasterizers[i]->fName); |
| 1046 continue; |
| 1047 } |
| 1048 |
| 1049 BitmapAndDigest bitmapAndDigest(pdfBitmap); |
| 1050 errors.add(compare_test_results_to_stored_expectations( |
| 1051 gm, gRec, &bitmapAndDigest)); |
| 1052 |
| 1053 SkString configName(gRec.fName); |
| 1054 configName.append("_"); |
| 1055 configName.append(pdfRasterizers[i]->fName); |
| 1056 |
| 1057 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { |
| 1058 path = make_bitmap_filename(writePath, gm->shortName(), conf
igName.c_str(), |
| 1059 "", bitmapAndDigest.fDigest); |
| 1060 errors.add(write_bitmap(path, bitmapAndDigest.fBitmap)); |
| 1061 } |
| 1062 } |
1061 } else if (gRec.fBackend == kXPS_Backend) { | 1063 } else if (gRec.fBackend == kXPS_Backend) { |
1062 generate_xps(gm, document); | 1064 generate_xps(gm, document); |
1063 bitmap = NULL; // we don't generate a bitmap rendering of the XPS f
ile | 1065 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream()
); |
| 1066 |
| 1067 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { |
| 1068 path = make_filename(writePath, gm->shortName(), gRec.fName, "",
"xps"); |
| 1069 errors.add(write_document(path, documentStream)); |
| 1070 } |
| 1071 } else { |
| 1072 SkASSERT(false); |
1064 } | 1073 } |
1065 | 1074 return errors; |
1066 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream()); | |
1067 if (NULL == bitmap) { | |
1068 return compare_test_results_to_stored_expectations( | |
1069 gm, gRec, writePath, NULL, documentStream); | |
1070 } else { | |
1071 BitmapAndDigest bitmapAndDigest(*bitmap); | |
1072 return compare_test_results_to_stored_expectations( | |
1073 gm, gRec, writePath, &bitmapAndDigest, documentStream); | |
1074 } | |
1075 } | 1075 } |
1076 | 1076 |
1077 ErrorCombination test_deferred_drawing(GM* gm, | 1077 ErrorCombination test_deferred_drawing(GM* gm, |
1078 const ConfigData& gRec, | 1078 const ConfigData& gRec, |
1079 const SkBitmap& referenceBitmap, | 1079 const SkBitmap& referenceBitmap, |
1080 GrSurface* gpuTarget) { | 1080 GrSurface* gpuTarget) { |
1081 if (gRec.fBackend == kRaster_Backend || | 1081 if (gRec.fBackend == kRaster_Backend || |
1082 gRec.fBackend == kGPU_Backend) { | 1082 gRec.fBackend == kGPU_Backend) { |
1083 const char renderModeDescriptor[] = "-deferred"; | 1083 const char renderModeDescriptor[] = "-deferred"; |
1084 SkBitmap bitmap; | 1084 SkBitmap bitmap; |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1216 Json::Value fJsonActualResults_Succeeded; | 1216 Json::Value fJsonActualResults_Succeeded; |
1217 | 1217 |
1218 }; // end of GMMain class definition | 1218 }; // end of GMMain class definition |
1219 | 1219 |
1220 #if SK_SUPPORT_GPU | 1220 #if SK_SUPPORT_GPU |
1221 static const GLContextType kDontCare_GLContextType = GrContextFactory::kNative_G
LContextType; | 1221 static const GLContextType kDontCare_GLContextType = GrContextFactory::kNative_G
LContextType; |
1222 #else | 1222 #else |
1223 static const GLContextType kDontCare_GLContextType = 0; | 1223 static const GLContextType kDontCare_GLContextType = 0; |
1224 #endif | 1224 #endif |
1225 | 1225 |
1226 // If the platform does not support writing PNGs of PDFs then there will be no | |
1227 // reference images to read. However, we can always write the .pdf files | |
1228 static const ConfigFlags kPDFConfigFlags = CAN_IMAGE_PDF ? kRW_ConfigFlag : | |
1229 kWrite_ConfigFlag; | |
1230 | |
1231 static const ConfigData gRec[] = { | 1226 static const ConfigData gRec[] = { |
1232 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextType,
0, kRW_ConfigFlag, "8888", true }, | 1227 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextType,
0, kRW_ConfigFlag, "8888", true }, |
1233 #if 0 // stop testing this (for now at least) since we want to remove support
for it (soon please!!!) | 1228 #if 0 // stop testing this (for now at least) since we want to remove support
for it (soon please!!!) |
1234 { SkBitmap::kARGB_4444_Config, kRaster_Backend, kDontCare_GLContextType,
0, kRW_ConfigFlag, "4444", true }, | 1229 { SkBitmap::kARGB_4444_Config, kRaster_Backend, kDontCare_GLContextType,
0, kRW_ConfigFlag, "4444", true }, |
1235 #endif | 1230 #endif |
1236 { SkBitmap::kRGB_565_Config, kRaster_Backend, kDontCare_GLContextType,
0, kRW_ConfigFlag, "565", true }, | 1231 { SkBitmap::kRGB_565_Config, kRaster_Backend, kDontCare_GLContextType,
0, kRW_ConfigFlag, "565", true }, |
1237 #if SK_SUPPORT_GPU | 1232 #if SK_SUPPORT_GPU |
1238 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL
ContextType, 0, kRW_ConfigFlag, "gpu", true }, | 1233 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL
ContextType, 0, kRW_ConfigFlag, "gpu", true }, |
1239 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL
ContextType, 16, kRW_ConfigFlag, "msaa16", false}, | 1234 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL
ContextType, 16, kRW_ConfigFlag, "msaa16", false}, |
1240 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL
ContextType, 4, kRW_ConfigFlag, "msaa4", false}, | 1235 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL
ContextType, 4, kRW_ConfigFlag, "msaa4", false}, |
(...skipping 11 matching lines...) Expand all Loading... |
1252 #endif // SK_ANGLE | 1247 #endif // SK_ANGLE |
1253 #ifdef SK_MESA | 1248 #ifdef SK_MESA |
1254 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kMESA_GLCo
ntextType, 0, kRW_ConfigFlag, "mesa", true }, | 1249 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kMESA_GLCo
ntextType, 0, kRW_ConfigFlag, "mesa", true }, |
1255 #endif // SK_MESA | 1250 #endif // SK_MESA |
1256 #endif // SK_SUPPORT_GPU | 1251 #endif // SK_SUPPORT_GPU |
1257 #ifdef SK_SUPPORT_XPS | 1252 #ifdef SK_SUPPORT_XPS |
1258 /* At present we have no way of comparing XPS files (either natively or by c
onverting to PNG). */ | 1253 /* At present we have no way of comparing XPS files (either natively or by c
onverting to PNG). */ |
1259 { SkBitmap::kARGB_8888_Config, kXPS_Backend, kDontCare_GLContextType,
0, kWrite_ConfigFlag, "xps", true }, | 1254 { SkBitmap::kARGB_8888_Config, kXPS_Backend, kDontCare_GLContextType,
0, kWrite_ConfigFlag, "xps", true }, |
1260 #endif // SK_SUPPORT_XPS | 1255 #endif // SK_SUPPORT_XPS |
1261 #ifdef SK_SUPPORT_PDF | 1256 #ifdef SK_SUPPORT_PDF |
1262 { SkBitmap::kARGB_8888_Config, kPDF_Backend, kDontCare_GLContextType,
0, kPDFConfigFlags, "pdf", true }, | 1257 { SkBitmap::kARGB_8888_Config, kPDF_Backend, kDontCare_GLContextType,
0, kRW_ConfigFlag, "pdf", true }, |
1263 #endif // SK_SUPPORT_PDF | 1258 #endif // SK_SUPPORT_PDF |
1264 }; | 1259 }; |
1265 | 1260 |
| 1261 static const PDFRasterizerData kPDFRasterizers[] = { |
| 1262 #ifdef SK_BUILD_FOR_MAC |
| 1263 { &SkPDFDocumentToBitmap, "mac", true }, |
| 1264 #endif |
| 1265 #ifdef SK_BUILD_POPPLER |
| 1266 { &SkPopplerRasterizePDF, "poppler", true }, |
| 1267 #endif |
| 1268 }; |
| 1269 |
1266 static const char kDefaultsConfigStr[] = "defaults"; | 1270 static const char kDefaultsConfigStr[] = "defaults"; |
1267 static const char kExcludeConfigChar = '~'; | 1271 static const char kExcludeConfigChar = '~'; |
1268 | 1272 |
1269 static SkString configUsage() { | 1273 static SkString configUsage() { |
1270 SkString result; | 1274 SkString result; |
1271 result.appendf("Space delimited list of which configs to run. Possible optio
ns: ["); | 1275 result.appendf("Space delimited list of which configs to run. Possible optio
ns: ["); |
1272 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | 1276 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { |
1273 SkASSERT(gRec[i].fName != kDefaultsConfigStr); | 1277 SkASSERT(gRec[i].fName != kDefaultsConfigStr); |
1274 if (i > 0) { | 1278 if (i > 0) { |
1275 result.append("|"); | 1279 result.append("|"); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1307 result.appendf("E.g. \"--config %s %c%s %s\" will run these configs:\n\t%s %
s", | 1311 result.appendf("E.g. \"--config %s %c%s %s\" will run these configs:\n\t%s %
s", |
1308 kDefaultsConfigStr, | 1312 kDefaultsConfigStr, |
1309 kExcludeConfigChar, | 1313 kExcludeConfigChar, |
1310 firstDefault.c_str(), | 1314 firstDefault.c_str(), |
1311 nonDefault.c_str(), | 1315 nonDefault.c_str(), |
1312 allButFirstDefaults.c_str(), | 1316 allButFirstDefaults.c_str(), |
1313 nonDefault.c_str()); | 1317 nonDefault.c_str()); |
1314 return result; | 1318 return result; |
1315 } | 1319 } |
1316 | 1320 |
| 1321 static SkString pdfRasterizerUsage() { |
| 1322 SkString result; |
| 1323 result.appendf("Space delimited list of which PDF rasterizers to run. Possib
le options: ["); |
| 1324 for (size_t i = 0; i < SK_ARRAY_COUNT(kPDFRasterizers); ++i) { |
| 1325 if (i > 0) { |
| 1326 result.append(" "); |
| 1327 } |
| 1328 result.append(kPDFRasterizers[i].fName); |
| 1329 } |
| 1330 result.append("]\n"); |
| 1331 result.append("The default value is: \""); |
| 1332 for (size_t i = 0; i < SK_ARRAY_COUNT(kPDFRasterizers); ++i) { |
| 1333 if (kPDFRasterizers[i].fRunByDefault) { |
| 1334 if (i > 0) { |
| 1335 result.append(" "); |
| 1336 } |
| 1337 result.append(kPDFRasterizers[i].fName); |
| 1338 } |
| 1339 } |
| 1340 result.append("\""); |
| 1341 return result; |
| 1342 } |
| 1343 |
1317 // Macro magic to convert a numeric preprocessor token into a string. | 1344 // Macro magic to convert a numeric preprocessor token into a string. |
1318 // Adapted from http://stackoverflow.com/questions/240353/convert-a-preprocessor
-token-to-a-string | 1345 // Adapted from http://stackoverflow.com/questions/240353/convert-a-preprocessor
-token-to-a-string |
1319 // This should probably be moved into one of our common headers... | 1346 // This should probably be moved into one of our common headers... |
1320 #define TOSTRING_INTERNAL(x) #x | 1347 #define TOSTRING_INTERNAL(x) #x |
1321 #define TOSTRING(x) TOSTRING_INTERNAL(x) | 1348 #define TOSTRING(x) TOSTRING_INTERNAL(x) |
1322 | 1349 |
1323 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath"). | 1350 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath"). |
1324 DEFINE_string(config, "", configUsage().c_str()); | 1351 DEFINE_string(config, "", configUsage().c_str()); |
| 1352 DEFINE_string(pdfRasterizers, "", pdfRasterizerUsage().c_str()); |
1325 DEFINE_bool(deferred, true, "Exercise the deferred rendering test pass."); | 1353 DEFINE_bool(deferred, true, "Exercise the deferred rendering test pass."); |
1326 DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip."); | 1354 DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip."); |
1327 DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing."); | 1355 DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing."); |
1328 #if SK_SUPPORT_GPU | 1356 #if SK_SUPPORT_GPU |
1329 DEFINE_string(gpuCacheSize, "", "<bytes> <count>: Limit the gpu cache to byte si
ze or " | 1357 DEFINE_string(gpuCacheSize, "", "<bytes> <count>: Limit the gpu cache to byte si
ze or " |
1330 "object count. " TOSTRING(DEFAULT_CACHE_VALUE) " for either value
means " | 1358 "object count. " TOSTRING(DEFAULT_CACHE_VALUE) " for either value
means " |
1331 "use the default. 0 for either disables the cache."); | 1359 "use the default. 0 for either disables the cache."); |
1332 #endif | 1360 #endif |
1333 DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure " | 1361 DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure " |
1334 "when reading/writing files."); | 1362 "when reading/writing files."); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1403 | 1431 |
1404 static int findConfig(const char config[]) { | 1432 static int findConfig(const char config[]) { |
1405 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) { | 1433 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) { |
1406 if (!strcmp(config, gRec[i].fName)) { | 1434 if (!strcmp(config, gRec[i].fName)) { |
1407 return (int) i; | 1435 return (int) i; |
1408 } | 1436 } |
1409 } | 1437 } |
1410 return -1; | 1438 return -1; |
1411 } | 1439 } |
1412 | 1440 |
| 1441 static const PDFRasterizerData* findPDFRasterizer(const char rasterizer[]) { |
| 1442 for (size_t i = 0; i < SK_ARRAY_COUNT(kPDFRasterizers); i++) { |
| 1443 if (!strcmp(rasterizer, kPDFRasterizers[i].fName)) { |
| 1444 return &kPDFRasterizers[i]; |
| 1445 } |
| 1446 } |
| 1447 return NULL; |
| 1448 } |
| 1449 |
1413 namespace skiagm { | 1450 namespace skiagm { |
1414 #if SK_SUPPORT_GPU | 1451 #if SK_SUPPORT_GPU |
1415 SkAutoTUnref<GrContext> gGrContext; | 1452 SkAutoTUnref<GrContext> gGrContext; |
1416 /** | 1453 /** |
1417 * Sets the global GrContext, accessible by individual GMs | 1454 * Sets the global GrContext, accessible by individual GMs |
1418 */ | 1455 */ |
1419 static void SetGr(GrContext* grContext) { | 1456 static void SetGr(GrContext* grContext) { |
1420 SkSafeRef(grContext); | 1457 SkSafeRef(grContext); |
1421 gGrContext.reset(grContext); | 1458 gGrContext.reset(grContext); |
1422 } | 1459 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1459 } | 1496 } |
1460 } | 1497 } |
1461 | 1498 |
1462 /** | 1499 /** |
1463 * Run this test in a number of different configs (8888, 565, PDF, | 1500 * Run this test in a number of different configs (8888, 565, PDF, |
1464 * etc.), confirming that the resulting bitmaps match expectations | 1501 * etc.), confirming that the resulting bitmaps match expectations |
1465 * (which may be different for each config). | 1502 * (which may be different for each config). |
1466 * | 1503 * |
1467 * Returns all errors encountered while doing so. | 1504 * Returns all errors encountered while doing so. |
1468 */ | 1505 */ |
1469 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si
ze_t> &configs, | 1506 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, |
| 1507 const SkTDArray<size_t> &configs, |
| 1508 const SkTDArray<const PDFRasterizerData*>
&pdfRasterizers, |
1470 GrContextFactory *grFactory); | 1509 GrContextFactory *grFactory); |
1471 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si
ze_t> &configs, | 1510 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, |
| 1511 const SkTDArray<size_t> &configs, |
| 1512 const SkTDArray<const PDFRasterizerData*>
&pdfRasterizers, |
1472 GrContextFactory *grFactory) { | 1513 GrContextFactory *grFactory) { |
1473 const char renderModeDescriptor[] = ""; | 1514 const char renderModeDescriptor[] = ""; |
1474 ErrorCombination errorsForAllConfigs; | 1515 ErrorCombination errorsForAllConfigs; |
1475 uint32_t gmFlags = gm->getFlags(); | 1516 uint32_t gmFlags = gm->getFlags(); |
1476 | 1517 |
1477 for (int i = 0; i < configs.count(); i++) { | 1518 for (int i = 0; i < configs.count(); i++) { |
1478 ConfigData config = gRec[configs[i]]; | 1519 ConfigData config = gRec[configs[i]]; |
1479 const SkString shortNamePlusConfig = gmmain.make_shortname_plus_config(g
m->shortName(), | 1520 const SkString shortNamePlusConfig = gmmain.make_shortname_plus_config(g
m->shortName(), |
1480 c
onfig.fName); | 1521 c
onfig.fName); |
1481 | 1522 |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1552 #endif | 1593 #endif |
1553 | 1594 |
1554 SkBitmap comparisonBitmap; | 1595 SkBitmap comparisonBitmap; |
1555 | 1596 |
1556 const char* writePath; | 1597 const char* writePath; |
1557 if (FLAGS_writePath.count() == 1) { | 1598 if (FLAGS_writePath.count() == 1) { |
1558 writePath = FLAGS_writePath[0]; | 1599 writePath = FLAGS_writePath[0]; |
1559 } else { | 1600 } else { |
1560 writePath = NULL; | 1601 writePath = NULL; |
1561 } | 1602 } |
| 1603 |
1562 if (errorsForThisConfig.isEmpty()) { | 1604 if (errorsForThisConfig.isEmpty()) { |
1563 errorsForThisConfig.add(gmmain.test_drawing(gm,config, writePath, gp
uTarget, | 1605 errorsForThisConfig.add(gmmain.test_drawing(gm, config, pdfRasterize
rs, |
| 1606 writePath, gpuTarget, |
1564 &comparisonBitmap)); | 1607 &comparisonBitmap)); |
| 1608 gmmain.RecordTestResults(errorsForThisConfig, shortNamePlusConfig, "
"); |
1565 } | 1609 } |
1566 | 1610 |
1567 if (FLAGS_deferred && errorsForThisConfig.isEmpty() && | 1611 if (FLAGS_deferred && errorsForThisConfig.isEmpty() && |
1568 (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBacke
nd)) { | 1612 (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBacke
nd)) { |
1569 errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, com
parisonBitmap, | 1613 errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, com
parisonBitmap, |
1570 gpuTarget)); | 1614 gpuTarget)); |
1571 } | 1615 } |
1572 | 1616 |
1573 errorsForAllConfigs.add(errorsForThisConfig); | 1617 errorsForAllConfigs.add(errorsForThisConfig); |
1574 } | 1618 } |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1741 total.append(", "); | 1785 total.append(", "); |
1742 } | 1786 } |
1743 total.append("\""); | 1787 total.append("\""); |
1744 total.append(gRec[configs[i]].fName); | 1788 total.append(gRec[configs[i]].fName); |
1745 total.append("\""); | 1789 total.append("\""); |
1746 } | 1790 } |
1747 return total; | 1791 return total; |
1748 } | 1792 } |
1749 | 1793 |
1750 bool prepare_subdirectories(const char *root, bool useFileHierarchy, | 1794 bool prepare_subdirectories(const char *root, bool useFileHierarchy, |
1751 const SkTDArray<size_t> &configs); | 1795 const SkTDArray<size_t> &configs, |
| 1796 const SkTDArray<const PDFRasterizerData*>& pdfRaster
izers); |
1752 bool prepare_subdirectories(const char *root, bool useFileHierarchy, | 1797 bool prepare_subdirectories(const char *root, bool useFileHierarchy, |
1753 const SkTDArray<size_t> &configs) { | 1798 const SkTDArray<size_t> &configs, |
| 1799 const SkTDArray<const PDFRasterizerData*>& pdfRaster
izers) { |
1754 if (!sk_mkdir(root)) { | 1800 if (!sk_mkdir(root)) { |
1755 return false; | 1801 return false; |
1756 } | 1802 } |
1757 if (useFileHierarchy) { | 1803 if (useFileHierarchy) { |
1758 for (int i = 0; i < configs.count(); i++) { | 1804 for (int i = 0; i < configs.count(); i++) { |
1759 ConfigData config = gRec[configs[i]]; | 1805 ConfigData config = gRec[configs[i]]; |
1760 SkString subdir; | 1806 SkString subdir; |
1761 subdir.appendf("%s%c%s", root, SkPATH_SEPARATOR, config.fName); | 1807 subdir.appendf("%s%c%s", root, SkPATH_SEPARATOR, config.fName); |
1762 if (!sk_mkdir(subdir.c_str())) { | 1808 if (!sk_mkdir(subdir.c_str())) { |
1763 return false; | 1809 return false; |
1764 } | 1810 } |
| 1811 |
| 1812 if (config.fBackend == kPDF_Backend) { |
| 1813 for (int j = 0; j < pdfRasterizers.count(); j++) { |
| 1814 SkString pdfSubdir = subdir; |
| 1815 pdfSubdir.appendf("_%s", pdfRasterizers[j]->fName); |
| 1816 if (!sk_mkdir(pdfSubdir.c_str())) { |
| 1817 return false; |
| 1818 } |
| 1819 } |
| 1820 } |
1765 } | 1821 } |
1766 } | 1822 } |
1767 return true; | 1823 return true; |
1768 } | 1824 } |
1769 | 1825 |
1770 static bool parse_flags_configs(SkTDArray<size_t>* outConfigs, | 1826 static bool parse_flags_configs(SkTDArray<size_t>* outConfigs, |
1771 GrContextFactory* grFactory) { | 1827 GrContextFactory* grFactory) { |
1772 SkTDArray<size_t> excludeConfigs; | 1828 SkTDArray<size_t> excludeConfigs; |
1773 | 1829 |
1774 for (int i = 0; i < FLAGS_config.count(); i++) { | 1830 for (int i = 0; i < FLAGS_config.count(); i++) { |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1863 SkString configStr("These configs will be run: "); | 1919 SkString configStr("These configs will be run: "); |
1864 // show the user the config that will run. | 1920 // show the user the config that will run. |
1865 for (int i = 0; i < outConfigs->count(); ++i) { | 1921 for (int i = 0; i < outConfigs->count(); ++i) { |
1866 configStr.appendf("%s ", gRec[(*outConfigs)[i]].fName); | 1922 configStr.appendf("%s ", gRec[(*outConfigs)[i]].fName); |
1867 } | 1923 } |
1868 gm_fprintf(stdout, "%s\n", configStr.c_str()); | 1924 gm_fprintf(stdout, "%s\n", configStr.c_str()); |
1869 | 1925 |
1870 return true; | 1926 return true; |
1871 } | 1927 } |
1872 | 1928 |
| 1929 static bool parse_flags_pdf_rasterizers(const SkTDArray<size_t>& configs, |
| 1930 SkTDArray<const PDFRasterizerData*>* out
Rasterizers) { |
| 1931 // No need to run this check (and display the PDF rasterizers message) |
| 1932 // if no PDF backends are in the configs. |
| 1933 bool configHasPDF = false; |
| 1934 for (int i = 0; i < configs.count(); i++) { |
| 1935 if (gRec[configs[i]].fBackend == kPDF_Backend) { |
| 1936 configHasPDF = true; |
| 1937 break; |
| 1938 } |
| 1939 } |
| 1940 if (!configHasPDF) { |
| 1941 return true; |
| 1942 } |
| 1943 |
| 1944 for (int i = 0; i < FLAGS_pdfRasterizers.count(); i++) { |
| 1945 const char* rasterizer = FLAGS_pdfRasterizers[i]; |
| 1946 const PDFRasterizerData* rasterizerPtr = findPDFRasterizer(rasterizer); |
| 1947 |
| 1948 if (rasterizerPtr == NULL) { |
| 1949 gm_fprintf(stderr, "unrecognized rasterizer %s\n", rasterizer); |
| 1950 return false; |
| 1951 } |
| 1952 appendUnique<const PDFRasterizerData*>(outRasterizers, |
| 1953 rasterizerPtr); |
| 1954 } |
| 1955 |
| 1956 if (outRasterizers->count() == 0) { |
| 1957 // if no config is specified by user, add the defaults |
| 1958 for (size_t i = 0; i < SK_ARRAY_COUNT(kPDFRasterizers); ++i) { |
| 1959 if (kPDFRasterizers[i].fRunByDefault) { |
| 1960 *outRasterizers->append() = &kPDFRasterizers[i]; |
| 1961 } |
| 1962 } |
| 1963 } |
| 1964 |
| 1965 // now show the user the set of configs that will be run. |
| 1966 SkString configStr("These PDF rasterizers will be run: "); |
| 1967 // show the user the config that will run. |
| 1968 for (int i = 0; i < outRasterizers->count(); ++i) { |
| 1969 configStr.appendf("%s ", (*outRasterizers)[i]->fName); |
| 1970 } |
| 1971 gm_fprintf(stdout, "%s\n", configStr.c_str()); |
| 1972 |
| 1973 return true; |
| 1974 } |
| 1975 |
1873 static bool parse_flags_ignore_error_types(ErrorCombination* outErrorTypes) { | 1976 static bool parse_flags_ignore_error_types(ErrorCombination* outErrorTypes) { |
1874 if (FLAGS_ignoreErrorTypes.count() > 0) { | 1977 if (FLAGS_ignoreErrorTypes.count() > 0) { |
1875 *outErrorTypes = ErrorCombination(); | 1978 *outErrorTypes = ErrorCombination(); |
1876 for (int i = 0; i < FLAGS_ignoreErrorTypes.count(); i++) { | 1979 for (int i = 0; i < FLAGS_ignoreErrorTypes.count(); i++) { |
1877 ErrorType type; | 1980 ErrorType type; |
1878 const char *name = FLAGS_ignoreErrorTypes[i]; | 1981 const char *name = FLAGS_ignoreErrorTypes[i]; |
1879 if (!getErrorTypeByName(name, &type)) { | 1982 if (!getErrorTypeByName(name, &type)) { |
1880 gm_fprintf(stderr, "cannot find ErrorType with name '%s'\n", nam
e); | 1983 gm_fprintf(stderr, "cannot find ErrorType with name '%s'\n", nam
e); |
1881 return false; | 1984 return false; |
1882 } else { | 1985 } else { |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2005 | 2108 |
2006 setSystemPreferences(); | 2109 setSystemPreferences(); |
2007 GMMain gmmain; | 2110 GMMain gmmain; |
2008 | 2111 |
2009 SkString usage; | 2112 SkString usage; |
2010 usage.printf("Run the golden master tests.\n"); | 2113 usage.printf("Run the golden master tests.\n"); |
2011 SkCommandLineFlags::SetUsage(usage.c_str()); | 2114 SkCommandLineFlags::SetUsage(usage.c_str()); |
2012 SkCommandLineFlags::Parse(argc, argv); | 2115 SkCommandLineFlags::Parse(argc, argv); |
2013 | 2116 |
2014 SkTDArray<size_t> configs; | 2117 SkTDArray<size_t> configs; |
| 2118 |
2015 int moduloRemainder = -1; | 2119 int moduloRemainder = -1; |
2016 int moduloDivisor = -1; | 2120 int moduloDivisor = -1; |
| 2121 SkTDArray<const PDFRasterizerData*> pdfRasterizers; |
2017 SkTDArray<SkScalar> tileGridReplayScales; | 2122 SkTDArray<SkScalar> tileGridReplayScales; |
2018 #if SK_SUPPORT_GPU | 2123 #if SK_SUPPORT_GPU |
2019 GrContextFactory* grFactory = new GrContextFactory; | 2124 GrContextFactory* grFactory = new GrContextFactory; |
2020 #else | 2125 #else |
2021 GrContextFactory* grFactory = NULL; | 2126 GrContextFactory* grFactory = NULL; |
2022 #endif | 2127 #endif |
2023 SkTDArray<const char*> matchStrs; | 2128 SkTDArray<const char*> matchStrs; |
2024 | 2129 |
2025 if (!parse_flags_modulo(&moduloRemainder, &moduloDivisor) || | 2130 if (!parse_flags_modulo(&moduloRemainder, &moduloDivisor) || |
2026 !parse_flags_ignore_error_types(&gmmain.fIgnorableErrorTypes) || | 2131 !parse_flags_ignore_error_types(&gmmain.fIgnorableErrorTypes) || |
2027 #if SK_SUPPORT_GPU | 2132 #if SK_SUPPORT_GPU |
2028 !parse_flags_gpu_cache(&gGpuCacheSizeBytes, &gGpuCacheSizeCount) || | 2133 !parse_flags_gpu_cache(&gGpuCacheSizeBytes, &gGpuCacheSizeCount) || |
2029 #endif | 2134 #endif |
2030 !parse_flags_tile_grid_replay_scales(&tileGridReplayScales) || | 2135 !parse_flags_tile_grid_replay_scales(&tileGridReplayScales) || |
2031 !parse_flags_gmmain_paths(&gmmain) || | |
2032 !parse_flags_resource_path() || | 2136 !parse_flags_resource_path() || |
2033 !parse_flags_match_strs(&matchStrs) || | 2137 !parse_flags_match_strs(&matchStrs) || |
2034 !parse_flags_jpeg_quality() || | 2138 !parse_flags_jpeg_quality() || |
2035 !parse_flags_configs(&configs, grFactory)) { | 2139 !parse_flags_configs(&configs, grFactory) || |
| 2140 !parse_flags_pdf_rasterizers(configs, &pdfRasterizers) || |
| 2141 !parse_flags_gmmain_paths(&gmmain)) { |
2036 return -1; | 2142 return -1; |
2037 } | 2143 } |
2038 | 2144 |
2039 if (FLAGS_verbose) { | 2145 if (FLAGS_verbose) { |
2040 if (FLAGS_writePath.count() == 1) { | 2146 if (FLAGS_writePath.count() == 1) { |
2041 gm_fprintf(stdout, "writing to %s\n", FLAGS_writePath[0]); | 2147 gm_fprintf(stdout, "writing to %s\n", FLAGS_writePath[0]); |
2042 } | 2148 } |
2043 if (NULL != gmmain.fMismatchPath) { | 2149 if (NULL != gmmain.fMismatchPath) { |
2044 gm_fprintf(stdout, "writing mismatches to %s\n", gmmain.fMismatchPat
h); | 2150 gm_fprintf(stdout, "writing mismatches to %s\n", gmmain.fMismatchPat
h); |
2045 } | 2151 } |
2046 if (NULL != gmmain.fMissingExpectationsPath) { | 2152 if (NULL != gmmain.fMissingExpectationsPath) { |
2047 gm_fprintf(stdout, "writing images without expectations to %s\n", | 2153 gm_fprintf(stdout, "writing images without expectations to %s\n", |
2048 gmmain.fMissingExpectationsPath); | 2154 gmmain.fMissingExpectationsPath); |
2049 } | 2155 } |
2050 if (FLAGS_writePicturePath.count() == 1) { | 2156 if (FLAGS_writePicturePath.count() == 1) { |
2051 gm_fprintf(stdout, "writing pictures to %s\n", FLAGS_writePicturePat
h[0]); | 2157 gm_fprintf(stdout, "writing pictures to %s\n", FLAGS_writePicturePat
h[0]); |
2052 } | 2158 } |
2053 if (FLAGS_resourcePath.count() == 1) { | 2159 if (FLAGS_resourcePath.count() == 1) { |
2054 gm_fprintf(stdout, "reading resources from %s\n", FLAGS_resourcePath
[0]); | 2160 gm_fprintf(stdout, "reading resources from %s\n", FLAGS_resourcePath
[0]); |
2055 } | 2161 } |
2056 } | 2162 } |
2057 | 2163 |
2058 int gmsRun = 0; | 2164 int gmsRun = 0; |
2059 int gmIndex = -1; | 2165 int gmIndex = -1; |
2060 SkString moduloStr; | 2166 SkString moduloStr; |
2061 | 2167 |
2062 // If we will be writing out files, prepare subdirectories. | 2168 // If we will be writing out files, prepare subdirectories. |
2063 if (FLAGS_writePath.count() == 1) { | 2169 if (FLAGS_writePath.count() == 1) { |
2064 if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy
, configs)) { | 2170 if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy
, |
| 2171 configs, pdfRasterizers)) { |
2065 return -1; | 2172 return -1; |
2066 } | 2173 } |
2067 } | 2174 } |
2068 if (NULL != gmmain.fMismatchPath) { | 2175 if (NULL != gmmain.fMismatchPath) { |
2069 if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarc
hy, configs)) { | 2176 if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarc
hy, |
| 2177 configs, pdfRasterizers)) { |
2070 return -1; | 2178 return -1; |
2071 } | 2179 } |
2072 } | 2180 } |
2073 if (NULL != gmmain.fMissingExpectationsPath) { | 2181 if (NULL != gmmain.fMissingExpectationsPath) { |
2074 if (!prepare_subdirectories(gmmain.fMissingExpectationsPath, gmmain.fUse
FileHierarchy, | 2182 if (!prepare_subdirectories(gmmain.fMissingExpectationsPath, gmmain.fUse
FileHierarchy, |
2075 configs)) { | 2183 configs, pdfRasterizers)) { |
2076 return -1; | 2184 return -1; |
2077 } | 2185 } |
2078 } | 2186 } |
2079 | 2187 |
2080 Iter iter; | 2188 Iter iter; |
2081 GM* gm; | 2189 GM* gm; |
2082 while ((gm = iter.next()) != NULL) { | 2190 while ((gm = iter.next()) != NULL) { |
2083 SkAutoTDelete<GM> adgm(gm); | 2191 SkAutoTDelete<GM> adgm(gm); |
2084 ++gmIndex; | 2192 ++gmIndex; |
2085 if (moduloRemainder >= 0) { | 2193 if (moduloRemainder >= 0) { |
2086 if ((gmIndex % moduloDivisor) != moduloRemainder) { | 2194 if ((gmIndex % moduloDivisor) != moduloRemainder) { |
2087 continue; | 2195 continue; |
2088 } | 2196 } |
2089 moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor); | 2197 moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor); |
2090 } | 2198 } |
2091 | 2199 |
2092 const char* shortName = gm->shortName(); | 2200 const char* shortName = gm->shortName(); |
2093 | 2201 |
2094 if (SkCommandLineFlags::ShouldSkip(matchStrs, shortName)) { | 2202 if (SkCommandLineFlags::ShouldSkip(matchStrs, shortName)) { |
2095 continue; | 2203 continue; |
2096 } | 2204 } |
2097 | 2205 |
2098 gmsRun++; | 2206 gmsRun++; |
2099 SkISize size = gm->getISize(); | 2207 SkISize size = gm->getISize(); |
2100 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
Name, | 2208 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
Name, |
2101 size.width(), size.height()); | 2209 size.width(), size.height()); |
2102 | 2210 |
2103 run_multiple_configs(gmmain, gm, configs, grFactory); | 2211 run_multiple_configs(gmmain, gm, configs, pdfRasterizers, grFactory); |
2104 | 2212 |
2105 SkBitmap comparisonBitmap; | 2213 SkBitmap comparisonBitmap; |
2106 const ConfigData compareConfig = | 2214 const ConfigData compareConfig = |
2107 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
ype, 0, kRW_ConfigFlag, "comparison", false }; | 2215 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
ype, 0, kRW_ConfigFlag, "comparison", false }; |
2108 gmmain.generate_image(gm, compareConfig, NULL, &comparisonBitmap, false)
; | 2216 gmmain.generate_image(gm, compareConfig, NULL, &comparisonBitmap, false)
; |
2109 | 2217 |
2110 // TODO(epoger): only run this if gmmain.generate_image() succeeded? | 2218 // TODO(epoger): only run this if gmmain.generate_image() succeeded? |
2111 // Otherwise, what are we comparing against? | 2219 // Otherwise, what are we comparing against? |
2112 run_multiple_modes(gmmain, gm, compareConfig, comparisonBitmap, tileGrid
ReplayScales); | 2220 run_multiple_modes(gmmain, gm, compareConfig, comparisonBitmap, tileGrid
ReplayScales); |
2113 } | 2221 } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2177 if (FLAGS_forceBWtext) { | 2285 if (FLAGS_forceBWtext) { |
2178 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 2286 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); |
2179 } | 2287 } |
2180 } | 2288 } |
2181 | 2289 |
2182 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 2290 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
2183 int main(int argc, char * const argv[]) { | 2291 int main(int argc, char * const argv[]) { |
2184 return tool_main(argc, (char**) argv); | 2292 return tool_main(argc, (char**) argv); |
2185 } | 2293 } |
2186 #endif | 2294 #endif |
OLD | NEW |