Chromium Code Reviews| 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 { | |
|
vandebo (ex-Chrome)
2013/08/09 16:26:34
PDFRasterizer PDFRasterizerInfo ?
ducky
2013/08/09 23:29:41
Naming was to be consistent with ConfigData, which
| |
| 162 bool (*fRasterizerFunction)(SkStream*, SkBitmap*); | |
| 163 const char* fName; | |
|
vandebo (ex-Chrome)
2013/08/09 16:26:34
spacing
ducky
2013/08/09 23:29:41
Shrunk. This was to be consistent with ConfigData
vandebo (ex-Chrome)
2013/08/12 17:41:56
To be consistent, you'd line up fRasterizerFunctio
ducky
2013/08/12 21:57:09
Done.
| |
| 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 bool success = SkImageEncoder::EncodeFile(path.c_str(), copy, |
| 292 SkImageEncoder::kPNG_Type, 100); | 296 SkImageEncoder::kPNG_Type, |
| 297 100); | |
| 298 if (success) { | |
| 299 return kEmpty_ErrorCombination; | |
| 300 } else { | |
| 301 gm_fprintf(stderr, "FAILED to write bitmap: %s\n", path.c_str()); | |
| 302 return ErrorCombination(kWritingReferenceImage_ErrorType); | |
| 303 } | |
| 293 } | 304 } |
| 294 | 305 |
| 295 /** | 306 /** |
| 296 * Add all render modes encountered thus far to the "modes" array. | 307 * Add all render modes encountered thus far to the "modes" array. |
| 297 */ | 308 */ |
| 298 void GetRenderModesEncountered(SkTArray<SkString> &modes) { | 309 void GetRenderModesEncountered(SkTArray<SkString> &modes) { |
| 299 SkTDict<int>::Iter iter(this->fRenderModesEncountered); | 310 SkTDict<int>::Iter iter(this->fRenderModesEncountered); |
| 300 const char* mode; | 311 const char* mode; |
| 301 while ((mode = iter.next(NULL)) != NULL) { | 312 while ((mode = iter.next(NULL)) != NULL) { |
| 302 SkString modeAsString = SkString(mode); | 313 SkString modeAsString = SkString(mode); |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 } | 414 } |
| 404 gm_fprintf(stdout, "%s\n", summary.c_str()); | 415 gm_fprintf(stdout, "%s\n", summary.c_str()); |
| 405 | 416 |
| 406 // Now, for each failure type, list the tests that failed that way. | 417 // Now, for each failure type, list the tests that failed that way. |
| 407 for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) { | 418 for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) { |
| 408 this->DisplayResultTypeSummary(static_cast<ErrorType>(typeInt), verb ose); | 419 this->DisplayResultTypeSummary(static_cast<ErrorType>(typeInt), verb ose); |
| 409 } | 420 } |
| 410 gm_fprintf(stdout, "(results marked with [*] will cause nonzero return v alue)\n"); | 421 gm_fprintf(stdout, "(results marked with [*] will cause nonzero return v alue)\n"); |
| 411 } | 422 } |
| 412 | 423 |
| 413 static bool write_document(const SkString& path, SkStreamAsset* asset) { | 424 static ErrorCombination write_document(const SkString& path, SkStreamAsset* asset) { |
| 414 SkFILEWStream stream(path.c_str()); | 425 SkFILEWStream stream(path.c_str()); |
| 415 return stream.writeStream(asset, asset->getLength()); | 426 bool success = stream.writeStream(asset, asset->getLength()); |
| 427 if (success) { | |
| 428 return kEmpty_ErrorCombination; | |
| 429 } else { | |
| 430 gm_fprintf(stderr, "FAILED to write document: %s\n", path.c_str()); | |
| 431 return ErrorCombination(kWritingReferenceImage_ErrorType); | |
| 432 } | |
| 416 } | 433 } |
| 417 | 434 |
| 418 /** | 435 /** |
| 419 * Prepare an SkBitmap to render a GM into. | 436 * Prepare an SkBitmap to render a GM into. |
| 420 * | 437 * |
| 421 * After you've rendered the GM into the SkBitmap, you must call | 438 * After you've rendered the GM into the SkBitmap, you must call |
| 422 * complete_bitmap()! | 439 * complete_bitmap()! |
| 423 * | 440 * |
| 424 * @todo thudson 22 April 2011 - could refactor this to take in | 441 * @todo thudson 22 April 2011 - could refactor this to take in |
| 425 * a factory to generate the context, always call readPixels() | 442 * 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); | 669 SkCanvas c(dev); |
| 653 dev->beginPortfolio(&xps); | 670 dev->beginPortfolio(&xps); |
| 654 dev->beginSheet(unitsPerMeter, pixelsPerMeter, trimSize); | 671 dev->beginSheet(unitsPerMeter, pixelsPerMeter, trimSize); |
| 655 invokeGM(gm, &c, false, false); | 672 invokeGM(gm, &c, false, false); |
| 656 dev->endSheet(); | 673 dev->endSheet(); |
| 657 dev->endPortfolio(); | 674 dev->endPortfolio(); |
| 658 | 675 |
| 659 #endif | 676 #endif |
| 660 } | 677 } |
| 661 | 678 |
| 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 /** | 679 /** |
| 708 * Log more detail about the mistmatch between expectedBitmap and | 680 * Log more detail about the mistmatch between expectedBitmap and |
| 709 * actualBitmap. | 681 * actualBitmap. |
| 710 */ | 682 */ |
| 711 void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act ualBitmap, | 683 void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act ualBitmap, |
| 712 const char *testName) { | 684 const char *testName) { |
| 713 const int expectedWidth = expectedBitmap.width(); | 685 const int expectedWidth = expectedBitmap.width(); |
| 714 const int expectedHeight = expectedBitmap.height(); | 686 const int expectedHeight = expectedBitmap.height(); |
| 715 const int width = actualBitmap.width(); | 687 const int width = actualBitmap.width(); |
| 716 const int height = actualBitmap.height(); | 688 const int height = actualBitmap.height(); |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 901 * | 873 * |
| 902 * @param gm which test generated the actualBitmap | 874 * @param gm which test generated the actualBitmap |
| 903 * @param gRec | 875 * @param gRec |
| 904 * @param writePath unless this is NULL, write out actual images into this | 876 * @param writePath unless this is NULL, write out actual images into this |
| 905 * directory | 877 * directory |
| 906 * @param actualBitmapAndDigest ptr to bitmap generated by this run, or NULL | 878 * @param actualBitmapAndDigest ptr to bitmap generated by this run, or NULL |
| 907 * if we don't have a usable bitmap representation | 879 * if we don't have a usable bitmap representation |
| 908 * @param document pdf or xps representation, if appropriate | 880 * @param document pdf or xps representation, if appropriate |
| 909 */ | 881 */ |
| 910 ErrorCombination compare_test_results_to_stored_expectations( | 882 ErrorCombination compare_test_results_to_stored_expectations( |
| 911 GM* gm, const ConfigData& gRec, const char writePath[], | 883 GM* gm, const ConfigData& gRec, |
| 912 const BitmapAndDigest* actualBitmapAndDigest, SkStreamAsset* document) { | 884 const BitmapAndDigest* actualBitmapAndDigest) { |
| 913 | 885 |
| 914 SkString shortNamePlusConfig = make_shortname_plus_config(gm->shortName( ), gRec.fName); | 886 SkString shortNamePlusConfig = make_shortname_plus_config(gm->shortName( ), gRec.fName); |
| 915 SkString nameWithExtension(shortNamePlusConfig); | |
| 916 nameWithExtension.append("."); | |
| 917 nameWithExtension.append(kPNG_FileExtension); | |
| 918 | 887 |
| 919 ErrorCombination errors; | 888 ErrorCombination errors; |
| 920 | 889 |
| 921 if (NULL == actualBitmapAndDigest) { | 890 if (NULL == actualBitmapAndDigest) { |
| 922 // Note that we intentionally skipped validating the results for | 891 // Note that we intentionally skipped validating the results for |
| 923 // this test, because we don't know how to generate an SkBitmap | 892 // this test, because we don't know how to generate an SkBitmap |
| 924 // version of the output. | 893 // version of the output. |
| 925 RecordTestResults(ErrorCombination(kIntentionallySkipped_ErrorType), | 894 errors.add(ErrorCombination(kIntentionallySkipped_ErrorType)); |
| 926 shortNamePlusConfig, ""); | |
| 927 } else if (!(gRec.fFlags & kWrite_ConfigFlag)) { | 895 } else if (!(gRec.fFlags & kWrite_ConfigFlag)) { |
| 928 // We don't record the results for this test or compare them | 896 // We don't record the results for this test or compare them |
| 929 // against any expectations, because the output image isn't | 897 // against any expectations, because the output image isn't |
| 930 // meaningful. | 898 // meaningful. |
| 931 // See https://code.google.com/p/skia/issues/detail?id=1410 ('some | 899 // See https://code.google.com/p/skia/issues/detail?id=1410 ('some |
| 932 // GM result images not available for download from Google Storage') | 900 // GM result images not available for download from Google Storage') |
| 933 RecordTestResults(ErrorCombination(kIntentionallySkipped_ErrorType), | 901 errors.add(ErrorCombination(kIntentionallySkipped_ErrorType)); |
| 934 shortNamePlusConfig, ""); | |
| 935 } else { | 902 } else { |
| 936 ExpectationsSource *expectationsSource = this->fExpectationsSource.g et(); | 903 ExpectationsSource *expectationsSource = this->fExpectationsSource.g et(); |
| 904 SkString nameWithExtension(shortNamePlusConfig); | |
| 905 nameWithExtension.append("."); | |
| 906 nameWithExtension.append(kPNG_FileExtension); | |
| 907 | |
| 937 if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) { | 908 if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) { |
| 938 /* | 909 /* |
| 939 * Get the expected results for this test, as one or more allowe d | 910 * Get the expected results for this test, as one or more allowe d |
| 940 * hash digests. The current implementation of expectationsSourc e | 911 * hash digests. The current implementation of expectationsSourc e |
| 941 * get this by computing the hash digest of a single PNG file on disk. | 912 * get this by computing the hash digest of a single PNG file on disk. |
| 942 * | 913 * |
| 943 * TODO(epoger): This relies on the fact that | 914 * TODO(epoger): This relies on the fact that |
| 944 * force_all_opaque() was called on the bitmap before it | 915 * force_all_opaque() was called on the bitmap before it |
| 945 * was written to disk as a PNG in the first place. If | 916 * was written to disk as a PNG in the first place. If |
| 946 * not, the hash digest returned here may not match the | 917 * not, the hash digest returned here may not match the |
| 947 * hash digest of actualBitmap, which *has* been run through | 918 * hash digest of actualBitmap, which *has* been run through |
| 948 * force_all_opaque(). | 919 * force_all_opaque(). |
| 949 * See comments above complete_bitmap() for more detail. | 920 * See comments above complete_bitmap() for more detail. |
| 950 */ | 921 */ |
| 951 Expectations expectations = expectationsSource->get(nameWithExte nsion.c_str()); | 922 Expectations expectations = expectationsSource->get(nameWithExte nsion.c_str()); |
| 952 errors.add(compare_to_expectations(expectations, *actualBitmapAn dDigest, | 923 errors.add(compare_to_expectations(expectations, *actualBitmapAn dDigest, |
| 953 gm->shortName(), gRec.fName, "", true)); | 924 gm->shortName(), gRec.fName, "", true)); |
| 954 } else { | 925 } else { |
| 955 // If we are running without expectations, we still want to | 926 // If we are running without expectations, we still want to |
| 956 // record the actual results. | 927 // record the actual results. |
| 957 add_actual_results_to_json_summary(nameWithExtension.c_str(), | 928 add_actual_results_to_json_summary(nameWithExtension.c_str(), |
| 958 actualBitmapAndDigest->fDiges t, | 929 actualBitmapAndDigest->fDiges t, |
| 959 ErrorCombination(kMissingExpe ctations_ErrorType), | 930 ErrorCombination(kMissingExpe ctations_ErrorType), |
| 960 false); | 931 false); |
| 961 RecordTestResults(ErrorCombination(kMissingExpectations_ErrorTyp e), | 932 errors.add(ErrorCombination(kMissingExpectations_ErrorType)); |
| 962 shortNamePlusConfig, ""); | |
| 963 } | 933 } |
| 964 } | 934 } |
| 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; | 935 return errors; |
| 976 } | 936 } |
| 977 | 937 |
| 978 /** | 938 /** |
| 979 * Compare actualBitmap to referenceBitmap. | 939 * Compare actualBitmap to referenceBitmap. |
| 980 * | 940 * |
| 981 * @param shortName test name, e.g. "selftest1" | 941 * @param shortName test name, e.g. "selftest1" |
| 982 * @param configName configuration name, e.g. "8888" | 942 * @param configName configuration name, e.g. "8888" |
| 983 * @param renderModeDescriptor | 943 * @param renderModeDescriptor |
| 984 * @param actualBitmap actual bitmap generated by this run | 944 * @param actualBitmap actual bitmap generated by this run |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1025 static SkPicture* stream_to_new_picture(const SkPicture& src) { | 985 static SkPicture* stream_to_new_picture(const SkPicture& src) { |
| 1026 SkDynamicMemoryWStream storage; | 986 SkDynamicMemoryWStream storage; |
| 1027 src.serialize(&storage); | 987 src.serialize(&storage); |
| 1028 SkAutoTUnref<SkStreamAsset> pictReadback(storage.detachAsStream()); | 988 SkAutoTUnref<SkStreamAsset> pictReadback(storage.detachAsStream()); |
| 1029 SkPicture* retval = SkPicture::CreateFromStream(pictReadback); | 989 SkPicture* retval = SkPicture::CreateFromStream(pictReadback); |
| 1030 return retval; | 990 return retval; |
| 1031 } | 991 } |
| 1032 | 992 |
| 1033 // Test: draw into a bitmap or pdf. | 993 // Test: draw into a bitmap or pdf. |
| 1034 // Depending on flags, possibly compare to an expected image. | 994 // Depending on flags, possibly compare to an expected image. |
| 1035 ErrorCombination test_drawing(GM* gm, | 995 ErrorCombination test_drawing(GM* gm, const ConfigData& gRec, |
| 1036 const ConfigData& gRec, | 996 const SkTDArray<const PDFRasterizerData*> &pdf Rasterizers, |
| 1037 const char writePath [], | 997 const char writePath [], |
| 1038 GrSurface* gpuTarget, | 998 GrSurface* gpuTarget, |
| 1039 SkBitmap* bitmap) { | 999 SkBitmap* bitmap) { |
| 1000 ErrorCombination errors; | |
| 1040 SkDynamicMemoryWStream document; | 1001 SkDynamicMemoryWStream document; |
| 1002 SkString path; | |
| 1041 | 1003 |
| 1042 if (gRec.fBackend == kRaster_Backend || | 1004 if (gRec.fBackend == kRaster_Backend || |
| 1043 gRec.fBackend == kGPU_Backend) { | 1005 gRec.fBackend == kGPU_Backend) { |
| 1044 // Early exit if we can't generate the image. | 1006 // Early exit if we can't generate the image. |
| 1045 ErrorCombination errors = generate_image(gm, gRec, gpuTarget, bitmap , false); | 1007 errors.add(generate_image(gm, gRec, gpuTarget, bitmap, false)); |
| 1046 if (!errors.isEmpty()) { | 1008 if (!errors.isEmpty()) { |
| 1047 // TODO: Add a test to exercise what the stdout and | 1009 // TODO: Add a test to exercise what the stdout and |
| 1048 // JSON look like if we get an "early error" while | 1010 // JSON look like if we get an "early error" while |
| 1049 // trying to generate the image. | 1011 // trying to generate the image. |
| 1050 return errors; | 1012 return errors; |
| 1051 } | 1013 } |
| 1014 BitmapAndDigest bitmapAndDigest(*bitmap); | |
| 1015 errors.add(compare_test_results_to_stored_expectations( | |
| 1016 gm, gRec, &bitmapAndDigest)); | |
| 1017 | |
| 1018 if (gRec.fFlags & kWrite_ConfigFlag) { | |
| 1019 path = make_bitmap_filename(writePath, gm->shortName(), gRec.fNa me, | |
| 1020 "", bitmapAndDigest.fDigest); | |
| 1021 errors.add(write_bitmap(path, bitmapAndDigest.fBitmap)); | |
| 1022 } | |
| 1052 } else if (gRec.fBackend == kPDF_Backend) { | 1023 } else if (gRec.fBackend == kPDF_Backend) { |
| 1053 generate_pdf(gm, document); | 1024 generate_pdf(gm, document); |
| 1054 #if CAN_IMAGE_PDF | 1025 |
| 1055 SkAutoDataUnref data(document.copyToData()); | 1026 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream() ); |
| 1056 SkMemoryStream stream(data->data(), data->size()); | 1027 if (gRec.fFlags & kWrite_ConfigFlag) { |
| 1057 SkPDFDocumentToBitmap(&stream, bitmap); | 1028 path = make_filename(writePath, gm->shortName(), gRec.fName, "", "pdf"); |
| 1058 #else | 1029 errors.add(write_document(path, documentStream)); |
| 1059 bitmap = NULL; // we don't generate a bitmap rendering of the PDF f ile | 1030 } |
| 1060 #endif | 1031 |
| 1032 for (int i = 0; i < pdfRasterizers.count(); i++) { | |
| 1033 SkASSERT(documentStream->rewind()); | |
| 1034 bool success = (*pdfRasterizers[i]->fRasterizerFunction) | |
| 1035 (documentStream.get(), bitmap); | |
| 1036 if (!success) { | |
| 1037 gm_fprintf(stderr, "FAILED to render PDF for %s using render er %s\n", | |
| 1038 gm->shortName(), | |
| 1039 pdfRasterizers[i]->fName); | |
| 1040 continue; | |
| 1041 } | |
| 1042 | |
| 1043 BitmapAndDigest bitmapAndDigest(*bitmap); | |
| 1044 errors.add(compare_test_results_to_stored_expectations( | |
| 1045 gm, gRec, &bitmapAndDigest)); | |
| 1046 | |
| 1047 SkString configName(gRec.fName); | |
| 1048 configName.append("_"); | |
| 1049 configName.append(pdfRasterizers[i]->fName); | |
| 1050 | |
| 1051 if (gRec.fFlags & kWrite_ConfigFlag) { | |
| 1052 path = make_bitmap_filename(writePath, gm->shortName(), conf igName.c_str(), | |
| 1053 "", bitmapAndDigest.fDigest); | |
| 1054 errors.add(write_bitmap(path, bitmapAndDigest.fBitmap)); | |
| 1055 } | |
| 1056 } | |
| 1057 | |
| 1058 // Though we may have a rasterizer and it may output a bitmap, | |
|
vandebo (ex-Chrome)
2013/08/09 16:26:34
Instead of having this comment and clearing the bi
ducky
2013/08/09 23:29:41
Done.
| |
| 1059 // we may also have multiple rasterizers outputting different | |
| 1060 // bitmaps. Since the output bitmap isn't used by anything except | |
| 1061 // raster and GPU, the output bitmap is cleared. | |
| 1062 bitmap = NULL; | |
| 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 (gRec.fFlags & kWrite_ConfigFlag) { | |
| 1068 path = make_filename(writePath, gm->shortName(), gRec.fName, "", "xps"); | |
| 1069 errors.add(write_document(path, documentStream)); | |
| 1070 } | |
| 1071 | |
| 1072 bitmap = NULL; | |
| 1073 } else { | |
| 1074 SkASSERT(false); | |
| 1064 } | 1075 } |
| 1065 | 1076 return errors; |
| 1066 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream()); | |
|
vandebo (ex-Chrome)
2013/08/09 16:26:34
It looks like you can leave this block of code her
ducky
2013/08/09 23:29:41
Not really. The PDF case can now have multiple bit
vandebo (ex-Chrome)
2013/08/12 17:41:56
Hmm, I see. In that sense, different PDF renders
ducky
2013/08/12 21:57:09
I don't think it would roll into configs easily, e
| |
| 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 } | 1077 } |
| 1076 | 1078 |
| 1077 ErrorCombination test_deferred_drawing(GM* gm, | 1079 ErrorCombination test_deferred_drawing(GM* gm, |
| 1078 const ConfigData& gRec, | 1080 const ConfigData& gRec, |
| 1079 const SkBitmap& referenceBitmap, | 1081 const SkBitmap& referenceBitmap, |
| 1080 GrSurface* gpuTarget) { | 1082 GrSurface* gpuTarget) { |
| 1081 if (gRec.fBackend == kRaster_Backend || | 1083 if (gRec.fBackend == kRaster_Backend || |
| 1082 gRec.fBackend == kGPU_Backend) { | 1084 gRec.fBackend == kGPU_Backend) { |
| 1083 const char renderModeDescriptor[] = "-deferred"; | 1085 const char renderModeDescriptor[] = "-deferred"; |
| 1084 SkBitmap bitmap; | 1086 SkBitmap bitmap; |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1216 Json::Value fJsonActualResults_Succeeded; | 1218 Json::Value fJsonActualResults_Succeeded; |
| 1217 | 1219 |
| 1218 }; // end of GMMain class definition | 1220 }; // end of GMMain class definition |
| 1219 | 1221 |
| 1220 #if SK_SUPPORT_GPU | 1222 #if SK_SUPPORT_GPU |
| 1221 static const GLContextType kDontCare_GLContextType = GrContextFactory::kNative_G LContextType; | 1223 static const GLContextType kDontCare_GLContextType = GrContextFactory::kNative_G LContextType; |
| 1222 #else | 1224 #else |
| 1223 static const GLContextType kDontCare_GLContextType = 0; | 1225 static const GLContextType kDontCare_GLContextType = 0; |
| 1224 #endif | 1226 #endif |
| 1225 | 1227 |
| 1228 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_POPPLER) | |
| 1229 #define CAN_IMAGE_PDF 1 | |
| 1230 #else | |
| 1231 #define CAN_IMAGE_PDF 0 | |
| 1232 #endif | |
| 1226 // If the platform does not support writing PNGs of PDFs then there will be no | 1233 // 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 | 1234 // reference images to read. However, we can always write the .pdf files |
| 1228 static const ConfigFlags kPDFConfigFlags = CAN_IMAGE_PDF ? kRW_ConfigFlag : | 1235 static const ConfigFlags kPDFConfigFlags = CAN_IMAGE_PDF ? kRW_ConfigFlag : |
| 1229 kWrite_ConfigFlag; | 1236 kWrite_ConfigFlag; |
| 1230 | 1237 |
| 1231 static const ConfigData gRec[] = { | 1238 static const ConfigData gRec[] = { |
| 1232 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "8888", true }, | 1239 { 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!!!) | 1240 #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 }, | 1241 { SkBitmap::kARGB_4444_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "4444", true }, |
| 1235 #endif | 1242 #endif |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 1256 #endif // SK_SUPPORT_GPU | 1263 #endif // SK_SUPPORT_GPU |
| 1257 #ifdef SK_SUPPORT_XPS | 1264 #ifdef SK_SUPPORT_XPS |
| 1258 /* At present we have no way of comparing XPS files (either natively or by c onverting to PNG). */ | 1265 /* 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 }, | 1266 { SkBitmap::kARGB_8888_Config, kXPS_Backend, kDontCare_GLContextType, 0, kWrite_ConfigFlag, "xps", true }, |
| 1260 #endif // SK_SUPPORT_XPS | 1267 #endif // SK_SUPPORT_XPS |
| 1261 #ifdef SK_SUPPORT_PDF | 1268 #ifdef SK_SUPPORT_PDF |
| 1262 { SkBitmap::kARGB_8888_Config, kPDF_Backend, kDontCare_GLContextType, 0, kPDFConfigFlags, "pdf", true }, | 1269 { SkBitmap::kARGB_8888_Config, kPDF_Backend, kDontCare_GLContextType, 0, kPDFConfigFlags, "pdf", true }, |
| 1263 #endif // SK_SUPPORT_PDF | 1270 #endif // SK_SUPPORT_PDF |
| 1264 }; | 1271 }; |
| 1265 | 1272 |
| 1273 static const PDFRasterizerData kPDFRasterizers[] = { | |
| 1274 #ifdef SK_BUILD_FOR_MAC | |
| 1275 { &SkPDFDocumentToBitmap, "macnative", true }, | |
| 1276 #endif | |
| 1277 #ifdef SK_BUILD_POPPLER | |
| 1278 { &SkPopplerRasterizePDF, "poppler", true }, | |
| 1279 #endif | |
| 1280 }; | |
| 1281 | |
| 1266 static const char kDefaultsConfigStr[] = "defaults"; | 1282 static const char kDefaultsConfigStr[] = "defaults"; |
| 1267 static const char kExcludeConfigChar = '~'; | 1283 static const char kExcludeConfigChar = '~'; |
| 1268 | 1284 |
| 1269 static SkString configUsage() { | 1285 static SkString configUsage() { |
| 1270 SkString result; | 1286 SkString result; |
| 1271 result.appendf("Space delimited list of which configs to run. Possible optio ns: ["); | 1287 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) { | 1288 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { |
| 1273 SkASSERT(gRec[i].fName != kDefaultsConfigStr); | 1289 SkASSERT(gRec[i].fName != kDefaultsConfigStr); |
| 1274 if (i > 0) { | 1290 if (i > 0) { |
| 1275 result.append("|"); | 1291 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", | 1323 result.appendf("E.g. \"--config %s %c%s %s\" will run these configs:\n\t%s % s", |
| 1308 kDefaultsConfigStr, | 1324 kDefaultsConfigStr, |
| 1309 kExcludeConfigChar, | 1325 kExcludeConfigChar, |
| 1310 firstDefault.c_str(), | 1326 firstDefault.c_str(), |
| 1311 nonDefault.c_str(), | 1327 nonDefault.c_str(), |
| 1312 allButFirstDefaults.c_str(), | 1328 allButFirstDefaults.c_str(), |
| 1313 nonDefault.c_str()); | 1329 nonDefault.c_str()); |
| 1314 return result; | 1330 return result; |
| 1315 } | 1331 } |
| 1316 | 1332 |
| 1333 static SkString pdfRasterizerUsage() { | |
| 1334 SkString result; | |
| 1335 result.appendf("Space delimited list of which PDF rasterizers to run. Possib le options: ["); | |
| 1336 for (size_t i = 0; i < SK_ARRAY_COUNT(kPDFRasterizers); ++i) { | |
| 1337 if (i > 0) { | |
| 1338 result.append("|"); | |
| 1339 } | |
| 1340 result.append(kPDFRasterizers[i].fName); | |
| 1341 } | |
| 1342 result.append("]\n"); | |
| 1343 result.append("The default value is: \""); | |
| 1344 for (size_t i = 0; i < SK_ARRAY_COUNT(kPDFRasterizers); ++i) { | |
| 1345 if (kPDFRasterizers[i].fRunByDefault) { | |
| 1346 if (i > 0) { | |
| 1347 result.append(" "); | |
| 1348 } | |
| 1349 result.append(kPDFRasterizers[i].fName); | |
| 1350 } | |
| 1351 } | |
| 1352 result.append("\""); | |
| 1353 return result; | |
| 1354 } | |
| 1355 | |
| 1317 // Macro magic to convert a numeric preprocessor token into a string. | 1356 // 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 | 1357 // 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... | 1358 // This should probably be moved into one of our common headers... |
| 1320 #define TOSTRING_INTERNAL(x) #x | 1359 #define TOSTRING_INTERNAL(x) #x |
| 1321 #define TOSTRING(x) TOSTRING_INTERNAL(x) | 1360 #define TOSTRING(x) TOSTRING_INTERNAL(x) |
| 1322 | 1361 |
| 1323 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath"). | 1362 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath"). |
| 1324 DEFINE_string(config, "", configUsage().c_str()); | 1363 DEFINE_string(config, "", configUsage().c_str()); |
| 1364 DEFINE_string(pdfRasterizers, "", pdfRasterizerUsage().c_str()); | |
| 1325 DEFINE_bool(deferred, true, "Exercise the deferred rendering test pass."); | 1365 DEFINE_bool(deferred, true, "Exercise the deferred rendering test pass."); |
| 1326 DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip."); | 1366 DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip."); |
| 1327 DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing."); | 1367 DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing."); |
| 1328 #if SK_SUPPORT_GPU | 1368 #if SK_SUPPORT_GPU |
| 1329 DEFINE_string(gpuCacheSize, "", "<bytes> <count>: Limit the gpu cache to byte si ze or " | 1369 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 " | 1370 "object count. " TOSTRING(DEFAULT_CACHE_VALUE) " for either value means " |
| 1331 "use the default. 0 for either disables the cache."); | 1371 "use the default. 0 for either disables the cache."); |
| 1332 #endif | 1372 #endif |
| 1333 DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure " | 1373 DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure " |
| 1334 "when reading/writing files."); | 1374 "when reading/writing files."); |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1403 | 1443 |
| 1404 static int findConfig(const char config[]) { | 1444 static int findConfig(const char config[]) { |
| 1405 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) { | 1445 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) { |
| 1406 if (!strcmp(config, gRec[i].fName)) { | 1446 if (!strcmp(config, gRec[i].fName)) { |
| 1407 return (int) i; | 1447 return (int) i; |
| 1408 } | 1448 } |
| 1409 } | 1449 } |
| 1410 return -1; | 1450 return -1; |
| 1411 } | 1451 } |
| 1412 | 1452 |
| 1453 static const PDFRasterizerData* findPDFRasterizer(const char rasterizer[]) { | |
| 1454 for (size_t i = 0; i < SK_ARRAY_COUNT(kPDFRasterizers); i++) { | |
| 1455 if (!strcmp(rasterizer, kPDFRasterizers[i].fName)) { | |
| 1456 return &kPDFRasterizers[i]; | |
| 1457 } | |
| 1458 } | |
| 1459 return NULL; | |
| 1460 } | |
| 1461 | |
| 1413 namespace skiagm { | 1462 namespace skiagm { |
| 1414 #if SK_SUPPORT_GPU | 1463 #if SK_SUPPORT_GPU |
| 1415 SkAutoTUnref<GrContext> gGrContext; | 1464 SkAutoTUnref<GrContext> gGrContext; |
| 1416 /** | 1465 /** |
| 1417 * Sets the global GrContext, accessible by individual GMs | 1466 * Sets the global GrContext, accessible by individual GMs |
| 1418 */ | 1467 */ |
| 1419 static void SetGr(GrContext* grContext) { | 1468 static void SetGr(GrContext* grContext) { |
| 1420 SkSafeRef(grContext); | 1469 SkSafeRef(grContext); |
| 1421 gGrContext.reset(grContext); | 1470 gGrContext.reset(grContext); |
| 1422 } | 1471 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1459 } | 1508 } |
| 1460 } | 1509 } |
| 1461 | 1510 |
| 1462 /** | 1511 /** |
| 1463 * Run this test in a number of different configs (8888, 565, PDF, | 1512 * Run this test in a number of different configs (8888, 565, PDF, |
| 1464 * etc.), confirming that the resulting bitmaps match expectations | 1513 * etc.), confirming that the resulting bitmaps match expectations |
| 1465 * (which may be different for each config). | 1514 * (which may be different for each config). |
| 1466 * | 1515 * |
| 1467 * Returns all errors encountered while doing so. | 1516 * Returns all errors encountered while doing so. |
| 1468 */ | 1517 */ |
| 1469 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si ze_t> &configs, | 1518 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, |
| 1519 const SkTDArray<size_t> &configs, | |
| 1520 const SkTDArray<const PDFRasterizerData*> &pdfRasterizers, | |
| 1470 GrContextFactory *grFactory); | 1521 GrContextFactory *grFactory); |
| 1471 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si ze_t> &configs, | 1522 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, |
| 1523 const SkTDArray<size_t> &configs, | |
| 1524 const SkTDArray<const PDFRasterizerData*> &pdfRasterizers, | |
| 1472 GrContextFactory *grFactory) { | 1525 GrContextFactory *grFactory) { |
| 1473 const char renderModeDescriptor[] = ""; | 1526 const char renderModeDescriptor[] = ""; |
| 1474 ErrorCombination errorsForAllConfigs; | 1527 ErrorCombination errorsForAllConfigs; |
| 1475 uint32_t gmFlags = gm->getFlags(); | 1528 uint32_t gmFlags = gm->getFlags(); |
| 1476 | 1529 |
| 1477 for (int i = 0; i < configs.count(); i++) { | 1530 for (int i = 0; i < configs.count(); i++) { |
| 1478 ConfigData config = gRec[configs[i]]; | 1531 ConfigData config = gRec[configs[i]]; |
| 1479 const SkString shortNamePlusConfig = gmmain.make_shortname_plus_config(g m->shortName(), | 1532 const SkString shortNamePlusConfig = gmmain.make_shortname_plus_config(g m->shortName(), |
| 1480 c onfig.fName); | 1533 c onfig.fName); |
| 1481 | 1534 |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1552 #endif | 1605 #endif |
| 1553 | 1606 |
| 1554 SkBitmap comparisonBitmap; | 1607 SkBitmap comparisonBitmap; |
| 1555 | 1608 |
| 1556 const char* writePath; | 1609 const char* writePath; |
| 1557 if (FLAGS_writePath.count() == 1) { | 1610 if (FLAGS_writePath.count() == 1) { |
| 1558 writePath = FLAGS_writePath[0]; | 1611 writePath = FLAGS_writePath[0]; |
| 1559 } else { | 1612 } else { |
| 1560 writePath = NULL; | 1613 writePath = NULL; |
| 1561 } | 1614 } |
| 1615 | |
| 1562 if (errorsForThisConfig.isEmpty()) { | 1616 if (errorsForThisConfig.isEmpty()) { |
| 1563 errorsForThisConfig.add(gmmain.test_drawing(gm,config, writePath, gp uTarget, | 1617 errorsForThisConfig.add(gmmain.test_drawing(gm, config, pdfRasterize rs, |
| 1618 writePath, gpuTarget, | |
| 1564 &comparisonBitmap)); | 1619 &comparisonBitmap)); |
| 1620 gmmain.RecordTestResults(errorsForThisConfig, shortNamePlusConfig, " "); | |
| 1565 } | 1621 } |
| 1566 | 1622 |
| 1567 if (FLAGS_deferred && errorsForThisConfig.isEmpty() && | 1623 if (FLAGS_deferred && errorsForThisConfig.isEmpty() && |
| 1568 (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBacke nd)) { | 1624 (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBacke nd)) { |
| 1569 errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, com parisonBitmap, | 1625 errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, com parisonBitmap, |
| 1570 gpuTarget)); | 1626 gpuTarget)); |
| 1571 } | 1627 } |
| 1572 | 1628 |
| 1573 errorsForAllConfigs.add(errorsForThisConfig); | 1629 errorsForAllConfigs.add(errorsForThisConfig); |
| 1574 } | 1630 } |
| (...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1760 SkString subdir; | 1816 SkString subdir; |
| 1761 subdir.appendf("%s%c%s", root, SkPATH_SEPARATOR, config.fName); | 1817 subdir.appendf("%s%c%s", root, SkPATH_SEPARATOR, config.fName); |
| 1762 if (!sk_mkdir(subdir.c_str())) { | 1818 if (!sk_mkdir(subdir.c_str())) { |
| 1763 return false; | 1819 return false; |
| 1764 } | 1820 } |
| 1765 } | 1821 } |
| 1766 } | 1822 } |
| 1767 return true; | 1823 return true; |
| 1768 } | 1824 } |
| 1769 | 1825 |
| 1770 int tool_main(int argc, char** argv); | 1826 static bool parse_flags_configs(SkTDArray<size_t>* outConfigs, |
| 1771 int tool_main(int argc, char** argv) { | 1827 GrContextFactory* grFactory) { |
| 1772 | |
| 1773 #if SK_ENABLE_INST_COUNT | |
| 1774 gPrintInstCount = true; | |
| 1775 #endif | |
| 1776 | |
| 1777 SkGraphics::Init(); | |
| 1778 // we don't need to see this during a run | |
| 1779 gSkSuppressFontCachePurgeSpew = true; | |
| 1780 | |
| 1781 setSystemPreferences(); | |
| 1782 GMMain gmmain; | |
| 1783 | |
| 1784 SkTDArray<size_t> configs; | |
| 1785 SkTDArray<size_t> excludeConfigs; | 1828 SkTDArray<size_t> excludeConfigs; |
| 1786 bool userConfig = false; | |
| 1787 | |
| 1788 SkString usage; | |
| 1789 usage.printf("Run the golden master tests.\n"); | |
| 1790 SkCommandLineFlags::SetUsage(usage.c_str()); | |
| 1791 SkCommandLineFlags::Parse(argc, argv); | |
| 1792 | |
| 1793 gmmain.fUseFileHierarchy = FLAGS_hierarchy; | |
| 1794 gmmain.fWriteChecksumBasedFilenames = FLAGS_writeChecksumBasedFilenames; | |
| 1795 if (FLAGS_mismatchPath.count() == 1) { | |
| 1796 gmmain.fMismatchPath = FLAGS_mismatchPath[0]; | |
| 1797 } | |
| 1798 if (FLAGS_missingExpectationsPath.count() == 1) { | |
| 1799 gmmain.fMissingExpectationsPath = FLAGS_missingExpectationsPath[0]; | |
| 1800 } | |
| 1801 | 1829 |
| 1802 for (int i = 0; i < FLAGS_config.count(); i++) { | 1830 for (int i = 0; i < FLAGS_config.count(); i++) { |
| 1803 const char* config = FLAGS_config[i]; | 1831 const char* config = FLAGS_config[i]; |
| 1804 userConfig = true; | |
| 1805 bool exclude = false; | 1832 bool exclude = false; |
| 1806 if (*config == kExcludeConfigChar) { | 1833 if (*config == kExcludeConfigChar) { |
| 1807 exclude = true; | 1834 exclude = true; |
| 1808 config += 1; | 1835 config += 1; |
| 1809 } | 1836 } |
| 1810 int index = findConfig(config); | 1837 int index = findConfig(config); |
| 1811 if (index >= 0) { | 1838 if (index >= 0) { |
| 1812 if (exclude) { | 1839 if (exclude) { |
| 1813 *excludeConfigs.append() = index; | 1840 *excludeConfigs.append() = index; |
| 1814 } else { | 1841 } else { |
| 1815 appendUnique<size_t>(&configs, index); | 1842 appendUnique<size_t>(outConfigs, index); |
| 1816 } | 1843 } |
| 1817 } else if (0 == strcmp(kDefaultsConfigStr, config)) { | 1844 } else if (0 == strcmp(kDefaultsConfigStr, config)) { |
| 1845 if (exclude) { | |
| 1846 gm_fprintf(stderr, "%c%s is not allowed.\n", | |
| 1847 kExcludeConfigChar, kDefaultsConfigStr); | |
| 1848 return false; | |
| 1849 } | |
| 1818 for (size_t c = 0; c < SK_ARRAY_COUNT(gRec); ++c) { | 1850 for (size_t c = 0; c < SK_ARRAY_COUNT(gRec); ++c) { |
| 1819 if (gRec[c].fRunByDefault) { | 1851 if (gRec[c].fRunByDefault) { |
| 1820 if (exclude) { | 1852 appendUnique<size_t>(outConfigs, c); |
| 1821 gm_fprintf(stderr, "%c%s is not allowed.\n", | |
| 1822 kExcludeConfigChar, kDefaultsConfigStr); | |
| 1823 return -1; | |
| 1824 } else { | |
| 1825 appendUnique<size_t>(&configs, c); | |
| 1826 } | |
| 1827 } | 1853 } |
| 1828 } | 1854 } |
| 1829 } else { | 1855 } else { |
| 1830 gm_fprintf(stderr, "unrecognized config %s\n", config); | 1856 gm_fprintf(stderr, "unrecognized config %s\n", config); |
| 1831 return -1; | 1857 return false; |
| 1832 } | 1858 } |
| 1833 } | 1859 } |
| 1834 | 1860 |
| 1835 for (int i = 0; i < FLAGS_excludeConfig.count(); i++) { | 1861 for (int i = 0; i < FLAGS_excludeConfig.count(); i++) { |
| 1836 int index = findConfig(FLAGS_excludeConfig[i]); | 1862 int index = findConfig(FLAGS_excludeConfig[i]); |
| 1837 if (index >= 0) { | 1863 if (index >= 0) { |
| 1838 *excludeConfigs.append() = index; | 1864 *excludeConfigs.append() = index; |
| 1839 } else { | 1865 } else { |
| 1840 gm_fprintf(stderr, "unrecognized excludeConfig %s\n", FLAGS_excludeC onfig[i]); | 1866 gm_fprintf(stderr, "unrecognized excludeConfig %s\n", FLAGS_excludeC onfig[i]); |
| 1841 return -1; | 1867 return false; |
| 1842 } | 1868 } |
| 1843 } | 1869 } |
| 1844 | 1870 |
| 1845 int moduloRemainder = -1; | 1871 if (outConfigs->count() == 0) { |
| 1846 int moduloDivisor = -1; | 1872 // if no config is specified by user, add the defaults |
| 1847 | 1873 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { |
| 1848 if (FLAGS_modulo.count() == 2) { | 1874 if (gRec[i].fRunByDefault) { |
| 1849 moduloRemainder = atoi(FLAGS_modulo[0]); | 1875 *outConfigs->append() = i; |
| 1850 moduloDivisor = atoi(FLAGS_modulo[1]); | 1876 } |
| 1851 if (moduloRemainder < 0 || moduloDivisor <= 0 || moduloRemainder >= modu loDivisor) { | 1877 } |
| 1852 gm_fprintf(stderr, "invalid modulo values."); | 1878 } |
| 1853 return -1; | 1879 // now remove any explicitly excluded configs |
| 1854 } | 1880 for (int i = 0; i < excludeConfigs.count(); ++i) { |
| 1855 } | 1881 int index = outConfigs->find(excludeConfigs[i]); |
| 1856 | 1882 if (index >= 0) { |
| 1883 outConfigs->remove(index); | |
| 1884 // now assert that there was only one copy in configs[] | |
| 1885 SkASSERT(outConfigs->find(excludeConfigs[i]) < 0); | |
| 1886 } | |
| 1887 } | |
| 1888 | |
| 1889 #if SK_SUPPORT_GPU | |
| 1890 SkASSERT(grFactory != NULL); | |
| 1891 for (int i = 0; i < outConfigs->count(); ++i) { | |
| 1892 size_t index = (*outConfigs)[i]; | |
| 1893 if (kGPU_Backend == gRec[index].fBackend) { | |
| 1894 GrContext* ctx = grFactory->get(gRec[index].fGLContextType); | |
| 1895 if (NULL == ctx) { | |
| 1896 gm_fprintf(stderr, "GrContext could not be created for config %s ." | |
| 1897 " Config will be skipped.\n", gRec[index].fName); | |
| 1898 outConfigs->remove(i); | |
| 1899 --i; | |
| 1900 continue; | |
| 1901 } | |
| 1902 if (gRec[index].fSampleCnt > ctx->getMaxSampleCount()) { | |
| 1903 gm_fprintf(stderr, "Sample count (%d) of config %s is not suppor ted." | |
| 1904 " Config will be skipped.\n", | |
| 1905 gRec[index].fSampleCnt, gRec[index].fName); | |
| 1906 outConfigs->remove(i); | |
| 1907 --i; | |
| 1908 } | |
| 1909 } | |
| 1910 } | |
| 1911 #endif | |
| 1912 | |
| 1913 if (outConfigs->isEmpty()) { | |
| 1914 gm_fprintf(stderr, "No configs to run."); | |
| 1915 return false; | |
| 1916 } | |
| 1917 | |
| 1918 // now show the user the set of configs that will be run. | |
| 1919 SkString configStr("These configs will be run: "); | |
| 1920 // show the user the config that will run. | |
| 1921 for (int i = 0; i < outConfigs->count(); ++i) { | |
| 1922 configStr.appendf("%s ", gRec[(*outConfigs)[i]].fName); | |
| 1923 } | |
| 1924 gm_fprintf(stdout, "%s\n", configStr.c_str()); | |
| 1925 | |
| 1926 return true; | |
| 1927 } | |
| 1928 | |
| 1929 static bool parse_flags_pdf_rasterizers(SkTDArray<const PDFRasterizerData*>* out Rasterizers) { | |
| 1930 for (int i = 0; i < FLAGS_pdfRasterizers.count(); i++) { | |
| 1931 const char* rasterizer = FLAGS_pdfRasterizers[i]; | |
| 1932 const PDFRasterizerData* rasterizerPtr = findPDFRasterizer(rasterizer); | |
| 1933 | |
| 1934 if (rasterizer != NULL) { | |
| 1935 appendUnique<const PDFRasterizerData*>(outRasterizers, | |
| 1936 rasterizerPtr); | |
| 1937 } else { | |
| 1938 gm_fprintf(stderr, "unrecognized rasterizer %s\n", rasterizer); | |
| 1939 return false; | |
| 1940 } | |
| 1941 } | |
| 1942 | |
| 1943 if (outRasterizers->count() == 0) { | |
| 1944 // if no config is specified by user, add the defaults | |
| 1945 for (size_t i = 0; i < SK_ARRAY_COUNT(kPDFRasterizers); ++i) { | |
| 1946 if (kPDFRasterizers[i].fRunByDefault) { | |
| 1947 *outRasterizers->append() = &kPDFRasterizers[i]; | |
| 1948 } | |
| 1949 } | |
| 1950 } | |
| 1951 | |
| 1952 // now show the user the set of configs that will be run. | |
| 1953 SkString configStr("These PDF rasterizers will be run: "); | |
| 1954 // show the user the config that will run. | |
| 1955 for (int i = 0; i < outRasterizers->count(); ++i) { | |
| 1956 configStr.appendf("%s ", (*outRasterizers)[i]->fName); | |
| 1957 } | |
| 1958 gm_fprintf(stdout, "%s\n", configStr.c_str()); | |
| 1959 | |
| 1960 return true; | |
| 1961 } | |
| 1962 | |
| 1963 static bool parse_flags_ignore_error_types(ErrorCombination* outErrorTypes) { | |
| 1857 if (FLAGS_ignoreErrorTypes.count() > 0) { | 1964 if (FLAGS_ignoreErrorTypes.count() > 0) { |
| 1858 gmmain.fIgnorableErrorTypes = ErrorCombination(); | 1965 *outErrorTypes = ErrorCombination(); |
| 1859 for (int i = 0; i < FLAGS_ignoreErrorTypes.count(); i++) { | 1966 for (int i = 0; i < FLAGS_ignoreErrorTypes.count(); i++) { |
| 1860 ErrorType type; | 1967 ErrorType type; |
| 1861 const char *name = FLAGS_ignoreErrorTypes[i]; | 1968 const char *name = FLAGS_ignoreErrorTypes[i]; |
| 1862 if (!getErrorTypeByName(name, &type)) { | 1969 if (!getErrorTypeByName(name, &type)) { |
| 1863 gm_fprintf(stderr, "cannot find ErrorType with name '%s'\n", nam e); | 1970 gm_fprintf(stderr, "cannot find ErrorType with name '%s'\n", nam e); |
| 1864 return -1; | 1971 return false; |
| 1865 } else { | 1972 } else { |
| 1866 gmmain.fIgnorableErrorTypes.add(type); | 1973 outErrorTypes->add(type); |
| 1867 } | 1974 } |
| 1868 } | 1975 } |
| 1869 } | 1976 } |
| 1870 | 1977 return true; |
| 1871 #if SK_SUPPORT_GPU | 1978 } |
| 1979 | |
| 1980 static bool parse_flags_modulo(int* moduloRemainder, int* moduloDivisor) { | |
| 1981 if (FLAGS_modulo.count() == 2) { | |
| 1982 *moduloRemainder = atoi(FLAGS_modulo[0]); | |
| 1983 *moduloDivisor = atoi(FLAGS_modulo[1]); | |
| 1984 if (*moduloRemainder < 0 || *moduloDivisor <= 0 || | |
| 1985 *moduloRemainder >= *moduloDivisor) { | |
| 1986 gm_fprintf(stderr, "invalid modulo values."); | |
| 1987 return false; | |
| 1988 } | |
| 1989 } | |
| 1990 return true; | |
| 1991 } | |
| 1992 | |
| 1993 #if SK_SUPPORT_GPU | |
| 1994 static bool parse_flags_gpu_cache(int* sizeBytes, int* sizeCount) { | |
| 1872 if (FLAGS_gpuCacheSize.count() > 0) { | 1995 if (FLAGS_gpuCacheSize.count() > 0) { |
| 1873 if (FLAGS_gpuCacheSize.count() != 2) { | 1996 if (FLAGS_gpuCacheSize.count() != 2) { |
| 1874 gm_fprintf(stderr, "--gpuCacheSize requires two arguments\n"); | 1997 gm_fprintf(stderr, "--gpuCacheSize requires two arguments\n"); |
| 1875 return -1; | 1998 return false; |
| 1876 } | 1999 } |
| 1877 gGpuCacheSizeBytes = atoi(FLAGS_gpuCacheSize[0]); | 2000 *sizeBytes = atoi(FLAGS_gpuCacheSize[0]); |
| 1878 gGpuCacheSizeCount = atoi(FLAGS_gpuCacheSize[1]); | 2001 *sizeCount = atoi(FLAGS_gpuCacheSize[1]); |
| 1879 } else { | 2002 } else { |
| 1880 gGpuCacheSizeBytes = DEFAULT_CACHE_VALUE; | 2003 *sizeBytes = DEFAULT_CACHE_VALUE; |
| 1881 gGpuCacheSizeCount = DEFAULT_CACHE_VALUE; | 2004 *sizeCount = DEFAULT_CACHE_VALUE; |
| 1882 } | 2005 } |
| 1883 #endif | 2006 return true; |
| 1884 | 2007 } |
| 1885 SkTDArray<SkScalar> tileGridReplayScales; | 2008 #endif |
| 1886 *tileGridReplayScales.append() = SK_Scalar1; // By default only test at scal e 1.0 | 2009 |
| 2010 static bool parse_flags_tile_grid_replay_scales(SkTDArray<SkScalar>* outScales) { | |
| 2011 *outScales->append() = SK_Scalar1; // By default only test at scale 1.0 | |
| 1887 if (FLAGS_tileGridReplayScales.count() > 0) { | 2012 if (FLAGS_tileGridReplayScales.count() > 0) { |
| 1888 tileGridReplayScales.reset(); | 2013 outScales->reset(); |
| 1889 for (int i = 0; i < FLAGS_tileGridReplayScales.count(); i++) { | 2014 for (int i = 0; i < FLAGS_tileGridReplayScales.count(); i++) { |
| 1890 double val = atof(FLAGS_tileGridReplayScales[i]); | 2015 double val = atof(FLAGS_tileGridReplayScales[i]); |
| 1891 if (0 < val) { | 2016 if (0 < val) { |
| 1892 *tileGridReplayScales.append() = SkDoubleToScalar(val); | 2017 *outScales->append() = SkDoubleToScalar(val); |
| 1893 } | 2018 } |
| 1894 } | 2019 } |
| 1895 if (0 == tileGridReplayScales.count()) { | 2020 if (0 == outScales->count()) { |
| 1896 // Should have at least one scale | 2021 // Should have at least one scale |
| 1897 gm_fprintf(stderr, "--tileGridReplayScales requires at least one sca le.\n"); | 2022 gm_fprintf(stderr, "--tileGridReplayScales requires at least one sca le.\n"); |
| 1898 return -1; | 2023 return false; |
| 1899 } | 2024 } |
| 1900 } | 2025 } |
| 1901 | 2026 return true; |
| 1902 if (!userConfig) { | 2027 } |
| 1903 // if no config is specified by user, add the defaults | 2028 |
| 1904 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | 2029 static bool parse_flags_gmmain_paths(GMMain* gmmain) { |
| 1905 if (gRec[i].fRunByDefault) { | 2030 gmmain->fUseFileHierarchy = FLAGS_hierarchy; |
| 1906 *configs.append() = i; | 2031 gmmain->fWriteChecksumBasedFilenames = FLAGS_writeChecksumBasedFilenames; |
| 1907 } | 2032 |
| 1908 } | 2033 if (FLAGS_mismatchPath.count() == 1) { |
| 1909 } | 2034 gmmain->fMismatchPath = FLAGS_mismatchPath[0]; |
| 1910 // now remove any explicitly excluded configs | 2035 } |
| 1911 for (int i = 0; i < excludeConfigs.count(); ++i) { | 2036 |
| 1912 int index = configs.find(excludeConfigs[i]); | 2037 if (FLAGS_missingExpectationsPath.count() == 1) { |
| 1913 if (index >= 0) { | 2038 gmmain->fMissingExpectationsPath = FLAGS_missingExpectationsPath[0]; |
| 1914 configs.remove(index); | |
| 1915 // now assert that there was only one copy in configs[] | |
| 1916 SkASSERT(configs.find(excludeConfigs[i]) < 0); | |
| 1917 } | |
| 1918 } | |
| 1919 | |
| 1920 #if SK_SUPPORT_GPU | |
| 1921 GrContextFactory* grFactory = new GrContextFactory; | |
| 1922 for (int i = 0; i < configs.count(); ++i) { | |
| 1923 size_t index = configs[i]; | |
| 1924 if (kGPU_Backend == gRec[index].fBackend) { | |
| 1925 GrContext* ctx = grFactory->get(gRec[index].fGLContextType); | |
| 1926 if (NULL == ctx) { | |
| 1927 gm_fprintf(stderr, "GrContext could not be created for config %s ." | |
| 1928 " Config will be skipped.\n", gRec[index].fName); | |
| 1929 configs.remove(i); | |
| 1930 --i; | |
| 1931 continue; | |
| 1932 } | |
| 1933 if (gRec[index].fSampleCnt > ctx->getMaxSampleCount()) { | |
| 1934 gm_fprintf(stderr, "Sample count (%d) of config %s is not suppor ted." | |
| 1935 " Config will be skipped.\n", gRec[index].fSampleCnt, gRec[index].fName); | |
| 1936 configs.remove(i); | |
| 1937 --i; | |
| 1938 } | |
| 1939 } | |
| 1940 } | |
| 1941 #else | |
| 1942 GrContextFactory* grFactory = NULL; | |
| 1943 #endif | |
| 1944 | |
| 1945 if (configs.isEmpty()) { | |
| 1946 gm_fprintf(stderr, "No configs to run."); | |
| 1947 return -1; | |
| 1948 } | |
| 1949 | |
| 1950 // now show the user the set of configs that will be run. | |
| 1951 SkString configStr("These configs will be run: "); | |
| 1952 // show the user the config that will run. | |
| 1953 for (int i = 0; i < configs.count(); ++i) { | |
| 1954 configStr.appendf("%s%s", gRec[configs[i]].fName, (i == configs.count() - 1) ? "\n" : " "); | |
| 1955 } | |
| 1956 gm_fprintf(stdout, "%s", configStr.c_str()); | |
| 1957 | |
| 1958 if (FLAGS_resourcePath.count() == 1) { | |
| 1959 GM::SetResourcePath(FLAGS_resourcePath[0]); | |
| 1960 } | 2039 } |
| 1961 | 2040 |
| 1962 if (FLAGS_readPath.count() == 1) { | 2041 if (FLAGS_readPath.count() == 1) { |
| 1963 const char* readPath = FLAGS_readPath[0]; | 2042 const char* readPath = FLAGS_readPath[0]; |
| 1964 if (!sk_exists(readPath)) { | 2043 if (!sk_exists(readPath)) { |
| 1965 gm_fprintf(stderr, "readPath %s does not exist!\n", readPath); | 2044 gm_fprintf(stderr, "readPath %s does not exist!\n", readPath); |
| 1966 return -1; | 2045 return false; |
| 1967 } | 2046 } |
| 1968 if (sk_isdir(readPath)) { | 2047 if (sk_isdir(readPath)) { |
| 1969 if (FLAGS_verbose) { | 2048 if (FLAGS_verbose) { |
| 1970 gm_fprintf(stdout, "reading from %s\n", readPath); | 2049 gm_fprintf(stdout, "reading from %s\n", readPath); |
| 1971 } | 2050 } |
| 1972 gmmain.fExpectationsSource.reset(SkNEW_ARGS( | 2051 gmmain->fExpectationsSource.reset(SkNEW_ARGS( |
| 1973 IndividualImageExpectationsSource, (readPath))); | 2052 IndividualImageExpectationsSource, (readPath))); |
| 1974 } else { | 2053 } else { |
| 1975 if (FLAGS_verbose) { | 2054 if (FLAGS_verbose) { |
| 1976 gm_fprintf(stdout, "reading expectations from JSON summary file %s\n", readPath); | 2055 gm_fprintf(stdout, "reading expectations from JSON summary file %s\n", readPath); |
| 1977 } | 2056 } |
| 1978 gmmain.fExpectationsSource.reset(SkNEW_ARGS( | 2057 gmmain->fExpectationsSource.reset(SkNEW_ARGS(JsonExpectationsSource, (readPath))); |
| 1979 JsonExpectationsSource, (readPath))); | 2058 } |
| 1980 } | 2059 } |
| 1981 } | 2060 return true; |
| 2061 } | |
| 2062 | |
| 2063 static bool parse_flags_match_strs(SkTDArray<const char*>* matchStrs) { | |
| 2064 for (int i = 0; i < FLAGS_match.count(); ++i) { | |
| 2065 matchStrs->push(FLAGS_match[i]); | |
| 2066 } | |
| 2067 return true; | |
| 2068 } | |
| 2069 | |
| 2070 static bool parse_flags_resource_path() { | |
| 2071 if (FLAGS_resourcePath.count() == 1) { | |
| 2072 GM::SetResourcePath(FLAGS_resourcePath[0]); | |
| 2073 } | |
| 2074 return true; | |
| 2075 } | |
| 2076 | |
| 2077 static bool parse_flags_jpeg_quality() { | |
| 2078 if (FLAGS_pdfJpegQuality < -1 || FLAGS_pdfJpegQuality > 100) { | |
| 2079 gm_fprintf(stderr, "%s\n", "pdfJpegQuality must be in [-1 .. 100] range. "); | |
| 2080 return false; | |
| 2081 } | |
| 2082 return true; | |
| 2083 } | |
| 2084 | |
| 2085 int tool_main(int argc, char** argv); | |
| 2086 int tool_main(int argc, char** argv) { | |
| 2087 | |
| 2088 #if SK_ENABLE_INST_COUNT | |
| 2089 gPrintInstCount = true; | |
| 2090 #endif | |
| 2091 | |
| 2092 SkGraphics::Init(); | |
| 2093 // we don't need to see this during a run | |
| 2094 gSkSuppressFontCachePurgeSpew = true; | |
| 2095 | |
| 2096 setSystemPreferences(); | |
| 2097 GMMain gmmain; | |
| 2098 | |
| 2099 SkString usage; | |
| 2100 usage.printf("Run the golden master tests.\n"); | |
| 2101 SkCommandLineFlags::SetUsage(usage.c_str()); | |
| 2102 SkCommandLineFlags::Parse(argc, argv); | |
| 2103 | |
| 2104 SkTDArray<size_t> configs; | |
| 2105 | |
| 2106 int moduloRemainder = -1; | |
| 2107 int moduloDivisor = -1; | |
| 2108 SkTDArray<const PDFRasterizerData*> pdfRasterizers; | |
| 2109 SkTDArray<SkScalar> tileGridReplayScales; | |
| 2110 #if SK_SUPPORT_GPU | |
| 2111 GrContextFactory* grFactory = new GrContextFactory; | |
| 2112 #else | |
| 2113 GrContextFactory* grFactory = NULL; | |
| 2114 #endif | |
| 2115 SkTDArray<const char*> matchStrs; | |
| 2116 | |
| 2117 if (!parse_flags_modulo(&moduloRemainder, &moduloDivisor) || | |
|
vandebo (ex-Chrome)
2013/08/09 16:26:34
It looks like your flags refactor has leaked into
ducky
2013/08/09 23:29:41
Looks like I set the wrong cl upload base...
| |
| 2118 !parse_flags_ignore_error_types(&gmmain.fIgnorableErrorTypes) || | |
| 2119 #if SK_SUPPORT_GPU | |
| 2120 !parse_flags_gpu_cache(&gGpuCacheSizeBytes, &gGpuCacheSizeCount) || | |
| 2121 #endif | |
| 2122 !parse_flags_tile_grid_replay_scales(&tileGridReplayScales) || | |
| 2123 !parse_flags_gmmain_paths(&gmmain) || | |
| 2124 !parse_flags_resource_path() || | |
| 2125 !parse_flags_match_strs(&matchStrs) || | |
| 2126 !parse_flags_jpeg_quality() || | |
| 2127 !parse_flags_configs(&configs, grFactory) || | |
| 2128 !parse_flags_pdf_rasterizers(&pdfRasterizers)) { | |
| 2129 return -1; | |
| 2130 } | |
| 2131 | |
| 1982 if (FLAGS_verbose) { | 2132 if (FLAGS_verbose) { |
| 1983 if (FLAGS_writePath.count() == 1) { | 2133 if (FLAGS_writePath.count() == 1) { |
| 1984 gm_fprintf(stdout, "writing to %s\n", FLAGS_writePath[0]); | 2134 gm_fprintf(stdout, "writing to %s\n", FLAGS_writePath[0]); |
| 1985 } | 2135 } |
| 1986 if (NULL != gmmain.fMismatchPath) { | 2136 if (NULL != gmmain.fMismatchPath) { |
| 1987 gm_fprintf(stdout, "writing mismatches to %s\n", gmmain.fMismatchPat h); | 2137 gm_fprintf(stdout, "writing mismatches to %s\n", gmmain.fMismatchPat h); |
| 1988 } | 2138 } |
| 1989 if (NULL != gmmain.fMissingExpectationsPath) { | 2139 if (NULL != gmmain.fMissingExpectationsPath) { |
| 1990 gm_fprintf(stdout, "writing images without expectations to %s\n", | 2140 gm_fprintf(stdout, "writing images without expectations to %s\n", |
| 1991 gmmain.fMissingExpectationsPath); | 2141 gmmain.fMissingExpectationsPath); |
| 1992 } | 2142 } |
| 1993 if (FLAGS_writePicturePath.count() == 1) { | 2143 if (FLAGS_writePicturePath.count() == 1) { |
| 1994 gm_fprintf(stdout, "writing pictures to %s\n", FLAGS_writePicturePat h[0]); | 2144 gm_fprintf(stdout, "writing pictures to %s\n", FLAGS_writePicturePat h[0]); |
| 1995 } | 2145 } |
| 1996 if (FLAGS_resourcePath.count() == 1) { | 2146 if (FLAGS_resourcePath.count() == 1) { |
| 1997 gm_fprintf(stdout, "reading resources from %s\n", FLAGS_resourcePath [0]); | 2147 gm_fprintf(stdout, "reading resources from %s\n", FLAGS_resourcePath [0]); |
| 1998 } | 2148 } |
| 1999 } | 2149 } |
| 2000 | 2150 |
| 2001 if (moduloDivisor <= 0) { | |
| 2002 moduloRemainder = -1; | |
| 2003 } | |
| 2004 if (moduloRemainder < 0 || moduloRemainder >= moduloDivisor) { | |
| 2005 moduloRemainder = -1; | |
| 2006 } | |
| 2007 | |
| 2008 int gmsRun = 0; | 2151 int gmsRun = 0; |
| 2009 int gmIndex = -1; | 2152 int gmIndex = -1; |
| 2010 SkString moduloStr; | 2153 SkString moduloStr; |
| 2011 | 2154 |
| 2012 // If we will be writing out files, prepare subdirectories. | 2155 // If we will be writing out files, prepare subdirectories. |
| 2013 if (FLAGS_writePath.count() == 1) { | 2156 if (FLAGS_writePath.count() == 1) { |
| 2014 if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy , configs)) { | 2157 if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy , configs)) { |
| 2015 return -1; | 2158 return -1; |
| 2016 } | 2159 } |
| 2017 } | 2160 } |
| 2018 if (NULL != gmmain.fMismatchPath) { | 2161 if (NULL != gmmain.fMismatchPath) { |
| 2019 if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarc hy, configs)) { | 2162 if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarc hy, configs)) { |
| 2020 return -1; | 2163 return -1; |
| 2021 } | 2164 } |
| 2022 } | 2165 } |
| 2023 if (NULL != gmmain.fMissingExpectationsPath) { | 2166 if (NULL != gmmain.fMissingExpectationsPath) { |
| 2024 if (!prepare_subdirectories(gmmain.fMissingExpectationsPath, gmmain.fUse FileHierarchy, | 2167 if (!prepare_subdirectories(gmmain.fMissingExpectationsPath, gmmain.fUse FileHierarchy, |
| 2025 configs)) { | 2168 configs)) { |
| 2026 return -1; | 2169 return -1; |
| 2027 } | 2170 } |
| 2028 } | 2171 } |
| 2029 | 2172 |
| 2030 if (FLAGS_pdfJpegQuality < -1 || FLAGS_pdfJpegQuality > 100) { | |
| 2031 gm_fprintf(stderr, "%s\n", "pdfJpegQuality must be in [-1 .. 100] range. "); | |
| 2032 } | |
| 2033 | |
| 2034 Iter iter; | 2173 Iter iter; |
| 2035 GM* gm; | 2174 GM* gm; |
| 2036 while ((gm = iter.next()) != NULL) { | 2175 while ((gm = iter.next()) != NULL) { |
| 2037 SkAutoTDelete<GM> adgm(gm); | 2176 SkAutoTDelete<GM> adgm(gm); |
| 2038 ++gmIndex; | 2177 ++gmIndex; |
| 2039 if (moduloRemainder >= 0) { | 2178 if (moduloRemainder >= 0) { |
| 2040 if ((gmIndex % moduloDivisor) != moduloRemainder) { | 2179 if ((gmIndex % moduloDivisor) != moduloRemainder) { |
| 2041 continue; | 2180 continue; |
| 2042 } | 2181 } |
| 2043 moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor); | 2182 moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor); |
| 2044 } | 2183 } |
| 2045 | 2184 |
| 2046 const char* shortName = gm->shortName(); | 2185 const char* shortName = gm->shortName(); |
| 2047 | 2186 |
| 2048 SkTDArray<const char*> matchStrs; | |
| 2049 for (int i = 0; i < FLAGS_match.count(); ++i) { | |
| 2050 matchStrs.push(FLAGS_match[i]); | |
| 2051 } | |
| 2052 if (SkCommandLineFlags::ShouldSkip(matchStrs, shortName)) { | 2187 if (SkCommandLineFlags::ShouldSkip(matchStrs, shortName)) { |
| 2053 continue; | 2188 continue; |
| 2054 } | 2189 } |
| 2055 | 2190 |
| 2056 gmsRun++; | 2191 gmsRun++; |
| 2057 SkISize size = gm->getISize(); | 2192 SkISize size = gm->getISize(); |
| 2058 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short Name, | 2193 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short Name, |
| 2059 size.width(), size.height()); | 2194 size.width(), size.height()); |
| 2060 | 2195 |
| 2061 run_multiple_configs(gmmain, gm, configs, grFactory); | 2196 run_multiple_configs(gmmain, gm, configs, pdfRasterizers, grFactory); |
| 2062 | 2197 |
| 2063 SkBitmap comparisonBitmap; | 2198 SkBitmap comparisonBitmap; |
| 2064 const ConfigData compareConfig = | 2199 const ConfigData compareConfig = |
| 2065 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT ype, 0, kRW_ConfigFlag, "comparison", false }; | 2200 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT ype, 0, kRW_ConfigFlag, "comparison", false }; |
| 2066 gmmain.generate_image(gm, compareConfig, NULL, &comparisonBitmap, false) ; | 2201 gmmain.generate_image(gm, compareConfig, NULL, &comparisonBitmap, false) ; |
| 2067 | 2202 |
| 2068 // TODO(epoger): only run this if gmmain.generate_image() succeeded? | 2203 // TODO(epoger): only run this if gmmain.generate_image() succeeded? |
| 2069 // Otherwise, what are we comparing against? | 2204 // Otherwise, what are we comparing against? |
| 2070 run_multiple_modes(gmmain, gm, compareConfig, comparisonBitmap, tileGrid ReplayScales); | 2205 run_multiple_modes(gmmain, gm, compareConfig, comparisonBitmap, tileGrid ReplayScales); |
| 2071 } | 2206 } |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2135 if (FLAGS_forceBWtext) { | 2270 if (FLAGS_forceBWtext) { |
| 2136 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 2271 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); |
| 2137 } | 2272 } |
| 2138 } | 2273 } |
| 2139 | 2274 |
| 2140 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 2275 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
| 2141 int main(int argc, char * const argv[]) { | 2276 int main(int argc, char * const argv[]) { |
| 2142 return tool_main(argc, (char**) argv); | 2277 return tool_main(argc, (char**) argv); |
| 2143 } | 2278 } |
| 2144 #endif | 2279 #endif |
| OLD | NEW |