| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2011 Google Inc. | 2  * Copyright 2011 Google Inc. | 
| 3  * | 3  * | 
| 4  * Use of this source code is governed by a BSD-style license that can be | 4  * Use of this source code is governed by a BSD-style license that can be | 
| 5  * found in the LICENSE file. | 5  * found in the LICENSE file. | 
| 6  */ | 6  */ | 
| 7 | 7 | 
| 8 /* | 8 /* | 
| 9  * Code for the "gm" (Golden Master) rendering comparison tool. | 9  * Code for the "gm" (Golden Master) rendering comparison tool. | 
| 10  * | 10  * | 
| (...skipping 16 matching lines...) Expand all  Loading... | 
| 27 #include "SkDrawFilter.h" | 27 #include "SkDrawFilter.h" | 
| 28 #include "SkGPipe.h" | 28 #include "SkGPipe.h" | 
| 29 #include "SkGraphics.h" | 29 #include "SkGraphics.h" | 
| 30 #include "SkImageDecoder.h" | 30 #include "SkImageDecoder.h" | 
| 31 #include "SkImageEncoder.h" | 31 #include "SkImageEncoder.h" | 
| 32 #include "SkOSFile.h" | 32 #include "SkOSFile.h" | 
| 33 #include "SkPicture.h" | 33 #include "SkPicture.h" | 
| 34 #include "SkRefCnt.h" | 34 #include "SkRefCnt.h" | 
| 35 #include "SkStream.h" | 35 #include "SkStream.h" | 
| 36 #include "SkTArray.h" | 36 #include "SkTArray.h" | 
|  | 37 #include "SkTDict.h" | 
| 37 #include "SkTileGridPicture.h" | 38 #include "SkTileGridPicture.h" | 
| 38 #include "SamplePipeControllers.h" | 39 #include "SamplePipeControllers.h" | 
| 39 | 40 | 
| 40 #ifdef SK_BUILD_FOR_WIN | 41 #ifdef SK_BUILD_FOR_WIN | 
| 41     // json includes xlocale which generates warning 4530 because we're compilin
      g without | 42     // json includes xlocale which generates warning 4530 because we're compilin
      g without | 
| 42     // exceptions; see https://code.google.com/p/skia/issues/detail?id=1067 | 43     // exceptions; see https://code.google.com/p/skia/issues/detail?id=1067 | 
| 43     #pragma warning(push) | 44     #pragma warning(push) | 
| 44     #pragma warning(disable : 4530) | 45     #pragma warning(disable : 4530) | 
| 45 #endif | 46 #endif | 
| 46 #include "json/value.h" | 47 #include "json/value.h" | 
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 78 | 79 | 
| 79 #ifdef SK_BUILD_FOR_MAC | 80 #ifdef SK_BUILD_FOR_MAC | 
| 80     #include "SkCGUtils.h" | 81     #include "SkCGUtils.h" | 
| 81     #define CAN_IMAGE_PDF   1 | 82     #define CAN_IMAGE_PDF   1 | 
| 82 #else | 83 #else | 
| 83     #define CAN_IMAGE_PDF   0 | 84     #define CAN_IMAGE_PDF   0 | 
| 84 #endif | 85 #endif | 
| 85 | 86 | 
| 86 using namespace skiagm; | 87 using namespace skiagm; | 
| 87 | 88 | 
| 88 struct FailRec { |  | 
| 89     SkString    fName; |  | 
| 90     bool        fIsPixelError; |  | 
| 91 |  | 
| 92     FailRec() : fIsPixelError(false) {} |  | 
| 93     FailRec(const SkString& name) : fName(name), fIsPixelError(false) {} |  | 
| 94 }; |  | 
| 95 |  | 
| 96 class Iter { | 89 class Iter { | 
| 97 public: | 90 public: | 
| 98     Iter() { | 91     Iter() { | 
| 99         this->reset(); | 92         this->reset(); | 
| 100     } | 93     } | 
| 101 | 94 | 
| 102     void reset() { | 95     void reset() { | 
| 103         fReg = GMRegistry::Head(); | 96         fReg = GMRegistry::Head(); | 
| 104     } | 97     } | 
| 105 | 98 | 
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 176 | 169 | 
| 177 static PipeFlagComboData gPipeWritingFlagCombos[] = { | 170 static PipeFlagComboData gPipeWritingFlagCombos[] = { | 
| 178     { "", 0 }, | 171     { "", 0 }, | 
| 179     { " cross-process", SkGPipeWriter::kCrossProcess_Flag }, | 172     { " cross-process", SkGPipeWriter::kCrossProcess_Flag }, | 
| 180     { " cross-process, shared address", SkGPipeWriter::kCrossProcess_Flag | 173     { " cross-process, shared address", SkGPipeWriter::kCrossProcess_Flag | 
| 181         | SkGPipeWriter::kSharedAddressSpace_Flag } | 174         | SkGPipeWriter::kSharedAddressSpace_Flag } | 
| 182 }; | 175 }; | 
| 183 | 176 | 
| 184 class GMMain { | 177 class GMMain { | 
| 185 public: | 178 public: | 
| 186     GMMain() { | 179     GMMain() : fUseFileHierarchy(false), fMismatchPath(NULL), fTestsRun(0), | 
| 187         // Set default values of member variables, which tool_main() | 180                fRenderModesEncountered(1) { | 
| 188         // may override. |  | 
| 189         fUseFileHierarchy = false; |  | 
| 190         fIgnorableErrorCombination.add(kMissingExpectations_ErrorType); | 181         fIgnorableErrorCombination.add(kMissingExpectations_ErrorType); | 
| 191         fMismatchPath = NULL; |  | 
| 192     } | 182     } | 
| 193 | 183 | 
| 194     SkString make_name(const char shortName[], const char configName[]) { | 184     SkString make_name(const char shortName[], const char configName[]) { | 
| 195         SkString name; | 185         SkString name; | 
| 196         if (0 == strlen(configName)) { | 186         if (0 == strlen(configName)) { | 
| 197             name.append(shortName); | 187             name.append(shortName); | 
| 198         } else if (fUseFileHierarchy) { | 188         } else if (fUseFileHierarchy) { | 
| 199             name.appendf("%s%c%s", configName, SkPATH_SEPARATOR, shortName); | 189             name.appendf("%s%c%s", configName, SkPATH_SEPARATOR, shortName); | 
| 200         } else { | 190         } else { | 
| 201             name.appendf("%s_%s", shortName, configName); | 191             name.appendf("%s_%s", shortName, configName); | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 235         // TODO(epoger): Now that we have removed force_all_opaque() | 225         // TODO(epoger): Now that we have removed force_all_opaque() | 
| 236         // from this method, we should be able to get rid of the | 226         // from this method, we should be able to get rid of the | 
| 237         // transformation to 8888 format also. | 227         // transformation to 8888 format also. | 
| 238         SkBitmap copy; | 228         SkBitmap copy; | 
| 239         bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); | 229         bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); | 
| 240         return SkImageEncoder::EncodeFile(path.c_str(), copy, | 230         return SkImageEncoder::EncodeFile(path.c_str(), copy, | 
| 241                                           SkImageEncoder::kPNG_Type, 100); | 231                                           SkImageEncoder::kPNG_Type, 100); | 
| 242     } | 232     } | 
| 243 | 233 | 
| 244     /** | 234     /** | 
| 245      * Records the errors encountered in fFailedTests, except for any error | 235      * Add all render modes encountered thus far to the "modes" array. | 
| 246      * types we want to ignore. |  | 
| 247      */ | 236      */ | 
| 248     void RecordError(const ErrorCombination& errorCombination, const SkString& n
      ame, | 237     void GetRenderModesEncountered(SkTArray<SkString> &modes) { | 
| 249                      const char renderModeDescriptor []) { | 238         SkTDict<int>::Iter iter(this->fRenderModesEncountered); | 
| 250         // The common case: no error means nothing to record. | 239         const char* mode; | 
|  | 240         while ((mode = iter.next(NULL)) != NULL) { | 
|  | 241             SkString modeAsString = SkString(mode); | 
|  | 242             // TODO(epoger): It seems a bit silly that all of these modes were | 
|  | 243             // recorded with a leading "-" which we have to remove here | 
|  | 244             // (except for mode "", which means plain old original mode). | 
|  | 245             // But that's how renderModeDescriptor has been passed into | 
|  | 246             // compare_test_results_to_reference_bitmap() historically, | 
|  | 247             // and changing that now may affect other parts of our code. | 
|  | 248             if (modeAsString.startsWith("-")) { | 
|  | 249                 modeAsString.remove(0, 1); | 
|  | 250                 modes.push_back(modeAsString); | 
|  | 251             } | 
|  | 252         } | 
|  | 253     } | 
|  | 254 | 
|  | 255     /** | 
|  | 256      * Records the results of this test in fTestsRun and fFailedTests. | 
|  | 257      * | 
|  | 258      * We even record successes, and errors that we regard as | 
|  | 259      * "ignorable"; we can filter them out later. | 
|  | 260      */ | 
|  | 261     void RecordTestResults(const ErrorCombination& errorCombination, const SkStr
      ing& name, | 
|  | 262                            const char renderModeDescriptor []) { | 
|  | 263         // Things to do regardless of errorCombination. | 
|  | 264         fTestsRun++; | 
|  | 265         int renderModeCount = 0; | 
|  | 266         this->fRenderModesEncountered.find(renderModeDescriptor, &renderModeCoun
      t); | 
|  | 267         renderModeCount++; | 
|  | 268         this->fRenderModesEncountered.set(renderModeDescriptor, renderModeCount)
      ; | 
|  | 269 | 
| 251         if (errorCombination.isEmpty()) { | 270         if (errorCombination.isEmpty()) { | 
| 252             return; | 271             return; | 
| 253         } | 272         } | 
| 254 | 273 | 
| 255         // If only certain error type(s) were reported, we know we can ignore th
      em. | 274         // Things to do only if there is some error condition. | 
| 256         if (errorCombination.minus(fIgnorableErrorCombination).isEmpty()) { | 275         SkString fullName = make_name(name.c_str(), renderModeDescriptor); | 
| 257             return; | 276         for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) { | 
| 258         } | 277             ErrorType type = static_cast<ErrorType>(typeInt); | 
| 259 | 278             if (errorCombination.includes(type)) { | 
| 260         FailRec& rec = fFailedTests.push_back(make_name(name.c_str(), renderMode
      Descriptor)); | 279                 fFailedTests[type].push_back(fullName); | 
| 261         rec.fIsPixelError = errorCombination.includes(kImageMismatch_ErrorType); |  | 
| 262     } |  | 
| 263 |  | 
| 264     // List contents of fFailedTests via SkDebug. |  | 
| 265     void ListErrors() { |  | 
| 266         for (int i = 0; i < fFailedTests.count(); ++i) { |  | 
| 267             if (fFailedTests[i].fIsPixelError) { |  | 
| 268                 gm_fprintf(stderr, "\t\t%s pixel_error\n", fFailedTests[i].fName
      .c_str()); |  | 
| 269             } else { |  | 
| 270                 gm_fprintf(stderr, "\t\t%s\n", fFailedTests[i].fName.c_str()); |  | 
| 271             } | 280             } | 
| 272         } | 281         } | 
| 273     } | 282     } | 
| 274 | 283 | 
|  | 284     /** | 
|  | 285      * Return the number of significant (non-ignorable) errors we have | 
|  | 286      * encountered so far. | 
|  | 287      */ | 
|  | 288     int NumSignificantErrors() { | 
|  | 289         int significantErrors = 0; | 
|  | 290         for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) { | 
|  | 291             ErrorType type = static_cast<ErrorType>(typeInt); | 
|  | 292             if (!fIgnorableErrorCombination.includes(type)) { | 
|  | 293                 significantErrors += fFailedTests[type].count(); | 
|  | 294             } | 
|  | 295         } | 
|  | 296         return significantErrors; | 
|  | 297     } | 
|  | 298 | 
|  | 299     /** | 
|  | 300      * List contents of fFailedTests to stdout. | 
|  | 301      */ | 
|  | 302     void ListErrors() { | 
|  | 303         // First, print a single summary line. | 
|  | 304         SkString summary; | 
|  | 305         summary.appendf("Ran %d tests:", fTestsRun); | 
|  | 306         for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) { | 
|  | 307             ErrorType type = static_cast<ErrorType>(typeInt); | 
|  | 308             summary.appendf(" %s=%d", getErrorTypeName(type), fFailedTests[type]
      .count()); | 
|  | 309         } | 
|  | 310         gm_fprintf(stdout, "%s\n", summary.c_str()); | 
|  | 311 | 
|  | 312         // Now, for each failure type, list the tests that failed that way. | 
|  | 313         for (int typeInt = 0; typeInt <= kLast_ErrorType; typeInt++) { | 
|  | 314             SkString line; | 
|  | 315             ErrorType type = static_cast<ErrorType>(typeInt); | 
|  | 316             if (fIgnorableErrorCombination.includes(type)) { | 
|  | 317                 line.append("[ ] "); | 
|  | 318             } else { | 
|  | 319                 line.append("[*] "); | 
|  | 320             } | 
|  | 321 | 
|  | 322             SkTArray<SkString> *failedTestsOfThisType = &fFailedTests[type]; | 
|  | 323             int count = failedTestsOfThisType->count(); | 
|  | 324             line.appendf("%d %s:", count, getErrorTypeName(type)); | 
|  | 325             for (int i = 0; i < count; ++i) { | 
|  | 326                 line.append(" "); | 
|  | 327                 line.append((*failedTestsOfThisType)[i]); | 
|  | 328             } | 
|  | 329             gm_fprintf(stdout, "%s\n", line.c_str()); | 
|  | 330         } | 
|  | 331         gm_fprintf(stdout, "(results marked with [*] will cause nonzero return v
      alue)\n"); | 
|  | 332     } | 
|  | 333 | 
| 275     static bool write_document(const SkString& path, | 334     static bool write_document(const SkString& path, | 
| 276                                const SkDynamicMemoryWStream& document) { | 335                                const SkDynamicMemoryWStream& document) { | 
| 277         SkFILEWStream stream(path.c_str()); | 336         SkFILEWStream stream(path.c_str()); | 
| 278         SkAutoDataUnref data(document.copyToData()); | 337         SkAutoDataUnref data(document.copyToData()); | 
| 279         return stream.writeData(data.get()); | 338         return stream.writeData(data.get()); | 
| 280     } | 339     } | 
| 281 | 340 | 
| 282     /** | 341     /** | 
| 283      * Prepare an SkBitmap to render a GM into. | 342      * Prepare an SkBitmap to render a GM into. | 
| 284      * | 343      * | 
| (...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 535         if (kXPS_Backend == gRec.fBackend) { | 594         if (kXPS_Backend == gRec.fBackend) { | 
| 536             path = make_filename(writePath, renderModeDescriptor, name.c_str(), | 595             path = make_filename(writePath, renderModeDescriptor, name.c_str(), | 
| 537                                  "xps"); | 596                                  "xps"); | 
| 538             success = write_document(path, *document); | 597             success = write_document(path, *document); | 
| 539         } | 598         } | 
| 540         if (success) { | 599         if (success) { | 
| 541             return kEmpty_ErrorCombination; | 600             return kEmpty_ErrorCombination; | 
| 542         } else { | 601         } else { | 
| 543             gm_fprintf(stderr, "FAILED to write %s\n", path.c_str()); | 602             gm_fprintf(stderr, "FAILED to write %s\n", path.c_str()); | 
| 544             ErrorCombination errors(kWritingReferenceImage_ErrorType); | 603             ErrorCombination errors(kWritingReferenceImage_ErrorType); | 
| 545             RecordError(errors, name, renderModeDescriptor); | 604             // TODO(epoger): Don't call RecordTestResults() here... | 
|  | 605             // Instead, we should make sure to call RecordTestResults | 
|  | 606             // exactly ONCE per test.  (Otherwise, gmmain.fTestsRun | 
|  | 607             // will be incremented twice for this test: once in | 
|  | 608             // compare_test_results_to_stored_expectations() before | 
|  | 609             // that method calls this one, and again here.) | 
|  | 610             // | 
|  | 611             // When we make that change, we should probably add a | 
|  | 612             // WritingReferenceImage test to the gm self-tests.) | 
|  | 613             RecordTestResults(errors, name, renderModeDescriptor); | 
| 546             return errors; | 614             return errors; | 
| 547         } | 615         } | 
| 548     } | 616     } | 
| 549 | 617 | 
| 550     /** | 618     /** | 
| 551      * Log more detail about the mistmatch between expectedBitmap and | 619      * Log more detail about the mistmatch between expectedBitmap and | 
| 552      * actualBitmap. | 620      * actualBitmap. | 
| 553      */ | 621      */ | 
| 554     void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act
      ualBitmap, | 622     void report_bitmap_diffs(const SkBitmap& expectedBitmap, const SkBitmap& act
      ualBitmap, | 
| 555                              const char *testName) { | 623                              const char *testName) { | 
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 647                 write_bitmap(path, actualBitmap); | 715                 write_bitmap(path, actualBitmap); | 
| 648             } | 716             } | 
| 649 | 717 | 
| 650             // If we have access to a single expected bitmap, log more | 718             // If we have access to a single expected bitmap, log more | 
| 651             // detail about the mismatch. | 719             // detail about the mismatch. | 
| 652             const SkBitmap *expectedBitmapPtr = expectations.asBitmap(); | 720             const SkBitmap *expectedBitmapPtr = expectations.asBitmap(); | 
| 653             if (NULL != expectedBitmapPtr) { | 721             if (NULL != expectedBitmapPtr) { | 
| 654                 report_bitmap_diffs(*expectedBitmapPtr, actualBitmap, completeNa
      me); | 722                 report_bitmap_diffs(*expectedBitmapPtr, actualBitmap, completeNa
      me); | 
| 655             } | 723             } | 
| 656         } | 724         } | 
| 657         RecordError(errors, baseNameString, renderModeDescriptor); | 725         RecordTestResults(errors, baseNameString, renderModeDescriptor); | 
| 658 | 726 | 
| 659         if (addToJsonSummary) { | 727         if (addToJsonSummary) { | 
| 660             add_actual_results_to_json_summary(completeName, actualChecksum, err
      ors, | 728             add_actual_results_to_json_summary(completeName, actualChecksum, err
      ors, | 
| 661                                                expectations.ignoreFailure()); | 729                                                expectations.ignoreFailure()); | 
| 662             add_expected_results_to_json_summary(completeName, expectations); | 730             add_expected_results_to_json_summary(completeName, expectations); | 
| 663         } | 731         } | 
| 664 | 732 | 
| 665         return errors; | 733         return errors; | 
| 666     } | 734     } | 
| 667 | 735 | 
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 763             errors.add(compare_to_expectations(expectations, actualBitmap, | 831             errors.add(compare_to_expectations(expectations, actualBitmap, | 
| 764                                                name, "", true)); | 832                                                name, "", true)); | 
| 765         } else { | 833         } else { | 
| 766             // If we are running without expectations, we still want to | 834             // If we are running without expectations, we still want to | 
| 767             // record the actual results. | 835             // record the actual results. | 
| 768             Checksum actualChecksum = | 836             Checksum actualChecksum = | 
| 769                 SkBitmapChecksummer::Compute64(actualBitmap); | 837                 SkBitmapChecksummer::Compute64(actualBitmap); | 
| 770             add_actual_results_to_json_summary(name.c_str(), actualChecksum, | 838             add_actual_results_to_json_summary(name.c_str(), actualChecksum, | 
| 771                                                ErrorCombination(kMissingExpectat
      ions_ErrorType), | 839                                                ErrorCombination(kMissingExpectat
      ions_ErrorType), | 
| 772                                                false); | 840                                                false); | 
|  | 841             RecordTestResults(ErrorCombination(kMissingExpectations_ErrorType), 
      name, ""); | 
| 773         } | 842         } | 
| 774 | 843 | 
| 775         // TODO: Consider moving this into compare_to_expectations(), | 844         // TODO: Consider moving this into compare_to_expectations(), | 
| 776         // similar to fMismatchPath... for now, we don't do that, because | 845         // similar to fMismatchPath... for now, we don't do that, because | 
| 777         // we don't want to write out the actual bitmaps for all | 846         // we don't want to write out the actual bitmaps for all | 
| 778         // renderModes of all tests!  That would be a lot of files. | 847         // renderModes of all tests!  That would be a lot of files. | 
| 779         if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { | 848         if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { | 
| 780             errors.add(write_reference_image(gRec, writePath, "", | 849             errors.add(write_reference_image(gRec, writePath, "", | 
| 781                                              name, actualBitmap, pdf)); | 850                                              name, actualBitmap, pdf)); | 
| 782         } | 851         } | 
| 783 | 852 | 
| 784         return errors; | 853         return errors; | 
| 785     } | 854     } | 
| 786 | 855 | 
| 787     /** | 856     /** | 
| 788      * Compare actualBitmap to referenceBitmap. | 857      * Compare actualBitmap to referenceBitmap. | 
| 789      * | 858      * | 
| 790      * @param gm which test generated the bitmap | 859      * @param gm which test generated the bitmap | 
| 791      * @param gRec | 860      * @param gRec | 
| 792      * @param renderModeDescriptor | 861      * @param renderModeDescriptor | 
| 793      * @param actualBitmap actual bitmap generated by this run | 862      * @param actualBitmap actual bitmap generated by this run | 
| 794      * @param referenceBitmap bitmap we expected to be generated | 863      * @param referenceBitmap bitmap we expected to be generated | 
| 795      */ | 864      */ | 
| 796     ErrorCombination compare_test_results_to_reference_bitmap( | 865     ErrorCombination compare_test_results_to_reference_bitmap( | 
| 797         GM* gm, const ConfigData& gRec, const char renderModeDescriptor [], | 866         GM* gm, const ConfigData& gRec, const char renderModeDescriptor [], | 
| 798         SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) { | 867         SkBitmap& actualBitmap, const SkBitmap* referenceBitmap) { | 
| 799 | 868 | 
|  | 869         // TODO(epoger): This method is run to compare results across | 
|  | 870         // different rendering modes (as opposed to | 
|  | 871         // compare_test_results_to_stored_expectations(), which | 
|  | 872         // compares results against expectations stored on disk).  If | 
|  | 873         // we would like the GenerateGMs step to distinguish between | 
|  | 874         // those two types of mismatches, we should report image | 
|  | 875         // mismatches in here with a different ErrorType. | 
| 800         SkASSERT(referenceBitmap); | 876         SkASSERT(referenceBitmap); | 
| 801         SkString name = make_name(gm->shortName(), gRec.fName); | 877         SkString name = make_name(gm->shortName(), gRec.fName); | 
| 802         Expectations expectations(*referenceBitmap); | 878         Expectations expectations(*referenceBitmap); | 
| 803         return compare_to_expectations(expectations, actualBitmap, | 879         return compare_to_expectations(expectations, actualBitmap, | 
| 804                                        name, renderModeDescriptor); | 880                                        name, renderModeDescriptor); | 
| 805     } | 881     } | 
| 806 | 882 | 
| 807     static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t rec
      ordFlags, | 883     static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t rec
      ordFlags, | 
| 808                                            SkScalar scale = SK_Scalar1) { | 884                                            SkScalar scale = SK_Scalar1) { | 
| 809         // Pictures are refcounted so must be on heap | 885         // Pictures are refcounted so must be on heap | 
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 903             // -deferred image, we exit early!  We should fix this | 979             // -deferred image, we exit early!  We should fix this | 
| 904             // ASAP, because it is hiding -deferred errors... but for | 980             // ASAP, because it is hiding -deferred errors... but for | 
| 905             // now, I'm leaving the logic as it is so that the | 981             // now, I'm leaving the logic as it is so that the | 
| 906             // refactoring change | 982             // refactoring change | 
| 907             // https://codereview.chromium.org/12992003/ is unblocked. | 983             // https://codereview.chromium.org/12992003/ is unblocked. | 
| 908             // | 984             // | 
| 909             // Filed as https://code.google.com/p/skia/issues/detail?id=1180 | 985             // Filed as https://code.google.com/p/skia/issues/detail?id=1180 | 
| 910             // ('image-surface gm test is failing in "deferred" mode, | 986             // ('image-surface gm test is failing in "deferred" mode, | 
| 911             // and gm is not reporting the failure') | 987             // and gm is not reporting the failure') | 
| 912             if (errors.isEmpty()) { | 988             if (errors.isEmpty()) { | 
|  | 989                 // TODO(epoger): Report this as a new ErrorType, | 
|  | 990                 // something like kImageGeneration_ErrorType? | 
| 913                 return kEmpty_ErrorCombination; | 991                 return kEmpty_ErrorCombination; | 
| 914             } | 992             } | 
| 915             return compare_test_results_to_reference_bitmap( | 993             return compare_test_results_to_reference_bitmap( | 
| 916                 gm, gRec, "-deferred", bitmap, &referenceBitmap); | 994                 gm, gRec, "-deferred", bitmap, &referenceBitmap); | 
| 917         } | 995         } | 
| 918         return kEmpty_ErrorCombination; | 996         return kEmpty_ErrorCombination; | 
| 919     } | 997     } | 
| 920 | 998 | 
| 921     ErrorCombination test_pipe_playback(GM* gm, | 999     ErrorCombination test_pipe_playback(GM* gm, | 
| 922                                         const ConfigData& gRec, | 1000                                         const ConfigData& gRec, | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 976     // | 1054     // | 
| 977     // member variables. | 1055     // member variables. | 
| 978     // They are public for now, to allow easier setting by tool_main(). | 1056     // They are public for now, to allow easier setting by tool_main(). | 
| 979     // | 1057     // | 
| 980 | 1058 | 
| 981     bool fUseFileHierarchy; | 1059     bool fUseFileHierarchy; | 
| 982     ErrorCombination fIgnorableErrorCombination; | 1060     ErrorCombination fIgnorableErrorCombination; | 
| 983 | 1061 | 
| 984     const char* fMismatchPath; | 1062     const char* fMismatchPath; | 
| 985 | 1063 | 
| 986     // information about all failed tests we have encountered so far | 1064     // collection of tests that have failed with each ErrorType | 
| 987     SkTArray<FailRec> fFailedTests; | 1065     SkTArray<SkString> fFailedTests[kLast_ErrorType+1]; | 
|  | 1066     int fTestsRun; | 
|  | 1067     SkTDict<int> fRenderModesEncountered; | 
| 988 | 1068 | 
| 989     // Where to read expectations (expected image checksums, etc.) from. | 1069     // Where to read expectations (expected image checksums, etc.) from. | 
| 990     // If unset, we don't do comparisons. | 1070     // If unset, we don't do comparisons. | 
| 991     SkAutoTUnref<ExpectationsSource> fExpectationsSource; | 1071     SkAutoTUnref<ExpectationsSource> fExpectationsSource; | 
| 992 | 1072 | 
| 993     // JSON summaries that we generate as we go (just for output). | 1073     // JSON summaries that we generate as we go (just for output). | 
| 994     Json::Value fJsonExpectedResults; | 1074     Json::Value fJsonExpectedResults; | 
| 995     Json::Value fJsonActualResults_Failed; | 1075     Json::Value fJsonActualResults_Failed; | 
| 996     Json::Value fJsonActualResults_FailureIgnored; | 1076     Json::Value fJsonActualResults_FailureIgnored; | 
| 997     Json::Value fJsonActualResults_NoComparison; | 1077     Json::Value fJsonActualResults_NoComparison; | 
| (...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1285  */ | 1365  */ | 
| 1286 ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &co
      mpareConfig, | 1366 ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &co
      mpareConfig, | 
| 1287                                     const SkBitmap &comparisonBitmap, | 1367                                     const SkBitmap &comparisonBitmap, | 
| 1288                                     const SkTDArray<SkScalar> &tileGridReplaySca
      les); | 1368                                     const SkTDArray<SkScalar> &tileGridReplaySca
      les); | 
| 1289 ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &co
      mpareConfig, | 1369 ErrorCombination run_multiple_modes(GMMain &gmmain, GM *gm, const ConfigData &co
      mpareConfig, | 
| 1290                                     const SkBitmap &comparisonBitmap, | 1370                                     const SkBitmap &comparisonBitmap, | 
| 1291                                     const SkTDArray<SkScalar> &tileGridReplaySca
      les) { | 1371                                     const SkTDArray<SkScalar> &tileGridReplaySca
      les) { | 
| 1292     ErrorCombination errorsForAllModes; | 1372     ErrorCombination errorsForAllModes; | 
| 1293     uint32_t gmFlags = gm->getFlags(); | 1373     uint32_t gmFlags = gm->getFlags(); | 
| 1294 | 1374 | 
| 1295     // run the picture centric GM steps | 1375     // TODO(epoger): We should start recording any per-GM skipped | 
|  | 1376     // modes (i.e. those we skipped due to gmFlags) with a new | 
|  | 1377     // ErrorType, perhaps named kIntentionallySkipped_ErrorType. | 
| 1296     if (!(gmFlags & GM::kSkipPicture_Flag)) { | 1378     if (!(gmFlags & GM::kSkipPicture_Flag)) { | 
| 1297 | 1379 | 
| 1298         ErrorCombination pictErrors; | 1380         ErrorCombination pictErrors; | 
| 1299 | 1381 | 
| 1300         //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); | 1382         //SkAutoTUnref<SkPicture> pict(generate_new_picture(gm)); | 
| 1301         SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); | 1383         SkPicture* pict = gmmain.generate_new_picture(gm, kNone_BbhType, 0); | 
| 1302         SkAutoUnref aur(pict); | 1384         SkAutoUnref aur(pict); | 
| 1303 | 1385 | 
| 1304         if (FLAGS_replay) { | 1386         if (FLAGS_replay) { | 
| 1305             SkBitmap bitmap; | 1387             SkBitmap bitmap; | 
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1383         if ((pipeErrors.isEmpty()) && | 1465         if ((pipeErrors.isEmpty()) && | 
| 1384             FLAGS_tiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { | 1466             FLAGS_tiledPipe && !(gmFlags & GM::kSkipTiled_Flag)) { | 
| 1385             pipeErrors.add(gmmain.test_tiled_pipe_playback(gm, compareConfig, co
      mparisonBitmap)); | 1467             pipeErrors.add(gmmain.test_tiled_pipe_playback(gm, compareConfig, co
      mparisonBitmap)); | 
| 1386         } | 1468         } | 
| 1387 | 1469 | 
| 1388         errorsForAllModes.add(pipeErrors); | 1470         errorsForAllModes.add(pipeErrors); | 
| 1389     } | 1471     } | 
| 1390     return errorsForAllModes; | 1472     return errorsForAllModes; | 
| 1391 } | 1473 } | 
| 1392 | 1474 | 
|  | 1475 /** | 
|  | 1476  * Return a list of all entries in an array of strings as a single string | 
|  | 1477  * of this form: | 
|  | 1478  * "item1", "item2", "item3" | 
|  | 1479  */ | 
|  | 1480 SkString list_all(const SkTArray<SkString> &stringArray); | 
|  | 1481 SkString list_all(const SkTArray<SkString> &stringArray) { | 
|  | 1482     SkString total; | 
|  | 1483     for (int i = 0; i < stringArray.count(); i++) { | 
|  | 1484         if (i > 0) { | 
|  | 1485             total.append(", "); | 
|  | 1486         } | 
|  | 1487         total.append("\""); | 
|  | 1488         total.append(stringArray[i]); | 
|  | 1489         total.append("\""); | 
|  | 1490     } | 
|  | 1491     return total; | 
|  | 1492 } | 
|  | 1493 | 
|  | 1494 /** | 
|  | 1495  * Return a list of configuration names, as a single string of this form: | 
|  | 1496  * "item1", "item2", "item3" | 
|  | 1497  * | 
|  | 1498  * @param configs configurations, as a list of indices into gRec | 
|  | 1499  */ | 
|  | 1500 SkString list_all_config_names(const SkTDArray<size_t> &configs); | 
|  | 1501 SkString list_all_config_names(const SkTDArray<size_t> &configs) { | 
|  | 1502     SkString total; | 
|  | 1503     for (int i = 0; i < configs.count(); i++) { | 
|  | 1504         if (i > 0) { | 
|  | 1505             total.append(", "); | 
|  | 1506         } | 
|  | 1507         total.append("\""); | 
|  | 1508         total.append(gRec[configs[i]].fName); | 
|  | 1509         total.append("\""); | 
|  | 1510     } | 
|  | 1511     return total; | 
|  | 1512 } | 
|  | 1513 | 
| 1393 int tool_main(int argc, char** argv); | 1514 int tool_main(int argc, char** argv); | 
| 1394 int tool_main(int argc, char** argv) { | 1515 int tool_main(int argc, char** argv) { | 
| 1395 | 1516 | 
| 1396 #if SK_ENABLE_INST_COUNT | 1517 #if SK_ENABLE_INST_COUNT | 
| 1397     gPrintInstCount = true; | 1518     gPrintInstCount = true; | 
| 1398 #endif | 1519 #endif | 
| 1399 | 1520 | 
| 1400     SkGraphics::Init(); | 1521     SkGraphics::Init(); | 
| 1401     // we don't need to see this during a run | 1522     // we don't need to see this during a run | 
| 1402     gSkSuppressFontCachePurgeSpew = true; | 1523     gSkSuppressFontCachePurgeSpew = true; | 
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1564         gm_fprintf(stderr, "reading resources from %s\n", FLAGS_resourcePath[0])
      ; | 1685         gm_fprintf(stderr, "reading resources from %s\n", FLAGS_resourcePath[0])
      ; | 
| 1565     } | 1686     } | 
| 1566 | 1687 | 
| 1567     if (moduloDivisor <= 0) { | 1688     if (moduloDivisor <= 0) { | 
| 1568         moduloRemainder = -1; | 1689         moduloRemainder = -1; | 
| 1569     } | 1690     } | 
| 1570     if (moduloRemainder < 0 || moduloRemainder >= moduloDivisor) { | 1691     if (moduloRemainder < 0 || moduloRemainder >= moduloDivisor) { | 
| 1571         moduloRemainder = -1; | 1692         moduloRemainder = -1; | 
| 1572     } | 1693     } | 
| 1573 | 1694 | 
| 1574     // Accumulate success of all tests. | 1695     int gmsRun = 0; | 
| 1575     int testsRun = 0; |  | 
| 1576     int testsPassed = 0; |  | 
| 1577     int testsFailed = 0; |  | 
| 1578     int testsMissingReferenceImages = 0; |  | 
| 1579 |  | 
| 1580     int gmIndex = -1; | 1696     int gmIndex = -1; | 
| 1581     SkString moduloStr; | 1697     SkString moduloStr; | 
| 1582 | 1698 | 
| 1583     // If we will be writing out files, prepare subdirectories. | 1699     // If we will be writing out files, prepare subdirectories. | 
| 1584     if (FLAGS_writePath.count() == 1) { | 1700     if (FLAGS_writePath.count() == 1) { | 
| 1585         if (!sk_mkdir(FLAGS_writePath[0])) { | 1701         if (!sk_mkdir(FLAGS_writePath[0])) { | 
| 1586             return -1; | 1702             return -1; | 
| 1587         } | 1703         } | 
| 1588         if (gmmain.fUseFileHierarchy) { | 1704         if (gmmain.fUseFileHierarchy) { | 
| 1589             for (int i = 0; i < configs.count(); i++) { | 1705             for (int i = 0; i < configs.count(); i++) { | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 1609             } | 1725             } | 
| 1610             moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor); | 1726             moduloStr.printf("[%d.%d] ", gmIndex, moduloDivisor); | 
| 1611         } | 1727         } | 
| 1612 | 1728 | 
| 1613         const char* shortName = gm->shortName(); | 1729         const char* shortName = gm->shortName(); | 
| 1614         if (skip_name(FLAGS_match, shortName)) { | 1730         if (skip_name(FLAGS_match, shortName)) { | 
| 1615             SkDELETE(gm); | 1731             SkDELETE(gm); | 
| 1616             continue; | 1732             continue; | 
| 1617         } | 1733         } | 
| 1618 | 1734 | 
|  | 1735         gmsRun++; | 
| 1619         SkISize size = gm->getISize(); | 1736         SkISize size = gm->getISize(); | 
| 1620         gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
      Name, | 1737         gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), short
      Name, | 
| 1621                    size.width(), size.height()); | 1738                    size.width(), size.height()); | 
| 1622 | 1739 | 
| 1623         ErrorCombination testErrors; | 1740         run_multiple_configs(gmmain, gm, configs, grFactory); | 
| 1624         testErrors.add(run_multiple_configs(gmmain, gm, configs, grFactory)); |  | 
| 1625 | 1741 | 
| 1626         SkBitmap comparisonBitmap; | 1742         SkBitmap comparisonBitmap; | 
| 1627         const ConfigData compareConfig = | 1743         const ConfigData compareConfig = | 
| 1628             { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
      ype, 0, kRW_ConfigFlag, "comparison", false }; | 1744             { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextT
      ype, 0, kRW_ConfigFlag, "comparison", false }; | 
| 1629         testErrors.add(gmmain.generate_image(gm, compareConfig, NULL, &compariso
      nBitmap, false)); | 1745         gmmain.generate_image(gm, compareConfig, NULL, &comparisonBitmap, false)
      ; | 
| 1630 | 1746 | 
| 1631         // TODO(epoger): only run this if gmmain.generate_image() succeeded? | 1747         // TODO(epoger): only run this if gmmain.generate_image() succeeded? | 
| 1632         // Otherwise, what are we comparing against? | 1748         // Otherwise, what are we comparing against? | 
| 1633         testErrors.add(run_multiple_modes(gmmain, gm, compareConfig, comparisonB
      itmap, | 1749         run_multiple_modes(gmmain, gm, compareConfig, comparisonBitmap, tileGrid
      ReplayScales); | 
| 1634                                           tileGridReplayScales)); |  | 
| 1635 |  | 
| 1636         // Update overall results. |  | 
| 1637         // We only tabulate the particular error types that we currently |  | 
| 1638         // care about (e.g., missing reference images). Later on, if we |  | 
| 1639         // want to also tabulate other error types, we can do so. |  | 
| 1640         testsRun++; |  | 
| 1641         if (!gmmain.fExpectationsSource.get() || |  | 
| 1642             (testErrors.includes(kMissingExpectations_ErrorType))) { |  | 
| 1643             testsMissingReferenceImages++; |  | 
| 1644         } |  | 
| 1645         if (testErrors.minus(gmmain.fIgnorableErrorCombination).isEmpty()) { |  | 
| 1646             testsPassed++; |  | 
| 1647         } else { |  | 
| 1648             testsFailed++; |  | 
| 1649         } |  | 
| 1650 | 1750 | 
| 1651         SkDELETE(gm); | 1751         SkDELETE(gm); | 
| 1652     } | 1752     } | 
| 1653     gm_fprintf(stdout, "Ran %d tests: %d passed, %d failed, %d missing reference
       images\n", | 1753 | 
| 1654                testsRun, testsPassed, testsFailed, testsMissingReferenceImages); | 1754     SkTArray<SkString> modes; | 
|  | 1755     gmmain.GetRenderModesEncountered(modes); | 
|  | 1756 | 
|  | 1757     // Output summary to stdout. | 
|  | 1758     gm_fprintf(stdout, "Ran %d GMs\n", gmsRun); | 
|  | 1759     gm_fprintf(stdout, "... over %2d configs [%s]\n", configs.count(), | 
|  | 1760                list_all_config_names(configs).c_str()); | 
|  | 1761     gm_fprintf(stdout, "...  and %2d modes   [%s]\n", modes.count(), list_all(mo
      des).c_str()); | 
|  | 1762     gm_fprintf(stdout, "... so there should be a total of %d tests.\n", | 
|  | 1763                gmsRun * (configs.count() + modes.count())); | 
|  | 1764 | 
|  | 1765     // TODO(epoger): Ultimately, we should signal an error if the | 
|  | 1766     // expected total number of tests (displayed above) does not match | 
|  | 1767     // gmmain.fTestsRun.  But for now, there are cases where those | 
|  | 1768     // numbers won't match: specifically, if some configs/modes are | 
|  | 1769     // skipped on a per-GM basis (due to gm->getFlags() for a specific | 
|  | 1770     // GM).  Later on, we should record tests like that using some new | 
|  | 1771     // ErrorType, like kIntentionallySkipped_ErrorType.  Then we could | 
|  | 1772     // signal an error if the totals didn't match up. | 
| 1655     gmmain.ListErrors(); | 1773     gmmain.ListErrors(); | 
| 1656 | 1774 | 
| 1657     if (FLAGS_writeJsonSummaryPath.count() == 1) { | 1775     if (FLAGS_writeJsonSummaryPath.count() == 1) { | 
| 1658         Json::Value actualResults; | 1776         Json::Value actualResults; | 
| 1659         actualResults[kJsonKey_ActualResults_Failed] = | 1777         actualResults[kJsonKey_ActualResults_Failed] = | 
| 1660             gmmain.fJsonActualResults_Failed; | 1778             gmmain.fJsonActualResults_Failed; | 
| 1661         actualResults[kJsonKey_ActualResults_FailureIgnored] = | 1779         actualResults[kJsonKey_ActualResults_FailureIgnored] = | 
| 1662             gmmain.fJsonActualResults_FailureIgnored; | 1780             gmmain.fJsonActualResults_FailureIgnored; | 
| 1663         actualResults[kJsonKey_ActualResults_NoComparison] = | 1781         actualResults[kJsonKey_ActualResults_NoComparison] = | 
| 1664             gmmain.fJsonActualResults_NoComparison; | 1782             gmmain.fJsonActualResults_NoComparison; | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 1684             gm_fprintf(stdout, "config: %s %x\n", config.fName, gr); | 1802             gm_fprintf(stdout, "config: %s %x\n", config.fName, gr); | 
| 1685             gr->printCacheStats(); | 1803             gr->printCacheStats(); | 
| 1686         } | 1804         } | 
| 1687     } | 1805     } | 
| 1688 #endif | 1806 #endif | 
| 1689 | 1807 | 
| 1690     delete grFactory; | 1808     delete grFactory; | 
| 1691 #endif | 1809 #endif | 
| 1692     SkGraphics::Term(); | 1810     SkGraphics::Term(); | 
| 1693 | 1811 | 
| 1694     return (0 == testsFailed) ? 0 : -1; | 1812     return (0 == gmmain.NumSignificantErrors()) ? 0 : -1; | 
| 1695 } | 1813 } | 
| 1696 | 1814 | 
| 1697 void GMMain::installFilter(SkCanvas* canvas) { | 1815 void GMMain::installFilter(SkCanvas* canvas) { | 
| 1698     if (FLAGS_forceBWtext) { | 1816     if (FLAGS_forceBWtext) { | 
| 1699         canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 1817         canvas->setDrawFilter(SkNEW(BWTextDrawFilter))->unref(); | 
| 1700     } | 1818     } | 
| 1701 } | 1819 } | 
| 1702 | 1820 | 
| 1703 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 1821 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 
| 1704 int main(int argc, char * const argv[]) { | 1822 int main(int argc, char * const argv[]) { | 
| 1705     return tool_main(argc, (char**) argv); | 1823     return tool_main(argc, (char**) argv); | 
| 1706 } | 1824 } | 
| 1707 #endif | 1825 #endif | 
| OLD | NEW | 
|---|