Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(234)

Side by Side Diff: gm/gmmain.cpp

Issue 21669004: Support multiple PDF rendering backends in the GM (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Eliminate warnings/errors on empty PDF rasterizer list Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gm/gm.h ('k') | gm/mixedxfermodes.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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(&copy, SkBitmap::kARGB_8888_Config); 294 bitmap.copyTo(&copy, 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
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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 SkCanvas c(dev); 657 SkCanvas c(dev);
645 dev->beginPortfolio(&xps); 658 dev->beginPortfolio(&xps);
646 dev->beginSheet(unitsPerMeter, pixelsPerMeter, trimSize); 659 dev->beginSheet(unitsPerMeter, pixelsPerMeter, trimSize);
647 invokeGM(gm, &c, false, false); 660 invokeGM(gm, &c, false, false);
648 dev->endSheet(); 661 dev->endSheet();
649 dev->endPortfolio(); 662 dev->endPortfolio();
650 663
651 #endif 664 #endif
652 } 665 }
653 666
654 ErrorCombination write_reference_image(const ConfigData& gRec, const char wr itePath [],
655 const char renderModeDescriptor [],
656 const char *shortName,
657 const BitmapAndDigest* bitmapAndDiges t,
658 SkStreamAsset* document) {
659 SkString path;
660 bool success = false;
661 if (gRec.fBackend == kRaster_Backend ||
662 gRec.fBackend == kGPU_Backend ||
663 (gRec.fBackend == kPDF_Backend && CAN_IMAGE_PDF)) {
664
665 path = make_bitmap_filename(writePath, shortName, gRec.fName, render ModeDescriptor,
666 bitmapAndDigest->fDigest);
667 success = write_bitmap(path, bitmapAndDigest->fBitmap);
668 }
669 if (kPDF_Backend == gRec.fBackend) {
670 path = make_filename(writePath, shortName, gRec.fName, renderModeDes criptor,
671 "pdf");
672 success = write_document(path, document);
673 }
674 if (kXPS_Backend == gRec.fBackend) {
675 path = make_filename(writePath, shortName, gRec.fName, renderModeDes criptor,
676 "xps");
677 success = write_document(path, document);
678 }
679 if (success) {
680 return kEmpty_ErrorCombination;
681 } else {
682 gm_fprintf(stderr, "FAILED to write %s\n", path.c_str());
683 ErrorCombination errors(kWritingReferenceImage_ErrorType);
684 // TODO(epoger): Don't call RecordTestResults() here...
685 // Instead, we should make sure to call RecordTestResults
686 // exactly ONCE per test. (Otherwise, gmmain.fTestsRun
687 // will be incremented twice for this test: once in
688 // compare_test_results_to_stored_expectations() before
689 // that method calls this one, and again here.)
690 //
691 // When we make that change, we should probably add a
692 // WritingReferenceImage test to the gm self-tests.)
693 RecordTestResults(errors, make_shortname_plus_config(shortName, gRec .fName),
694 renderModeDescriptor);
695 return errors;
696 }
697 }
698
699 /** 667 /**
700 * Log more detail about the mistmatch between expectedBitmap and 668 * Log more detail about the mistmatch between expectedBitmap and
701 * actualBitmap. 669 * actualBitmap.
702 */ 670 */
703 void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act ualBitmap, 671 void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act ualBitmap,
704 const char *testName) { 672 const char *testName) {
705 const int expectedWidth = expectedBitmap.width(); 673 const int expectedWidth = expectedBitmap.width();
706 const int expectedHeight = expectedBitmap.height(); 674 const int expectedHeight = expectedBitmap.height();
707 const int width = actualBitmap.width(); 675 const int width = actualBitmap.width();
708 const int height = actualBitmap.height(); 676 const int height = actualBitmap.height();
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 } 785 }
818 786
819 // If we have access to a single expected bitmap, log more 787 // If we have access to a single expected bitmap, log more
820 // detail about the mismatch. 788 // detail about the mismatch.
821 const SkBitmap *expectedBitmapPtr = expectations.asBitmap(); 789 const SkBitmap *expectedBitmapPtr = expectations.asBitmap();
822 if (NULL != expectedBitmapPtr) { 790 if (NULL != expectedBitmapPtr) {
823 report_bitmap_diffs(*expectedBitmapPtr, actualBitmapAndDigest.fB itmap, 791 report_bitmap_diffs(*expectedBitmapPtr, actualBitmapAndDigest.fB itmap,
824 completeName); 792 completeName);
825 } 793 }
826 } 794 }
827 RecordTestResults(errors, shortNamePlusConfig, renderModeDescriptor);
828 795
829 if (addToJsonSummary) { 796 if (addToJsonSummary) {
830 add_actual_results_to_json_summary(completeName, actualBitmapAndDige st.fDigest, errors, 797 add_actual_results_to_json_summary(completeName, actualBitmapAndDige st.fDigest, errors,
831 expectations.ignoreFailure()); 798 expectations.ignoreFailure());
832 add_expected_results_to_json_summary(completeName, expectations); 799 add_expected_results_to_json_summary(completeName, expectations);
833 } 800 }
834 801
835 return errors; 802 return errors;
836 } 803 }
837 804
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
886 void add_expected_results_to_json_summary(const char testName[], 853 void add_expected_results_to_json_summary(const char testName[],
887 Expectations expectations) { 854 Expectations expectations) {
888 this->fJsonExpectedResults[testName] = expectations.asJsonValue(); 855 this->fJsonExpectedResults[testName] = expectations.asJsonValue();
889 } 856 }
890 857
891 /** 858 /**
892 * Compare actualBitmap to expectations stored in this->fExpectationsSource. 859 * Compare actualBitmap to expectations stored in this->fExpectationsSource.
893 * 860 *
894 * @param gm which test generated the actualBitmap 861 * @param gm which test generated the actualBitmap
895 * @param gRec 862 * @param gRec
896 * @param writePath unless this is NULL, write out actual images into this
897 * directory
898 * @param actualBitmapAndDigest ptr to bitmap generated by this run, or NULL 863 * @param actualBitmapAndDigest ptr to bitmap generated by this run, or NULL
899 * if we don't have a usable bitmap representation 864 * if we don't have a usable bitmap representation
900 * @param document pdf or xps representation, if appropriate
901 */ 865 */
902 ErrorCombination compare_test_results_to_stored_expectations( 866 ErrorCombination compare_test_results_to_stored_expectations(
903 GM* gm, const ConfigData& gRec, const char writePath[], 867 GM* gm, const ConfigData& gRec,
904 const BitmapAndDigest* actualBitmapAndDigest, SkStreamAsset* document) { 868 const BitmapAndDigest* actualBitmapAndDigest) {
905 869
906 SkString shortNamePlusConfig = make_shortname_plus_config(gm->shortName( ), gRec.fName); 870 SkString shortNamePlusConfig = make_shortname_plus_config(gm->shortName( ), gRec.fName);
907 SkString nameWithExtension(shortNamePlusConfig);
908 nameWithExtension.append(".");
909 nameWithExtension.append(kPNG_FileExtension);
910 871
911 ErrorCombination errors; 872 ErrorCombination errors;
912 873
913 if (NULL == actualBitmapAndDigest) { 874 if (NULL == actualBitmapAndDigest) {
914 // Note that we intentionally skipped validating the results for 875 // Note that we intentionally skipped validating the results for
915 // this test, because we don't know how to generate an SkBitmap 876 // this test, because we don't know how to generate an SkBitmap
916 // version of the output. 877 // version of the output.
917 RecordTestResults(ErrorCombination(kIntentionallySkipped_ErrorType), 878 errors.add(ErrorCombination(kIntentionallySkipped_ErrorType));
918 shortNamePlusConfig, "");
919 } else if (!(gRec.fFlags & kWrite_ConfigFlag)) { 879 } else if (!(gRec.fFlags & kWrite_ConfigFlag)) {
920 // We don't record the results for this test or compare them 880 // We don't record the results for this test or compare them
921 // against any expectations, because the output image isn't 881 // against any expectations, because the output image isn't
922 // meaningful. 882 // meaningful.
923 // See https://code.google.com/p/skia/issues/detail?id=1410 ('some 883 // See https://code.google.com/p/skia/issues/detail?id=1410 ('some
924 // GM result images not available for download from Google Storage') 884 // GM result images not available for download from Google Storage')
925 RecordTestResults(ErrorCombination(kIntentionallySkipped_ErrorType), 885 errors.add(ErrorCombination(kIntentionallySkipped_ErrorType));
926 shortNamePlusConfig, "");
927 } else { 886 } else {
928 ExpectationsSource *expectationsSource = this->fExpectationsSource.g et(); 887 ExpectationsSource *expectationsSource = this->fExpectationsSource.g et();
888 SkString nameWithExtension(shortNamePlusConfig);
889 nameWithExtension.append(".");
890 nameWithExtension.append(kPNG_FileExtension);
891
929 if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) { 892 if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) {
930 /* 893 /*
931 * Get the expected results for this test, as one or more allowe d 894 * Get the expected results for this test, as one or more allowe d
932 * hash digests. The current implementation of expectationsSourc e 895 * hash digests. The current implementation of expectationsSourc e
933 * get this by computing the hash digest of a single PNG file on disk. 896 * get this by computing the hash digest of a single PNG file on disk.
934 * 897 *
935 * TODO(epoger): This relies on the fact that 898 * TODO(epoger): This relies on the fact that
936 * force_all_opaque() was called on the bitmap before it 899 * force_all_opaque() was called on the bitmap before it
937 * was written to disk as a PNG in the first place. If 900 * was written to disk as a PNG in the first place. If
938 * not, the hash digest returned here may not match the 901 * not, the hash digest returned here may not match the
939 * hash digest of actualBitmap, which *has* been run through 902 * hash digest of actualBitmap, which *has* been run through
940 * force_all_opaque(). 903 * force_all_opaque().
941 * See comments above complete_bitmap() for more detail. 904 * See comments above complete_bitmap() for more detail.
942 */ 905 */
943 Expectations expectations = expectationsSource->get(nameWithExte nsion.c_str()); 906 Expectations expectations = expectationsSource->get(nameWithExte nsion.c_str());
944 errors.add(compare_to_expectations(expectations, *actualBitmapAn dDigest, 907 errors.add(compare_to_expectations(expectations, *actualBitmapAn dDigest,
945 gm->shortName(), gRec.fName, "", true)); 908 gm->shortName(), gRec.fName, "", true));
946 } else { 909 } else {
947 // If we are running without expectations, we still want to 910 // If we are running without expectations, we still want to
948 // record the actual results. 911 // record the actual results.
949 add_actual_results_to_json_summary(nameWithExtension.c_str(), 912 add_actual_results_to_json_summary(nameWithExtension.c_str(),
950 actualBitmapAndDigest->fDiges t, 913 actualBitmapAndDigest->fDiges t,
951 ErrorCombination(kMissingExpe ctations_ErrorType), 914 ErrorCombination(kMissingExpe ctations_ErrorType),
952 false); 915 false);
953 RecordTestResults(ErrorCombination(kMissingExpectations_ErrorTyp e), 916 errors.add(ErrorCombination(kMissingExpectations_ErrorType));
954 shortNamePlusConfig, "");
955 } 917 }
956 } 918 }
957
958 // TODO: Consider moving this into compare_to_expectations(),
959 // similar to fMismatchPath... for now, we don't do that, because
960 // we don't want to write out the actual bitmaps for all
961 // renderModes of all tests! That would be a lot of files.
962 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) {
963 errors.add(write_reference_image(gRec, writePath, "", gm->shortName( ),
964 actualBitmapAndDigest, document));
965 }
966
967 return errors; 919 return errors;
968 } 920 }
969 921
970 /** 922 /**
971 * Compare actualBitmap to referenceBitmap. 923 * Compare actualBitmap to referenceBitmap.
972 * 924 *
973 * @param shortName test name, e.g. "selftest1" 925 * @param shortName test name, e.g. "selftest1"
974 * @param configName configuration name, e.g. "8888" 926 * @param configName configuration name, e.g. "8888"
975 * @param renderModeDescriptor 927 * @param renderModeDescriptor
976 * @param actualBitmap actual bitmap generated by this run 928 * @param actualBitmap actual bitmap generated by this run
977 * @param referenceBitmap bitmap we expected to be generated 929 * @param referenceBitmap bitmap we expected to be generated
978 */ 930 */
979 ErrorCombination compare_test_results_to_reference_bitmap( 931 ErrorCombination compare_test_results_to_reference_bitmap(
980 const char *shortName, const char *configName, const char *renderModeDes criptor, 932 const char *shortName, const char *configName, const char *renderModeDes criptor,
981 SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) { 933 SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) {
982 934
983 SkASSERT(referenceBitmap); 935 SkASSERT(referenceBitmap);
984 Expectations expectations(*referenceBitmap); 936 Expectations expectations(*referenceBitmap);
985 BitmapAndDigest actualBitmapAndDigest(actualBitmap); 937 BitmapAndDigest actualBitmapAndDigest(actualBitmap);
986 return compare_to_expectations(expectations, actualBitmapAndDigest, shor tName, 938
987 configName, renderModeDescriptor, false); 939 // TODO: Eliminate RecordTestResults from here.
940 // Results recording code for the test_drawing path has been refactored so that
941 // RecordTestResults is only called once, at the topmost level. However, the
942 // other paths have not yet been refactored, and RecordTestResults has b een added
943 // here to maintain proper behavior for calls not coming from the test_d rawing path.
944 ErrorCombination errors;
945 errors.add(compare_to_expectations(expectations, actualBitmapAndDigest, shortName,
946 configName, renderModeDescriptor, fal se));
947 SkString shortNamePlusConfig = make_shortname_plus_config(shortName, con figName);
948 RecordTestResults(errors, shortNamePlusConfig, renderModeDescriptor);
949
950 return errors;
988 } 951 }
989 952
990 static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t rec ordFlags, 953 static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t rec ordFlags,
991 SkScalar scale = SK_Scalar1) { 954 SkScalar scale = SK_Scalar1) {
992 // Pictures are refcounted so must be on heap 955 // Pictures are refcounted so must be on heap
993 SkPicture* pict; 956 SkPicture* pict;
994 int width = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().w idth()), scale)); 957 int width = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().w idth()), scale));
995 int height = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize(). height()), scale)); 958 int height = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize(). height()), scale));
996 959
997 if (kTileGrid_BbhType == bbhType) { 960 if (kTileGrid_BbhType == bbhType) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 SkDynamicMemoryWStream storage; 993 SkDynamicMemoryWStream storage;
1031 src.serialize(&storage, &bitmap_encoder); 994 src.serialize(&storage, &bitmap_encoder);
1032 SkAutoTUnref<SkStreamAsset> pictReadback(storage.detachAsStream()); 995 SkAutoTUnref<SkStreamAsset> pictReadback(storage.detachAsStream());
1033 SkPicture* retval = SkPicture::CreateFromStream(pictReadback, 996 SkPicture* retval = SkPicture::CreateFromStream(pictReadback,
1034 &SkImageDecoder::DecodeM emory); 997 &SkImageDecoder::DecodeM emory);
1035 return retval; 998 return retval;
1036 } 999 }
1037 1000
1038 // Test: draw into a bitmap or pdf. 1001 // Test: draw into a bitmap or pdf.
1039 // Depending on flags, possibly compare to an expected image. 1002 // Depending on flags, possibly compare to an expected image.
1040 ErrorCombination test_drawing(GM* gm, 1003 // If writePath is not NULL, also write images (or documents) to the specifi ed path.
1041 const ConfigData& gRec, 1004 ErrorCombination test_drawing(GM* gm, const ConfigData& gRec,
1005 const SkTDArray<const PDFRasterizerData*> &pdf Rasterizers,
1042 const char writePath [], 1006 const char writePath [],
1043 GrSurface* gpuTarget, 1007 GrSurface* gpuTarget,
1044 SkBitmap* bitmap) { 1008 SkBitmap* bitmap) {
1009 ErrorCombination errors;
1045 SkDynamicMemoryWStream document; 1010 SkDynamicMemoryWStream document;
1011 SkString path;
1046 1012
1047 if (gRec.fBackend == kRaster_Backend || 1013 if (gRec.fBackend == kRaster_Backend ||
1048 gRec.fBackend == kGPU_Backend) { 1014 gRec.fBackend == kGPU_Backend) {
1049 // Early exit if we can't generate the image. 1015 // Early exit if we can't generate the image.
1050 ErrorCombination errors = generate_image(gm, gRec, gpuTarget, bitmap , false); 1016 errors.add(generate_image(gm, gRec, gpuTarget, bitmap, false));
1051 if (!errors.isEmpty()) { 1017 if (!errors.isEmpty()) {
1052 // TODO: Add a test to exercise what the stdout and 1018 // TODO: Add a test to exercise what the stdout and
1053 // JSON look like if we get an "early error" while 1019 // JSON look like if we get an "early error" while
1054 // trying to generate the image. 1020 // trying to generate the image.
1055 return errors; 1021 return errors;
1056 } 1022 }
1023 BitmapAndDigest bitmapAndDigest(*bitmap);
1024 errors.add(compare_test_results_to_stored_expectations(
1025 gm, gRec, &bitmapAndDigest));
1026
1027 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) {
1028 path = make_bitmap_filename(writePath, gm->shortName(), gRec.fNa me,
1029 "", bitmapAndDigest.fDigest);
1030 errors.add(write_bitmap(path, bitmapAndDigest.fBitmap));
1031 }
1057 } else if (gRec.fBackend == kPDF_Backend) { 1032 } else if (gRec.fBackend == kPDF_Backend) {
1058 generate_pdf(gm, document); 1033 generate_pdf(gm, document);
1059 #if CAN_IMAGE_PDF 1034
1060 SkAutoDataUnref data(document.copyToData()); 1035 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream() );
1061 SkMemoryStream stream(data->data(), data->size()); 1036 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) {
1062 SkPDFDocumentToBitmap(&stream, bitmap); 1037 path = make_filename(writePath, gm->shortName(), gRec.fName, "", "pdf");
1063 #else 1038 errors.add(write_document(path, documentStream));
1064 bitmap = NULL; // we don't generate a bitmap rendering of the PDF f ile 1039 }
1065 #endif 1040
1041 if (!(gm->getFlags() & GM::kSkipPDFRasterization_Flag)) {
1042 for (int i = 0; i < pdfRasterizers.count(); i++) {
1043 SkBitmap pdfBitmap;
1044 SkASSERT(documentStream->rewind());
1045 bool success = (*pdfRasterizers[i]->fRasterizerFunction)(
1046 documentStream.get(), &pdfBitmap);
1047 if (!success) {
1048 gm_fprintf(stderr, "FAILED to render PDF for %s using re nderer %s\n",
1049 gm->shortName(),
1050 pdfRasterizers[i]->fName);
1051 continue;
1052 }
1053
1054 BitmapAndDigest bitmapAndDigest(pdfBitmap);
1055 errors.add(compare_test_results_to_stored_expectations(
1056 gm, gRec, &bitmapAndDigest));
1057
1058 SkString configName(gRec.fName);
1059 configName.append("_");
1060 configName.append(pdfRasterizers[i]->fName);
1061
1062 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) {
1063 path = make_bitmap_filename(writePath, gm->shortName(), configName.c_str(),
1064 "", bitmapAndDigest.fDigest) ;
1065 errors.add(write_bitmap(path, bitmapAndDigest.fBitmap));
1066 }
1067 }
1068 } else {
1069 errors.add(kIntentionallySkipped_ErrorType);
1070 }
1066 } else if (gRec.fBackend == kXPS_Backend) { 1071 } else if (gRec.fBackend == kXPS_Backend) {
1067 generate_xps(gm, document); 1072 generate_xps(gm, document);
1068 bitmap = NULL; // we don't generate a bitmap rendering of the XPS f ile 1073 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream() );
1074
1075 errors.add(compare_test_results_to_stored_expectations(
1076 gm, gRec, NULL));
1077
1078 if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) {
1079 path = make_filename(writePath, gm->shortName(), gRec.fName, "", "xps");
1080 errors.add(write_document(path, documentStream));
1081 }
1082 } else {
1083 SkASSERT(false);
1069 } 1084 }
1070 1085 return errors;
1071 SkAutoTUnref<SkStreamAsset> documentStream(document.detachAsStream());
1072 if (NULL == bitmap) {
1073 return compare_test_results_to_stored_expectations(
1074 gm, gRec, writePath, NULL, documentStream);
1075 } else {
1076 BitmapAndDigest bitmapAndDigest(*bitmap);
1077 return compare_test_results_to_stored_expectations(
1078 gm, gRec, writePath, &bitmapAndDigest, documentStream);
1079 }
1080 } 1086 }
1081 1087
1082 ErrorCombination test_deferred_drawing(GM* gm, 1088 ErrorCombination test_deferred_drawing(GM* gm,
1083 const ConfigData& gRec, 1089 const ConfigData& gRec,
1084 const SkBitmap& referenceBitmap, 1090 const SkBitmap& referenceBitmap,
1085 GrSurface* gpuTarget) { 1091 GrSurface* gpuTarget) {
1086 if (gRec.fBackend == kRaster_Backend || 1092 if (gRec.fBackend == kRaster_Backend ||
1087 gRec.fBackend == kGPU_Backend) { 1093 gRec.fBackend == kGPU_Backend) {
1088 const char renderModeDescriptor[] = "-deferred"; 1094 const char renderModeDescriptor[] = "-deferred";
1089 SkBitmap bitmap; 1095 SkBitmap bitmap;
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1223 Json::Value fJsonActualResults_Succeeded; 1229 Json::Value fJsonActualResults_Succeeded;
1224 1230
1225 }; // end of GMMain class definition 1231 }; // end of GMMain class definition
1226 1232
1227 #if SK_SUPPORT_GPU 1233 #if SK_SUPPORT_GPU
1228 static const GLContextType kDontCare_GLContextType = GrContextFactory::kNative_G LContextType; 1234 static const GLContextType kDontCare_GLContextType = GrContextFactory::kNative_G LContextType;
1229 #else 1235 #else
1230 static const GLContextType kDontCare_GLContextType = 0; 1236 static const GLContextType kDontCare_GLContextType = 0;
1231 #endif 1237 #endif
1232 1238
1233 // If the platform does not support writing PNGs of PDFs then there will be no
1234 // reference images to read. However, we can always write the .pdf files
1235 static const ConfigFlags kPDFConfigFlags = CAN_IMAGE_PDF ? kRW_ConfigFlag :
1236 kWrite_ConfigFlag;
1237
1238 static const ConfigData gRec[] = { 1239 static const ConfigData gRec[] = {
1239 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "8888", true }, 1240 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "8888", true },
1240 #if 0 // stop testing this (for now at least) since we want to remove support for it (soon please!!!) 1241 #if 0 // stop testing this (for now at least) since we want to remove support for it (soon please!!!)
1241 { SkBitmap::kARGB_4444_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "4444", true }, 1242 { SkBitmap::kARGB_4444_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "4444", true },
1242 #endif 1243 #endif
1243 { SkBitmap::kRGB_565_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "565", true }, 1244 { SkBitmap::kRGB_565_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "565", true },
1244 #if SK_SUPPORT_GPU 1245 #if SK_SUPPORT_GPU
1245 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL ContextType, 0, kRW_ConfigFlag, "gpu", true }, 1246 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL ContextType, 0, kRW_ConfigFlag, "gpu", true },
1246 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL ContextType, 16, kRW_ConfigFlag, "msaa16", false}, 1247 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL ContextType, 16, kRW_ConfigFlag, "msaa16", false},
1247 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL ContextType, 4, kRW_ConfigFlag, "msaa4", false}, 1248 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kNative_GL ContextType, 4, kRW_ConfigFlag, "msaa4", false},
(...skipping 11 matching lines...) Expand all
1259 #endif // SK_ANGLE 1260 #endif // SK_ANGLE
1260 #ifdef SK_MESA 1261 #ifdef SK_MESA
1261 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kMESA_GLCo ntextType, 0, kRW_ConfigFlag, "mesa", true }, 1262 { SkBitmap::kARGB_8888_Config, kGPU_Backend, GrContextFactory::kMESA_GLCo ntextType, 0, kRW_ConfigFlag, "mesa", true },
1262 #endif // SK_MESA 1263 #endif // SK_MESA
1263 #endif // SK_SUPPORT_GPU 1264 #endif // SK_SUPPORT_GPU
1264 #ifdef SK_SUPPORT_XPS 1265 #ifdef SK_SUPPORT_XPS
1265 /* At present we have no way of comparing XPS files (either natively or by c onverting to PNG). */ 1266 /* At present we have no way of comparing XPS files (either natively or by c onverting to PNG). */
1266 { SkBitmap::kARGB_8888_Config, kXPS_Backend, kDontCare_GLContextType, 0, kWrite_ConfigFlag, "xps", true }, 1267 { SkBitmap::kARGB_8888_Config, kXPS_Backend, kDontCare_GLContextType, 0, kWrite_ConfigFlag, "xps", true },
1267 #endif // SK_SUPPORT_XPS 1268 #endif // SK_SUPPORT_XPS
1268 #ifdef SK_SUPPORT_PDF 1269 #ifdef SK_SUPPORT_PDF
1269 { SkBitmap::kARGB_8888_Config, kPDF_Backend, kDontCare_GLContextType, 0, kPDFConfigFlags, "pdf", true }, 1270 { SkBitmap::kARGB_8888_Config, kPDF_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "pdf", true },
1270 #endif // SK_SUPPORT_PDF 1271 #endif // SK_SUPPORT_PDF
1271 }; 1272 };
1272 1273
1274 static const PDFRasterizerData kPDFRasterizers[] = {
1275 #ifdef SK_BUILD_FOR_MAC
1276 { &SkPDFDocumentToBitmap, "mac", true },
1277 #endif
1278 #ifdef SK_BUILD_POPPLER
1279 { &SkPopplerRasterizePDF, "poppler", true },
1280 #endif
1281 };
1282
1273 static const char kDefaultsConfigStr[] = "defaults"; 1283 static const char kDefaultsConfigStr[] = "defaults";
1274 static const char kExcludeConfigChar = '~'; 1284 static const char kExcludeConfigChar = '~';
1275 1285
1276 static SkString configUsage() { 1286 static SkString configUsage() {
1277 SkString result; 1287 SkString result;
1278 result.appendf("Space delimited list of which configs to run. Possible optio ns: ["); 1288 result.appendf("Space delimited list of which configs to run. Possible optio ns: [");
1279 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { 1289 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) {
1280 SkASSERT(gRec[i].fName != kDefaultsConfigStr); 1290 SkASSERT(gRec[i].fName != kDefaultsConfigStr);
1281 if (i > 0) { 1291 if (i > 0) {
1282 result.append("|"); 1292 result.append("|");
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 result.appendf("E.g. \"--config %s %c%s %s\" will run these configs:\n\t%s % s", 1324 result.appendf("E.g. \"--config %s %c%s %s\" will run these configs:\n\t%s % s",
1315 kDefaultsConfigStr, 1325 kDefaultsConfigStr,
1316 kExcludeConfigChar, 1326 kExcludeConfigChar,
1317 firstDefault.c_str(), 1327 firstDefault.c_str(),
1318 nonDefault.c_str(), 1328 nonDefault.c_str(),
1319 allButFirstDefaults.c_str(), 1329 allButFirstDefaults.c_str(),
1320 nonDefault.c_str()); 1330 nonDefault.c_str());
1321 return result; 1331 return result;
1322 } 1332 }
1323 1333
1334 static SkString pdfRasterizerUsage() {
1335 SkString result;
1336 result.appendf("Space delimited list of which PDF rasterizers to run. Possib le options: [");
1337 // For this (and further) loops through kPDFRasterizers, there is a typecast to int to avoid
1338 // the compiler giving an "comparison of unsigned expression < 0 is always f alse" warning
1339 // and turning it into a build-breaking error.
1340 for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); ++i) {
1341 if (i > 0) {
1342 result.append(" ");
1343 }
1344 result.append(kPDFRasterizers[i].fName);
1345 }
1346 result.append("]\n");
1347 result.append("The default value is: \"");
1348 for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); ++i) {
1349 if (kPDFRasterizers[i].fRunByDefault) {
1350 if (i > 0) {
1351 result.append(" ");
1352 }
1353 result.append(kPDFRasterizers[i].fName);
1354 }
1355 }
1356 result.append("\"");
1357 return result;
1358 }
1359
1324 // Macro magic to convert a numeric preprocessor token into a string. 1360 // Macro magic to convert a numeric preprocessor token into a string.
1325 // Adapted from http://stackoverflow.com/questions/240353/convert-a-preprocessor -token-to-a-string 1361 // Adapted from http://stackoverflow.com/questions/240353/convert-a-preprocessor -token-to-a-string
1326 // This should probably be moved into one of our common headers... 1362 // This should probably be moved into one of our common headers...
1327 #define TOSTRING_INTERNAL(x) #x 1363 #define TOSTRING_INTERNAL(x) #x
1328 #define TOSTRING(x) TOSTRING_INTERNAL(x) 1364 #define TOSTRING(x) TOSTRING_INTERNAL(x)
1329 1365
1330 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath"). 1366 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath").
1331 DEFINE_string(config, "", configUsage().c_str()); 1367 DEFINE_string(config, "", configUsage().c_str());
1368 DEFINE_string(pdfRasterizers, "", pdfRasterizerUsage().c_str());
1332 DEFINE_bool(deferred, true, "Exercise the deferred rendering test pass."); 1369 DEFINE_bool(deferred, true, "Exercise the deferred rendering test pass.");
1333 DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip."); 1370 DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip.");
1334 DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing."); 1371 DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing.");
1335 #if SK_SUPPORT_GPU 1372 #if SK_SUPPORT_GPU
1336 DEFINE_string(gpuCacheSize, "", "<bytes> <count>: Limit the gpu cache to byte si ze or " 1373 DEFINE_string(gpuCacheSize, "", "<bytes> <count>: Limit the gpu cache to byte si ze or "
1337 "object count. " TOSTRING(DEFAULT_CACHE_VALUE) " for either value means " 1374 "object count. " TOSTRING(DEFAULT_CACHE_VALUE) " for either value means "
1338 "use the default. 0 for either disables the cache."); 1375 "use the default. 0 for either disables the cache.");
1339 #endif 1376 #endif
1340 DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure " 1377 DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure "
1341 "when reading/writing files."); 1378 "when reading/writing files.");
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 1447
1411 static int findConfig(const char config[]) { 1448 static int findConfig(const char config[]) {
1412 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) { 1449 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) {
1413 if (!strcmp(config, gRec[i].fName)) { 1450 if (!strcmp(config, gRec[i].fName)) {
1414 return (int) i; 1451 return (int) i;
1415 } 1452 }
1416 } 1453 }
1417 return -1; 1454 return -1;
1418 } 1455 }
1419 1456
1457 static const PDFRasterizerData* findPDFRasterizer(const char rasterizer[]) {
1458 for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); i++) {
1459 if (!strcmp(rasterizer, kPDFRasterizers[i].fName)) {
1460 return &kPDFRasterizers[i];
1461 }
1462 }
1463 return NULL;
1464 }
1465
1420 namespace skiagm { 1466 namespace skiagm {
1421 #if SK_SUPPORT_GPU 1467 #if SK_SUPPORT_GPU
1422 SkAutoTUnref<GrContext> gGrContext; 1468 SkAutoTUnref<GrContext> gGrContext;
1423 /** 1469 /**
1424 * Sets the global GrContext, accessible by individual GMs 1470 * Sets the global GrContext, accessible by individual GMs
1425 */ 1471 */
1426 static void SetGr(GrContext* grContext) { 1472 static void SetGr(GrContext* grContext) {
1427 SkSafeRef(grContext); 1473 SkSafeRef(grContext);
1428 gGrContext.reset(grContext); 1474 gGrContext.reset(grContext);
1429 } 1475 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1466 } 1512 }
1467 } 1513 }
1468 1514
1469 /** 1515 /**
1470 * Run this test in a number of different configs (8888, 565, PDF, 1516 * Run this test in a number of different configs (8888, 565, PDF,
1471 * etc.), confirming that the resulting bitmaps match expectations 1517 * etc.), confirming that the resulting bitmaps match expectations
1472 * (which may be different for each config). 1518 * (which may be different for each config).
1473 * 1519 *
1474 * Returns all errors encountered while doing so. 1520 * Returns all errors encountered while doing so.
1475 */ 1521 */
1476 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,
1477 GrContextFactory *grFactory); 1525 GrContextFactory *grFactory);
1478 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<si ze_t> &configs, 1526 ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm,
1527 const SkTDArray<size_t> &configs,
1528 const SkTDArray<const PDFRasterizerData*> &pdfRasterizers,
1479 GrContextFactory *grFactory) { 1529 GrContextFactory *grFactory) {
1480 const char renderModeDescriptor[] = ""; 1530 const char renderModeDescriptor[] = "";
1481 ErrorCombination errorsForAllConfigs; 1531 ErrorCombination errorsForAllConfigs;
1482 uint32_t gmFlags = gm->getFlags(); 1532 uint32_t gmFlags = gm->getFlags();
1483 1533
1484 for (int i = 0; i < configs.count(); i++) { 1534 for (int i = 0; i < configs.count(); i++) {
1485 ConfigData config = gRec[configs[i]]; 1535 ConfigData config = gRec[configs[i]];
1486 const SkString shortNamePlusConfig = gmmain.make_shortname_plus_config(g m->shortName(), 1536 const SkString shortNamePlusConfig = gmmain.make_shortname_plus_config(g m->shortName(),
1487 c onfig.fName); 1537 c onfig.fName);
1488 1538
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 #endif 1609 #endif
1560 1610
1561 SkBitmap comparisonBitmap; 1611 SkBitmap comparisonBitmap;
1562 1612
1563 const char* writePath; 1613 const char* writePath;
1564 if (FLAGS_writePath.count() == 1) { 1614 if (FLAGS_writePath.count() == 1) {
1565 writePath = FLAGS_writePath[0]; 1615 writePath = FLAGS_writePath[0];
1566 } else { 1616 } else {
1567 writePath = NULL; 1617 writePath = NULL;
1568 } 1618 }
1619
1569 if (errorsForThisConfig.isEmpty()) { 1620 if (errorsForThisConfig.isEmpty()) {
1570 errorsForThisConfig.add(gmmain.test_drawing(gm,config, writePath, gp uTarget, 1621 errorsForThisConfig.add(gmmain.test_drawing(gm, config, pdfRasterize rs,
1622 writePath, gpuTarget,
1571 &comparisonBitmap)); 1623 &comparisonBitmap));
1624 gmmain.RecordTestResults(errorsForThisConfig, shortNamePlusConfig, " ");
1572 } 1625 }
1573 1626
1574 if (FLAGS_deferred && errorsForThisConfig.isEmpty() && 1627 if (FLAGS_deferred && errorsForThisConfig.isEmpty() &&
1575 (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBacke nd)) { 1628 (kGPU_Backend == config.fBackend || kRaster_Backend == config.fBacke nd)) {
1576 errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, com parisonBitmap, 1629 errorsForThisConfig.add(gmmain.test_deferred_drawing(gm, config, com parisonBitmap,
1577 gpuTarget)); 1630 gpuTarget));
1578 } 1631 }
1579 1632
1580 errorsForAllConfigs.add(errorsForThisConfig); 1633 errorsForAllConfigs.add(errorsForThisConfig);
1581 } 1634 }
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1747 if (i > 0) { 1800 if (i > 0) {
1748 total.append(", "); 1801 total.append(", ");
1749 } 1802 }
1750 total.append("\""); 1803 total.append("\"");
1751 total.append(gRec[configs[i]].fName); 1804 total.append(gRec[configs[i]].fName);
1752 total.append("\""); 1805 total.append("\"");
1753 } 1806 }
1754 return total; 1807 return total;
1755 } 1808 }
1756 1809
1757 bool prepare_subdirectories(const char *root, bool useFileHierarchy, 1810 static bool prepare_subdirectories(const char *root, bool useFileHierarchy,
1758 const SkTDArray<size_t> &configs); 1811 const SkTDArray<size_t> &configs,
1759 bool prepare_subdirectories(const char *root, bool useFileHierarchy, 1812 const SkTDArray<const PDFRasterizerData*>& pd fRasterizers) {
1760 const SkTDArray<size_t> &configs) {
1761 if (!sk_mkdir(root)) { 1813 if (!sk_mkdir(root)) {
1762 return false; 1814 return false;
1763 } 1815 }
1764 if (useFileHierarchy) { 1816 if (useFileHierarchy) {
1765 for (int i = 0; i < configs.count(); i++) { 1817 for (int i = 0; i < configs.count(); i++) {
1766 ConfigData config = gRec[configs[i]]; 1818 ConfigData config = gRec[configs[i]];
1767 SkString subdir; 1819 SkString subdir;
1768 subdir.appendf("%s%c%s", root, SkPATH_SEPARATOR, config.fName); 1820 subdir.appendf("%s%c%s", root, SkPATH_SEPARATOR, config.fName);
1769 if (!sk_mkdir(subdir.c_str())) { 1821 if (!sk_mkdir(subdir.c_str())) {
1770 return false; 1822 return false;
1771 } 1823 }
1824
1825 if (config.fBackend == kPDF_Backend) {
1826 for (int j = 0; j < pdfRasterizers.count(); j++) {
1827 SkString pdfSubdir = subdir;
1828 pdfSubdir.appendf("_%s", pdfRasterizers[j]->fName);
1829 if (!sk_mkdir(pdfSubdir.c_str())) {
1830 return false;
1831 }
1832 }
1833 }
1772 } 1834 }
1773 } 1835 }
1774 return true; 1836 return true;
1775 } 1837 }
1776 1838
1777 static bool parse_flags_configs(SkTDArray<size_t>* outConfigs, 1839 static bool parse_flags_configs(SkTDArray<size_t>* outConfigs,
1778 GrContextFactory* grFactory) { 1840 GrContextFactory* grFactory) {
1779 SkTDArray<size_t> excludeConfigs; 1841 SkTDArray<size_t> excludeConfigs;
1780 1842
1781 for (int i = 0; i < FLAGS_config.count(); i++) { 1843 for (int i = 0; i < FLAGS_config.count(); i++) {
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
1870 SkString configStr("These configs will be run:"); 1932 SkString configStr("These configs will be run:");
1871 // show the user the config that will run. 1933 // show the user the config that will run.
1872 for (int i = 0; i < outConfigs->count(); ++i) { 1934 for (int i = 0; i < outConfigs->count(); ++i) {
1873 configStr.appendf(" %s", gRec[(*outConfigs)[i]].fName); 1935 configStr.appendf(" %s", gRec[(*outConfigs)[i]].fName);
1874 } 1936 }
1875 gm_fprintf(stdout, "%s\n", configStr.c_str()); 1937 gm_fprintf(stdout, "%s\n", configStr.c_str());
1876 1938
1877 return true; 1939 return true;
1878 } 1940 }
1879 1941
1942 static bool parse_flags_pdf_rasterizers(const SkTDArray<size_t>& configs,
1943 SkTDArray<const PDFRasterizerData*>* out Rasterizers) {
1944 // No need to run this check (and display the PDF rasterizers message)
1945 // if no PDF backends are in the configs.
1946 bool configHasPDF = false;
1947 for (int i = 0; i < configs.count(); i++) {
1948 if (gRec[configs[i]].fBackend == kPDF_Backend) {
1949 configHasPDF = true;
1950 break;
1951 }
1952 }
1953 if (!configHasPDF) {
1954 return true;
1955 }
1956
1957 for (int i = 0; i < FLAGS_pdfRasterizers.count(); i++) {
1958 const char* rasterizer = FLAGS_pdfRasterizers[i];
1959 const PDFRasterizerData* rasterizerPtr = findPDFRasterizer(rasterizer);
1960
1961 if (rasterizerPtr == NULL) {
1962 gm_fprintf(stderr, "unrecognized rasterizer %s\n", rasterizer);
1963 return false;
1964 }
1965 appendUnique<const PDFRasterizerData*>(outRasterizers,
1966 rasterizerPtr);
1967 }
1968
1969 if (outRasterizers->count() == 0) {
1970 // if no config is specified by user, add the defaults
1971 for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); ++i) {
1972 if (kPDFRasterizers[i].fRunByDefault) {
1973 *outRasterizers->append() = &kPDFRasterizers[i];
1974 }
1975 }
1976 }
1977
1978 // now show the user the set of configs that will be run.
1979 SkString configStr("These PDF rasterizers will be run:");
1980 // show the user the config that will run.
1981 for (int i = 0; i < outRasterizers->count(); ++i) {
1982 configStr.appendf(" %s", (*outRasterizers)[i]->fName);
1983 }
1984 gm_fprintf(stdout, "%s\n", configStr.c_str());
1985
1986 return true;
1987 }
1988
1880 static bool parse_flags_ignore_error_types(ErrorCombination* outErrorTypes) { 1989 static bool parse_flags_ignore_error_types(ErrorCombination* outErrorTypes) {
1881 if (FLAGS_ignoreErrorTypes.count() > 0) { 1990 if (FLAGS_ignoreErrorTypes.count() > 0) {
1882 *outErrorTypes = ErrorCombination(); 1991 *outErrorTypes = ErrorCombination();
1883 for (int i = 0; i < FLAGS_ignoreErrorTypes.count(); i++) { 1992 for (int i = 0; i < FLAGS_ignoreErrorTypes.count(); i++) {
1884 ErrorType type; 1993 ErrorType type;
1885 const char *name = FLAGS_ignoreErrorTypes[i]; 1994 const char *name = FLAGS_ignoreErrorTypes[i];
1886 if (!getErrorTypeByName(name, &type)) { 1995 if (!getErrorTypeByName(name, &type)) {
1887 gm_fprintf(stderr, "cannot find ErrorType with name '%s'\n", nam e); 1996 gm_fprintf(stderr, "cannot find ErrorType with name '%s'\n", nam e);
1888 return false; 1997 return false;
1889 } else { 1998 } else {
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
2012 2121
2013 setSystemPreferences(); 2122 setSystemPreferences();
2014 GMMain gmmain; 2123 GMMain gmmain;
2015 2124
2016 SkString usage; 2125 SkString usage;
2017 usage.printf("Run the golden master tests.\n"); 2126 usage.printf("Run the golden master tests.\n");
2018 SkCommandLineFlags::SetUsage(usage.c_str()); 2127 SkCommandLineFlags::SetUsage(usage.c_str());
2019 SkCommandLineFlags::Parse(argc, argv); 2128 SkCommandLineFlags::Parse(argc, argv);
2020 2129
2021 SkTDArray<size_t> configs; 2130 SkTDArray<size_t> configs;
2131
2022 int moduloRemainder = -1; 2132 int moduloRemainder = -1;
2023 int moduloDivisor = -1; 2133 int moduloDivisor = -1;
2134 SkTDArray<const PDFRasterizerData*> pdfRasterizers;
2024 SkTDArray<SkScalar> tileGridReplayScales; 2135 SkTDArray<SkScalar> tileGridReplayScales;
2025 #if SK_SUPPORT_GPU 2136 #if SK_SUPPORT_GPU
2026 GrContextFactory* grFactory = new GrContextFactory; 2137 GrContextFactory* grFactory = new GrContextFactory;
2027 #else 2138 #else
2028 GrContextFactory* grFactory = NULL; 2139 GrContextFactory* grFactory = NULL;
2029 #endif 2140 #endif
2030 SkTDArray<const char*> matchStrs; 2141 SkTDArray<const char*> matchStrs;
2031 2142
2032 if (!parse_flags_modulo(&moduloRemainder, &moduloDivisor) || 2143 if (!parse_flags_modulo(&moduloRemainder, &moduloDivisor) ||
2033 !parse_flags_ignore_error_types(&gmmain.fIgnorableErrorTypes) || 2144 !parse_flags_ignore_error_types(&gmmain.fIgnorableErrorTypes) ||
2034 #if SK_SUPPORT_GPU 2145 #if SK_SUPPORT_GPU
2035 !parse_flags_gpu_cache(&gGpuCacheSizeBytes, &gGpuCacheSizeCount) || 2146 !parse_flags_gpu_cache(&gGpuCacheSizeBytes, &gGpuCacheSizeCount) ||
2036 #endif 2147 #endif
2037 !parse_flags_tile_grid_replay_scales(&tileGridReplayScales) || 2148 !parse_flags_tile_grid_replay_scales(&tileGridReplayScales) ||
2038 !parse_flags_resource_path() || 2149 !parse_flags_resource_path() ||
2039 !parse_flags_match_strs(&matchStrs) || 2150 !parse_flags_match_strs(&matchStrs) ||
2040 !parse_flags_jpeg_quality() || 2151 !parse_flags_jpeg_quality() ||
2041 !parse_flags_configs(&configs, grFactory) || 2152 !parse_flags_configs(&configs, grFactory) ||
2153 !parse_flags_pdf_rasterizers(configs, &pdfRasterizers) ||
2042 !parse_flags_gmmain_paths(&gmmain)) { 2154 !parse_flags_gmmain_paths(&gmmain)) {
2043 return -1; 2155 return -1;
2044 } 2156 }
2045 2157
2046 if (FLAGS_verbose) { 2158 if (FLAGS_verbose) {
2047 if (FLAGS_writePath.count() == 1) { 2159 if (FLAGS_writePath.count() == 1) {
2048 gm_fprintf(stdout, "writing to %s\n", FLAGS_writePath[0]); 2160 gm_fprintf(stdout, "writing to %s\n", FLAGS_writePath[0]);
2049 } 2161 }
2050 if (NULL != gmmain.fMismatchPath) { 2162 if (NULL != gmmain.fMismatchPath) {
2051 gm_fprintf(stdout, "writing mismatches to %s\n", gmmain.fMismatchPat h); 2163 gm_fprintf(stdout, "writing mismatches to %s\n", gmmain.fMismatchPat h);
2052 } 2164 }
2053 if (NULL != gmmain.fMissingExpectationsPath) { 2165 if (NULL != gmmain.fMissingExpectationsPath) {
2054 gm_fprintf(stdout, "writing images without expectations to %s\n", 2166 gm_fprintf(stdout, "writing images without expectations to %s\n",
2055 gmmain.fMissingExpectationsPath); 2167 gmmain.fMissingExpectationsPath);
2056 } 2168 }
2057 if (FLAGS_writePicturePath.count() == 1) { 2169 if (FLAGS_writePicturePath.count() == 1) {
2058 gm_fprintf(stdout, "writing pictures to %s\n", FLAGS_writePicturePat h[0]); 2170 gm_fprintf(stdout, "writing pictures to %s\n", FLAGS_writePicturePat h[0]);
2059 } 2171 }
2060 if (FLAGS_resourcePath.count() == 1) { 2172 if (FLAGS_resourcePath.count() == 1) {
2061 gm_fprintf(stdout, "reading resources from %s\n", FLAGS_resourcePath [0]); 2173 gm_fprintf(stdout, "reading resources from %s\n", FLAGS_resourcePath [0]);
2062 } 2174 }
2063 } 2175 }
2064 2176
2065 int gmsRun = 0; 2177 int gmsRun = 0;
2066 int gmIndex = -1; 2178 int gmIndex = -1;
2067 SkString moduloStr; 2179 SkString moduloStr;
2068 2180
2069 // If we will be writing out files, prepare subdirectories. 2181 // If we will be writing out files, prepare subdirectories.
2070 if (FLAGS_writePath.count() == 1) { 2182 if (FLAGS_writePath.count() == 1) {
2071 if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy , configs)) { 2183 if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy ,
2184 configs, pdfRasterizers)) {
2072 return -1; 2185 return -1;
2073 } 2186 }
2074 } 2187 }
2075 if (NULL != gmmain.fMismatchPath) { 2188 if (NULL != gmmain.fMismatchPath) {
2076 if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarc hy, configs)) { 2189 if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarc hy,
2190 configs, pdfRasterizers)) {
2077 return -1; 2191 return -1;
2078 } 2192 }
2079 } 2193 }
2080 if (NULL != gmmain.fMissingExpectationsPath) { 2194 if (NULL != gmmain.fMissingExpectationsPath) {
2081 if (!prepare_subdirectories(gmmain.fMissingExpectationsPath, gmmain.fUse FileHierarchy, 2195 if (!prepare_subdirectories(gmmain.fMissingExpectationsPath, gmmain.fUse FileHierarchy,
2082 configs)) { 2196 configs, pdfRasterizers)) {
2083 return -1; 2197 return -1;
2084 } 2198 }
2085 } 2199 }
2086 2200
2087 Iter iter; 2201 Iter iter;
2088 GM* gm; 2202 GM* gm;
2089 while ((gm = iter.next()) != NULL) { 2203 while ((gm = iter.next()) != NULL) {
2090 SkAutoTDelete<GM> adgm(gm); 2204 SkAutoTDelete<GM> adgm(gm);
2091 ++gmIndex; 2205 ++gmIndex;
2092 if (moduloRemainder >= 0) { 2206 if (moduloRemainder >= 0) {
2093 if ((gmIndex % moduloDivisor) != moduloRemainder) { 2207 if ((gmIndex % moduloDivisor) != moduloRemainder) {
2094 continue; 2208 continue;
2095 } 2209 }
2096 moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor); 2210 moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor);
2097 } 2211 }
2098 2212
2099 const char* shortName = gm->shortName(); 2213 const char* shortName = gm->shortName();
2100 2214
2101 if (SkCommandLineFlags::ShouldSkip(matchStrs, shortName)) { 2215 if (SkCommandLineFlags::ShouldSkip(matchStrs, shortName)) {
2102 continue; 2216 continue;
2103 } 2217 }
2104 2218
2105 gmsRun++; 2219 gmsRun++;
2106 SkISize size = gm->getISize(); 2220 SkISize size = gm->getISize();
2107 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short Name, 2221 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short Name,
2108 size.width(), size.height()); 2222 size.width(), size.height());
2109 2223
2110 run_multiple_configs(gmmain, gm, configs, grFactory); 2224 run_multiple_configs(gmmain, gm, configs, pdfRasterizers, grFactory);
2111 2225
2112 SkBitmap comparisonBitmap; 2226 SkBitmap comparisonBitmap;
2113 const ConfigData compareConfig = 2227 const ConfigData compareConfig =
2114 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT ype, 0, kRW_ConfigFlag, "comparison", false }; 2228 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT ype, 0, kRW_ConfigFlag, "comparison", false };
2115 gmmain.generate_image(gm, compareConfig, NULL, &comparisonBitmap, false) ; 2229 gmmain.generate_image(gm, compareConfig, NULL, &comparisonBitmap, false) ;
2116 2230
2117 // TODO(epoger): only run this if gmmain.generate_image() succeeded? 2231 // TODO(epoger): only run this if gmmain.generate_image() succeeded?
2118 // Otherwise, what are we comparing against? 2232 // Otherwise, what are we comparing against?
2119 run_multiple_modes(gmmain, gm, compareConfig, comparisonBitmap, tileGrid ReplayScales); 2233 run_multiple_modes(gmmain, gm, compareConfig, comparisonBitmap, tileGrid ReplayScales);
2120 } 2234 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
2184 if (FLAGS_forceBWtext) { 2298 if (FLAGS_forceBWtext) {
2185 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); 2299 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref();
2186 } 2300 }
2187 } 2301 }
2188 2302
2189 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) 2303 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
2190 int main(int argc, char * const argv[]) { 2304 int main(int argc, char * const argv[]) {
2191 return tool_main(argc, (char**) argv); 2305 return tool_main(argc, (char**) argv);
2192 } 2306 }
2193 #endif 2307 #endif
OLDNEW
« no previous file with comments | « gm/gm.h ('k') | gm/mixedxfermodes.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698