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

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

Powered by Google App Engine
This is Rietveld 408576698