diff options
Diffstat (limited to 'tools/render_pictures_main.cpp')
-rw-r--r-- | tools/render_pictures_main.cpp | 511 |
1 files changed, 0 insertions, 511 deletions
diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp deleted file mode 100644 index 401c205d67..0000000000 --- a/tools/render_pictures_main.cpp +++ /dev/null @@ -1,511 +0,0 @@ -/* - * Copyright 2012 Google Inc. - * - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#include "LazyDecodeBitmap.h" -#include "CopyTilesRenderer.h" -#include "SkBitmap.h" -#include "SkDevice.h" -#include "SkCommandLineFlags.h" -#include "SkGraphics.h" -#include "SkImageDecoder.h" -#include "SkImageEncoder.h" -#include "SkMath.h" -#include "SkOSFile.h" -#include "SkPicture.h" -#include "SkPictureRecorder.h" -#include "SkStream.h" -#include "SkString.h" - -#include "image_expectations.h" -#include "PictureRenderer.h" -#include "PictureRenderingFlags.h" -#include "picture_utils.h" - -#include <stdlib.h> - -// Flags used by this file, alphabetically: -DEFINE_bool(bench_record, false, "If true, drop into an infinite loop of recording the picture."); -DECLARE_bool(deferImageDecoding); -DEFINE_string(descriptions, "", "one or more key=value pairs to add to the descriptions section " - "of the JSON summary."); -DEFINE_string(imageBaseGSUrl, "", "The Google Storage image base URL the images are stored in."); -DEFINE_int32(maxComponentDiff, 256, "Maximum diff on a component, 0 - 256. Components that differ " - "by more than this amount are considered errors, though all diffs are reported. " - "Requires --validate."); -DEFINE_string(mismatchPath, "", "Write images for tests that failed due to " - "pixel mismatches into this directory."); -#if GR_GPU_STATS -DEFINE_bool(gpuStats, false, "Only meaningful with gpu configurations. " - "Report some GPU call statistics."); -#endif -DEFINE_bool(mpd, false, "If true, use MultiPictureDraw for rendering."); -DEFINE_string(readJsonSummaryPath, "", "JSON file to read image expectations from."); -DECLARE_string(readPath); -DEFINE_bool(writeChecksumBasedFilenames, false, - "When writing out images, use checksum-based filenames."); -DEFINE_bool(writeEncodedImages, false, "Any time the skp contains an encoded image, write it to a " - "file rather than decoding it. Requires writePath to be set. Skips drawing the full " - "skp to a file. Not compatible with deferImageDecoding."); -DEFINE_string(writeJsonSummaryPath, "", "File to write a JSON summary of image results to."); -DEFINE_string2(writePath, w, "", "Directory to write the rendered images into."); -DEFINE_bool(writeWholeImage, false, "In tile mode, write the entire rendered image to a " - "file, instead of an image for each tile."); -DEFINE_bool(validate, false, "Verify that the rendered image contains the same pixels as " - "the picture rendered in simple mode. When used in conjunction with --bbh, results " - "are validated against the picture rendered in the same mode, but without the bbh."); - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * Table for translating from format of data to a suffix. - */ -struct Format { - SkImageDecoder::Format fFormat; - const char* fSuffix; -}; -static const Format gFormats[] = { - { SkImageDecoder::kBMP_Format, ".bmp" }, - { SkImageDecoder::kGIF_Format, ".gif" }, - { SkImageDecoder::kICO_Format, ".ico" }, - { SkImageDecoder::kJPEG_Format, ".jpg" }, - { SkImageDecoder::kPNG_Format, ".png" }, - { SkImageDecoder::kWBMP_Format, ".wbmp" }, - { SkImageDecoder::kWEBP_Format, ".webp" }, - { SkImageDecoder::kUnknown_Format, "" }, -}; - -/** - * Get an appropriate suffix for an image format. - */ -static const char* get_suffix_from_format(SkImageDecoder::Format format) { - for (size_t i = 0; i < SK_ARRAY_COUNT(gFormats); i++) { - if (gFormats[i].fFormat == format) { - return gFormats[i].fSuffix; - } - } - return ""; -} - -/** - * Base name for an image file created from the encoded data in an skp. - */ -static SkString gInputFileName; - -/** - * Number to be appended to the image file name so that it is unique. - */ -static uint32_t gImageNo; - -/** - * Set up the name for writing encoded data to a file. - * Sets gInputFileName to name, minus any extension ".*" - * Sets gImageNo to 0, so images from file "X.skp" will - * look like "X_<gImageNo>.<suffix>", beginning with 0 - * for each new skp. - */ -static void reset_image_file_base_name(const SkString& name) { - gImageNo = 0; - // Remove ".skp" - const char* cName = name.c_str(); - const char* dot = strrchr(cName, '.'); - if (dot != nullptr) { - gInputFileName.set(cName, dot - cName); - } else { - gInputFileName.set(name); - } -} - -/** - * Write the raw encoded bitmap data to a file. - */ -static bool write_image_to_file(const void* buffer, size_t size, SkBitmap* bitmap) { - SkASSERT(!FLAGS_writePath.isEmpty()); - SkMemoryStream memStream(buffer, size); - SkString outPath; - SkImageDecoder::Format format = SkImageDecoder::GetStreamFormat(&memStream); - SkString name = SkStringPrintf("%s_%d%s", gInputFileName.c_str(), gImageNo++, - get_suffix_from_format(format)); - SkString dir(FLAGS_writePath[0]); - outPath = SkOSPath::Join(dir.c_str(), name.c_str()); - SkFILEWStream fileStream(outPath.c_str()); - if (!(fileStream.isValid() && fileStream.write(buffer, size))) { - SkDebugf("Failed to write encoded data to \"%s\"\n", outPath.c_str()); - } - // Put in a dummy bitmap. - return SkImageDecoder::DecodeStream(&memStream, bitmap, kUnknown_SkColorType, - SkImageDecoder::kDecodeBounds_Mode); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/** - * Called only by render_picture(). - */ -static bool render_picture_internal(const SkString& inputPath, const SkString* writePath, - const SkString* mismatchPath, - sk_tools::PictureRenderer& renderer, - SkBitmap** out) { - SkString inputFilename = SkOSPath::Basename(inputPath.c_str()); - SkString writePathString; - if (writePath && writePath->size() > 0 && !FLAGS_writeEncodedImages) { - writePathString.set(*writePath); - } - SkString mismatchPathString; - if (mismatchPath && mismatchPath->size() > 0) { - mismatchPathString.set(*mismatchPath); - } - - SkFILEStream inputStream; - inputStream.setPath(inputPath.c_str()); - if (!inputStream.isValid()) { - SkDebugf("Could not open file %s\n", inputPath.c_str()); - return false; - } - - SkPicture::InstallPixelRefProc proc; - if (FLAGS_deferImageDecoding) { - proc = &sk_tools::LazyDecodeBitmap; - } else if (FLAGS_writeEncodedImages) { - SkASSERT(!FLAGS_writePath.isEmpty()); - reset_image_file_base_name(inputFilename); - proc = &write_image_to_file; - } else { - proc = &SkImageDecoder::DecodeMemory; - } - - SkDebugf("deserializing... %s\n", inputPath.c_str()); - - SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&inputStream, proc)); - - if (nullptr == picture) { - SkDebugf("Could not read an SkPicture from %s\n", inputPath.c_str()); - return false; - } - - while (FLAGS_bench_record) { - SkPictureRecorder recorder; - picture->playback(recorder.beginRecording(picture->cullRect().width(), - picture->cullRect().height(), - nullptr, 0)); - SkAutoTUnref<SkPicture> other(recorder.endRecording()); - } - - SkDebugf("drawing... [%f %f %f %f] %s\n", - picture->cullRect().fLeft, picture->cullRect().fTop, - picture->cullRect().fRight, picture->cullRect().fBottom, - inputPath.c_str()); - - renderer.init(picture, &writePathString, &mismatchPathString, &inputFilename, - FLAGS_writeChecksumBasedFilenames, FLAGS_mpd); - - renderer.setup(); - renderer.enableWrites(); - - bool success = renderer.render(out); - if (!success) { - SkDebugf("Failed to render %s\n", inputFilename.c_str()); - } - - renderer.end(); - - return success; -} - -static inline int getByte(uint32_t value, int index) { - SkASSERT(0 <= index && index < 4); - return (value >> (index * 8)) & 0xFF; -} - -static int MaxByteDiff(uint32_t v1, uint32_t v2) { - return SkMax32(SkMax32(SkTAbs(getByte(v1, 0) - getByte(v2, 0)), SkTAbs(getByte(v1, 1) - getByte(v2, 1))), - SkMax32(SkTAbs(getByte(v1, 2) - getByte(v2, 2)), SkTAbs(getByte(v1, 3) - getByte(v2, 3)))); -} - -class AutoRestoreBbhType { -public: - AutoRestoreBbhType() { - fRenderer = nullptr; - fSavedBbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType; - } - - void set(sk_tools::PictureRenderer* renderer, - sk_tools::PictureRenderer::BBoxHierarchyType bbhType) { - fRenderer = renderer; - fSavedBbhType = renderer->getBBoxHierarchyType(); - renderer->setBBoxHierarchyType(bbhType); - } - - ~AutoRestoreBbhType() { - if (fRenderer) { - fRenderer->setBBoxHierarchyType(fSavedBbhType); - } - } - -private: - sk_tools::PictureRenderer* fRenderer; - sk_tools::PictureRenderer::BBoxHierarchyType fSavedBbhType; -}; - -/** - * Render the SKP file(s) within inputPath. - * - * @param inputPath path to an individual SKP file, or a directory of SKP files - * @param writePath if not nullptr, write all image(s) generated into this directory - * @param mismatchPath if not nullptr, write any image(s) not matching expectations into this directory - * @param renderer PictureRenderer to use to render the SKPs - * @param jsonSummaryPtr if not nullptr, add the image(s) generated to this summary - */ -static bool render_picture(const SkString& inputPath, const SkString* writePath, - const SkString* mismatchPath, sk_tools::PictureRenderer& renderer, - sk_tools::ImageResultsAndExpectations *jsonSummaryPtr) { - int diffs[256] = {0}; - SkBitmap* bitmap = nullptr; - renderer.setJsonSummaryPtr(jsonSummaryPtr); - bool success = render_picture_internal(inputPath, - FLAGS_writeWholeImage ? nullptr : writePath, - FLAGS_writeWholeImage ? nullptr : mismatchPath, - renderer, - FLAGS_validate || FLAGS_writeWholeImage ? &bitmap : nullptr); - - if (!success || ((FLAGS_validate || FLAGS_writeWholeImage) && bitmap == nullptr)) { - SkDebugf("Failed to draw the picture.\n"); - delete bitmap; - return false; - } - - if (FLAGS_validate) { - SkBitmap* referenceBitmap = nullptr; - sk_tools::PictureRenderer* referenceRenderer; - // If the renderer uses a BBoxHierarchy, then the reference renderer - // will be the same renderer, without the bbh. - AutoRestoreBbhType arbbh; - if (sk_tools::PictureRenderer::kNone_BBoxHierarchyType != - renderer.getBBoxHierarchyType()) { - referenceRenderer = &renderer; - referenceRenderer->ref(); // to match auto unref below - arbbh.set(referenceRenderer, sk_tools::PictureRenderer::kNone_BBoxHierarchyType); - } else { -#if SK_SUPPORT_GPU - referenceRenderer = new sk_tools::SimplePictureRenderer(renderer.getGrContextOptions()); -#else - referenceRenderer = new sk_tools::SimplePictureRenderer; -#endif - } - SkAutoTUnref<sk_tools::PictureRenderer> aurReferenceRenderer(referenceRenderer); - - success = render_picture_internal(inputPath, nullptr, nullptr, *referenceRenderer, - &referenceBitmap); - - if (!success || nullptr == referenceBitmap || nullptr == referenceBitmap->getPixels()) { - SkDebugf("Failed to draw the reference picture.\n"); - delete bitmap; - delete referenceBitmap; - return false; - } - - if (success && (bitmap->width() != referenceBitmap->width())) { - SkDebugf("Expected image width: %i, actual image width %i.\n", - referenceBitmap->width(), bitmap->width()); - delete bitmap; - delete referenceBitmap; - return false; - } - if (success && (bitmap->height() != referenceBitmap->height())) { - SkDebugf("Expected image height: %i, actual image height %i", - referenceBitmap->height(), bitmap->height()); - delete bitmap; - delete referenceBitmap; - return false; - } - - for (int y = 0; success && y < bitmap->height(); y++) { - for (int x = 0; success && x < bitmap->width(); x++) { - int diff = MaxByteDiff(*referenceBitmap->getAddr32(x, y), - *bitmap->getAddr32(x, y)); - SkASSERT(diff >= 0 && diff <= 255); - diffs[diff]++; - - if (diff > FLAGS_maxComponentDiff) { - SkDebugf("Expected pixel at (%i %i) exceedds maximum " - "component diff of %i: 0x%x, actual 0x%x\n", - x, y, FLAGS_maxComponentDiff, - *referenceBitmap->getAddr32(x, y), - *bitmap->getAddr32(x, y)); - delete bitmap; - delete referenceBitmap; - return false; - } - } - } - delete referenceBitmap; - - for (int i = 1; i <= 255; ++i) { - if(diffs[i] > 0) { - SkDebugf("Number of pixels with max diff of %i is %i\n", i, diffs[i]); - } - } - } - - if (FLAGS_writeWholeImage) { - sk_tools::force_all_opaque(*bitmap); - - SkString inputFilename = SkOSPath::Basename(inputPath.c_str()); - SkString outputFilename(inputFilename); - sk_tools::replace_char(&outputFilename, '.', '_'); - outputFilename.append(".png"); - - if (jsonSummaryPtr) { - sk_tools::ImageDigest imageDigest(*bitmap); - jsonSummaryPtr->add(inputFilename.c_str(), outputFilename.c_str(), imageDigest); - if ((mismatchPath) && !mismatchPath->isEmpty() && - !jsonSummaryPtr->getExpectation(inputFilename.c_str()).matches(imageDigest)) { - success &= sk_tools::write_bitmap_to_disk(*bitmap, *mismatchPath, nullptr, - outputFilename); - } - } - - if ((writePath) && !writePath->isEmpty()) { - success &= sk_tools::write_bitmap_to_disk(*bitmap, *writePath, nullptr, outputFilename); - } - } - delete bitmap; - - return success; -} - - -static int process_input(const char* input, const SkString* writePath, - const SkString* mismatchPath, sk_tools::PictureRenderer& renderer, - sk_tools::ImageResultsAndExpectations *jsonSummaryPtr) { - SkOSFile::Iter iter(input, "skp"); - SkString inputFilename; - int failures = 0; - SkDebugf("process_input, %s\n", input); - if (iter.next(&inputFilename)) { - do { - SkString inputPath = SkOSPath::Join(input, inputFilename.c_str()); - if (!render_picture(inputPath, writePath, mismatchPath, renderer, jsonSummaryPtr)) { - ++failures; - } - } while(iter.next(&inputFilename)); - } else if (SkStrEndsWith(input, ".skp")) { - SkString inputPath(input); - if (!render_picture(inputPath, writePath, mismatchPath, renderer, jsonSummaryPtr)) { - ++failures; - } - } else { - SkString warning; - warning.printf("Warning: skipping %s\n", input); - SkDebugf("%s", warning.c_str()); - } - return failures; -} - -int tool_main(int argc, char** argv); -int tool_main(int argc, char** argv) { - SkCommandLineFlags::SetUsage("Render .skp files."); - SkCommandLineFlags::Parse(argc, argv); - - if (FLAGS_readPath.isEmpty()) { - SkDebugf(".skp files or directories are required.\n"); - exit(-1); - } - - if (FLAGS_maxComponentDiff < 0 || FLAGS_maxComponentDiff > 256) { - SkDebugf("--maxComponentDiff must be between 0 and 256\n"); - exit(-1); - } - - if (FLAGS_maxComponentDiff != 256 && !FLAGS_validate) { - SkDebugf("--maxComponentDiff requires --validate\n"); - exit(-1); - } - - if (FLAGS_writeEncodedImages) { - if (FLAGS_writePath.isEmpty()) { - SkDebugf("--writeEncodedImages requires --writePath\n"); - exit(-1); - } - if (FLAGS_deferImageDecoding) { - SkDebugf("--writeEncodedImages is not compatible with --deferImageDecoding\n"); - exit(-1); - } - } - - SkString errorString; - SkAutoTUnref<sk_tools::PictureRenderer> renderer(parseRenderer(errorString, - kRender_PictureTool)); - if (errorString.size() > 0) { - SkDebugf("%s\n", errorString.c_str()); - } - - if (renderer.get() == nullptr) { - exit(-1); - } - - SkAutoGraphics ag; - - SkString writePath; - if (FLAGS_writePath.count() == 1) { - writePath.set(FLAGS_writePath[0]); - } - SkString mismatchPath; - if (FLAGS_mismatchPath.count() == 1) { - mismatchPath.set(FLAGS_mismatchPath[0]); - } - sk_tools::ImageResultsAndExpectations jsonSummary; - sk_tools::ImageResultsAndExpectations* jsonSummaryPtr = nullptr; - if (FLAGS_writeJsonSummaryPath.count() == 1) { - jsonSummaryPtr = &jsonSummary; - if (FLAGS_readJsonSummaryPath.count() == 1) { - SkASSERT(jsonSummary.readExpectationsFile(FLAGS_readJsonSummaryPath[0])); - } - } - - int failures = 0; - for (int i = 0; i < FLAGS_readPath.count(); i ++) { - failures += process_input(FLAGS_readPath[i], &writePath, &mismatchPath, *renderer.get(), - jsonSummaryPtr); - } - if (failures != 0) { - SkDebugf("Failed to render %i pictures.\n", failures); - return 1; - } -#if GR_CACHE_STATS && SK_SUPPORT_GPU - if (renderer->isUsingGpuDevice()) { - GrContext* ctx = renderer->getGrContext(); - ctx->printCacheStats(); - } -#endif - -#if GR_GPU_STATS && SK_SUPPORT_GPU - if (FLAGS_gpuStats && renderer->isUsingGpuDevice()) { - renderer->getGrContext()->printGpuStats(); - } -#endif - - if (FLAGS_writeJsonSummaryPath.count() == 1) { - // If there were any descriptions on the command line, insert them now. - for (int i=0; i<FLAGS_descriptions.count(); i++) { - SkTArray<SkString> tokens; - SkStrSplit(FLAGS_descriptions[i], "=", &tokens); - SkASSERT(tokens.count() == 2); - jsonSummary.addDescription(tokens[0].c_str(), tokens[1].c_str()); - } - if (FLAGS_imageBaseGSUrl.count() == 1) { - jsonSummary.setImageBaseGSUrl(FLAGS_imageBaseGSUrl[0]); - } - jsonSummary.writeToFile(FLAGS_writeJsonSummaryPath[0]); - } - return 0; -} - -#if !defined SK_BUILD_FOR_IOS -int main(int argc, char * const argv[]) { - return tool_main(argc, (char**) argv); -} -#endif |