From 0dcbece326ce2fa1f9046aa69a21bb99de08714a Mon Sep 17 00:00:00 2001 From: "vandebo@chromium.org" Date: Tue, 20 Aug 2013 23:08:40 +0000 Subject: [PATCH] Support multiple PDF rendering backends in the GM R=epoger@google.com, vandebo@chromium.org Review URL: https://codereview.chromium.org/21669004 git-svn-id: http://skia.googlecode.com/svn/trunk@10841 2bbb7eff-a529-9590-31e7-b0007b416f81 --- gm/gm.h | 1 + gm/gmmain.cpp | 346 ++++++++++++++------- gm/mixedxfermodes.cpp | 5 + .../output-expected/json-summary.txt | 8 +- .../mismatchPath/pdf_poppler/bogusfile | 1 + .../missingExpectationsPath/pdf/selftest1.png | 1 + .../missingExpectationsPath/pdf_poppler/bogusfile | 1 + .../outputs/add-config-pdf/output-expected/stdout | 7 +- .../writePath/pdf_poppler/bogusfile | 1 + .../writePath/pdf_poppler/selftest1.png | 1 + .../pipe-playback-failure/output-expected/stderr | 1 + 11 files changed, 253 insertions(+), 120 deletions(-) create mode 100644 gm/tests/outputs/add-config-pdf/output-expected/mismatchPath/pdf_poppler/bogusfile create mode 100644 gm/tests/outputs/add-config-pdf/output-expected/missingExpectationsPath/pdf/selftest1.png create mode 100644 gm/tests/outputs/add-config-pdf/output-expected/missingExpectationsPath/pdf_poppler/bogusfile create mode 100644 gm/tests/outputs/add-config-pdf/output-expected/writePath/pdf_poppler/bogusfile create mode 100644 gm/tests/outputs/add-config-pdf/output-expected/writePath/pdf_poppler/selftest1.png diff --git a/gm/gm.h b/gm/gm.h index f806973..dbd7f42 100644 --- a/gm/gm.h +++ b/gm/gm.h @@ -42,6 +42,7 @@ namespace skiagm { kSkip565_Flag = 1 << 5, kSkipScaledReplay_Flag = 1 << 6, kSkipGPU_Flag = 1 << 7, + kSkipPDFRasterization_Flag = 1 << 8, }; void draw(SkCanvas*); diff --git a/gm/gmmain.cpp b/gm/gmmain.cpp index 773e1e7..4db3a0d 100644 --- a/gm/gmmain.cpp +++ b/gm/gmmain.cpp @@ -30,6 +30,7 @@ #include "SkImageDecoder.h" #include "SkImageEncoder.h" #include "SkOSFile.h" +#include "SkPDFRasterizer.h" #include "SkPicture.h" #include "SkRefCnt.h" #include "SkStream.h" @@ -83,9 +84,6 @@ extern bool gSkSuppressFontCachePurgeSpew; #ifdef SK_BUILD_FOR_MAC #include "SkCGUtils.h" - #define CAN_IMAGE_PDF 1 -#else - #define CAN_IMAGE_PDF 0 #endif using namespace skiagm; @@ -160,6 +158,12 @@ struct ConfigData { bool fRunByDefault; }; +struct PDFRasterizerData { + bool (*fRasterizerFunction)(SkStream*, SkBitmap*); + const char* fName; + bool fRunByDefault; +}; + class BWTextDrawFilter : public SkDrawFilter { public: virtual bool filter(SkPaint*, Type) SK_OVERRIDE; @@ -282,14 +286,19 @@ public: } } - static bool write_bitmap(const SkString& path, const SkBitmap& bitmap) { + static ErrorCombination write_bitmap(const SkString& path, const SkBitmap& bitmap) { // TODO(epoger): Now that we have removed force_all_opaque() // from this method, we should be able to get rid of the // transformation to 8888 format also. SkBitmap copy; bitmap.copyTo(©, SkBitmap::kARGB_8888_Config); - return SkImageEncoder::EncodeFile(path.c_str(), copy, - SkImageEncoder::kPNG_Type, 100); + if (!SkImageEncoder::EncodeFile(path.c_str(), copy, + SkImageEncoder::kPNG_Type, + 100)) { + gm_fprintf(stderr, "FAILED to write bitmap: %s\n", path.c_str()); + return ErrorCombination(kWritingReferenceImage_ErrorType); + } + return kEmpty_ErrorCombination; } /** @@ -410,9 +419,13 @@ public: gm_fprintf(stdout, "(results marked with [*] will cause nonzero return value)\n"); } - static bool write_document(const SkString& path, SkStreamAsset* asset) { + static ErrorCombination write_document(const SkString& path, SkStreamAsset* asset) { SkFILEWStream stream(path.c_str()); - return stream.writeStream(asset, asset->getLength()); + if (!stream.writeStream(asset, asset->getLength())) { + gm_fprintf(stderr, "FAILED to write document: %s\n", path.c_str()); + return ErrorCombination(kWritingReferenceImage_ErrorType); + } + return kEmpty_ErrorCombination; } /** @@ -651,51 +664,6 @@ public: #endif } - ErrorCombination write_reference_image(const ConfigData& gRec, const char writePath [], - const char renderModeDescriptor [], - const char *shortName, - const BitmapAndDigest* bitmapAndDigest, - SkStreamAsset* document) { - SkString path; - bool success = false; - if (gRec.fBackend == kRaster_Backend || - gRec.fBackend == kGPU_Backend || - (gRec.fBackend == kPDF_Backend && CAN_IMAGE_PDF)) { - - path = make_bitmap_filename(writePath, shortName, gRec.fName, renderModeDescriptor, - bitmapAndDigest->fDigest); - success = write_bitmap(path, bitmapAndDigest->fBitmap); - } - if (kPDF_Backend == gRec.fBackend) { - path = make_filename(writePath, shortName, gRec.fName, renderModeDescriptor, - "pdf"); - success = write_document(path, document); - } - if (kXPS_Backend == gRec.fBackend) { - path = make_filename(writePath, shortName, gRec.fName, renderModeDescriptor, - "xps"); - success = write_document(path, document); - } - if (success) { - return kEmpty_ErrorCombination; - } else { - gm_fprintf(stderr, "FAILED to write %s\n", path.c_str()); - ErrorCombination errors(kWritingReferenceImage_ErrorType); - // TODO(epoger): Don't call RecordTestResults() here... - // Instead, we should make sure to call RecordTestResults - // exactly ONCE per test. (Otherwise, gmmain.fTestsRun - // will be incremented twice for this test: once in - // compare_test_results_to_stored_expectations() before - // that method calls this one, and again here.) - // - // When we make that change, we should probably add a - // WritingReferenceImage test to the gm self-tests.) - RecordTestResults(errors, make_shortname_plus_config(shortName, gRec.fName), - renderModeDescriptor); - return errors; - } - } - /** * Log more detail about the mistmatch between expectedBitmap and * actualBitmap. @@ -824,7 +792,6 @@ public: completeName); } } - RecordTestResults(errors, shortNamePlusConfig, renderModeDescriptor); if (addToJsonSummary) { add_actual_results_to_json_summary(completeName, actualBitmapAndDigest.fDigest, errors, @@ -893,20 +860,14 @@ public: * * @param gm which test generated the actualBitmap * @param gRec - * @param writePath unless this is NULL, write out actual images into this - * directory * @param actualBitmapAndDigest ptr to bitmap generated by this run, or NULL * if we don't have a usable bitmap representation - * @param document pdf or xps representation, if appropriate */ ErrorCombination compare_test_results_to_stored_expectations( - GM* gm, const ConfigData& gRec, const char writePath[], - const BitmapAndDigest* actualBitmapAndDigest, SkStreamAsset* document) { + GM* gm, const ConfigData& gRec, + const BitmapAndDigest* actualBitmapAndDigest) { SkString shortNamePlusConfig = make_shortname_plus_config(gm->shortName(), gRec.fName); - SkString nameWithExtension(shortNamePlusConfig); - nameWithExtension.append("."); - nameWithExtension.append(kPNG_FileExtension); ErrorCombination errors; @@ -914,18 +875,20 @@ public: // Note that we intentionally skipped validating the results for // this test, because we don't know how to generate an SkBitmap // version of the output. - RecordTestResults(ErrorCombination(kIntentionallySkipped_ErrorType), - shortNamePlusConfig, ""); + errors.add(ErrorCombination(kIntentionallySkipped_ErrorType)); } else if (!(gRec.fFlags & kWrite_ConfigFlag)) { // We don't record the results for this test or compare them // against any expectations, because the output image isn't // meaningful. // See https://code.google.com/p/skia/issues/detail?id=1410 ('some // GM result images not available for download from Google Storage') - RecordTestResults(ErrorCombination(kIntentionallySkipped_ErrorType), - shortNamePlusConfig, ""); + errors.add(ErrorCombination(kIntentionallySkipped_ErrorType)); } else { ExpectationsSource *expectationsSource = this->fExpectationsSource.get(); + SkString nameWithExtension(shortNamePlusConfig); + nameWithExtension.append("."); + nameWithExtension.append(kPNG_FileExtension); + if (expectationsSource && (gRec.fFlags & kRead_ConfigFlag)) { /* * Get the expected results for this test, as one or more allowed @@ -950,20 +913,9 @@ public: actualBitmapAndDigest->fDigest, ErrorCombination(kMissingExpectations_ErrorType), false); - RecordTestResults(ErrorCombination(kMissingExpectations_ErrorType), - shortNamePlusConfig, ""); + errors.add(ErrorCombination(kMissingExpectations_ErrorType)); } } - - // TODO: Consider moving this into compare_to_expectations(), - // similar to fMismatchPath... for now, we don't do that, because - // we don't want to write out the actual bitmaps for all - // renderModes of all tests! That would be a lot of files. - if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { - errors.add(write_reference_image(gRec, writePath, "", gm->shortName(), - actualBitmapAndDigest, document)); - } - return errors; } @@ -983,8 +935,19 @@ public: SkASSERT(referenceBitmap); Expectations expectations(*referenceBitmap); BitmapAndDigest actualBitmapAndDigest(actualBitmap); - return compare_to_expectations(expectations, actualBitmapAndDigest, shortName, - configName, renderModeDescriptor, false); + + // TODO: Eliminate RecordTestResults from here. + // Results recording code for the test_drawing path has been refactored so that + // RecordTestResults is only called once, at the topmost level. However, the + // other paths have not yet been refactored, and RecordTestResults has been added + // here to maintain proper behavior for calls not coming from the test_drawing path. + ErrorCombination errors; + errors.add(compare_to_expectations(expectations, actualBitmapAndDigest, shortName, + configName, renderModeDescriptor, false)); + SkString shortNamePlusConfig = make_shortname_plus_config(shortName, configName); + RecordTestResults(errors, shortNamePlusConfig, renderModeDescriptor); + + return errors; } static SkPicture* generate_new_picture(GM* gm, BbhType bbhType, uint32_t recordFlags, @@ -1037,46 +1000,89 @@ public: // Test: draw into a bitmap or pdf. // Depending on flags, possibly compare to an expected image. - ErrorCombination test_drawing(GM* gm, - const ConfigData& gRec, + // If writePath is not NULL, also write images (or documents) to the specified path. + ErrorCombination test_drawing(GM* gm, const ConfigData& gRec, + const SkTDArray &pdfRasterizers, const char writePath [], GrSurface* gpuTarget, SkBitmap* bitmap) { + ErrorCombination errors; SkDynamicMemoryWStream document; + SkString path; if (gRec.fBackend == kRaster_Backend || gRec.fBackend == kGPU_Backend) { // Early exit if we can't generate the image. - ErrorCombination errors = generate_image(gm, gRec, gpuTarget, bitmap, false); + errors.add(generate_image(gm, gRec, gpuTarget, bitmap, false)); if (!errors.isEmpty()) { // TODO: Add a test to exercise what the stdout and // JSON look like if we get an "early error" while // trying to generate the image. return errors; } + BitmapAndDigest bitmapAndDigest(*bitmap); + errors.add(compare_test_results_to_stored_expectations( + gm, gRec, &bitmapAndDigest)); + + if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { + path = make_bitmap_filename(writePath, gm->shortName(), gRec.fName, + "", bitmapAndDigest.fDigest); + errors.add(write_bitmap(path, bitmapAndDigest.fBitmap)); + } } else if (gRec.fBackend == kPDF_Backend) { generate_pdf(gm, document); -#if CAN_IMAGE_PDF - SkAutoDataUnref data(document.copyToData()); - SkMemoryStream stream(data->data(), data->size()); - SkPDFDocumentToBitmap(&stream, bitmap); -#else - bitmap = NULL; // we don't generate a bitmap rendering of the PDF file -#endif + + SkAutoTUnref documentStream(document.detachAsStream()); + if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { + path = make_filename(writePath, gm->shortName(), gRec.fName, "", "pdf"); + errors.add(write_document(path, documentStream)); + } + + if (!(gm->getFlags() & GM::kSkipPDFRasterization_Flag)) { + for (int i = 0; i < pdfRasterizers.count(); i++) { + SkBitmap pdfBitmap; + SkASSERT(documentStream->rewind()); + bool success = (*pdfRasterizers[i]->fRasterizerFunction)( + documentStream.get(), &pdfBitmap); + if (!success) { + gm_fprintf(stderr, "FAILED to render PDF for %s using renderer %s\n", + gm->shortName(), + pdfRasterizers[i]->fName); + continue; + } + + BitmapAndDigest bitmapAndDigest(pdfBitmap); + errors.add(compare_test_results_to_stored_expectations( + gm, gRec, &bitmapAndDigest)); + + SkString configName(gRec.fName); + configName.append("_"); + configName.append(pdfRasterizers[i]->fName); + + if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { + path = make_bitmap_filename(writePath, gm->shortName(), configName.c_str(), + "", bitmapAndDigest.fDigest); + errors.add(write_bitmap(path, bitmapAndDigest.fBitmap)); + } + } + } else { + errors.add(kIntentionallySkipped_ErrorType); + } } else if (gRec.fBackend == kXPS_Backend) { generate_xps(gm, document); - bitmap = NULL; // we don't generate a bitmap rendering of the XPS file - } + SkAutoTUnref documentStream(document.detachAsStream()); + + errors.add(compare_test_results_to_stored_expectations( + gm, gRec, NULL)); - SkAutoTUnref documentStream(document.detachAsStream()); - if (NULL == bitmap) { - return compare_test_results_to_stored_expectations( - gm, gRec, writePath, NULL, documentStream); + if (writePath && (gRec.fFlags & kWrite_ConfigFlag)) { + path = make_filename(writePath, gm->shortName(), gRec.fName, "", "xps"); + errors.add(write_document(path, documentStream)); + } } else { - BitmapAndDigest bitmapAndDigest(*bitmap); - return compare_test_results_to_stored_expectations( - gm, gRec, writePath, &bitmapAndDigest, documentStream); + SkASSERT(false); } + return errors; } ErrorCombination test_deferred_drawing(GM* gm, @@ -1230,11 +1236,6 @@ static const GLContextType kDontCare_GLContextType = GrContextFactory::kNative_G static const GLContextType kDontCare_GLContextType = 0; #endif -// If the platform does not support writing PNGs of PDFs then there will be no -// reference images to read. However, we can always write the .pdf files -static const ConfigFlags kPDFConfigFlags = CAN_IMAGE_PDF ? kRW_ConfigFlag : - kWrite_ConfigFlag; - static const ConfigData gRec[] = { { SkBitmap::kARGB_8888_Config, kRaster_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "8888", true }, #if 0 // stop testing this (for now at least) since we want to remove support for it (soon please!!!) @@ -1266,10 +1267,19 @@ static const ConfigData gRec[] = { { SkBitmap::kARGB_8888_Config, kXPS_Backend, kDontCare_GLContextType, 0, kWrite_ConfigFlag, "xps", true }, #endif // SK_SUPPORT_XPS #ifdef SK_SUPPORT_PDF - { SkBitmap::kARGB_8888_Config, kPDF_Backend, kDontCare_GLContextType, 0, kPDFConfigFlags, "pdf", true }, + { SkBitmap::kARGB_8888_Config, kPDF_Backend, kDontCare_GLContextType, 0, kRW_ConfigFlag, "pdf", true }, #endif // SK_SUPPORT_PDF }; +static const PDFRasterizerData kPDFRasterizers[] = { +#ifdef SK_BUILD_FOR_MAC + { &SkPDFDocumentToBitmap, "mac", true }, +#endif +#ifdef SK_BUILD_POPPLER + { &SkPopplerRasterizePDF, "poppler", true }, +#endif +}; + static const char kDefaultsConfigStr[] = "defaults"; static const char kExcludeConfigChar = '~'; @@ -1321,6 +1331,32 @@ static SkString configUsage() { return result; } +static SkString pdfRasterizerUsage() { + SkString result; + result.appendf("Space delimited list of which PDF rasterizers to run. Possible options: ["); + // For this (and further) loops through kPDFRasterizers, there is a typecast to int to avoid + // the compiler giving an "comparison of unsigned expression < 0 is always false" warning + // and turning it into a build-breaking error. + for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); ++i) { + if (i > 0) { + result.append(" "); + } + result.append(kPDFRasterizers[i].fName); + } + result.append("]\n"); + result.append("The default value is: \""); + for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); ++i) { + if (kPDFRasterizers[i].fRunByDefault) { + if (i > 0) { + result.append(" "); + } + result.append(kPDFRasterizers[i].fName); + } + } + result.append("\""); + return result; +} + // Macro magic to convert a numeric preprocessor token into a string. // Adapted from http://stackoverflow.com/questions/240353/convert-a-preprocessor-token-to-a-string // This should probably be moved into one of our common headers... @@ -1329,6 +1365,7 @@ static SkString configUsage() { // Alphabetized ignoring "no" prefix ("readPath", "noreplay", "resourcePath"). DEFINE_string(config, "", configUsage().c_str()); +DEFINE_string(pdfRasterizers, "", pdfRasterizerUsage().c_str()); DEFINE_bool(deferred, true, "Exercise the deferred rendering test pass."); DEFINE_string(excludeConfig, "", "Space delimited list of configs to skip."); DEFINE_bool(forceBWtext, false, "Disable text anti-aliasing."); @@ -1417,6 +1454,15 @@ static int findConfig(const char config[]) { return -1; } +static const PDFRasterizerData* findPDFRasterizer(const char rasterizer[]) { + for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); i++) { + if (!strcmp(rasterizer, kPDFRasterizers[i].fName)) { + return &kPDFRasterizers[i]; + } + } + return NULL; +} + namespace skiagm { #if SK_SUPPORT_GPU SkAutoTUnref gGrContext; @@ -1473,9 +1519,13 @@ template void appendUnique(SkTDArray* array, const T& value) { * * Returns all errors encountered while doing so. */ -ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray &configs, +ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, + const SkTDArray &configs, + const SkTDArray &pdfRasterizers, GrContextFactory *grFactory); -ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray &configs, +ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, + const SkTDArray &configs, + const SkTDArray &pdfRasterizers, GrContextFactory *grFactory) { const char renderModeDescriptor[] = ""; ErrorCombination errorsForAllConfigs; @@ -1566,9 +1616,12 @@ ErrorCombination run_multiple_configs(GMMain &gmmain, GM *gm, const SkTDArray &configs) { return total; } -bool prepare_subdirectories(const char *root, bool useFileHierarchy, - const SkTDArray &configs); -bool prepare_subdirectories(const char *root, bool useFileHierarchy, - const SkTDArray &configs) { +static bool prepare_subdirectories(const char *root, bool useFileHierarchy, + const SkTDArray &configs, + const SkTDArray& pdfRasterizers) { if (!sk_mkdir(root)) { return false; } @@ -1769,6 +1821,16 @@ bool prepare_subdirectories(const char *root, bool useFileHierarchy, if (!sk_mkdir(subdir.c_str())) { return false; } + + if (config.fBackend == kPDF_Backend) { + for (int j = 0; j < pdfRasterizers.count(); j++) { + SkString pdfSubdir = subdir; + pdfSubdir.appendf("_%s", pdfRasterizers[j]->fName); + if (!sk_mkdir(pdfSubdir.c_str())) { + return false; + } + } + } } } return true; @@ -1877,6 +1939,53 @@ static bool parse_flags_configs(SkTDArray* outConfigs, return true; } +static bool parse_flags_pdf_rasterizers(const SkTDArray& configs, + SkTDArray* outRasterizers) { + // No need to run this check (and display the PDF rasterizers message) + // if no PDF backends are in the configs. + bool configHasPDF = false; + for (int i = 0; i < configs.count(); i++) { + if (gRec[configs[i]].fBackend == kPDF_Backend) { + configHasPDF = true; + break; + } + } + if (!configHasPDF) { + return true; + } + + for (int i = 0; i < FLAGS_pdfRasterizers.count(); i++) { + const char* rasterizer = FLAGS_pdfRasterizers[i]; + const PDFRasterizerData* rasterizerPtr = findPDFRasterizer(rasterizer); + + if (rasterizerPtr == NULL) { + gm_fprintf(stderr, "unrecognized rasterizer %s\n", rasterizer); + return false; + } + appendUnique(outRasterizers, + rasterizerPtr); + } + + if (outRasterizers->count() == 0) { + // if no config is specified by user, add the defaults + for (int i = 0; i < (int)SK_ARRAY_COUNT(kPDFRasterizers); ++i) { + if (kPDFRasterizers[i].fRunByDefault) { + *outRasterizers->append() = &kPDFRasterizers[i]; + } + } + } + + // now show the user the set of configs that will be run. + SkString configStr("These PDF rasterizers will be run:"); + // show the user the config that will run. + for (int i = 0; i < outRasterizers->count(); ++i) { + configStr.appendf(" %s", (*outRasterizers)[i]->fName); + } + gm_fprintf(stdout, "%s\n", configStr.c_str()); + + return true; +} + static bool parse_flags_ignore_error_types(ErrorCombination* outErrorTypes) { if (FLAGS_ignoreErrorTypes.count() > 0) { *outErrorTypes = ErrorCombination(); @@ -2019,8 +2128,10 @@ int tool_main(int argc, char** argv) { SkCommandLineFlags::Parse(argc, argv); SkTDArray configs; + int moduloRemainder = -1; int moduloDivisor = -1; + SkTDArray pdfRasterizers; SkTDArray tileGridReplayScales; #if SK_SUPPORT_GPU GrContextFactory* grFactory = new GrContextFactory; @@ -2039,6 +2150,7 @@ int tool_main(int argc, char** argv) { !parse_flags_match_strs(&matchStrs) || !parse_flags_jpeg_quality() || !parse_flags_configs(&configs, grFactory) || + !parse_flags_pdf_rasterizers(configs, &pdfRasterizers) || !parse_flags_gmmain_paths(&gmmain)) { return -1; } @@ -2068,18 +2180,20 @@ int tool_main(int argc, char** argv) { // If we will be writing out files, prepare subdirectories. if (FLAGS_writePath.count() == 1) { - if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy, configs)) { + if (!prepare_subdirectories(FLAGS_writePath[0], gmmain.fUseFileHierarchy, + configs, pdfRasterizers)) { return -1; } } if (NULL != gmmain.fMismatchPath) { - if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarchy, configs)) { + if (!prepare_subdirectories(gmmain.fMismatchPath, gmmain.fUseFileHierarchy, + configs, pdfRasterizers)) { return -1; } } if (NULL != gmmain.fMissingExpectationsPath) { if (!prepare_subdirectories(gmmain.fMissingExpectationsPath, gmmain.fUseFileHierarchy, - configs)) { + configs, pdfRasterizers)) { return -1; } } @@ -2107,7 +2221,7 @@ int tool_main(int argc, char** argv) { gm_fprintf(stdout, "%sdrawing... %s [%d %d]\n", moduloStr.c_str(), shortName, size.width(), size.height()); - run_multiple_configs(gmmain, gm, configs, grFactory); + run_multiple_configs(gmmain, gm, configs, pdfRasterizers, grFactory); SkBitmap comparisonBitmap; const ConfigData compareConfig = diff --git a/gm/mixedxfermodes.cpp b/gm/mixedxfermodes.cpp index f057672..645143a 100644 --- a/gm/mixedxfermodes.cpp +++ b/gm/mixedxfermodes.cpp @@ -125,6 +125,11 @@ protected: } } + virtual uint32_t onGetFlags() const { + // Skip PDF rasterization since rendering this PDF takes forever. + return kSkipPDFRasterization_Flag; + } + private: enum { kNumShapes = 100, diff --git a/gm/tests/outputs/add-config-pdf/output-expected/json-summary.txt b/gm/tests/outputs/add-config-pdf/output-expected/json-summary.txt index fad1ffe..52eedd4 100644 --- a/gm/tests/outputs/add-config-pdf/output-expected/json-summary.txt +++ b/gm/tests/outputs/add-config-pdf/output-expected/json-summary.txt @@ -2,7 +2,9 @@ "actual-results" : { "failed" : null, "failure-ignored" : null, - "no-comparison" : null, + "no-comparison" : { + "pdf/selftest1.png" : [ "bitmap-64bitMD5", 1149339852105949057 ] + }, "succeeded" : { "565/selftest1.png" : [ "bitmap-64bitMD5", 12927999507540085554 ], "8888/selftest1.png" : [ "bitmap-64bitMD5", 1209453360120438698 ] @@ -20,6 +22,10 @@ [ "bitmap-64bitMD5", 1209453360120438698 ] ], "ignore-failure" : false + }, + "pdf/selftest1.png" : { + "allowed-digests" : null, + "ignore-failure" : false } } } diff --git a/gm/tests/outputs/add-config-pdf/output-expected/mismatchPath/pdf_poppler/bogusfile b/gm/tests/outputs/add-config-pdf/output-expected/mismatchPath/pdf_poppler/bogusfile new file mode 100644 index 0000000..d86cd5b --- /dev/null +++ b/gm/tests/outputs/add-config-pdf/output-expected/mismatchPath/pdf_poppler/bogusfile @@ -0,0 +1 @@ +Created additional file to make sure directory isn't empty, because self-test cannot handle empty directories. diff --git a/gm/tests/outputs/add-config-pdf/output-expected/missingExpectationsPath/pdf/selftest1.png b/gm/tests/outputs/add-config-pdf/output-expected/missingExpectationsPath/pdf/selftest1.png new file mode 100644 index 0000000..e5584b8 --- /dev/null +++ b/gm/tests/outputs/add-config-pdf/output-expected/missingExpectationsPath/pdf/selftest1.png @@ -0,0 +1 @@ +[contents of gm/tests/outputs/add-config-pdf/output-actual/missingExpectationsPath/pdf/selftest1.png] diff --git a/gm/tests/outputs/add-config-pdf/output-expected/missingExpectationsPath/pdf_poppler/bogusfile b/gm/tests/outputs/add-config-pdf/output-expected/missingExpectationsPath/pdf_poppler/bogusfile new file mode 100644 index 0000000..d86cd5b --- /dev/null +++ b/gm/tests/outputs/add-config-pdf/output-expected/missingExpectationsPath/pdf_poppler/bogusfile @@ -0,0 +1 @@ +Created additional file to make sure directory isn't empty, because self-test cannot handle empty directories. diff --git a/gm/tests/outputs/add-config-pdf/output-expected/stdout b/gm/tests/outputs/add-config-pdf/output-expected/stdout index 4052bbf..0a1bda0 100644 --- a/gm/tests/outputs/add-config-pdf/output-expected/stdout +++ b/gm/tests/outputs/add-config-pdf/output-expected/stdout @@ -1,4 +1,5 @@ GM: These configs will be run: 8888 565 pdf +GM: These PDF rasterizers will be run: poppler GM: reading expectations from JSON summary file gm/tests/inputs/json/identical-bytes.json GM: writing to gm/tests/outputs/add-config-pdf/output-actual/writePath GM: writing mismatches to gm/tests/outputs/add-config-pdf/output-actual/mismatchPath @@ -8,11 +9,11 @@ GM: Ran 1 GMs GM: ... over 3 configs ["8888", "565", "pdf"] GM: ... and 7 modes ["pipe", "pipe cross-process", "pipe cross-process, shared address", "replay", "rtree", "serialize", "tilegrid"] GM: ... so there should be a total of 10 tests. -GM: Ran 10 tests: NoGpuContext=0 IntentionallySkipped=1 RenderModeMismatch=0 ExpectationsMismatch=0 MissingExpectations=0 WritingReferenceImage=0 +GM: Ran 10 tests: NoGpuContext=0 IntentionallySkipped=0 RenderModeMismatch=0 ExpectationsMismatch=0 MissingExpectations=1 WritingReferenceImage=0 GM: [*] 0 NoGpuContext: -GM: [ ] 1 IntentionallySkipped: pdf/selftest1 +GM: [ ] 0 IntentionallySkipped: GM: [*] 0 RenderModeMismatch: GM: [*] 0 ExpectationsMismatch: -GM: [ ] 0 MissingExpectations: +GM: [ ] 1 MissingExpectations: pdf/selftest1 GM: [*] 0 WritingReferenceImage: GM: (results marked with [*] will cause nonzero return value) diff --git a/gm/tests/outputs/add-config-pdf/output-expected/writePath/pdf_poppler/bogusfile b/gm/tests/outputs/add-config-pdf/output-expected/writePath/pdf_poppler/bogusfile new file mode 100644 index 0000000..d86cd5b --- /dev/null +++ b/gm/tests/outputs/add-config-pdf/output-expected/writePath/pdf_poppler/bogusfile @@ -0,0 +1 @@ +Created additional file to make sure directory isn't empty, because self-test cannot handle empty directories. diff --git a/gm/tests/outputs/add-config-pdf/output-expected/writePath/pdf_poppler/selftest1.png b/gm/tests/outputs/add-config-pdf/output-expected/writePath/pdf_poppler/selftest1.png new file mode 100644 index 0000000..5d008d8 --- /dev/null +++ b/gm/tests/outputs/add-config-pdf/output-expected/writePath/pdf_poppler/selftest1.png @@ -0,0 +1 @@ +[contents of gm/tests/outputs/add-config-pdf/output-actual/writePath/pdf_poppler/selftest1.png] diff --git a/gm/tests/outputs/pipe-playback-failure/output-expected/stderr b/gm/tests/outputs/pipe-playback-failure/output-expected/stderr index 573600f..150a10b 100644 --- a/gm/tests/outputs/pipe-playback-failure/output-expected/stderr +++ b/gm/tests/outputs/pipe-playback-failure/output-expected/stderr @@ -1 +1,2 @@ +GM: FAILED to write bitmap: gm/tests/outputs/pipe-playback-failure/output-actual/mismatchPath/comparison/selftest1-pipe.png GM: ---- comparison/selftest1-pipe.png: 60000 (of 60000) differing pixels, max per-channel mismatch R=135 G=246 B=135 A=0 -- 2.7.4