OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 /* | 8 /* |
9 * Code for the "gm" (Golden Master) rendering comparison tool. | 9 * Code for the "gm" (Golden Master) rendering comparison tool. |
10 * | 10 * |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 static bool encode_to_dct_stream(SkWStream* stream, const SkBitmap& bitmap, cons t SkIRect& rect); | 186 static bool encode_to_dct_stream(SkWStream* stream, const SkBitmap& bitmap, cons t SkIRect& rect); |
187 | 187 |
188 const static ErrorCombination kDefaultIgnorableErrorTypes = ErrorCombination() | 188 const static ErrorCombination kDefaultIgnorableErrorTypes = ErrorCombination() |
189 .plus(kMissingExpectations_ErrorType) | 189 .plus(kMissingExpectations_ErrorType) |
190 .plus(kIntentionallySkipped_ErrorType); | 190 .plus(kIntentionallySkipped_ErrorType); |
191 | 191 |
192 class GMMain { | 192 class GMMain { |
193 public: | 193 public: |
194 GMMain() : fUseFileHierarchy(false), fWriteChecksumBasedFilenames(false), | 194 GMMain() : fUseFileHierarchy(false), fWriteChecksumBasedFilenames(false), |
195 fIgnorableErrorTypes(kDefaultIgnorableErrorTypes), | 195 fIgnorableErrorTypes(kDefaultIgnorableErrorTypes), |
196 fMismatchPath(NULL), fTestsRun(0), fRenderModesEncountered(1) {} | 196 fMismatchPath(NULL), fMissingExpectationsPath(NULL), fTestsRun(0) , |
epoger
2013/06/21 17:46:44
Patchset 2 adds the new missingExpectationsPath fl
borenet
2013/06/21 18:01:14
So, we put the actuals for GMs with no expectation
epoger
2013/06/21 18:06:46
As you'll see in https://codereview.chromium.org/1
borenet
2013/06/21 18:14:09
I think that's fine, I just can't think of a case
| |
197 fRenderModesEncountered(1) {} | |
197 | 198 |
198 /** | 199 /** |
199 * Assemble shortNamePlusConfig from (surprise!) shortName and configName. | 200 * Assemble shortNamePlusConfig from (surprise!) shortName and configName. |
200 * | 201 * |
201 * The method for doing so depends on whether we are using hierarchical nami ng. | 202 * The method for doing so depends on whether we are using hierarchical nami ng. |
202 * For example, shortName "selftest1" and configName "8888" could be assembl ed into | 203 * For example, shortName "selftest1" and configName "8888" could be assembl ed into |
203 * either "selftest1_8888" or "8888/selftest1". | 204 * either "selftest1_8888" or "8888/selftest1". |
204 */ | 205 */ |
205 SkString make_shortname_plus_config(const char *shortName, const char *confi gName) { | 206 SkString make_shortname_plus_config(const char *shortName, const char *confi gName) { |
206 SkString name; | 207 SkString name; |
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
760 " max per-channel mismatch R=%d G=%d B=%d A=%d\n", | 761 " max per-channel mismatch R=%d G=%d B=%d A=%d\n", |
761 testName, differingPixels, width*height, errR, errG, errB, er rA); | 762 testName, differingPixels, width*height, errR, errG, errB, er rA); |
762 } | 763 } |
763 | 764 |
764 /** | 765 /** |
765 * Compares actual hash digest to expectations, returning the set of errors | 766 * Compares actual hash digest to expectations, returning the set of errors |
766 * (if any) that we saw along the way. | 767 * (if any) that we saw along the way. |
767 * | 768 * |
768 * If fMismatchPath has been set, and there are pixel diffs, then the | 769 * If fMismatchPath has been set, and there are pixel diffs, then the |
769 * actual bitmap will be written out to a file within fMismatchPath. | 770 * actual bitmap will be written out to a file within fMismatchPath. |
771 * And similarly for fMissingExpectationsPath... | |
770 * | 772 * |
771 * @param expectations what expectations to compare actualBitmap against | 773 * @param expectations what expectations to compare actualBitmap against |
772 * @param actualBitmapAndDigest the SkBitmap we actually generated, and its GmResultDigest | 774 * @param actualBitmapAndDigest the SkBitmap we actually generated, and its GmResultDigest |
773 * @param shortName name of test, e.g. "selftest1" | 775 * @param shortName name of test, e.g. "selftest1" |
774 * @param configName name of config, e.g. "8888" | 776 * @param configName name of config, e.g. "8888" |
775 * @param renderModeDescriptor e.g., "-rtree", "-deferred" | 777 * @param renderModeDescriptor e.g., "-rtree", "-deferred" |
776 * @param addToJsonSummary whether to add these results (both actual and | 778 * @param addToJsonSummary whether to add these results (both actual and |
777 * expected) to the JSON summary. Regardless of this setting, if | 779 * expected) to the JSON summary. Regardless of this setting, if |
778 * we find an image mismatch in this test, we will write these | 780 * we find an image mismatch in this test, we will write these |
779 * results to the JSON summary. (This is so that we will always | 781 * results to the JSON summary. (This is so that we will always |
780 * report errors across rendering modes, such as pipe vs tiled. | 782 * report errors across rendering modes, such as pipe vs tiled. |
781 * See https://codereview.chromium.org/13650002/ ) | 783 * See https://codereview.chromium.org/13650002/ ) |
782 */ | 784 */ |
783 ErrorCombination compare_to_expectations(Expectations expectations, | 785 ErrorCombination compare_to_expectations(Expectations expectations, |
784 const BitmapAndDigest& actualBitmap AndDigest, | 786 const BitmapAndDigest& actualBitmap AndDigest, |
785 const char *shortName, const char * configName, | 787 const char *shortName, const char * configName, |
786 const char *renderModeDescriptor, | 788 const char *renderModeDescriptor, |
787 bool addToJsonSummary) { | 789 bool addToJsonSummary) { |
788 ErrorCombination errors; | 790 ErrorCombination errors; |
789 SkString shortNamePlusConfig = make_shortname_plus_config(shortName, con figName); | 791 SkString shortNamePlusConfig = make_shortname_plus_config(shortName, con figName); |
790 SkString completeNameString(shortNamePlusConfig); | 792 SkString completeNameString(shortNamePlusConfig); |
791 completeNameString.append(renderModeDescriptor); | 793 completeNameString.append(renderModeDescriptor); |
792 completeNameString.append("."); | 794 completeNameString.append("."); |
793 completeNameString.append(kPNG_FileExtension); | 795 completeNameString.append(kPNG_FileExtension); |
794 const char* completeName = completeNameString.c_str(); | 796 const char* completeName = completeNameString.c_str(); |
795 | 797 |
796 if (expectations.empty()) { | 798 if (expectations.empty()) { |
797 errors.add(kMissingExpectations_ErrorType); | 799 errors.add(kMissingExpectations_ErrorType); |
800 | |
801 // Write out the "actuals" for any tests without expectations, if we have | |
802 // been directed to do so. | |
803 if (fMissingExpectationsPath) { | |
804 SkString path = make_bitmap_filename(fMissingExpectationsPath, s hortName, | |
805 configName, renderModeDescr iptor, | |
806 actualBitmapAndDigest.fDige st); | |
807 write_bitmap(path, actualBitmapAndDigest.fBitmap); | |
808 } | |
809 | |
798 } else if (!expectations.match(actualBitmapAndDigest.fDigest)) { | 810 } else if (!expectations.match(actualBitmapAndDigest.fDigest)) { |
799 addToJsonSummary = true; | 811 addToJsonSummary = true; |
800 // The error mode we record depends on whether this was running | 812 // The error mode we record depends on whether this was running |
801 // in a non-standard renderMode. | 813 // in a non-standard renderMode. |
802 if ('\0' == *renderModeDescriptor) { | 814 if ('\0' == *renderModeDescriptor) { |
803 errors.add(kExpectationsMismatch_ErrorType); | 815 errors.add(kExpectationsMismatch_ErrorType); |
804 } else { | 816 } else { |
805 errors.add(kRenderModeMismatch_ErrorType); | 817 errors.add(kRenderModeMismatch_ErrorType); |
806 } | 818 } |
807 | 819 |
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1171 | 1183 |
1172 // | 1184 // |
1173 // member variables. | 1185 // member variables. |
1174 // They are public for now, to allow easier setting by tool_main(). | 1186 // They are public for now, to allow easier setting by tool_main(). |
1175 // | 1187 // |
1176 | 1188 |
1177 bool fUseFileHierarchy, fWriteChecksumBasedFilenames; | 1189 bool fUseFileHierarchy, fWriteChecksumBasedFilenames; |
1178 ErrorCombination fIgnorableErrorTypes; | 1190 ErrorCombination fIgnorableErrorTypes; |
1179 | 1191 |
1180 const char* fMismatchPath; | 1192 const char* fMismatchPath; |
1193 const char* fMissingExpectationsPath; | |
1181 | 1194 |
1182 // collection of tests that have failed with each ErrorType | 1195 // collection of tests that have failed with each ErrorType |
1183 SkTArray<SkString> fFailedTests[kLast_ErrorType+1]; | 1196 SkTArray<SkString> fFailedTests[kLast_ErrorType+1]; |
1184 int fTestsRun; | 1197 int fTestsRun; |
1185 SkTDict<int> fRenderModesEncountered; | 1198 SkTDict<int> fRenderModesEncountered; |
1186 | 1199 |
1187 // Where to read expectations (expected image hash digests, etc.) from. | 1200 // Where to read expectations (expected image hash digests, etc.) from. |
1188 // If unset, we don't do comparisons. | 1201 // If unset, we don't do comparisons. |
1189 SkAutoTUnref<ExpectationsSource> fExpectationsSource; | 1202 SkAutoTUnref<ExpectationsSource> fExpectationsSource; |
1190 | 1203 |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1310 "Space-separated list of ErrorTypes that should be ignored. If any *other* error " | 1323 "Space-separated list of ErrorTypes that should be ignored. If any *other* error " |
1311 "types are encountered, the tool will exit with a nonzero return v alue."); | 1324 "types are encountered, the tool will exit with a nonzero return v alue."); |
1312 DEFINE_string(match, "", "[~][^]substring[$] [...] of test name to run.\n" | 1325 DEFINE_string(match, "", "[~][^]substring[$] [...] of test name to run.\n" |
1313 "Multiple matches may be separated by spaces.\n" | 1326 "Multiple matches may be separated by spaces.\n" |
1314 "~ causes a matching test to always be skipped\n" | 1327 "~ causes a matching test to always be skipped\n" |
1315 "^ requires the start of the test to match\n" | 1328 "^ requires the start of the test to match\n" |
1316 "$ requires the end of the test to match\n" | 1329 "$ requires the end of the test to match\n" |
1317 "^ and $ requires an exact match\n" | 1330 "^ and $ requires an exact match\n" |
1318 "If a test does not match any list entry,\n" | 1331 "If a test does not match any list entry,\n" |
1319 "it is skipped unless some list entry starts with ~"); | 1332 "it is skipped unless some list entry starts with ~"); |
1333 DEFINE_string(missingExpectationsPath, "", "Write images for tests without expec tations " | |
1334 "into this directory."); | |
1320 DEFINE_string(mismatchPath, "", "Write images for tests that failed due to " | 1335 DEFINE_string(mismatchPath, "", "Write images for tests that failed due to " |
1321 "pixel mismatches into this directory."); | 1336 "pixel mismatches into this directory."); |
1322 DEFINE_string(modulo, "", "[--modulo <remainder> <divisor>]: only run tests for which " | 1337 DEFINE_string(modulo, "", "[--modulo <remainder> <divisor>]: only run tests for which " |
1323 "testIndex %% divisor == remainder."); | 1338 "testIndex %% divisor == remainder."); |
1324 DEFINE_bool(pdf, true, "Exercise the pdf rendering test pass."); | 1339 DEFINE_bool(pdf, true, "Exercise the pdf rendering test pass."); |
1325 DEFINE_bool(pipe, true, "Exercise the SkGPipe replay test pass."); | 1340 DEFINE_bool(pipe, true, "Exercise the SkGPipe replay test pass."); |
1326 DEFINE_string2(readPath, r, "", "Read reference images from this dir, and report " | 1341 DEFINE_string2(readPath, r, "", "Read reference images from this dir, and report " |
1327 "any differences between those and the newly generated ones."); | 1342 "any differences between those and the newly generated ones."); |
1328 DEFINE_bool(replay, true, "Exercise the SkPicture replay test pass."); | 1343 DEFINE_bool(replay, true, "Exercise the SkPicture replay test pass."); |
1329 DEFINE_string2(resourcePath, i, "", "Directory that stores image resources."); | 1344 DEFINE_string2(resourcePath, i, "", "Directory that stores image resources."); |
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1792 SkString usage; | 1807 SkString usage; |
1793 usage.printf("Run the golden master tests.\n"); | 1808 usage.printf("Run the golden master tests.\n"); |
1794 SkCommandLineFlags::SetUsage(usage.c_str()); | 1809 SkCommandLineFlags::SetUsage(usage.c_str()); |
1795 SkCommandLineFlags::Parse(argc, argv); | 1810 SkCommandLineFlags::Parse(argc, argv); |
1796 | 1811 |
1797 gmmain.fUseFileHierarchy = FLAGS_hierarchy; | 1812 gmmain.fUseFileHierarchy = FLAGS_hierarchy; |
1798 gmmain.fWriteChecksumBasedFilenames = FLAGS_writeChecksumBasedFilenames; | 1813 gmmain.fWriteChecksumBasedFilenames = FLAGS_writeChecksumBasedFilenames; |
1799 if (FLAGS_mismatchPath.count() == 1) { | 1814 if (FLAGS_mismatchPath.count() == 1) { |
1800 gmmain.fMismatchPath = FLAGS_mismatchPath[0]; | 1815 gmmain.fMismatchPath = FLAGS_mismatchPath[0]; |
1801 } | 1816 } |
1817 if (FLAGS_missingExpectationsPath.count() == 1) { | |
1818 gmmain.fMissingExpectationsPath = FLAGS_missingExpectationsPath[0]; | |
1819 } | |
1802 | 1820 |
1803 for (int i = 0; i < FLAGS_config.count(); i++) { | 1821 for (int i = 0; i < FLAGS_config.count(); i++) { |
1804 const char* config = FLAGS_config[i]; | 1822 const char* config = FLAGS_config[i]; |
1805 userConfig = true; | 1823 userConfig = true; |
1806 bool exclude = false; | 1824 bool exclude = false; |
1807 if (*config == kExcludeConfigChar) { | 1825 if (*config == kExcludeConfigChar) { |
1808 exclude = true; | 1826 exclude = true; |
1809 config += 1; | 1827 config += 1; |
1810 } | 1828 } |
1811 int index = findConfig(config); | 1829 int index = findConfig(config); |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1980 JsonExpectationsSource, (readPath))); | 1998 JsonExpectationsSource, (readPath))); |
1981 } | 1999 } |
1982 } | 2000 } |
1983 if (FLAGS_verbose) { | 2001 if (FLAGS_verbose) { |
1984 if (FLAGS_writePath.count() == 1) { | 2002 if (FLAGS_writePath.count() == 1) { |
1985 gm_fprintf(stdout, "writing to %s\n", FLAGS_writePath[0]); | 2003 gm_fprintf(stdout, "writing to %s\n", FLAGS_writePath[0]); |
1986 } | 2004 } |
1987 if (NULL != gmmain.fMismatchPath) { | 2005 if (NULL != gmmain.fMismatchPath) { |
1988 gm_fprintf(stdout, "writing mismatches to %s\n", gmmain.fMismatchPat h); | 2006 gm_fprintf(stdout, "writing mismatches to %s\n", gmmain.fMismatchPat h); |
1989 } | 2007 } |
2008 if (NULL != gmmain.fMissingExpectationsPath) { | |
2009 gm_fprintf(stdout, "writing images without expectations to %s\n", | |
2010 gmmain.fMissingExpectationsPath); | |
2011 } | |
1990 if (FLAGS_writePicturePath.count() == 1) { | 2012 if (FLAGS_writePicturePath.count() == 1) { |
1991 gm_fprintf(stdout, "writing pictures to %s\n", FLAGS_writePicturePat h[0]); | 2013 gm_fprintf(stdout, "writing pictures to %s\n", FLAGS_writePicturePat h[0]); |
1992 } | 2014 } |
1993 if (FLAGS_resourcePath.count() == 1) { | 2015 if (FLAGS_resourcePath.count() == 1) { |
1994 gm_fprintf(stdout, "reading resources from %s\n", FLAGS_resourcePath [0]); | 2016 gm_fprintf(stdout, "reading resources from %s\n", FLAGS_resourcePath [0]); |
1995 } | 2017 } |
1996 } | 2018 } |
1997 | 2019 |
1998 if (moduloDivisor <= 0) { | 2020 if (moduloDivisor <= 0) { |
1999 moduloRemainder = -1; | 2021 moduloRemainder = -1; |
(...skipping 10 matching lines...) Expand all Loading... | |
2010 if (FLAGS_writePath.count() == 1) { | 2032 if (FLAGS_writePath.count() == 1) { |
2011 if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy , configs)) { | 2033 if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy , configs)) { |
2012 return -1; | 2034 return -1; |
2013 } | 2035 } |
2014 } | 2036 } |
2015 if (NULL != gmmain.fMismatchPath) { | 2037 if (NULL != gmmain.fMismatchPath) { |
2016 if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarc hy, configs)) { | 2038 if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarc hy, configs)) { |
2017 return -1; | 2039 return -1; |
2018 } | 2040 } |
2019 } | 2041 } |
2042 if (NULL != gmmain.fMissingExpectationsPath) { | |
2043 if (!prepare_subdirectories(gmmain.fMissingExpectationsPath, gmmain.fUse FileHierarchy, | |
2044 configs)) { | |
2045 return -1; | |
2046 } | |
2047 } | |
2020 | 2048 |
2021 if (FLAGS_pdfJpegQuality < -1 || FLAGS_pdfJpegQuality > 100) { | 2049 if (FLAGS_pdfJpegQuality < -1 || FLAGS_pdfJpegQuality > 100) { |
2022 gm_fprintf(stderr, "%s\n", "pdfJpegQuality must be in [-1 .. 100] range. "); | 2050 gm_fprintf(stderr, "%s\n", "pdfJpegQuality must be in [-1 .. 100] range. "); |
2023 } | 2051 } |
2024 | 2052 |
2025 Iter iter; | 2053 Iter iter; |
2026 GM* gm; | 2054 GM* gm; |
2027 while ((gm = iter.next()) != NULL) { | 2055 while ((gm = iter.next()) != NULL) { |
2028 SkAutoTDelete<GM> adgm(gm); | 2056 SkAutoTDelete<GM> adgm(gm); |
2029 ++gmIndex; | 2057 ++gmIndex; |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2121 if (FLAGS_forceBWtext) { | 2149 if (FLAGS_forceBWtext) { |
2122 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 2150 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); |
2123 } | 2151 } |
2124 } | 2152 } |
2125 | 2153 |
2126 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 2154 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
2127 int main(int argc, char * const argv[]) { | 2155 int main(int argc, char * const argv[]) { |
2128 return tool_main(argc, (char**) argv); | 2156 return tool_main(argc, (char**) argv); |
2129 } | 2157 } |
2130 #endif | 2158 #endif |
OLD | NEW |