OLD | NEW |
---|---|
1 /* | 1 /* |
epoger
2013/03/14 22:36:27
As of patchset 3+4, we now report any differences
| |
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 |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
187 { " cross-process, shared address", SkGPipeWriter::kCrossProcess_Flag | 187 { " cross-process, shared address", SkGPipeWriter::kCrossProcess_Flag |
188 | SkGPipeWriter::kSharedAddressSpace_Flag } | 188 | SkGPipeWriter::kSharedAddressSpace_Flag } |
189 }; | 189 }; |
190 | 190 |
191 class GMMain { | 191 class GMMain { |
192 public: | 192 public: |
193 GMMain() { | 193 GMMain() { |
194 // Set default values of member variables, which tool_main() | 194 // Set default values of member variables, which tool_main() |
195 // may override. | 195 // may override. |
196 fUseFileHierarchy = false; | 196 fUseFileHierarchy = false; |
197 fSimulatePipePlaybackFailure = false; | |
197 fMismatchPath = NULL; | 198 fMismatchPath = NULL; |
198 } | 199 } |
199 | 200 |
200 SkString make_name(const char shortName[], const char configName[]) { | 201 SkString make_name(const char shortName[], const char configName[]) { |
201 SkString name; | 202 SkString name; |
202 if (0 == strlen(configName)) { | 203 if (0 == strlen(configName)) { |
203 name.append(shortName); | 204 name.append(shortName); |
204 } else if (fUseFileHierarchy) { | 205 } else if (fUseFileHierarchy) { |
205 name.appendf("%s%c%s", configName, SkPATH_SEPARATOR, shortName); | 206 name.appendf("%s%c%s", configName, SkPATH_SEPARATOR, shortName); |
206 } else { | 207 } else { |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
254 // The common case: no error means nothing to record. | 255 // The common case: no error means nothing to record. |
255 if (kEmptyErrorBitfield == errorType) { | 256 if (kEmptyErrorBitfield == errorType) { |
256 return; | 257 return; |
257 } | 258 } |
258 | 259 |
259 // If only certain error type(s) were reported, we know we can ignore th em. | 260 // If only certain error type(s) were reported, we know we can ignore th em. |
260 if (errorType == (errorType & kIgnorable_ErrorBitmask)) { | 261 if (errorType == (errorType & kIgnorable_ErrorBitmask)) { |
261 return; | 262 return; |
262 } | 263 } |
263 | 264 |
264 FailRec& rec = fFailedTests.push_back(make_name( | 265 SkString completeName = name; |
265 name.c_str(), renderModeDescriptor)); | 266 completeName.append(renderModeDescriptor); |
267 FailRec& rec = fFailedTests.push_back(completeName); | |
266 rec.fIsPixelError = | 268 rec.fIsPixelError = |
267 (kEmptyErrorBitfield != (errorType & kImageMismatch_ErrorBitmask)); | 269 (kEmptyErrorBitfield != (errorType & kImageMismatch_ErrorBitmask)); |
268 } | 270 } |
269 | 271 |
270 // List contents of fFailedTests via SkDebug. | 272 // List contents of fFailedTests via SkDebug. |
271 void ListErrors() { | 273 void ListErrors() { |
272 for (int i = 0; i < fFailedTests.count(); ++i) { | 274 for (int i = 0; i < fFailedTests.count(); ++i) { |
273 if (fFailedTests[i].fIsPixelError) { | 275 if (fFailedTests[i].fIsPixelError) { |
274 gm_fprintf(stderr, "\t\t%s pixel_error\n", fFailedTests[i].fName .c_str()); | 276 gm_fprintf(stderr, "\t\t%s pixel_error\n", fFailedTests[i].fName .c_str()); |
275 } else { | 277 } else { |
(...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
587 * _ErrorBitmask values otherwise. | 589 * _ErrorBitmask values otherwise. |
588 * | 590 * |
589 * If fMismatchPath has been set, and there are pixel diffs, then the | 591 * If fMismatchPath has been set, and there are pixel diffs, then the |
590 * actual bitmap will be written out to a file within fMismatchPath. | 592 * actual bitmap will be written out to a file within fMismatchPath. |
591 * | 593 * |
592 * @param expectations what expectations to compare actualBitmap against | 594 * @param expectations what expectations to compare actualBitmap against |
593 * @param actualBitmap the image we actually generated | 595 * @param actualBitmap the image we actually generated |
594 * @param baseNameString name of test without renderModeDescriptor added | 596 * @param baseNameString name of test without renderModeDescriptor added |
595 * @param renderModeDescriptor e.g., "-rtree", "-deferred" | 597 * @param renderModeDescriptor e.g., "-rtree", "-deferred" |
596 * @param addToJsonSummary whether to add these results (both actual and | 598 * @param addToJsonSummary whether to add these results (both actual and |
597 * expected) to the JSON summary | 599 * expected) to the JSON summary. Regardless of this setting, if |
598 * | 600 * we find an image mismatch in this test, we will write these |
599 * TODO: For now, addToJsonSummary is only set to true within | 601 * results to the JSON summary. (This is so that we will always |
600 * compare_test_results_to_stored_expectations(), so results of our | 602 * report errors across rendering modes, such as pipe vs tiled. |
601 * in-memory comparisons (Rtree vs regular, etc.) are not written to the | 603 * See https://codereview.chromium.org/12825005/ |
602 * JSON summary. We may wish to change that. | |
603 */ | 604 */ |
604 ErrorBitfield compare_to_expectations(Expectations expectations, | 605 ErrorBitfield compare_to_expectations(Expectations expectations, |
605 const SkBitmap& actualBitmap, | 606 const SkBitmap& actualBitmap, |
606 const SkString& baseNameString, | 607 const SkString& baseNameString, |
607 const char renderModeDescriptor[], | 608 const char renderModeDescriptor[], |
608 bool addToJsonSummary=false) { | 609 bool addToJsonSummary) { |
609 ErrorBitfield retval; | 610 ErrorBitfield retval; |
610 Checksum actualChecksum = SkBitmapChecksummer::Compute64(actualBitmap); | 611 Checksum actualChecksum = SkBitmapChecksummer::Compute64(actualBitmap); |
611 SkString completeNameString = baseNameString; | 612 SkString completeNameString = baseNameString; |
612 completeNameString.append(renderModeDescriptor); | 613 completeNameString.append(renderModeDescriptor); |
613 const char* completeName = completeNameString.c_str(); | 614 const char* completeName = completeNameString.c_str(); |
614 | 615 |
615 if (expectations.empty()) { | 616 if (expectations.empty()) { |
616 retval = kMissingExpectations_ErrorBitmask; | 617 retval = kMissingExpectations_ErrorBitmask; |
617 } else if (expectations.match(actualChecksum)) { | 618 } else if (expectations.match(actualChecksum)) { |
618 retval = kEmptyErrorBitfield; | 619 retval = kEmptyErrorBitfield; |
619 } else { | 620 } else { |
621 addToJsonSummary = true; | |
620 retval = kImageMismatch_ErrorBitmask; | 622 retval = kImageMismatch_ErrorBitmask; |
621 | 623 |
622 // Write out the "actuals" for any mismatches, if we have | 624 // Write out the "actuals" for any mismatches, if we have |
623 // been directed to do so. | 625 // been directed to do so. |
624 if (fMismatchPath) { | 626 if (fMismatchPath) { |
625 SkString path = | 627 SkString path = |
626 make_filename(fMismatchPath, renderModeDescriptor, | 628 make_filename(fMismatchPath, renderModeDescriptor, |
627 baseNameString.c_str(), "png"); | 629 baseNameString.c_str(), "png"); |
628 write_bitmap(path, actualBitmap); | 630 write_bitmap(path, actualBitmap); |
629 } | 631 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
777 * @param referenceBitmap bitmap we expected to be generated | 779 * @param referenceBitmap bitmap we expected to be generated |
778 */ | 780 */ |
779 ErrorBitfield compare_test_results_to_reference_bitmap( | 781 ErrorBitfield compare_test_results_to_reference_bitmap( |
780 GM* gm, const ConfigData& gRec, const char renderModeDescriptor [], | 782 GM* gm, const ConfigData& gRec, const char renderModeDescriptor [], |
781 SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) { | 783 SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) { |
782 | 784 |
783 SkASSERT(referenceBitmap); | 785 SkASSERT(referenceBitmap); |
784 SkString name = make_name(gm->shortName(), gRec.fName); | 786 SkString name = make_name(gm->shortName(), gRec.fName); |
785 Expectations expectations(*referenceBitmap); | 787 Expectations expectations(*referenceBitmap); |
786 return compare_to_expectations(expectations, actualBitmap, | 788 return compare_to_expectations(expectations, actualBitmap, |
787 name, renderModeDescriptor); | 789 name, renderModeDescriptor, false); |
788 } | 790 } |
789 | 791 |
790 static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t rec ordFlags, | 792 static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t rec ordFlags, |
791 SkScalar scale = SK_Scalar1) { | 793 SkScalar scale = SK_Scalar1) { |
792 // Pictures are refcounted so must be on heap | 794 // Pictures are refcounted so must be on heap |
793 SkPicture* pict; | 795 SkPicture* pict; |
794 int width = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().w idth()), scale)); | 796 int width = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize().w idth()), scale)); |
795 int height = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize(). height()), scale)); | 797 int height = SkScalarCeilToInt(SkScalarMul(SkIntToScalar(gm->getISize(). height()), scale)); |
796 | 798 |
797 if (kTileGrid_BbhType == bbhType) { | 799 if (kTileGrid_BbhType == bbhType) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
898 ErrorBitfield errors = kEmptyErrorBitfield; | 900 ErrorBitfield errors = kEmptyErrorBitfield; |
899 for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) { | 901 for (size_t i = 0; i < SK_ARRAY_COUNT(gPipeWritingFlagCombos); ++i) { |
900 SkBitmap bitmap; | 902 SkBitmap bitmap; |
901 SkISize size = gm->getISize(); | 903 SkISize size = gm->getISize(); |
902 setup_bitmap(gRec, size, &bitmap); | 904 setup_bitmap(gRec, size, &bitmap); |
903 SkCanvas canvas(bitmap); | 905 SkCanvas canvas(bitmap); |
904 PipeController pipeController(&canvas); | 906 PipeController pipeController(&canvas); |
905 SkGPipeWriter writer; | 907 SkGPipeWriter writer; |
906 SkCanvas* pipeCanvas = writer.startRecording( | 908 SkCanvas* pipeCanvas = writer.startRecording( |
907 &pipeController, gPipeWritingFlagCombos[i].flags); | 909 &pipeController, gPipeWritingFlagCombos[i].flags); |
908 invokeGM(gm, pipeCanvas, false, false); | 910 if (!this->fSimulatePipePlaybackFailure) { |
911 invokeGM(gm, pipeCanvas, false, false); | |
912 } | |
909 complete_bitmap(&bitmap); | 913 complete_bitmap(&bitmap); |
910 writer.endRecording(); | 914 writer.endRecording(); |
911 SkString string("-pipe"); | 915 SkString string("-pipe"); |
912 string.append(gPipeWritingFlagCombos[i].name); | 916 string.append(gPipeWritingFlagCombos[i].name); |
913 errors |= compare_test_results_to_reference_bitmap( | 917 errors |= compare_test_results_to_reference_bitmap( |
914 gm, gRec, string.c_str(), bitmap, &referenceBitmap); | 918 gm, gRec, string.c_str(), bitmap, &referenceBitmap); |
915 if (errors != kEmptyErrorBitfield) { | 919 if (errors != kEmptyErrorBitfield) { |
916 break; | 920 break; |
917 } | 921 } |
918 } | 922 } |
(...skipping 25 matching lines...) Expand all Loading... | |
944 } | 948 } |
945 return errors; | 949 return errors; |
946 } | 950 } |
947 | 951 |
948 // | 952 // |
949 // member variables. | 953 // member variables. |
950 // They are public for now, to allow easier setting by tool_main(). | 954 // They are public for now, to allow easier setting by tool_main(). |
951 // | 955 // |
952 | 956 |
953 bool fUseFileHierarchy; | 957 bool fUseFileHierarchy; |
958 bool fSimulatePipePlaybackFailure; | |
954 | 959 |
955 const char* fMismatchPath; | 960 const char* fMismatchPath; |
956 | 961 |
957 // information about all failed tests we have encountered so far | 962 // information about all failed tests we have encountered so far |
958 SkTArray<FailRec> fFailedTests; | 963 SkTArray<FailRec> fFailedTests; |
959 | 964 |
960 // Where to read expectations (expected image checksums, etc.) from. | 965 // Where to read expectations (expected image checksums, etc.) from. |
961 // If unset, we don't do comparisons. | 966 // If unset, we don't do comparisons. |
962 SkAutoTUnref<ExpectationsSource> fExpectationsSource; | 967 SkAutoTUnref<ExpectationsSource> fExpectationsSource; |
963 | 968 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1047 " [--modulo <remainder> <divisor>]: only run tests for which \n" | 1052 " [--modulo <remainder> <divisor>]: only run tests for which \n" |
1048 " testIndex %% divisor == remainder\n" | 1053 " testIndex %% divisor == remainder\n" |
1049 " [--nopdf]: skip the pdf rendering test pass\n" | 1054 " [--nopdf]: skip the pdf rendering test pass\n" |
1050 " [--nopipe]: Skip SkGPipe replay\n" | 1055 " [--nopipe]: Skip SkGPipe replay\n" |
1051 " [--readPath|-r <path>]: read reference images from this dir, and report\n" | 1056 " [--readPath|-r <path>]: read reference images from this dir, and report\n" |
1052 " any differences between those and the newly generated ones\n" | 1057 " any differences between those and the newly generated ones\n" |
1053 " [--noreplay]: do not exercise SkPicture replay\n" | 1058 " [--noreplay]: do not exercise SkPicture replay\n" |
1054 " [--resourcePath|-i <path>]: directory that stores image resources\n" | 1059 " [--resourcePath|-i <path>]: directory that stores image resources\n" |
1055 " [--nortree]: Do not exercise the R-Tree variant of SkPicture\n" | 1060 " [--nortree]: Do not exercise the R-Tree variant of SkPicture\n" |
1056 " [--noserialize]: do not exercise SkPicture serialization & deserialization\ n" | 1061 " [--noserialize]: do not exercise SkPicture serialization & deserialization\ n" |
1062 " [--simulatePipePlaybackFailure]: simulate a rendering failure in pipe mode only\n" | |
1057 " [--tiledPipe]: Exercise tiled SkGPipe replay\n" | 1063 " [--tiledPipe]: Exercise tiled SkGPipe replay\n" |
1058 " [--notileGrid]: Do not exercise the tile grid variant of SkPicture\n" | 1064 " [--notileGrid]: Do not exercise the tile grid variant of SkPicture\n" |
1059 " [--tileGridReplayScales <scales>]: Comma separated list of floating-point s cale\n" | 1065 " [--tileGridReplayScales <scales>]: Comma separated list of floating-point s cale\n" |
1060 " factors to be used for tileGrid playback testing. Default value: 1.0\n" | 1066 " factors to be used for tileGrid playback testing. Default value: 1.0\n" |
1061 " [--writeJsonSummary <path>]: write a JSON-formatted result summary to this file\n" | 1067 " [--writeJsonSummary <path>]: write a JSON-formatted result summary to this file\n" |
1062 " [--verbose] print diagnostics (e.g. list each config to be tested)\n" | 1068 " [--verbose] print diagnostics (e.g. list each config to be tested)\n" |
1063 " [--writePath|-w <path>]: write rendered images into this directory\n" | 1069 " [--writePath|-w <path>]: write rendered images into this directory\n" |
1064 " [--writePicturePath|-wp <path>]: write .skp files into this directory\n" | 1070 " [--writePicturePath|-wp <path>]: write .skp files into this directory\n" |
1065 ); | 1071 ); |
1066 } | 1072 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1129 #endif | 1135 #endif |
1130 } | 1136 } |
1131 | 1137 |
1132 template <typename T> void appendUnique(SkTDArray<T>* array, const T& value) { | 1138 template <typename T> void appendUnique(SkTDArray<T>* array, const T& value) { |
1133 int index = array->find(value); | 1139 int index = array->find(value); |
1134 if (index < 0) { | 1140 if (index < 0) { |
1135 *array->append() = value; | 1141 *array->append() = value; |
1136 } | 1142 } |
1137 } | 1143 } |
1138 | 1144 |
1145 /** | |
1146 * Run this test in a number of different configs (8888, 565, PDF, | |
1147 * etc.), confirming that the resulting bitmaps match expectations | |
1148 * (which may be different for each config). | |
1149 */ | |
1150 ErrorBitfield run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray<size_ t> &configs, | |
1151 GrContextFactory *grFactory, int gpuCacheSize Bytes, | |
1152 int gpuCacheSizeCount, const char *writePath, bool doPDF, | |
1153 bool doDeferred) { | |
1154 uint32_t gmFlags = gm->getFlags(); | |
1155 ErrorBitfield testErrors = kEmptyErrorBitfield; | |
1156 for (int i = 0; i < configs.count(); i++) { | |
1157 ConfigData config = gRec[configs[i]]; | |
1158 | |
1159 // Skip any tests that we don't even need to try. | |
1160 if ((kPDF_Backend == config.fBackend) && | |
1161 (!doPDF || (gmFlags & GM::kSkipPDF_Flag))) | |
1162 { | |
1163 continue; | |
1164 } | |
1165 if ((gmFlags & GM::kSkip565_Flag) && | |
1166 (kRaster_Backend == config.fBackend) && | |
1167 (SkBitmap::kRGB_565_Config == config.fConfig)) { | |
1168 continue; | |
1169 } | |
1170 if ((gmFlags & GM::kSkipGPU_Flag) && | |
1171 kGPU_Backend == config.fBackend) { | |
1172 continue; | |
1173 } | |
1174 | |
1175 // Now we know that we want to run this test and record its | |
1176 // success or failure. | |
1177 ErrorBitfield renderErrors = kEmptyErrorBitfield; | |
1178 GrRenderTarget* renderTarget = NULL; | |
1179 #if SK_SUPPORT_GPU | |
1180 SkAutoTUnref<GrRenderTarget> rt; | |
1181 AutoResetGr autogr; | |
1182 if ((kEmptyErrorBitfield == renderErrors) && | |
1183 kGPU_Backend == config.fBackend) { | |
1184 GrContext* gr = grFactory->get(config.fGLContextType); | |
1185 bool grSuccess = false; | |
1186 if (gr) { | |
1187 // create a render target to back the device | |
1188 GrTextureDesc desc; | |
1189 desc.fConfig = kSkia8888_GrPixelConfig; | |
1190 desc.fFlags = kRenderTarget_GrTextureFlagBit; | |
1191 desc.fWidth = gm->getISize().width(); | |
1192 desc.fHeight = gm->getISize().height(); | |
1193 desc.fSampleCnt = config.fSampleCnt; | |
1194 GrTexture* tex = gr->createUncachedTexture(desc, NULL, 0); | |
1195 if (tex) { | |
1196 rt.reset(tex->asRenderTarget()); | |
1197 rt.get()->ref(); | |
1198 tex->unref(); | |
1199 autogr.set(gr); | |
1200 renderTarget = rt.get(); | |
1201 grSuccess = NULL != renderTarget; | |
1202 } | |
1203 // Set the user specified cache limits if non-default. | |
1204 size_t bytes; | |
1205 int count; | |
1206 gr->getTextureCacheLimits(&count, &bytes); | |
1207 if (-1 != gpuCacheSizeBytes) { | |
1208 bytes = static_cast<size_t>(gpuCacheSizeBytes); | |
1209 } | |
1210 if (-1 != gpuCacheSizeCount) { | |
1211 count = gpuCacheSizeCount; | |
1212 } | |
1213 gr->setTextureCacheLimits(count, bytes); | |
1214 } | |
1215 if (!grSuccess) { | |
1216 renderErrors |= kNoGpuContext_ErrorBitmask; | |
1217 } | |
1218 } | |
1219 #endif | |
1220 | |
1221 SkBitmap comparisonBitmap; | |
1222 | |
1223 if (kEmptyErrorBitfield == renderErrors) { | |
1224 renderErrors |= gmmain.test_drawing(gm, config, writePath, | |
1225 GetGr(), | |
1226 renderTarget, | |
1227 &comparisonBitmap); | |
1228 } | |
1229 | |
1230 if (doDeferred && !renderErrors && | |
1231 (kGPU_Backend == config.fBackend || | |
1232 kRaster_Backend == config.fBackend)) { | |
1233 renderErrors |= gmmain.test_deferred_drawing(gm, config, | |
1234 comparisonBitmap, | |
1235 GetGr(), | |
1236 renderTarget); | |
1237 } | |
1238 | |
1239 testErrors |= renderErrors; | |
1240 } | |
1241 return testErrors; | |
1242 } | |
1243 | |
1244 /** | |
1245 * Run this test in a number of different drawing modes (pipe, | |
1246 * deferred, tiled, etc.), confirming that the resulting bitmaps are | |
1247 * *exactly* the same in all drawing modes. | |
1248 * | |
1249 * TODO(epoger): Right now, we only run the different drawing modes | |
1250 * with the 8888 config. Would there be value in running all those | |
1251 * different drawing modes in whatever configs (8888, 565, PDF) we are | |
1252 * testing? | |
1253 */ | |
1254 ErrorBitfield run_multiple_drawing_modes(GMMain &gmmain, GM *gm, | |
1255 const char *writePicturePath, bool doRe play, | |
1256 bool doSerialize, bool doRTree, bool do TileGrid, | |
1257 const SkTDArray<SkScalar> &tileGridRepl ayScales, | |
1258 bool doPipe, bool doTiledPipe) { | |
1259 uint32_t gmFlags = gm->getFlags(); | |
1260 SkBitmap comparisonBitmap; | |
1261 const ConfigData compareConfig = | |
1262 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextType, 0, | |
1263 kRW_ConfigFlag, "comparison" }; | |
1264 ErrorBitfield testErrors = gmmain.generate_image(gm, compareConfig, NULL, NU LL, | |
1265 &comparisonBitmap, false); | |
1266 | |
1267 // run the picture centric GM steps | |
1268 if (!(gmFlags & GM::kSkipPicture_Flag)) { | |
1269 | |
1270 ErrorBitfield pictErrors = kEmptyErrorBitfield; | |
1271 | |
1272 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); | |
1273 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); | |
1274 SkAutoUnref aur(pict); | |
1275 | |
1276 if ((kEmptyErrorBitfield == testErrors) && doReplay) { | |
1277 SkBitmap bitmap; | |
1278 gmmain.generate_image_from_picture(gm, compareConfig, pict, | |
1279 &bitmap); | |
1280 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1281 gm, compareConfig, "-replay", bitmap, &comparisonBitmap); | |
1282 } | |
1283 | |
1284 if ((kEmptyErrorBitfield == testErrors) && | |
1285 (kEmptyErrorBitfield == pictErrors) && | |
1286 doSerialize) { | |
1287 SkPicture* repict = gmmain.stream_to_new_picture(*pict); | |
1288 SkAutoUnref aurr(repict); | |
1289 | |
1290 SkBitmap bitmap; | |
1291 gmmain.generate_image_from_picture(gm, compareConfig, repict, | |
1292 &bitmap); | |
1293 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1294 gm, co mpareConfig, "-serialize", bitmap, &comparisonBitmap); | |
1295 } | |
1296 | |
1297 if (writePicturePath) { | |
1298 const char* pictureSuffix = "skp"; | |
1299 SkString path = make_filename(writePicturePath, "", | |
1300 gm->shortName(), | |
1301 pictureSuffix); | |
1302 SkFILEWStream stream(path.c_str()); | |
1303 pict->serialize(&stream); | |
1304 } | |
1305 | |
1306 testErrors |= pictErrors; | |
1307 } | |
1308 | |
1309 // TODO: add a test in which the RTree rendering results in a | |
1310 // different bitmap than the standard rendering. It should | |
1311 // show up as failed in the JSON summary, and should be listed | |
1312 // in the stdout also. | |
1313 if (!(gmFlags & GM::kSkipPicture_Flag) && doRTree) { | |
1314 SkPicture* pict = gmmain.generate_new_picture( | |
1315 gm, kRTree_BbhType, SkPict ure::kUsePathBoundsForClip_RecordingFlag); | |
1316 SkAutoUnref aur(pict); | |
1317 SkBitmap bitmap; | |
1318 gmmain.generate_image_from_picture(gm, compareConfig, pict, | |
1319 &bitmap); | |
1320 testErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1321 gm, compar eConfig, "-rtree", bitmap, &comparisonBitmap); | |
1322 } | |
1323 | |
1324 if (!(gmFlags & GM::kSkipPicture_Flag) && doTileGrid) { | |
1325 for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); ++sca leIndex) { | |
1326 SkScalar replayScale = tileGridReplayScales[scaleIndex]; | |
1327 if ((gmFlags & GM::kSkipScaledReplay_Flag) && replayScale != 1) | |
1328 continue; | |
1329 // We record with the reciprocal scale to obtain a replay | |
1330 // result that can be validated against comparisonBitmap. | |
1331 SkScalar recordScale = SkScalarInvert(replayScale); | |
1332 SkPicture* pict = gmmain.generate_new_picture( | |
1333 gm, kTileGrid_BbhType, SkPicture::kUsePathBoundsForClip_RecordingFlag, | |
1334 recordScale); | |
1335 SkAutoUnref aur(pict); | |
1336 SkBitmap bitmap; | |
1337 gmmain.generate_image_from_picture(gm, compareConfig, pict, | |
1338 &bitmap, replayScale); | |
1339 SkString suffix("-tilegrid"); | |
1340 if (SK_Scalar1 != replayScale) { | |
1341 suffix += "-scale-"; | |
1342 suffix.appendScalar(replayScale); | |
1343 } | |
1344 testErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1345 gm, co mpareConfig, suffix.c_str(), bitmap, | |
1346 &compa risonBitmap); | |
1347 } | |
1348 } | |
1349 | |
1350 // run the pipe centric GM steps | |
1351 if (!(gmFlags & GM::kSkipPipe_Flag)) { | |
1352 | |
1353 ErrorBitfield pipeErrors = kEmptyErrorBitfield; | |
1354 | |
1355 if ((kEmptyErrorBitfield == testErrors) && doPipe) { | |
1356 pipeErrors |= gmmain.test_pipe_playback(gm, compareConfig, | |
1357 comparisonBitmap); | |
1358 } | |
1359 | |
1360 if ((kEmptyErrorBitfield == testErrors) && | |
1361 (kEmptyErrorBitfield == pipeErrors) && | |
1362 doTiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { | |
1363 pipeErrors |= gmmain.test_tiled_pipe_playback(gm, compareConfig, | |
1364 comparisonBitmap); | |
1365 } | |
1366 | |
1367 testErrors |= pipeErrors; | |
1368 } | |
1369 return testErrors; | |
1370 } | |
1371 | |
1139 int tool_main(int argc, char** argv); | 1372 int tool_main(int argc, char** argv); |
1140 int tool_main(int argc, char** argv) { | 1373 int tool_main(int argc, char** argv) { |
1141 | 1374 |
1142 #if SK_ENABLE_INST_COUNT | 1375 #if SK_ENABLE_INST_COUNT |
1143 gPrintInstCount = true; | 1376 gPrintInstCount = true; |
1144 #endif | 1377 #endif |
1145 | 1378 |
1146 SkGraphics::Init(); | 1379 SkGraphics::Init(); |
1147 // we don't need to see this during a run | 1380 // we don't need to see this during a run |
1148 gSkSuppressFontCachePurgeSpew = true; | 1381 gSkSuppressFontCachePurgeSpew = true; |
(...skipping 24 matching lines...) Expand all Loading... | |
1173 | 1406 |
1174 SkTDArray<size_t> configs; | 1407 SkTDArray<size_t> configs; |
1175 SkTDArray<size_t> excludeConfigs; | 1408 SkTDArray<size_t> excludeConfigs; |
1176 SkTDArray<SkScalar> tileGridReplayScales; | 1409 SkTDArray<SkScalar> tileGridReplayScales; |
1177 *tileGridReplayScales.append() = SK_Scalar1; // By default only test at scal e 1.0 | 1410 *tileGridReplayScales.append() = SK_Scalar1; // By default only test at scal e 1.0 |
1178 bool userConfig = false; | 1411 bool userConfig = false; |
1179 | 1412 |
1180 int moduloRemainder = -1; | 1413 int moduloRemainder = -1; |
1181 int moduloDivisor = -1; | 1414 int moduloDivisor = -1; |
1182 | 1415 |
1183 #if SK_SUPPORT_GPU | 1416 int gpuCacheSizeBytes = -1; |
1184 struct { | 1417 int gpuCacheSizeCount = -1; |
1185 int fBytes; | 1418 // -1 means use the default |
1186 int fCount; | |
1187 } gpuCacheSize = { -1, -1 }; // -1s mean use the default | |
1188 #endif | |
1189 | 1419 |
1190 const char* const commandName = argv[0]; | 1420 const char* const commandName = argv[0]; |
1191 char* const* stop = argv + argc; | 1421 char* const* stop = argv + argc; |
1192 for (++argv; argv < stop; ++argv) { | 1422 for (++argv; argv < stop; ++argv) { |
1193 if (strcmp(*argv, "--config") == 0) { | 1423 if (strcmp(*argv, "--config") == 0) { |
1194 argv++; | 1424 argv++; |
1195 if (argv < stop) { | 1425 if (argv < stop) { |
1196 int index = findConfig(*argv); | 1426 int index = findConfig(*argv); |
1197 if (index >= 0) { | 1427 if (index >= 0) { |
1198 appendUnique<size_t>(&configs, index); | 1428 appendUnique<size_t>(&configs, index); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1254 usage(commandName); | 1484 usage(commandName); |
1255 return -1; | 1485 return -1; |
1256 } | 1486 } |
1257 } else if (strcmp(*argv, "--enable-missing-warning") == 0) { | 1487 } else if (strcmp(*argv, "--enable-missing-warning") == 0) { |
1258 notifyMissingReadReference = true; | 1488 notifyMissingReadReference = true; |
1259 } else if (strcmp(*argv, "--forceBWtext") == 0) { | 1489 } else if (strcmp(*argv, "--forceBWtext") == 0) { |
1260 gForceBWtext = true; | 1490 gForceBWtext = true; |
1261 #if SK_SUPPORT_GPU | 1491 #if SK_SUPPORT_GPU |
1262 } else if (strcmp(*argv, "--gpuCacheSize") == 0) { | 1492 } else if (strcmp(*argv, "--gpuCacheSize") == 0) { |
1263 if (stop - argv > 2) { | 1493 if (stop - argv > 2) { |
1264 gpuCacheSize.fBytes = atoi(*++argv); | 1494 gpuCacheSizeBytes = atoi(*++argv); |
1265 gpuCacheSize.fCount = atoi(*++argv); | 1495 gpuCacheSizeCount = atoi(*++argv); |
1266 } else { | 1496 } else { |
1267 gm_fprintf(stderr, "missing arg for --gpuCacheSize\n"); | 1497 gm_fprintf(stderr, "missing arg for --gpuCacheSize\n"); |
1268 usage(commandName); | 1498 usage(commandName); |
1269 return -1; | 1499 return -1; |
1270 } | 1500 } |
1271 #endif | 1501 #endif |
1272 } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) { | 1502 } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) { |
1273 usage(commandName); | 1503 usage(commandName); |
1274 return -1; | 1504 return -1; |
1275 } else if (strcmp(*argv, "--hierarchy") == 0) { | 1505 } else if (strcmp(*argv, "--hierarchy") == 0) { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1313 } else if ((0 == strcmp(*argv, "--resourcePath")) || | 1543 } else if ((0 == strcmp(*argv, "--resourcePath")) || |
1314 (0 == strcmp(*argv, "-i"))) { | 1544 (0 == strcmp(*argv, "-i"))) { |
1315 argv++; | 1545 argv++; |
1316 if (argv < stop && **argv) { | 1546 if (argv < stop && **argv) { |
1317 resourcePath = *argv; | 1547 resourcePath = *argv; |
1318 } | 1548 } |
1319 } else if (strcmp(*argv, "--serialize") == 0) { | 1549 } else if (strcmp(*argv, "--serialize") == 0) { |
1320 doSerialize = true; | 1550 doSerialize = true; |
1321 } else if (strcmp(*argv, "--noserialize") == 0) { | 1551 } else if (strcmp(*argv, "--noserialize") == 0) { |
1322 doSerialize = false; | 1552 doSerialize = false; |
1553 } else if (strcmp(*argv, "--simulatePipePlaybackFailure") == 0) { | |
1554 gmmain.fSimulatePipePlaybackFailure = true; | |
1323 } else if (strcmp(*argv, "--tiledPipe") == 0) { | 1555 } else if (strcmp(*argv, "--tiledPipe") == 0) { |
1324 doTiledPipe = true; | 1556 doTiledPipe = true; |
1325 } else if (!strcmp(*argv, "--verbose") || !strcmp(*argv, "-v")) { | 1557 } else if (!strcmp(*argv, "--verbose") || !strcmp(*argv, "-v")) { |
1326 doVerbose = true; | 1558 doVerbose = true; |
1327 } else if ((0 == strcmp(*argv, "--writePath")) || | 1559 } else if ((0 == strcmp(*argv, "--writePath")) || |
1328 (0 == strcmp(*argv, "-w"))) { | 1560 (0 == strcmp(*argv, "-w"))) { |
1329 argv++; | 1561 argv++; |
1330 if (argv < stop && **argv) { | 1562 if (argv < stop && **argv) { |
1331 writePath = *argv; | 1563 writePath = *argv; |
1332 } | 1564 } |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1408 moduloRemainder = -1; | 1640 moduloRemainder = -1; |
1409 } | 1641 } |
1410 if (moduloRemainder < 0 || moduloRemainder >= moduloDivisor) { | 1642 if (moduloRemainder < 0 || moduloRemainder >= moduloDivisor) { |
1411 moduloRemainder = -1; | 1643 moduloRemainder = -1; |
1412 } | 1644 } |
1413 | 1645 |
1414 // Accumulate success of all tests. | 1646 // Accumulate success of all tests. |
1415 int testsRun = 0; | 1647 int testsRun = 0; |
1416 int testsPassed = 0; | 1648 int testsPassed = 0; |
1417 int testsFailed = 0; | 1649 int testsFailed = 0; |
1650 int testsWithDrawingModeDiscrepancies = 0; | |
1418 int testsMissingReferenceImages = 0; | 1651 int testsMissingReferenceImages = 0; |
1419 | 1652 |
1420 #if SK_SUPPORT_GPU | 1653 #if SK_SUPPORT_GPU |
1421 GrContextFactory* grFactory = new GrContextFactory; | 1654 GrContextFactory* grFactory = new GrContextFactory; |
1422 #endif | 1655 #endif |
1423 | 1656 |
1424 int gmIndex = -1; | 1657 int gmIndex = -1; |
1425 SkString moduloStr; | 1658 SkString moduloStr; |
1426 | 1659 |
1427 // If we will be writing out files, prepare subdirectories. | 1660 // If we will be writing out files, prepare subdirectories. |
(...skipping 29 matching lines...) Expand all Loading... | |
1457 const char* shortName = gm->shortName(); | 1690 const char* shortName = gm->shortName(); |
1458 if (skip_name(fMatches, shortName)) { | 1691 if (skip_name(fMatches, shortName)) { |
1459 SkDELETE(gm); | 1692 SkDELETE(gm); |
1460 continue; | 1693 continue; |
1461 } | 1694 } |
1462 | 1695 |
1463 SkISize size = gm->getISize(); | 1696 SkISize size = gm->getISize(); |
1464 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short Name, | 1697 gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short Name, |
1465 size.width(), size.height()); | 1698 size.width(), size.height()); |
1466 | 1699 |
1467 ErrorBitfield testErrors = kEmptyErrorBitfield; | 1700 ErrorBitfield compositeErrors = kEmptyErrorBitfield; |
1468 uint32_t gmFlags = gm->getFlags(); | 1701 ErrorBitfield multipleConfigErrors = run_multiple_configs( |
1702 gmmain, gm, configs, grFactory, gpuCacheSizeBytes, gpuCacheSizeCount , writePath, | |
1703 doPDF, doDeferred); | |
1704 compositeErrors |= multipleConfigErrors; | |
1705 ErrorBitfield multipleModeErrors = run_multiple_drawing_modes( | |
1706 gmmain, gm, writePicturePath, doReplay, doSerialize, doRTree, doTile Grid, | |
1707 tileGridReplayScales, doPipe, doTiledPipe); | |
1708 compositeErrors |= multipleModeErrors; | |
1469 | 1709 |
1470 for (int i = 0; i < configs.count(); i++) { | 1710 // A non-ignorable error in run_multiple_configs, or ANY error in |
1471 ConfigData config = gRec[configs[i]]; | 1711 // run_multiple_drawing_modes, counts as a failure. |
1472 | |
1473 // Skip any tests that we don't even need to try. | |
1474 if ((kPDF_Backend == config.fBackend) && | |
1475 (!doPDF || (gmFlags & GM::kSkipPDF_Flag))) | |
1476 { | |
1477 continue; | |
1478 } | |
1479 if ((gmFlags & GM::kSkip565_Flag) && | |
1480 (kRaster_Backend == config.fBackend) && | |
1481 (SkBitmap::kRGB_565_Config == config.fConfig)) { | |
1482 continue; | |
1483 } | |
1484 if ((gmFlags & GM::kSkipGPU_Flag) && | |
1485 kGPU_Backend == config.fBackend) { | |
1486 continue; | |
1487 } | |
1488 | |
1489 // Now we know that we want to run this test and record its | |
1490 // success or failure. | |
1491 ErrorBitfield renderErrors = kEmptyErrorBitfield; | |
1492 GrRenderTarget* renderTarget = NULL; | |
1493 #if SK_SUPPORT_GPU | |
1494 SkAutoTUnref<GrRenderTarget> rt; | |
1495 AutoResetGr autogr; | |
1496 if ((kEmptyErrorBitfield == renderErrors) && | |
1497 kGPU_Backend == config.fBackend) { | |
1498 GrContext* gr = grFactory->get(config.fGLContextType); | |
1499 bool grSuccess = false; | |
1500 if (gr) { | |
1501 // create a render target to back the device | |
1502 GrTextureDesc desc; | |
1503 desc.fConfig = kSkia8888_GrPixelConfig; | |
1504 desc.fFlags = kRenderTarget_GrTextureFlagBit; | |
1505 desc.fWidth = gm->getISize().width(); | |
1506 desc.fHeight = gm->getISize().height(); | |
1507 desc.fSampleCnt = config.fSampleCnt; | |
1508 GrTexture* tex = gr->createUncachedTexture(desc, NULL, 0); | |
1509 if (tex) { | |
1510 rt.reset(tex->asRenderTarget()); | |
1511 rt.get()->ref(); | |
1512 tex->unref(); | |
1513 autogr.set(gr); | |
1514 renderTarget = rt.get(); | |
1515 grSuccess = NULL != renderTarget; | |
1516 } | |
1517 // Set the user specified cache limits if non-default. | |
1518 size_t bytes; | |
1519 int count; | |
1520 gr->getTextureCacheLimits(&count, &bytes); | |
1521 if (-1 != gpuCacheSize.fBytes) { | |
1522 bytes = static_cast<size_t>(gpuCacheSize.fBytes); | |
1523 } | |
1524 if (-1 != gpuCacheSize.fCount) { | |
1525 count = gpuCacheSize.fCount; | |
1526 } | |
1527 gr->setTextureCacheLimits(count, bytes); | |
1528 } | |
1529 if (!grSuccess) { | |
1530 renderErrors |= kNoGpuContext_ErrorBitmask; | |
1531 } | |
1532 } | |
1533 #endif | |
1534 | |
1535 SkBitmap comparisonBitmap; | |
1536 | |
1537 if (kEmptyErrorBitfield == renderErrors) { | |
1538 renderErrors |= gmmain.test_drawing(gm, config, writePath, | |
1539 GetGr(), | |
1540 renderTarget, | |
1541 &comparisonBitmap); | |
1542 } | |
1543 | |
1544 if (doDeferred && !renderErrors && | |
1545 (kGPU_Backend == config.fBackend || | |
1546 kRaster_Backend == config.fBackend)) { | |
1547 renderErrors |= gmmain.test_deferred_drawing(gm, config, | |
1548 comparisonBitmap, | |
1549 GetGr(), | |
1550 renderTarget); | |
1551 } | |
1552 | |
1553 testErrors |= renderErrors; | |
1554 } | |
1555 | |
1556 SkBitmap comparisonBitmap; | |
1557 const ConfigData compareConfig = | |
1558 { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT ype, 0, kRW_ConfigFlag, "comparison" }; | |
1559 testErrors |= gmmain.generate_image(gm, compareConfig, NULL, NULL, &comp arisonBitmap, false); | |
1560 | |
1561 // run the picture centric GM steps | |
1562 if (!(gmFlags & GM::kSkipPicture_Flag)) { | |
1563 | |
1564 ErrorBitfield pictErrors = kEmptyErrorBitfield; | |
1565 | |
1566 //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); | |
1567 SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); | |
1568 SkAutoUnref aur(pict); | |
1569 | |
1570 if ((kEmptyErrorBitfield == testErrors) && doReplay) { | |
1571 SkBitmap bitmap; | |
1572 gmmain.generate_image_from_picture(gm, compareConfig, pict, | |
1573 &bitmap); | |
1574 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1575 gm, compareConfig, "-replay", bitmap, &comparisonBitmap); | |
1576 } | |
1577 | |
1578 if ((kEmptyErrorBitfield == testErrors) && | |
1579 (kEmptyErrorBitfield == pictErrors) && | |
1580 doSerialize) { | |
1581 SkPicture* repict = gmmain.stream_to_new_picture(*pict); | |
1582 SkAutoUnref aurr(repict); | |
1583 | |
1584 SkBitmap bitmap; | |
1585 gmmain.generate_image_from_picture(gm, compareConfig, repict, | |
1586 &bitmap); | |
1587 pictErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1588 gm, compareConfig, "-serialize", bitmap, &comparisonBitmap); | |
1589 } | |
1590 | |
1591 if (writePicturePath) { | |
1592 const char* pictureSuffix = "skp"; | |
1593 SkString path = make_filename(writePicturePath, "", | |
1594 gm->shortName(), | |
1595 pictureSuffix); | |
1596 SkFILEWStream stream(path.c_str()); | |
1597 pict->serialize(&stream); | |
1598 } | |
1599 | |
1600 testErrors |= pictErrors; | |
1601 } | |
1602 | |
1603 // TODO: add a test in which the RTree rendering results in a | |
1604 // different bitmap than the standard rendering. It should | |
1605 // show up as failed in the JSON summary, and should be listed | |
1606 // in the stdout also. | |
1607 if (!(gmFlags & GM::kSkipPicture_Flag) && doRTree) { | |
1608 SkPicture* pict = gmmain.generate_new_picture( | |
1609 gm, kRTree_BbhType, SkPicture::kUsePathBoundsForClip_RecordingFl ag); | |
1610 SkAutoUnref aur(pict); | |
1611 SkBitmap bitmap; | |
1612 gmmain.generate_image_from_picture(gm, compareConfig, pict, | |
1613 &bitmap); | |
1614 testErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1615 gm, compareConfig, "-rtree", bitmap, &comparisonBitmap); | |
1616 } | |
1617 | |
1618 if (!(gmFlags & GM::kSkipPicture_Flag) && doTileGrid) { | |
1619 for(int scaleIndex = 0; scaleIndex < tileGridReplayScales.count(); + +scaleIndex) { | |
1620 SkScalar replayScale = tileGridReplayScales[scaleIndex]; | |
1621 if ((gmFlags & GM::kSkipScaledReplay_Flag) && replayScale != 1) | |
1622 continue; | |
1623 // We record with the reciprocal scale to obtain a replay | |
1624 // result that can be validated against comparisonBitmap. | |
1625 SkScalar recordScale = SkScalarInvert(replayScale); | |
1626 SkPicture* pict = gmmain.generate_new_picture( | |
1627 gm, kTileGrid_BbhType, SkPicture::kUsePathBoundsForClip_Reco rdingFlag, | |
1628 recordScale); | |
1629 SkAutoUnref aur(pict); | |
1630 SkBitmap bitmap; | |
1631 gmmain.generate_image_from_picture(gm, compareConfig, pict, | |
1632 &bitmap, replayScale); | |
1633 SkString suffix("-tilegrid"); | |
1634 if (SK_Scalar1 != replayScale) { | |
1635 suffix += "-scale-"; | |
1636 suffix.appendScalar(replayScale); | |
1637 } | |
1638 testErrors |= gmmain.compare_test_results_to_reference_bitmap( | |
1639 gm, compareConfig, suffix.c_str(), bitmap, | |
1640 &comparisonBitmap); | |
1641 } | |
1642 } | |
1643 | |
1644 // run the pipe centric GM steps | |
1645 if (!(gmFlags & GM::kSkipPipe_Flag)) { | |
1646 | |
1647 ErrorBitfield pipeErrors = kEmptyErrorBitfield; | |
1648 | |
1649 if ((kEmptyErrorBitfield == testErrors) && doPipe) { | |
1650 pipeErrors |= gmmain.test_pipe_playback(gm, compareConfig, | |
1651 comparisonBitmap); | |
1652 } | |
1653 | |
1654 if ((kEmptyErrorBitfield == testErrors) && | |
1655 (kEmptyErrorBitfield == pipeErrors) && | |
1656 doTiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { | |
1657 pipeErrors |= gmmain.test_tiled_pipe_playback(gm, compareConfig, | |
1658 comparisonBitmap); | |
1659 } | |
1660 | |
1661 testErrors |= pipeErrors; | |
1662 } | |
1663 | |
1664 // Update overall results. | |
1665 // We only tabulate the particular error types that we currently | |
1666 // care about (e.g., missing reference images). Later on, if we | |
1667 // want to also tabulate other error types, we can do so. | |
1668 testsRun++; | 1712 testsRun++; |
1669 if (!gmmain.fExpectationsSource.get() || | 1713 if (kEmptyErrorBitfield != multipleModeErrors) { |
1670 (kEmptyErrorBitfield != (kMissingExpectations_ErrorBitmask & testErr ors))) { | 1714 testsWithDrawingModeDiscrepancies++; |
1671 testsMissingReferenceImages++; | 1715 testsFailed++; |
1672 } | 1716 } else if (compositeErrors == (compositeErrors & kIgnorable_ErrorBitmask )) { |
1673 if (testErrors == (testErrors & kIgnorable_ErrorBitmask)) { | |
1674 testsPassed++; | 1717 testsPassed++; |
1675 } else { | 1718 } else { |
1676 testsFailed++; | 1719 testsFailed++; |
1677 } | 1720 } |
1721 // Any other result categories we care to report. | |
1722 if (!gmmain.fExpectationsSource.get() || | |
1723 (kEmptyErrorBitfield != (kMissingExpectations_ErrorBitmask & composi teErrors))) { | |
1724 testsMissingReferenceImages++; | |
1725 } | |
1678 | 1726 |
1679 SkDELETE(gm); | 1727 SkDELETE(gm); |
1680 } | 1728 } |
1681 gm_fprintf(stdout, "Ran %d tests: %d passed, %d failed, %d missing reference images\n", | 1729 gm_fprintf(stdout, "Ran %d tests: %d passed, %d failed, %d with drawing mode discrepancies, " |
1682 testsRun, testsPassed, testsFailed, testsMissingReferenceImages); | 1730 "%d missing reference images\n", |
1731 testsRun, testsPassed, testsFailed, testsWithDrawingModeDiscrepan cies, | |
1732 testsMissingReferenceImages); | |
1683 gmmain.ListErrors(); | 1733 gmmain.ListErrors(); |
1684 | 1734 |
1685 if (NULL != writeJsonSummaryPath) { | 1735 if (NULL != writeJsonSummaryPath) { |
1686 Json::Value actualResults; | 1736 Json::Value actualResults; |
1687 actualResults[kJsonKey_ActualResults_Failed] = | 1737 actualResults[kJsonKey_ActualResults_Failed] = |
1688 gmmain.fJsonActualResults_Failed; | 1738 gmmain.fJsonActualResults_Failed; |
1689 actualResults[kJsonKey_ActualResults_FailureIgnored] = | 1739 actualResults[kJsonKey_ActualResults_FailureIgnored] = |
1690 gmmain.fJsonActualResults_FailureIgnored; | 1740 gmmain.fJsonActualResults_FailureIgnored; |
1691 actualResults[kJsonKey_ActualResults_NoComparison] = | 1741 actualResults[kJsonKey_ActualResults_NoComparison] = |
1692 gmmain.fJsonActualResults_NoComparison; | 1742 gmmain.fJsonActualResults_NoComparison; |
(...skipping 27 matching lines...) Expand all Loading... | |
1720 SkGraphics::Term(); | 1770 SkGraphics::Term(); |
1721 | 1771 |
1722 return (0 == testsFailed) ? 0 : -1; | 1772 return (0 == testsFailed) ? 0 : -1; |
1723 } | 1773 } |
1724 | 1774 |
1725 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 1775 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) |
1726 int main(int argc, char * const argv[]) { | 1776 int main(int argc, char * const argv[]) { |
1727 return tool_main(argc, (char**) argv); | 1777 return tool_main(argc, (char**) argv); |
1728 } | 1778 } |
1729 #endif | 1779 #endif |
OLD | NEW |