| 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 * |
| 11 * If you make changes to this, re-run the self-tests at gm/tests/run.sh | 11 * If you make changes to this, re-run the self-tests at gm/tests/run.sh |
| 12 * to make sure they still pass... you may need to change the expected | 12 * to make sure they still pass... you may need to change the expected |
| 13 * results of the self-test. | 13 * results of the self-test. |
| 14 */ | 14 */ |
| 15 | 15 |
| 16 #include "gm.h" | 16 #include "gm.h" |
| 17 #include "gm_expectations.h" | 17 #include "gm_expectations.h" |
| 18 #include "system_preferences.h" | 18 #include "system_preferences.h" |
| 19 #include "SkBitmap.h" | 19 #include "SkBitmap.h" |
| 20 #include "SkBitmapChecksummer.h" | 20 #include "SkBitmapChecksummer.h" |
| 21 #include "SkColorPriv.h" | 21 #include "SkColorPriv.h" |
| 22 #include "SkData.h" | 22 #include "SkData.h" |
| 23 #include "SkDeferredCanvas.h" | 23 #include "SkDeferredCanvas.h" |
| 24 #include "SkDevice.h" | 24 #include "SkDevice.h" |
| 25 #include "SkDrawFilter.h" | 25 #include "SkDrawFilter.h" |
| 26 #include "SkFlags.h" |
| 26 #include "SkGPipe.h" | 27 #include "SkGPipe.h" |
| 27 #include "SkGraphics.h" | 28 #include "SkGraphics.h" |
| 28 #include "SkImageDecoder.h" | 29 #include "SkImageDecoder.h" |
| 29 #include "SkImageEncoder.h" | 30 #include "SkImageEncoder.h" |
| 30 #include "SkOSFile.h" | 31 #include "SkOSFile.h" |
| 31 #include "SkPicture.h" | 32 #include "SkPicture.h" |
| 32 #include "SkRefCnt.h" | 33 #include "SkRefCnt.h" |
| 33 #include "SkStream.h" | 34 #include "SkStream.h" |
| 34 #include "SkTArray.h" | 35 #include "SkTArray.h" |
| 35 #include "SkTileGridPicture.h" | 36 #include "SkTileGridPicture.h" |
| (...skipping 14 matching lines...) Expand all Loading... |
| 50 #include "GrContextFactory.h" | 51 #include "GrContextFactory.h" |
| 51 #include "GrRenderTarget.h" | 52 #include "GrRenderTarget.h" |
| 52 #include "SkGpuDevice.h" | 53 #include "SkGpuDevice.h" |
| 53 typedef GrContextFactory::GLContextType GLContextType; | 54 typedef GrContextFactory::GLContextType GLContextType; |
| 54 #else | 55 #else |
| 55 class GrContext; | 56 class GrContext; |
| 56 class GrRenderTarget; | 57 class GrRenderTarget; |
| 57 typedef int GLContextType; | 58 typedef int GLContextType; |
| 58 #endif | 59 #endif |
| 59 | 60 |
| 60 static bool gForceBWtext; | |
| 61 | |
| 62 extern bool gSkSuppressFontCachePurgeSpew; | 61 extern bool gSkSuppressFontCachePurgeSpew; |
| 63 | 62 |
| 64 #ifdef SK_SUPPORT_PDF | 63 #ifdef SK_SUPPORT_PDF |
| 65 #include "SkPDFDevice.h" | 64 #include "SkPDFDevice.h" |
| 66 #include "SkPDFDocument.h" | 65 #include "SkPDFDocument.h" |
| 67 #endif | 66 #endif |
| 68 | 67 |
| 69 // Until we resolve http://code.google.com/p/skia/issues/detail?id=455 , | 68 // Until we resolve http://code.google.com/p/skia/issues/detail?id=455 , |
| 70 // stop writing out XPS-format image baselines in gm. | 69 // stop writing out XPS-format image baselines in gm. |
| 71 #undef SK_SUPPORT_XPS | 70 #undef SK_SUPPORT_XPS |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 * CON: Math is hard. | 356 * CON: Math is hard. |
| 358 * | 357 * |
| 359 * 4. Perform a "close enough" comparison of bitmaps (+/- 1 bit in each | 358 * 4. Perform a "close enough" comparison of bitmaps (+/- 1 bit in each |
| 360 * channel), rather than demanding absolute equality. | 359 * channel), rather than demanding absolute equality. |
| 361 * CON: Can't do this with checksums. | 360 * CON: Can't do this with checksums. |
| 362 */ | 361 */ |
| 363 static void complete_bitmap(SkBitmap* bitmap) { | 362 static void complete_bitmap(SkBitmap* bitmap) { |
| 364 force_all_opaque(*bitmap); | 363 force_all_opaque(*bitmap); |
| 365 } | 364 } |
| 366 | 365 |
| 367 static void installFilter(SkCanvas* canvas) { | 366 static void installFilter(SkCanvas* canvas); |
| 368 if (gForceBWtext) { | |
| 369 canvas->setDrawFilter(new BWTextDrawFilter)->unref(); | |
| 370 } | |
| 371 } | |
| 372 | 367 |
| 373 static void invokeGM(GM* gm, SkCanvas* canvas, bool isPDF, bool isDeferred)
{ | 368 static void invokeGM(GM* gm, SkCanvas* canvas, bool isPDF, bool isDeferred)
{ |
| 374 SkAutoCanvasRestore acr(canvas, true); | 369 SkAutoCanvasRestore acr(canvas, true); |
| 375 | 370 |
| 376 if (!isPDF) { | 371 if (!isPDF) { |
| 377 canvas->concat(gm->getInitialTransform()); | 372 canvas->concat(gm->getInitialTransform()); |
| 378 } | 373 } |
| 379 installFilter(canvas); | 374 installFilter(canvas); |
| 380 gm->setCanvasIsDeferred(isDeferred); | 375 gm->setCanvasIsDeferred(isDeferred); |
| 381 gm->draw(canvas); | 376 gm->draw(canvas); |
| (...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 | 814 |
| 820 // To do in-memory commiunications with a stream, we need to: | 815 // To do in-memory commiunications with a stream, we need to: |
| 821 // * create a dynamic memory stream | 816 // * create a dynamic memory stream |
| 822 // * copy it into a buffer | 817 // * copy it into a buffer |
| 823 // * create a read stream from it | 818 // * create a read stream from it |
| 824 // ?!?! | 819 // ?!?! |
| 825 | 820 |
| 826 SkDynamicMemoryWStream storage; | 821 SkDynamicMemoryWStream storage; |
| 827 src.serialize(&storage); | 822 src.serialize(&storage); |
| 828 | 823 |
| 829 int streamSize = storage.getOffset(); | 824 size_t streamSize = storage.getOffset(); |
| 830 SkAutoMalloc dstStorage(streamSize); | 825 SkAutoMalloc dstStorage(streamSize); |
| 831 void* dst = dstStorage.get(); | 826 void* dst = dstStorage.get(); |
| 832 //char* dst = new char [streamSize]; | 827 //char* dst = new char [streamSize]; |
| 833 //@todo thudson 22 April 2011 when can we safely delete [] dst? | 828 //@todo thudson 22 April 2011 when can we safely delete [] dst? |
| 834 storage.copyTo(dst); | 829 storage.copyTo(dst); |
| 835 SkMemoryStream pictReadback(dst, streamSize); | 830 SkMemoryStream pictReadback(dst, streamSize); |
| 836 SkPicture* retval = new SkPicture (&pictReadback); | 831 SkPicture* retval = new SkPicture (&pictReadback); |
| 837 return retval; | 832 return retval; |
| 838 } | 833 } |
| 839 | 834 |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 #endif // SK_SUPPORT_GPU | 1001 #endif // SK_SUPPORT_GPU |
| 1007 #ifdef SK_SUPPORT_XPS | 1002 #ifdef SK_SUPPORT_XPS |
| 1008 /* At present we have no way of comparing XPS files (either natively or by c
onverting to PNG). */ | 1003 /* At present we have no way of comparing XPS files (either natively or by c
onverting to PNG). */ |
| 1009 { SkBitmap::kARGB_8888_Config, kXPS_Backend, kDontCare_GLContextType,
0, kWrite_ConfigFlag, "xps", true }, | 1004 { SkBitmap::kARGB_8888_Config, kXPS_Backend, kDontCare_GLContextType,
0, kWrite_ConfigFlag, "xps", true }, |
| 1010 #endif // SK_SUPPORT_XPS | 1005 #endif // SK_SUPPORT_XPS |
| 1011 #ifdef SK_SUPPORT_PDF | 1006 #ifdef SK_SUPPORT_PDF |
| 1012 { SkBitmap::kARGB_8888_Config, kPDF_Backend, kDontCare_GLContextType,
0, kPDFConfigFlags, "pdf", true }, | 1007 { SkBitmap::kARGB_8888_Config, kPDF_Backend, kDontCare_GLContextType,
0, kPDFConfigFlags, "pdf", true }, |
| 1013 #endif // SK_SUPPORT_PDF | 1008 #endif // SK_SUPPORT_PDF |
| 1014 }; | 1009 }; |
| 1015 | 1010 |
| 1016 static void usage(const char * argv0) { | 1011 static SkString configUsage() { |
| 1017 fprintf(stderr, "%s\n", argv0); | 1012 SkString result("Possible options for --config: ["); |
| 1018 fprintf(stderr, " [--config "); | |
| 1019 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | 1013 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { |
| 1020 if (i > 0) { | 1014 if (i > 0) { |
| 1021 fprintf(stderr, "|"); | 1015 result.appendf("|"); |
| 1022 } | 1016 } |
| 1023 fprintf(stderr, "%s", gRec[i].fName); | 1017 result.appendf("%s", gRec[i].fName); |
| 1024 } | 1018 } |
| 1025 fprintf(stderr, "]:\n run these configurations\n"); | 1019 result.appendf("]"); |
| 1026 fprintf(stderr, | 1020 return result; |
| 1021 } |
| 1022 |
| 1027 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath"). | 1023 // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath"). |
| 1028 // It would probably be better if we allowed both yes-and-no settings for each | 1024 DEFINE_string(config, "", "Space delimited list of which configs to run. " |
| 1029 // one, e.g.: | 1025 "Possible configs listed above. If none are specified, " |
| 1030 // [--replay|--noreplay]: whether to exercise SkPicture replay; default is yes | 1026 "all will be run."); |
| 1031 " [--nodeferred]: skip the deferred rendering test pass\n" | 1027 DEFINE_bool(deferred, true, "Exercise the deferred rendering test pass."); |
| 1032 " [--disable-missing-warning]: don't print a message to stderr if\n" | 1028 DEFINE_bool(enableMissingWarning, true, "Print message to stderr (but don't fail
) if " |
| 1033 " unable to read a reference image for any tests (NOT default behavior)\n
" | 1029 "unable to read a reference image for any tests."); |
| 1034 " [--enable-missing-warning]: print message to stderr (but don't fail) if\n" | 1030 DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip."); |
| 1035 " unable to read a reference image for any tests (default behavior)\n" | 1031 DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing."); |
| 1036 " [--exclude-config]: disable this config (may be used multiple times)\n" | |
| 1037 " [--forceBWtext]: disable text anti-aliasing\n" | |
| 1038 #if SK_SUPPORT_GPU | 1032 #if SK_SUPPORT_GPU |
| 1039 " [--gpuCacheSize <bytes> <count>]: limits gpu cache to byte size or object c
ount\n" | 1033 DEFINE_string(gpuCacheSize, "", "<bytes> <count>: Limit the gpu cache to byte si
ze or " |
| 1040 " -1 for either value means use the default. 0 for either disables the ca
che.\n" | 1034 "object count. -1 for either value means use the default. 0 for ei
ther " |
| 1035 "disables the cache."); |
| 1041 #endif | 1036 #endif |
| 1042 " [--help|-h]: show this help message\n" | 1037 DEFINE_bool(hierarchy, false, "Whether to use multilevel directory structure " |
| 1043 " [--hierarchy|--nohierarchy]: whether to use multilevel directory structure\
n" | 1038 "when reading/writing files."); |
| 1044 " when reading/writing files; default is no\n" | 1039 DEFINE_string(match, "", "Only run tests whose name includes this substring/the
se substrings " |
| 1045 " [--match <substring>]: only run tests whose name includes this substring\n" | 1040 "(more than one can be supplied, separated by spaces)."); |
| 1046 " [--mismatchPath <path>]: write images for tests that failed due to\n" | 1041 DEFINE_string(mismatchPath, "", "Write images for tests that failed due to " |
| 1047 " pixel mismatched into this directory" | 1042 "pixel mismatches into this directory."); |
| 1048 " [--modulo <remainder> <divisor>]: only run tests for which \n" | 1043 DEFINE_string(modulo, "", "[--modulo <remainder> <divisor>]: only run tests for
which " |
| 1049 " testIndex %% divisor == remainder\n" | 1044 "testIndex %% divisor == remainder."); |
| 1050 " [--nopdf]: skip the pdf rendering test pass\n" | 1045 DEFINE_bool(pdf, true, "Exercise the pdf rendering test pass."); |
| 1051 " [--nopipe]: Skip SkGPipe replay\n" | 1046 DEFINE_bool(pipe, true, "Exercise the SkGPipe replay test pass."); |
| 1052 " [--readPath|-r <path>]: read reference images from this dir, and report\n" | 1047 DEFINE_string2(readPath, r, "", "Read reference images from this dir, and report
" |
| 1053 " any differences between those and the newly generated ones\n" | 1048 "any differences between those and the newly generated ones."); |
| 1054 " [--noreplay]: do not exercise SkPicture replay\n" | 1049 DEFINE_bool(replay, true, "Exercise the SkPicture replay test pass."); |
| 1055 " [--resourcePath|-i <path>]: directory that stores image resources\n" | 1050 DEFINE_string2(resourcePath, i, "", "Directory that stores image resources."); |
| 1056 " [--nortree]: Do not exercise the R-Tree variant of SkPicture\n" | 1051 DEFINE_bool(rtree, true, "Exercise the R-Tree variant of SkPicture test pass."); |
| 1057 " [--noserialize]: do not exercise SkPicture serialization & deserialization\
n" | 1052 DEFINE_bool(serialize, true, "Exercise the SkPicture serialization & deserializa
tion test pass."); |
| 1058 " [--tiledPipe]: Exercise tiled SkGPipe replay\n" | 1053 DEFINE_bool(tiledPipe, false, "Exercise tiled SkGPipe replay."); |
| 1059 " [--notileGrid]: Do not exercise the tile grid variant of SkPicture\n" | 1054 DEFINE_bool(tileGrid, true, "Exercise the tile grid variant of SkPicture."); |
| 1060 " [--tileGridReplayScales <scales>]: Comma separated list of floating-point s
cale\n" | 1055 DEFINE_string(tileGridReplayScales, "", "Space separated list of floating-point
scale " |
| 1061 " factors to be used for tileGrid playback testing. Default value: 1.0\n" | 1056 "factors to be used for tileGrid playback testing. Default value:
1.0"); |
| 1062 " [--writeJsonSummary <path>]: write a JSON-formatted result summary to this
file\n" | 1057 DEFINE_string(writeJsonSummaryPath, "", "Write a JSON-formatted result summary t
o this file."); |
| 1063 " [--verbose] print diagnostics (e.g. list each config to be tested)\n" | 1058 DEFINE_bool2(verbose, v, false, "Print diagnostics (e.g. list each config to be
tested)."); |
| 1064 " [--writePath|-w <path>]: write rendered images into this directory\n" | 1059 DEFINE_string2(writePath, w, "", "Write rendered images into this directory."); |
| 1065 " [--writePicturePath|-wp <path>]: write .skp files into this directory\n" | 1060 DEFINE_string2(writePicturePath, wp, "", "Write .skp files into this directory."
); |
| 1066 ); | |
| 1067 } | |
| 1068 | 1061 |
| 1069 static int findConfig(const char config[]) { | 1062 static int findConfig(const char config[]) { |
| 1070 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) { | 1063 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); i++) { |
| 1071 if (!strcmp(config, gRec[i].fName)) { | 1064 if (!strcmp(config, gRec[i].fName)) { |
| 1072 return i; | 1065 return (int) i; |
| 1073 } | 1066 } |
| 1074 } | 1067 } |
| 1075 return -1; | 1068 return -1; |
| 1076 } | 1069 } |
| 1077 | 1070 |
| 1078 static bool skip_name(const SkTDArray<const char*> array, const char name[]) { | 1071 static bool skip_name(const SkTDArray<const char*> array, const char name[]) { |
| 1079 if (0 == array.count()) { | 1072 if (0 == array.count()) { |
| 1080 // no names, so don't skip anything | 1073 // no names, so don't skip anything |
| 1081 return false; | 1074 return false; |
| 1082 } | 1075 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1144 gPrintInstCount = true; | 1137 gPrintInstCount = true; |
| 1145 #endif | 1138 #endif |
| 1146 | 1139 |
| 1147 SkGraphics::Init(); | 1140 SkGraphics::Init(); |
| 1148 // we don't need to see this during a run | 1141 // we don't need to see this during a run |
| 1149 gSkSuppressFontCachePurgeSpew = true; | 1142 gSkSuppressFontCachePurgeSpew = true; |
| 1150 | 1143 |
| 1151 setSystemPreferences(); | 1144 setSystemPreferences(); |
| 1152 GMMain gmmain; | 1145 GMMain gmmain; |
| 1153 | 1146 |
| 1154 const char* writeJsonSummaryPath = NULL;// if non-null, where we write the J
SON summary | |
| 1155 const char* writePath = NULL; // if non-null, where we write the originals | |
| 1156 const char* writePicturePath = NULL; // if non-null, where we write seria
lized pictures | |
| 1157 const char* readPath = NULL; // if non-null, were we read from to compare | |
| 1158 const char* resourcePath = NULL;// if non-null, where we read from for image
resources | |
| 1159 | |
| 1160 // if true, emit a message when we can't find a reference image to compare | |
| 1161 bool notifyMissingReadReference = true; | |
| 1162 | |
| 1163 SkTDArray<const char*> fMatches; | |
| 1164 | |
| 1165 bool doPDF = true; | |
| 1166 bool doReplay = true; | |
| 1167 bool doPipe = true; | |
| 1168 bool doTiledPipe = false; | |
| 1169 bool doSerialize = true; | |
| 1170 bool doDeferred = true; | |
| 1171 bool doRTree = true; | |
| 1172 bool doTileGrid = true; | |
| 1173 bool doVerbose = false; | |
| 1174 | |
| 1175 SkTDArray<size_t> configs; | 1147 SkTDArray<size_t> configs; |
| 1176 SkTDArray<size_t> excludeConfigs; | 1148 SkTDArray<size_t> excludeConfigs; |
| 1177 SkTDArray<SkScalar> tileGridReplayScales; | 1149 SkTDArray<SkScalar> tileGridReplayScales; |
| 1178 *tileGridReplayScales.append() = SK_Scalar1; // By default only test at scal
e 1.0 | 1150 *tileGridReplayScales.append() = SK_Scalar1; // By default only test at scal
e 1.0 |
| 1179 bool userConfig = false; | 1151 bool userConfig = false; |
| 1180 | 1152 |
| 1181 int moduloRemainder = -1; | 1153 SkString usage; |
| 1182 int moduloDivisor = -1; | 1154 usage.printf("Run the golden master tests.\n\t%s", configUsage().c_str()); |
| 1155 SkFlags::SetUsage(usage.c_str()); |
| 1156 SkFlags::ParseCommandLine(argc, argv); |
| 1183 | 1157 |
| 1184 #if SK_SUPPORT_GPU | 1158 #if SK_SUPPORT_GPU |
| 1185 struct { | 1159 struct { |
| 1186 int fBytes; | 1160 int fBytes; |
| 1187 int fCount; | 1161 int fCount; |
| 1188 } gpuCacheSize = { -1, -1 }; // -1s mean use the default | 1162 } gpuCacheSize = { -1, -1 }; // -1s mean use the default |
| 1163 |
| 1164 if (FLAGS_gpuCacheSize.count() > 0) { |
| 1165 if (FLAGS_gpuCacheSize.count() != 2) { |
| 1166 gm_fprintf(stderr, "--gpuCacheSize requires two arguments\n"); |
| 1167 return -1; |
| 1168 } |
| 1169 gpuCacheSize.fBytes = atoi(FLAGS_gpuCacheSize[0]); |
| 1170 gpuCacheSize.fCount = atoi(FLAGS_gpuCacheSize[1]); |
| 1171 } |
| 1189 #endif | 1172 #endif |
| 1190 | 1173 |
| 1191 const char* const commandName = argv[0]; | 1174 gmmain.fUseFileHierarchy = FLAGS_hierarchy; |
| 1192 char* const* stop = argv + argc; | 1175 if (FLAGS_mismatchPath.count() == 1) { |
| 1193 for (++argv; argv < stop; ++argv) { | 1176 gmmain.fMismatchPath = FLAGS_mismatchPath[0]; |
| 1194 if (strcmp(*argv, "--config") == 0) { | 1177 } |
| 1195 argv++; | |
| 1196 if (argv < stop) { | |
| 1197 int index = findConfig(*argv); | |
| 1198 if (index >= 0) { | |
| 1199 appendUnique<size_t>(&configs, index); | |
| 1200 userConfig = true; | |
| 1201 } else { | |
| 1202 gm_fprintf(stderr, "unrecognized config %s\n", *argv); | |
| 1203 usage(commandName); | |
| 1204 return -1; | |
| 1205 } | |
| 1206 } else { | |
| 1207 gm_fprintf(stderr, "missing arg for --config\n"); | |
| 1208 usage(commandName); | |
| 1209 return -1; | |
| 1210 } | |
| 1211 } else if (strcmp(*argv, "--exclude-config") == 0) { | |
| 1212 argv++; | |
| 1213 if (argv < stop) { | |
| 1214 int index = findConfig(*argv); | |
| 1215 if (index >= 0) { | |
| 1216 *excludeConfigs.append() = index; | |
| 1217 } else { | |
| 1218 gm_fprintf(stderr, "unrecognized exclude-config %s\n", *argv
); | |
| 1219 usage(commandName); | |
| 1220 return -1; | |
| 1221 } | |
| 1222 } else { | |
| 1223 gm_fprintf(stderr, "missing arg for --exclude-config\n"); | |
| 1224 usage(commandName); | |
| 1225 return -1; | |
| 1226 } | |
| 1227 } else if (strcmp(*argv, "--nodeferred") == 0) { | |
| 1228 doDeferred = false; | |
| 1229 } else if (strcmp(*argv, "--disable-missing-warning") == 0) { | |
| 1230 notifyMissingReadReference = false; | |
| 1231 } else if (strcmp(*argv, "--mismatchPath") == 0) { | |
| 1232 argv++; | |
| 1233 if (argv < stop && **argv) { | |
| 1234 gmmain.fMismatchPath = *argv; | |
| 1235 } | |
| 1236 } else if (strcmp(*argv, "--nortree") == 0) { | |
| 1237 doRTree = false; | |
| 1238 } else if (strcmp(*argv, "--notileGrid") == 0) { | |
| 1239 doTileGrid = false; | |
| 1240 } else if (strcmp(*argv, "--tileGridReplayScales") == 0) { | |
| 1241 tileGridReplayScales.reset(); | |
| 1242 ++argv; | |
| 1243 if (argv < stop) { | |
| 1244 char* token = strtok(*argv, ","); | |
| 1245 while (NULL != token) { | |
| 1246 double val = atof(token); | |
| 1247 if (0 < val) { | |
| 1248 *tileGridReplayScales.append() = SkDoubleToScalar(val); | |
| 1249 } | |
| 1250 token = strtok(NULL, ","); | |
| 1251 } | |
| 1252 } | |
| 1253 if (0 == tileGridReplayScales.count()) { | |
| 1254 // Should have at least one scale | |
| 1255 usage(commandName); | |
| 1256 return -1; | |
| 1257 } | |
| 1258 } else if (strcmp(*argv, "--enable-missing-warning") == 0) { | |
| 1259 notifyMissingReadReference = true; | |
| 1260 } else if (strcmp(*argv, "--forceBWtext") == 0) { | |
| 1261 gForceBWtext = true; | |
| 1262 #if SK_SUPPORT_GPU | |
| 1263 } else if (strcmp(*argv, "--gpuCacheSize") == 0) { | |
| 1264 if (stop - argv > 2) { | |
| 1265 gpuCacheSize.fBytes = atoi(*++argv); | |
| 1266 gpuCacheSize.fCount = atoi(*++argv); | |
| 1267 } else { | |
| 1268 gm_fprintf(stderr, "missing arg for --gpuCacheSize\n"); | |
| 1269 usage(commandName); | |
| 1270 return -1; | |
| 1271 } | |
| 1272 #endif | |
| 1273 } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) { | |
| 1274 usage(commandName); | |
| 1275 return -1; | |
| 1276 } else if (strcmp(*argv, "--hierarchy") == 0) { | |
| 1277 gmmain.fUseFileHierarchy = true; | |
| 1278 } else if (strcmp(*argv, "--nohierarchy") == 0) { | |
| 1279 gmmain.fUseFileHierarchy = false; | |
| 1280 } else if (strcmp(*argv, "--match") == 0) { | |
| 1281 ++argv; | |
| 1282 if (argv < stop && **argv) { | |
| 1283 // just record the ptr, no need for a deep copy | |
| 1284 *fMatches.append() = *argv; | |
| 1285 } | |
| 1286 } else if (strcmp(*argv, "--modulo") == 0) { | |
| 1287 ++argv; | |
| 1288 if (argv >= stop) { | |
| 1289 continue; | |
| 1290 } | |
| 1291 moduloRemainder = atoi(*argv); | |
| 1292 | 1178 |
| 1293 ++argv; | 1179 for (int i = 0; i < FLAGS_config.count(); i++) { |
| 1294 if (argv >= stop) { | 1180 int index = findConfig(FLAGS_config[i]); |
| 1295 continue; | 1181 if (index >= 0) { |
| 1296 } | 1182 appendUnique<size_t>(&configs, index); |
| 1297 moduloDivisor = atoi(*argv); | 1183 userConfig = true; |
| 1298 if (moduloRemainder < 0 || moduloDivisor <= 0 || moduloRemainder >=
moduloDivisor) { | |
| 1299 gm_fprintf(stderr, "invalid modulo values."); | |
| 1300 return -1; | |
| 1301 } | |
| 1302 } else if (strcmp(*argv, "--nopdf") == 0) { | |
| 1303 doPDF = false; | |
| 1304 } else if (strcmp(*argv, "--nopipe") == 0) { | |
| 1305 doPipe = false; | |
| 1306 } else if ((0 == strcmp(*argv, "--readPath")) || | |
| 1307 (0 == strcmp(*argv, "-r"))) { | |
| 1308 argv++; | |
| 1309 if (argv < stop && **argv) { | |
| 1310 readPath = *argv; | |
| 1311 } | |
| 1312 } else if (strcmp(*argv, "--noreplay") == 0) { | |
| 1313 doReplay = false; | |
| 1314 } else if ((0 == strcmp(*argv, "--resourcePath")) || | |
| 1315 (0 == strcmp(*argv, "-i"))) { | |
| 1316 argv++; | |
| 1317 if (argv < stop && **argv) { | |
| 1318 resourcePath = *argv; | |
| 1319 } | |
| 1320 } else if (strcmp(*argv, "--serialize") == 0) { | |
| 1321 doSerialize = true; | |
| 1322 } else if (strcmp(*argv, "--noserialize") == 0) { | |
| 1323 doSerialize = false; | |
| 1324 } else if (strcmp(*argv, "--tiledPipe") == 0) { | |
| 1325 doTiledPipe = true; | |
| 1326 } else if (!strcmp(*argv, "--verbose") || !strcmp(*argv, "-v")) { | |
| 1327 doVerbose = true; | |
| 1328 } else if ((0 == strcmp(*argv, "--writePath")) || | |
| 1329 (0 == strcmp(*argv, "-w"))) { | |
| 1330 argv++; | |
| 1331 if (argv < stop && **argv) { | |
| 1332 writePath = *argv; | |
| 1333 } | |
| 1334 } else if (0 == strcmp(*argv, "--writeJsonSummary")) { | |
| 1335 argv++; | |
| 1336 if (argv < stop && **argv) { | |
| 1337 writeJsonSummaryPath = *argv; | |
| 1338 } | |
| 1339 } else if ((0 == strcmp(*argv, "--writePicturePath")) || | |
| 1340 (0 == strcmp(*argv, "-wp"))) { | |
| 1341 argv++; | |
| 1342 if (argv < stop && **argv) { | |
| 1343 writePicturePath = *argv; | |
| 1344 } | |
| 1345 } else { | 1184 } else { |
| 1346 usage(commandName); | 1185 gm_fprintf(stderr, "unrecognized config %s\n", FLAGS_config[i]); |
| 1347 return -1; | 1186 return -1; |
| 1348 } | 1187 } |
| 1349 } | 1188 } |
| 1350 if (argv != stop) { | 1189 |
| 1351 usage(commandName); | 1190 for (int i = 0; i < FLAGS_excludeConfig.count(); i++) { |
| 1352 return -1; | 1191 int index = findConfig(FLAGS_excludeConfig[i]); |
| 1192 if (index >= 0) { |
| 1193 *excludeConfigs.append() = index; |
| 1194 } else { |
| 1195 gm_fprintf(stderr, "unrecognized excludeConfig %s\n", FLAGS_excludeC
onfig[i]); |
| 1196 return -1; |
| 1197 } |
| 1198 } |
| 1199 |
| 1200 if (FLAGS_tileGridReplayScales.count() > 0) { |
| 1201 tileGridReplayScales.reset(); |
| 1202 for (int i = 0; i < FLAGS_tileGridReplayScales.count(); i++) { |
| 1203 double val = atof(FLAGS_tileGridReplayScales[i]); |
| 1204 if (0 < val) { |
| 1205 *tileGridReplayScales.append() = SkDoubleToScalar(val); |
| 1206 } |
| 1207 } |
| 1208 if (0 == tileGridReplayScales.count()) { |
| 1209 // Should have at least one scale |
| 1210 gm_fprintf(stderr, "--tileGridReplayScales requires at least one sca
le.\n"); |
| 1211 return -1; |
| 1212 } |
| 1213 } |
| 1214 |
| 1215 int moduloRemainder = -1; |
| 1216 int moduloDivisor = -1; |
| 1217 |
| 1218 if (FLAGS_modulo.count() == 2) { |
| 1219 moduloRemainder = atoi(FLAGS_modulo[0]); |
| 1220 moduloDivisor = atoi(FLAGS_modulo[1]); |
| 1221 if (moduloRemainder < 0 || moduloDivisor <= 0 || moduloRemainder >= modu
loDivisor) { |
| 1222 gm_fprintf(stderr, "invalid modulo values."); |
| 1223 return -1; |
| 1224 } |
| 1353 } | 1225 } |
| 1354 | 1226 |
| 1355 if (!userConfig) { | 1227 if (!userConfig) { |
| 1356 // if no config is specified by user, add the defaults | 1228 // if no config is specified by user, add the defaults |
| 1357 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { | 1229 for (size_t i = 0; i < SK_ARRAY_COUNT(gRec); ++i) { |
| 1358 if (gRec[i].fRunByDefault) { | 1230 if (gRec[i].fRunByDefault) { |
| 1359 *configs.append() = i; | 1231 *configs.append() = i; |
| 1360 } | 1232 } |
| 1361 } | 1233 } |
| 1362 } | 1234 } |
| 1363 // now remove any explicitly excluded configs | 1235 // now remove any explicitly excluded configs |
| 1364 for (int i = 0; i < excludeConfigs.count(); ++i) { | 1236 for (int i = 0; i < excludeConfigs.count(); ++i) { |
| 1365 int index = configs.find(excludeConfigs[i]); | 1237 int index = configs.find(excludeConfigs[i]); |
| 1366 if (index >= 0) { | 1238 if (index >= 0) { |
| 1367 configs.remove(index); | 1239 configs.remove(index); |
| 1368 // now assert that there was only one copy in configs[] | 1240 // now assert that there was only one copy in configs[] |
| 1369 SkASSERT(configs.find(excludeConfigs[i]) < 0); | 1241 SkASSERT(configs.find(excludeConfigs[i]) < 0); |
| 1370 } | 1242 } |
| 1371 } | 1243 } |
| 1372 | 1244 |
| 1373 #if SK_SUPPORT_GPU | 1245 #if SK_SUPPORT_GPU |
| 1374 GrContextFactory* grFactory = new GrContextFactory; | 1246 GrContextFactory* grFactory = new GrContextFactory; |
| 1375 for (int i = 0; i < configs.count(); ++i) { | 1247 for (int i = 0; i < configs.count(); ++i) { |
| 1376 int index = configs[i]; | 1248 size_t index = configs[i]; |
| 1377 if (kGPU_Backend == gRec[index].fBackend) { | 1249 if (kGPU_Backend == gRec[index].fBackend) { |
| 1378 GrContext* ctx = grFactory->get(gRec[index].fGLContextType); | 1250 GrContext* ctx = grFactory->get(gRec[index].fGLContextType); |
| 1379 if (NULL == ctx) { | 1251 if (NULL == ctx) { |
| 1380 SkDebugf("GrContext could not be created for config %s. Config w
ill be skipped.", | 1252 SkDebugf("GrContext could not be created for config %s. Config w
ill be skipped.", |
| 1381 gRec[index].fName); | 1253 gRec[index].fName); |
| 1382 configs.remove(i); | 1254 configs.remove(i); |
| 1383 --i; | 1255 --i; |
| 1384 } | 1256 } |
| 1385 if (gRec[index].fSampleCnt > ctx->getMaxSampleCount()) { | 1257 if (gRec[index].fSampleCnt > ctx->getMaxSampleCount()) { |
| 1386 SkDebugf("Sample count (%d) of config %s is not supported. Confi
g will be skipped.", | 1258 SkDebugf("Sample count (%d) of config %s is not supported. Confi
g will be skipped.", |
| 1387 gRec[index].fSampleCnt, gRec[index].fName); | 1259 gRec[index].fSampleCnt, gRec[index].fName); |
| 1388 configs.remove(i); | 1260 configs.remove(i); |
| 1389 --i; | 1261 --i; |
| 1390 } | 1262 } |
| 1391 } | 1263 } |
| 1392 } | 1264 } |
| 1393 #endif | 1265 #endif |
| 1394 | 1266 |
| 1395 if (doVerbose) { | 1267 if (FLAGS_verbose) { |
| 1396 SkString str; | 1268 SkString str; |
| 1397 str.printf("%d configs:", configs.count()); | 1269 str.printf("%d configs:", configs.count()); |
| 1398 for (int i = 0; i < configs.count(); ++i) { | 1270 for (int i = 0; i < configs.count(); ++i) { |
| 1399 str.appendf(" %s", gRec[configs[i]].fName); | 1271 str.appendf(" %s", gRec[configs[i]].fName); |
| 1400 } | 1272 } |
| 1401 gm_fprintf(stderr, "%s\n", str.c_str()); | 1273 gm_fprintf(stderr, "%s\n", str.c_str()); |
| 1402 } | 1274 } |
| 1403 | 1275 |
| 1404 GM::SetResourcePath(resourcePath); | 1276 if (FLAGS_resourcePath.count() == 1) { |
| 1277 GM::SetResourcePath(FLAGS_resourcePath[0]); |
| 1278 } |
| 1405 | 1279 |
| 1406 if (readPath) { | 1280 if (FLAGS_readPath.count() == 1) { |
| 1281 const char* readPath = FLAGS_readPath[0]; |
| 1407 if (!sk_exists(readPath)) { | 1282 if (!sk_exists(readPath)) { |
| 1408 gm_fprintf(stderr, "readPath %s does not exist!\n", readPath); | 1283 gm_fprintf(stderr, "readPath %s does not exist!\n", readPath); |
| 1409 return -1; | 1284 return -1; |
| 1410 } | 1285 } |
| 1411 if (sk_isdir(readPath)) { | 1286 if (sk_isdir(readPath)) { |
| 1412 gm_fprintf(stdout, "reading from %s\n", readPath); | 1287 gm_fprintf(stdout, "reading from %s\n", readPath); |
| 1413 gmmain.fExpectationsSource.reset(SkNEW_ARGS( | 1288 gmmain.fExpectationsSource.reset(SkNEW_ARGS( |
| 1414 IndividualImageExpectationsSource, | 1289 IndividualImageExpectationsSource, |
| 1415 (readPath, notifyMissingReadReference))); | 1290 (readPath, FLAGS_enableMissingWarning))); |
| 1416 } else { | 1291 } else { |
| 1417 gm_fprintf(stdout, "reading expectations from JSON summary file %s\n
", readPath); | 1292 gm_fprintf(stdout, "reading expectations from JSON summary file %s\n
", readPath); |
| 1418 gmmain.fExpectationsSource.reset(SkNEW_ARGS( | 1293 gmmain.fExpectationsSource.reset(SkNEW_ARGS( |
| 1419 JsonExpectationsSource, (readPath))); | 1294 JsonExpectationsSource, (readPath))); |
| 1420 } | 1295 } |
| 1421 } | 1296 } |
| 1422 if (writePath) { | 1297 if (FLAGS_writePath.count() == 1) { |
| 1423 gm_fprintf(stdout, "writing to %s\n", writePath); | 1298 gm_fprintf(stderr, "writing to %s\n", FLAGS_writePath[0]); |
| 1424 } | 1299 } |
| 1425 if (writePicturePath) { | 1300 if (FLAGS_writePicturePath.count() == 1) { |
| 1426 gm_fprintf(stdout, "writing pictures to %s\n", writePicturePath); | 1301 gm_fprintf(stderr, "writing pictures to %s\n", FLAGS_writePicturePath[0]
); |
| 1427 } | 1302 } |
| 1428 if (resourcePath) { | 1303 if (FLAGS_resourcePath.count() == 1) { |
| 1429 gm_fprintf(stdout, "reading resources from %s\n", resourcePath); | 1304 gm_fprintf(stderr, "reading resources from %s\n", FLAGS_resourcePath[0])
; |
| 1430 } | 1305 } |
| 1431 | 1306 |
| 1432 if (moduloDivisor <= 0) { | 1307 if (moduloDivisor <= 0) { |
| 1433 moduloRemainder = -1; | 1308 moduloRemainder = -1; |
| 1434 } | 1309 } |
| 1435 if (moduloRemainder < 0 || moduloRemainder >= moduloDivisor) { | 1310 if (moduloRemainder < 0 || moduloRemainder >= moduloDivisor) { |
| 1436 moduloRemainder = -1; | 1311 moduloRemainder = -1; |
| 1437 } | 1312 } |
| 1438 | 1313 |
| 1439 // Accumulate success of all tests. | 1314 // Accumulate success of all tests. |
| 1440 int testsRun = 0; | 1315 int testsRun = 0; |
| 1441 int testsPassed = 0; | 1316 int testsPassed = 0; |
| 1442 int testsFailed = 0; | 1317 int testsFailed = 0; |
| 1443 int testsMissingReferenceImages = 0; | 1318 int testsMissingReferenceImages = 0; |
| 1444 | 1319 |
| 1445 int gmIndex = -1; | 1320 int gmIndex = -1; |
| 1446 SkString moduloStr; | 1321 SkString moduloStr; |
| 1447 | 1322 |
| 1448 // If we will be writing out files, prepare subdirectories. | 1323 // If we will be writing out files, prepare subdirectories. |
| 1449 if (writePath) { | 1324 if (FLAGS_writePath.count() == 1) { |
| 1450 if (!sk_mkdir(writePath)) { | 1325 if (!sk_mkdir(FLAGS_writePath[0])) { |
| 1451 return -1; | 1326 return -1; |
| 1452 } | 1327 } |
| 1453 if (gmmain.fUseFileHierarchy) { | 1328 if (gmmain.fUseFileHierarchy) { |
| 1454 for (int i = 0; i < configs.count(); i++) { | 1329 for (int i = 0; i < configs.count(); i++) { |
| 1455 ConfigData config = gRec[configs[i]]; | 1330 ConfigData config = gRec[configs[i]]; |
| 1456 SkString subdir; | 1331 SkString subdir; |
| 1457 subdir.appendf("%s%c%s", writePath, SkPATH_SEPARATOR, | 1332 subdir.appendf("%s%c%s", FLAGS_writePath[0], SkPATH_SEPARATOR, |
| 1458 config.fName); | 1333 config.fName); |
| 1459 if (!sk_mkdir(subdir.c_str())) { | 1334 if (!sk_mkdir(subdir.c_str())) { |
| 1460 return -1; | 1335 return -1; |
| 1461 } | 1336 } |
| 1462 } | 1337 } |
| 1463 } | 1338 } |
| 1464 } | 1339 } |
| 1465 | 1340 |
| 1466 Iter iter; | 1341 Iter iter; |
| 1467 GM* gm; | 1342 GM* gm; |
| 1468 while ((gm = iter.next()) != NULL) { | 1343 while ((gm = iter.next()) != NULL) { |
| 1469 | 1344 |
| 1470 ++gmIndex; | 1345 ++gmIndex; |
| 1471 if (moduloRemainder >= 0) { | 1346 if (moduloRemainder >= 0) { |
| 1472 if ((gmIndex % moduloDivisor) != moduloRemainder) { | 1347 if ((gmIndex % moduloDivisor) != moduloRemainder) { |
| 1473 continue; | 1348 continue; |
| 1474 } | 1349 } |
| 1475 moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor); | 1350 moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor); |
| 1476 } | 1351 } |
| 1477 | 1352 |
| 1478 const char* shortName = gm->shortName(); | 1353 const char* shortName = gm->shortName(); |
| 1479 if (skip_name(fMatches, shortName)) { | 1354 if (skip_name(FLAGS_match, shortName)) { |
| 1480 SkDELETE(gm); | 1355 SkDELETE(gm); |
| 1481 continue; | 1356 continue; |
| 1482 } | 1357 } |
| 1483 | 1358 |
| 1484 SkISize size = gm->getISize(); | 1359 SkISize size = gm->getISize(); |
| 1485 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
Name, | 1360 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
Name, |
| 1486 size.width(), size.height()); | 1361 size.width(), size.height()); |
| 1487 | 1362 |
| 1488 ErrorBitfield testErrors = kEmptyErrorBitfield; | 1363 ErrorBitfield testErrors = kEmptyErrorBitfield; |
| 1489 uint32_t gmFlags = gm->getFlags(); | 1364 uint32_t gmFlags = gm->getFlags(); |
| 1490 | 1365 |
| 1491 for (int i = 0; i < configs.count(); i++) { | 1366 for (int i = 0; i < configs.count(); i++) { |
| 1492 ConfigData config = gRec[configs[i]]; | 1367 ConfigData config = gRec[configs[i]]; |
| 1493 | 1368 |
| 1494 // Skip any tests that we don't even need to try. | 1369 // Skip any tests that we don't even need to try. |
| 1495 if ((kPDF_Backend == config.fBackend) && | 1370 if ((kPDF_Backend == config.fBackend) && |
| 1496 (!doPDF || (gmFlags & GM::kSkipPDF_Flag))) | 1371 (!FLAGS_pdf|| (gmFlags & GM::kSkipPDF_Flag))) |
| 1497 { | 1372 { |
| 1498 continue; | 1373 continue; |
| 1499 } | 1374 } |
| 1500 if ((gmFlags & GM::kSkip565_Flag) && | 1375 if ((gmFlags & GM::kSkip565_Flag) && |
| 1501 (kRaster_Backend == config.fBackend) && | 1376 (kRaster_Backend == config.fBackend) && |
| 1502 (SkBitmap::kRGB_565_Config == config.fConfig)) { | 1377 (SkBitmap::kRGB_565_Config == config.fConfig)) { |
| 1503 continue; | 1378 continue; |
| 1504 } | 1379 } |
| 1505 if ((gmFlags & GM::kSkipGPU_Flag) && | 1380 if ((gmFlags & GM::kSkipGPU_Flag) && |
| 1506 kGPU_Backend == config.fBackend) { | 1381 kGPU_Backend == config.fBackend) { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1548 gr->setTextureCacheLimits(count, bytes); | 1423 gr->setTextureCacheLimits(count, bytes); |
| 1549 } | 1424 } |
| 1550 if (!grSuccess) { | 1425 if (!grSuccess) { |
| 1551 renderErrors |= kNoGpuContext_ErrorBitmask; | 1426 renderErrors |= kNoGpuContext_ErrorBitmask; |
| 1552 } | 1427 } |
| 1553 } | 1428 } |
| 1554 #endif | 1429 #endif |
| 1555 | 1430 |
| 1556 SkBitmap comparisonBitmap; | 1431 SkBitmap comparisonBitmap; |
| 1557 | 1432 |
| 1433 const char* writePath; |
| 1434 if (FLAGS_writePath.count() == 1) { |
| 1435 writePath = FLAGS_writePath[0]; |
| 1436 } else { |
| 1437 writePath = NULL; |
| 1438 } |
| 1558 if (kEmptyErrorBitfield == renderErrors) { | 1439 if (kEmptyErrorBitfield == renderErrors) { |
| 1559 renderErrors |= gmmain.test_drawing(gm, config, writePath, | 1440 renderErrors |= gmmain.test_drawing(gm, config, writePath, |
| 1560 GetGr(), | 1441 GetGr(), |
| 1561 renderTarget, | 1442 renderTarget, |
| 1562 &comparisonBitmap); | 1443 &comparisonBitmap); |
| 1563 } | 1444 } |
| 1564 | 1445 |
| 1565 if (doDeferred && !renderErrors && | 1446 if (FLAGS_deferred && !renderErrors && |
| 1566 (kGPU_Backend == config.fBackend || | 1447 (kGPU_Backend == config.fBackend || |
| 1567 kRaster_Backend == config.fBackend)) { | 1448 kRaster_Backend == config.fBackend)) { |
| 1568 renderErrors |= gmmain.test_deferred_drawing(gm, config, | 1449 renderErrors |= gmmain.test_deferred_drawing(gm, config, |
| 1569 comparisonBitmap, | 1450 comparisonBitmap, |
| 1570 GetGr(), | 1451 GetGr(), |
| 1571 renderTarget); | 1452 renderTarget); |
| 1572 } | 1453 } |
| 1573 | 1454 |
| 1574 testErrors |= renderErrors; | 1455 testErrors |= renderErrors; |
| 1575 } | 1456 } |
| 1576 | 1457 |
| 1577 SkBitmap comparisonBitmap; | 1458 SkBitmap comparisonBitmap; |
| 1578 const ConfigData compareConfig = | 1459 const ConfigData compareConfig = |
| 1579 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
ype, 0, kRW_ConfigFlag, "comparison", false }; | 1460 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
ype, 0, kRW_ConfigFlag, "comparison", false }; |
| 1580 testErrors |= gmmain.generate_image(gm, compareConfig, NULL, NULL, &comp
arisonBitmap, false); | 1461 testErrors |= gmmain.generate_image(gm, compareConfig, NULL, NULL, &comp
arisonBitmap, false); |
| 1581 | 1462 |
| 1582 // run the picture centric GM steps | 1463 // run the picture centric GM steps |
| 1583 if (!(gmFlags & GM::kSkipPicture_Flag)) { | 1464 if (!(gmFlags & GM::kSkipPicture_Flag)) { |
| 1584 | 1465 |
| 1585 ErrorBitfield pictErrors = kEmptyErrorBitfield; | 1466 ErrorBitfield pictErrors = kEmptyErrorBitfield; |
| 1586 | 1467 |
| 1587 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); | 1468 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); |
| 1588 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); | 1469 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); |
| 1589 SkAutoUnref aur(pict); | 1470 SkAutoUnref aur(pict); |
| 1590 | 1471 |
| 1591 if ((kEmptyErrorBitfield == testErrors) && doReplay) { | 1472 if ((kEmptyErrorBitfield == testErrors) && FLAGS_replay) { |
| 1592 SkBitmap bitmap; | 1473 SkBitmap bitmap; |
| 1593 gmmain.generate_image_from_picture(gm, compareConfig, pict, | 1474 gmmain.generate_image_from_picture(gm, compareConfig, pict, |
| 1594 &bitmap); | 1475 &bitmap); |
| 1595 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | 1476 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( |
| 1596 gm, compareConfig, "-replay", bitmap, &comparisonBitmap); | 1477 gm, compareConfig, "-replay", bitmap, &comparisonBitmap); |
| 1597 } | 1478 } |
| 1598 | 1479 |
| 1599 if ((kEmptyErrorBitfield == testErrors) && | 1480 if ((kEmptyErrorBitfield == testErrors) && |
| 1600 (kEmptyErrorBitfield == pictErrors) && | 1481 (kEmptyErrorBitfield == pictErrors) && |
| 1601 doSerialize) { | 1482 FLAGS_serialize) { |
| 1602 SkPicture* repict = gmmain.stream_to_new_picture(*pict); | 1483 SkPicture* repict = gmmain.stream_to_new_picture(*pict); |
| 1603 SkAutoUnref aurr(repict); | 1484 SkAutoUnref aurr(repict); |
| 1604 | 1485 |
| 1605 SkBitmap bitmap; | 1486 SkBitmap bitmap; |
| 1606 gmmain.generate_image_from_picture(gm, compareConfig, repict, | 1487 gmmain.generate_image_from_picture(gm, compareConfig, repict, |
| 1607 &bitmap); | 1488 &bitmap); |
| 1608 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | 1489 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( |
| 1609 gm, compareConfig, "-serialize", bitmap, &comparisonBitmap); | 1490 gm, compareConfig, "-serialize", bitmap, &comparisonBitmap); |
| 1610 } | 1491 } |
| 1611 | 1492 |
| 1612 if (writePicturePath) { | 1493 if (FLAGS_writePicturePath.count() == 1) { |
| 1613 const char* pictureSuffix = "skp"; | 1494 const char* pictureSuffix = "skp"; |
| 1614 SkString path = make_filename(writePicturePath, "", | 1495 SkString path = make_filename(FLAGS_writePicturePath[0], "", |
| 1615 gm->shortName(), | 1496 gm->shortName(), |
| 1616 pictureSuffix); | 1497 pictureSuffix); |
| 1617 SkFILEWStream stream(path.c_str()); | 1498 SkFILEWStream stream(path.c_str()); |
| 1618 pict->serialize(&stream); | 1499 pict->serialize(&stream); |
| 1619 } | 1500 } |
| 1620 | 1501 |
| 1621 testErrors |= pictErrors; | 1502 testErrors |= pictErrors; |
| 1622 } | 1503 } |
| 1623 | 1504 |
| 1624 // TODO: add a test in which the RTree rendering results in a | 1505 // TODO: add a test in which the RTree rendering results in a |
| 1625 // different bitmap than the standard rendering. It should | 1506 // different bitmap than the standard rendering. It should |
| 1626 // show up as failed in the JSON summary, and should be listed | 1507 // show up as failed in the JSON summary, and should be listed |
| 1627 // in the stdout also. | 1508 // in the stdout also. |
| 1628 if (!(gmFlags & GM::kSkipPicture_Flag) && doRTree) { | 1509 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_rtree) { |
| 1629 SkPicture* pict = gmmain.generate_new_picture( | 1510 SkPicture* pict = gmmain.generate_new_picture( |
| 1630 gm, kRTree_BbhType, SkPicture::kUsePathBoundsForClip_RecordingFl
ag); | 1511 gm, kRTree_BbhType, SkPicture::kUsePathBoundsForClip_RecordingFl
ag); |
| 1631 SkAutoUnref aur(pict); | 1512 SkAutoUnref aur(pict); |
| 1632 SkBitmap bitmap; | 1513 SkBitmap bitmap; |
| 1633 gmmain.generate_image_from_picture(gm, compareConfig, pict, | 1514 gmmain.generate_image_from_picture(gm, compareConfig, pict, |
| 1634 &bitmap); | 1515 &bitmap); |
| 1635 testErrors |= gmmain.compare_test_results_to_reference_bitmap( | 1516 testErrors |= gmmain.compare_test_results_to_reference_bitmap( |
| 1636 gm, compareConfig, "-rtree", bitmap, &comparisonBitmap); | 1517 gm, compareConfig, "-rtree", bitmap, &comparisonBitmap); |
| 1637 } | 1518 } |
| 1638 | 1519 |
| 1639 if (!(gmFlags & GM::kSkipPicture_Flag) && doTileGrid) { | 1520 if (!(gmFlags & GM::kSkipPicture_Flag) && FLAGS_tileGrid) { |
| 1640 for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); +
+scaleIndex) { | 1521 for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); +
+scaleIndex) { |
| 1641 SkScalar replayScale = tileGridReplayScales[scaleIndex]; | 1522 SkScalar replayScale = tileGridReplayScales[scaleIndex]; |
| 1642 if ((gmFlags & GM::kSkipScaledReplay_Flag) && replayScale != 1) | 1523 if ((gmFlags & GM::kSkipScaledReplay_Flag) && replayScale != 1) |
| 1643 continue; | 1524 continue; |
| 1644 // We record with the reciprocal scale to obtain a replay | 1525 // We record with the reciprocal scale to obtain a replay |
| 1645 // result that can be validated against comparisonBitmap. | 1526 // result that can be validated against comparisonBitmap. |
| 1646 SkScalar recordScale = SkScalarInvert(replayScale); | 1527 SkScalar recordScale = SkScalarInvert(replayScale); |
| 1647 SkPicture* pict = gmmain.generate_new_picture( | 1528 SkPicture* pict = gmmain.generate_new_picture( |
| 1648 gm, kTileGrid_BbhType, SkPicture::kUsePathBoundsForClip_Reco
rdingFlag, | 1529 gm, kTileGrid_BbhType, SkPicture::kUsePathBoundsForClip_Reco
rdingFlag, |
| 1649 recordScale); | 1530 recordScale); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1660 gm, compareConfig, suffix.c_str(), bitmap, | 1541 gm, compareConfig, suffix.c_str(), bitmap, |
| 1661 &comparisonBitmap); | 1542 &comparisonBitmap); |
| 1662 } | 1543 } |
| 1663 } | 1544 } |
| 1664 | 1545 |
| 1665 // run the pipe centric GM steps | 1546 // run the pipe centric GM steps |
| 1666 if (!(gmFlags & GM::kSkipPipe_Flag)) { | 1547 if (!(gmFlags & GM::kSkipPipe_Flag)) { |
| 1667 | 1548 |
| 1668 ErrorBitfield pipeErrors = kEmptyErrorBitfield; | 1549 ErrorBitfield pipeErrors = kEmptyErrorBitfield; |
| 1669 | 1550 |
| 1670 if ((kEmptyErrorBitfield == testErrors) && doPipe) { | 1551 if ((kEmptyErrorBitfield == testErrors) && FLAGS_pipe) { |
| 1671 pipeErrors |= gmmain.test_pipe_playback(gm, compareConfig, | 1552 pipeErrors |= gmmain.test_pipe_playback(gm, compareConfig, |
| 1672 comparisonBitmap); | 1553 comparisonBitmap); |
| 1673 } | 1554 } |
| 1674 | 1555 |
| 1675 if ((kEmptyErrorBitfield == testErrors) && | 1556 if ((kEmptyErrorBitfield == testErrors) && |
| 1676 (kEmptyErrorBitfield == pipeErrors) && | 1557 (kEmptyErrorBitfield == pipeErrors) && |
| 1677 doTiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { | 1558 FLAGS_tiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { |
| 1678 pipeErrors |= gmmain.test_tiled_pipe_playback(gm, compareConfig, | 1559 pipeErrors |= gmmain.test_tiled_pipe_playback(gm, compareConfig, |
| 1679 comparisonBitmap); | 1560 comparisonBitmap); |
| 1680 } | 1561 } |
| 1681 | 1562 |
| 1682 testErrors |= pipeErrors; | 1563 testErrors |= pipeErrors; |
| 1683 } | 1564 } |
| 1684 | 1565 |
| 1685 // Update overall results. | 1566 // Update overall results. |
| 1686 // We only tabulate the particular error types that we currently | 1567 // We only tabulate the particular error types that we currently |
| 1687 // care about (e.g., missing reference images). Later on, if we | 1568 // care about (e.g., missing reference images). Later on, if we |
| 1688 // want to also tabulate other error types, we can do so. | 1569 // want to also tabulate other error types, we can do so. |
| 1689 testsRun++; | 1570 testsRun++; |
| 1690 if (!gmmain.fExpectationsSource.get() || | 1571 if (!gmmain.fExpectationsSource.get() || |
| 1691 (kEmptyErrorBitfield != (kMissingExpectations_ErrorBitmask & testErr
ors))) { | 1572 (kEmptyErrorBitfield != (kMissingExpectations_ErrorBitmask & testErr
ors))) { |
| 1692 testsMissingReferenceImages++; | 1573 testsMissingReferenceImages++; |
| 1693 } | 1574 } |
| 1694 if (testErrors == (testErrors & kIgnorable_ErrorBitmask)) { | 1575 if (testErrors == (testErrors & kIgnorable_ErrorBitmask)) { |
| 1695 testsPassed++; | 1576 testsPassed++; |
| 1696 } else { | 1577 } else { |
| 1697 testsFailed++; | 1578 testsFailed++; |
| 1698 } | 1579 } |
| 1699 | 1580 |
| 1700 SkDELETE(gm); | 1581 SkDELETE(gm); |
| 1701 } | 1582 } |
| 1702 gm_fprintf(stdout, "Ran %d tests: %d passed, %d failed, %d missing reference
images\n", | 1583 gm_fprintf(stdout, "Ran %d tests: %d passed, %d failed, %d missing reference
images\n", |
| 1703 testsRun, testsPassed, testsFailed, testsMissingReferenceImages); | 1584 testsRun, testsPassed, testsFailed, testsMissingReferenceImages); |
| 1704 gmmain.ListErrors(); | 1585 gmmain.ListErrors(); |
| 1705 | 1586 |
| 1706 if (NULL != writeJsonSummaryPath) { | 1587 if (FLAGS_writeJsonSummaryPath.count() == 1) { |
| 1707 Json::Value actualResults; | 1588 Json::Value actualResults; |
| 1708 actualResults[kJsonKey_ActualResults_Failed] = | 1589 actualResults[kJsonKey_ActualResults_Failed] = |
| 1709 gmmain.fJsonActualResults_Failed; | 1590 gmmain.fJsonActualResults_Failed; |
| 1710 actualResults[kJsonKey_ActualResults_FailureIgnored] = | 1591 actualResults[kJsonKey_ActualResults_FailureIgnored] = |
| 1711 gmmain.fJsonActualResults_FailureIgnored; | 1592 gmmain.fJsonActualResults_FailureIgnored; |
| 1712 actualResults[kJsonKey_ActualResults_NoComparison] = | 1593 actualResults[kJsonKey_ActualResults_NoComparison] = |
| 1713 gmmain.fJsonActualResults_NoComparison; | 1594 gmmain.fJsonActualResults_NoComparison; |
| 1714 actualResults[kJsonKey_ActualResults_Succeeded] = | 1595 actualResults[kJsonKey_ActualResults_Succeeded] = |
| 1715 gmmain.fJsonActualResults_Succeeded; | 1596 gmmain.fJsonActualResults_Succeeded; |
| 1716 Json::Value root; | 1597 Json::Value root; |
| 1717 root[kJsonKey_ActualResults] = actualResults; | 1598 root[kJsonKey_ActualResults] = actualResults; |
| 1718 root[kJsonKey_ExpectedResults] = gmmain.fJsonExpectedResults; | 1599 root[kJsonKey_ExpectedResults] = gmmain.fJsonExpectedResults; |
| 1719 std::string jsonStdString = root.toStyledString(); | 1600 std::string jsonStdString = root.toStyledString(); |
| 1720 SkFILEWStream stream(writeJsonSummaryPath); | 1601 SkFILEWStream stream(FLAGS_writeJsonSummaryPath[0]); |
| 1721 stream.write(jsonStdString.c_str(), jsonStdString.length()); | 1602 stream.write(jsonStdString.c_str(), jsonStdString.length()); |
| 1722 } | 1603 } |
| 1723 | 1604 |
| 1724 #if SK_SUPPORT_GPU | 1605 #if SK_SUPPORT_GPU |
| 1725 | 1606 |
| 1726 #if GR_CACHE_STATS | 1607 #if GR_CACHE_STATS |
| 1727 for (int i = 0; i < configs.count(); i++) { | 1608 for (int i = 0; i < configs.count(); i++) { |
| 1728 ConfigData config = gRec[configs[i]]; | 1609 ConfigData config = gRec[configs[i]]; |
| 1729 | 1610 |
| 1730 if (kGPU_Backend == config.fBackend) { | 1611 if (kGPU_Backend == config.fBackend) { |
| 1731 GrContext* gr = grFactory->get(config.fGLContextType); | 1612 GrContext* gr = grFactory->get(config.fGLContextType); |
| 1732 | 1613 |
| 1733 gm_fprintf(stdout, "config: %s %x\n", config.fName, gr); | 1614 gm_fprintf(stdout, "config: %s %x\n", config.fName, gr); |
| 1734 gr->printCacheStats(); | 1615 gr->printCacheStats(); |
| 1735 } | 1616 } |
| 1736 } | 1617 } |
| 1737 #endif | 1618 #endif |
| 1738 | 1619 |
| 1739 delete grFactory; | 1620 delete grFactory; |
| 1740 #endif | 1621 #endif |
| 1741 SkGraphics::Term(); | 1622 SkGraphics::Term(); |
| 1742 | 1623 |
| 1743 return (0 == testsFailed) ? 0 : -1; | 1624 return (0 == testsFailed) ? 0 : -1; |
| 1744 } | 1625 } |
| 1745 | 1626 |
| 1627 void GMMain::installFilter(SkCanvas* canvas) { |
| 1628 if (FLAGS_forceBWtext) { |
| 1629 canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); |
| 1630 } |
| 1631 } |
| 1632 |
| 1746 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 1633 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
| 1747 int main(int argc, char * const argv[]) { | 1634 int main(int argc, char * const argv[]) { |
| 1748 return tool_main(argc, (char**) argv); | 1635 return tool_main(argc, (char**) argv); |
| 1749 } | 1636 } |
| 1750 #endif | 1637 #endif |
| OLD | NEW |