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

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

Powered by Google App Engine
This is Rietveld 408576698