diff options
author | 2012-12-18 22:24:03 +0000 | |
---|---|---|
committer | 2012-12-18 22:24:03 +0000 | |
commit | 84f548cc9daf77bb3ee7c59ad986eebe9ad1168e (patch) | |
tree | 48a9440e316e3034e861edcf5af3199df32164c9 | |
parent | 6d0673042f6225f16fc5ea91cb1fdf4c8e96d880 (diff) |
Flags for render_pictures: verify, clone and writeWholeImage:
1) flag to verify PNGs produced by render_picture that produce the same pixels
as simple renderer.
2) flag to write one single image (in tile we write individual tiles) - this
will help running skdiff also
3) flag to clone the picture before rendering
git-svn-id: http://skia.googlecode.com/svn/trunk@6890 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | tools/CopyTilesRenderer.cpp | 2 | ||||
-rw-r--r-- | tools/CopyTilesRenderer.h | 2 | ||||
-rw-r--r-- | tools/PictureRenderer.cpp | 88 | ||||
-rw-r--r-- | tools/PictureRenderer.h | 14 | ||||
-rw-r--r-- | tools/render_pictures_main.cpp | 222 |
5 files changed, 300 insertions, 28 deletions
diff --git a/tools/CopyTilesRenderer.cpp b/tools/CopyTilesRenderer.cpp index e5cbdbd749..d3f266b028 100644 --- a/tools/CopyTilesRenderer.cpp +++ b/tools/CopyTilesRenderer.cpp @@ -34,7 +34,7 @@ namespace sk_tools { fCanvas.reset(this->INHERITED::setupCanvas(fLargeTileWidth, fLargeTileHeight)); } - bool CopyTilesRenderer::render(const SkString* path) { + bool CopyTilesRenderer::render(const SkString* path, SkBitmap** out) { int i = 0; bool success = true; SkBitmap dst; diff --git a/tools/CopyTilesRenderer.h b/tools/CopyTilesRenderer.h index 55abc9c5cb..5546604ee8 100644 --- a/tools/CopyTilesRenderer.h +++ b/tools/CopyTilesRenderer.h @@ -29,7 +29,7 @@ namespace sk_tools { * Similar to TiledPictureRenderer, this will draw a PNG for each tile. However, the * numbering (and actual tiles) will be different. */ - virtual bool render(const SkString* path) SK_OVERRIDE; + virtual bool render(const SkString* path, SkBitmap** out) SK_OVERRIDE; private: int fXTilesPerLargeTile; diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp index ab8727470c..61de8c63b0 100644 --- a/tools/PictureRenderer.cpp +++ b/tools/PictureRenderer.cpp @@ -243,7 +243,7 @@ static bool PNGEncodeBitmapToStream(SkWStream* wStream, const SkBitmap& bm) { return SkImageEncoder::EncodeStream(wStream, bm, SkImageEncoder::kPNG_Type, 100); } -bool RecordPictureRenderer::render(const SkString* path) { +bool RecordPictureRenderer::render(const SkString* path, SkBitmap** out) { SkAutoTUnref<SkPicture> replayer(this->createPicture()); SkCanvas* recorder = replayer->beginRecording(this->getViewWidth(), this->getViewHeight(), this->recordFlags()); @@ -268,7 +268,7 @@ SkString RecordPictureRenderer::getConfigNameInternal() { /////////////////////////////////////////////////////////////////////////////////////////////// -bool PipePictureRenderer::render(const SkString* path) { +bool PipePictureRenderer::render(const SkString* path, SkBitmap** out) { SkASSERT(fCanvas.get() != NULL); SkASSERT(fPicture != NULL); if (NULL == fCanvas.get() || NULL == fPicture) { @@ -284,6 +284,11 @@ bool PipePictureRenderer::render(const SkString* path) { if (NULL != path) { return write(fCanvas, *path); } + if (NULL != out) { + *out = SkNEW(SkBitmap); + setup_bitmap(*out, fPicture->width(), fPicture->height()); + fCanvas->readPixels(*out, 0, 0); + } return true; } @@ -298,7 +303,7 @@ void SimplePictureRenderer::init(SkPicture* picture) { this->buildBBoxHierarchy(); } -bool SimplePictureRenderer::render(const SkString* path) { +bool SimplePictureRenderer::render(const SkString* path, SkBitmap** out) { SkASSERT(fCanvas.get() != NULL); SkASSERT(fPicture != NULL); if (NULL == fCanvas.get() || NULL == fPicture) { @@ -310,6 +315,13 @@ bool SimplePictureRenderer::render(const SkString* path) { if (NULL != path) { return write(fCanvas, *path); } + + if (NULL != out) { + *out = SkNEW(SkBitmap); + setup_bitmap(*out, fPicture->width(), fPicture->height()); + fCanvas->readPixels(*out, 0, 0); + } + return true; } @@ -467,6 +479,15 @@ static void DrawTileToCanvas(SkCanvas* canvas, const SkRect& tileRect, T* playba /////////////////////////////////////////////////////////////////////////////////////////////// +static void bitmapCopySubset(const SkBitmap& src, SkBitmap* dst, int xDst, + int yDst) { + for (int y = 0; y <src.height() && y + yDst < dst->height() ; y++) { + for (int x = 0; x < src.width() && x + xDst < dst->width() ; x++) { + *dst->getAddr32(xDst + x, yDst + y) = *src.getAddr32(x, y); + } + } +} + bool TiledPictureRenderer::nextTile(int &i, int &j) { if (++fCurrentTileOffset < fTileRects.count()) { i = fCurrentTileOffset % fTilesX; @@ -481,18 +502,32 @@ void TiledPictureRenderer::drawCurrentTile() { DrawTileToCanvas(fCanvas, fTileRects[fCurrentTileOffset], fPicture); } -bool TiledPictureRenderer::render(const SkString* path) { +bool TiledPictureRenderer::render(const SkString* path, SkBitmap** out) { SkASSERT(fPicture != NULL); if (NULL == fPicture) { return false; } + SkBitmap bitmap; + if (out){ + *out = SkNEW(SkBitmap); + setup_bitmap(*out, fPicture->width(), fPicture->height()); + setup_bitmap(&bitmap, fTileWidth, fTileHeight); + } bool success = true; for (int i = 0; i < fTileRects.count(); ++i) { DrawTileToCanvas(fCanvas, fTileRects[i], fPicture); if (NULL != path) { success &= writeAppendNumber(fCanvas, path, i); } + if (NULL != out) { + if (fCanvas->readPixels(&bitmap, 0, 0)) { + bitmapCopySubset(bitmap, *out, fTileRects[i].left(), + fTileRects[i].top()); + } else { + success = false; + } + } } return success; } @@ -555,6 +590,13 @@ public: virtual void run() SK_OVERRIDE { SkGraphics::SetTLSFontCacheLimit(1024 * 1024); + + SkBitmap bitmap; + if (fBitmap != NULL) { + // All tiles are the same size. + setup_bitmap(&bitmap, fRects[0].width(), fRects[0].height()); + } + for (int i = fStart; i < fEnd; i++) { DrawTileToCanvas(fCanvas, fRects[i], fClone); if (fPath != NULL && !writeAppendNumber(fCanvas, fPath, i) @@ -563,6 +605,17 @@ public: // If one tile fails to write to a file, do not continue drawing the rest. break; } + if (fBitmap != NULL) { + if (fCanvas->readPixels(&bitmap, 0, 0)) { + SkAutoLockPixels alp(*fBitmap); + bitmapCopySubset(bitmap, fBitmap, fRects[i].left(), + fRects[i].top()); + } else { + *fSuccess = false; + // If one tile fails to read pixels, do not continue drawing the rest. + break; + } + } } fDone->run(); } @@ -572,6 +625,10 @@ public: fSuccess = success; } + void setBitmap(SkBitmap* bitmap) { + fBitmap = bitmap; + } + private: // All pointers unowned. SkPicture* fClone; // Picture to draw from. Each CloneData has a unique one which @@ -584,6 +641,7 @@ private: bool* fSuccess; // Only meaningful if path is non-null. Shared by all threads, // and only set to false upon failure to write to a PNG. SkRunnable* fDone; + SkBitmap* fBitmap; }; MultiCorePictureRenderer::MultiCorePictureRenderer(int threadCount) @@ -623,7 +681,7 @@ void MultiCorePictureRenderer::init(SkPicture *pict) { } } -bool MultiCorePictureRenderer::render(const SkString *path) { +bool MultiCorePictureRenderer::render(const SkString *path, SkBitmap** out) { bool success = true; if (path != NULL) { for (int i = 0; i < fNumThreads-1; i++) { @@ -631,6 +689,18 @@ bool MultiCorePictureRenderer::render(const SkString *path) { } } + if (NULL != out) { + *out = SkNEW(SkBitmap); + setup_bitmap(*out, fPicture->width(), fPicture->height()); + for (int i = 0; i < fNumThreads; i++) { + fCloneData[i]->setBitmap(*out); + } + } else { + for (int i = 0; i < fNumThreads; i++) { + fCloneData[i]->setBitmap(NULL); + } + } + fCountdown.reset(fNumThreads); for (int i = 0; i < fNumThreads; i++) { fThreadPool.add(fCloneData[i]); @@ -673,7 +743,7 @@ void PlaybackCreationRenderer::setup() { fPicture->draw(recorder); } -bool PlaybackCreationRenderer::render(const SkString*) { +bool PlaybackCreationRenderer::render(const SkString*, SkBitmap** out) { fReplayer->endRecording(); // Since this class does not actually render, return false. return false; @@ -716,7 +786,8 @@ SkPicture* PictureRenderer::createPicture() { class GatherRenderer : public PictureRenderer { public: - virtual bool render(const SkString* path) SK_OVERRIDE { + virtual bool render(const SkString* path, SkBitmap** out = NULL) + SK_OVERRIDE { SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->width()), SkIntToScalar(fPicture->height())); SkData* data = SkPictureUtils::GatherPixelRefs(fPicture, bounds); @@ -739,7 +810,8 @@ PictureRenderer* CreateGatherPixelRefsRenderer() { class PictureCloneRenderer : public PictureRenderer { public: - virtual bool render(const SkString* path) SK_OVERRIDE { + virtual bool render(const SkString* path, SkBitmap** out = NULL) + SK_OVERRIDE { for (int i = 0; i < 100; ++i) { SkPicture* clone = fPicture->clone(); SkSafeUnref(clone); diff --git a/tools/PictureRenderer.h b/tools/PictureRenderer.h index 262e8997e6..5d6c5166a2 100644 --- a/tools/PictureRenderer.h +++ b/tools/PictureRenderer.h @@ -96,7 +96,7 @@ public: * @return bool True if rendering succeeded and, if path is non-null, the output was * successfully written to a file. */ - virtual bool render(const SkString* path) = 0; + virtual bool render(const SkString* path, SkBitmap** out = NULL) = 0; /** * Called once finished with a particular SkPicture, before calling init again, and before @@ -245,7 +245,7 @@ private: * to time. */ class RecordPictureRenderer : public PictureRenderer { - virtual bool render(const SkString*) SK_OVERRIDE; + virtual bool render(const SkString*, SkBitmap** out = NULL) SK_OVERRIDE; virtual SkString getPerIterTimeFormat() SK_OVERRIDE { return SkString("%.4f"); } @@ -260,7 +260,7 @@ private: class PipePictureRenderer : public PictureRenderer { public: - virtual bool render(const SkString*) SK_OVERRIDE; + virtual bool render(const SkString*, SkBitmap** out = NULL) SK_OVERRIDE; private: virtual SkString getConfigNameInternal() SK_OVERRIDE; @@ -272,7 +272,7 @@ class SimplePictureRenderer : public PictureRenderer { public: virtual void init(SkPicture* pict) SK_OVERRIDE; - virtual bool render(const SkString*) SK_OVERRIDE; + virtual bool render(const SkString*, SkBitmap** out = NULL) SK_OVERRIDE; private: virtual SkString getConfigNameInternal() SK_OVERRIDE; @@ -291,7 +291,7 @@ public: * created for each tile, named "path0.png", "path1.png", etc. * Multithreaded mode currently does not support writing to a file. */ - virtual bool render(const SkString* path) SK_OVERRIDE; + virtual bool render(const SkString* path, SkBitmap** out = NULL) SK_OVERRIDE; virtual void end() SK_OVERRIDE; @@ -410,7 +410,7 @@ public: /** * Behaves like TiledPictureRenderer::render(), only using multiple threads. */ - virtual bool render(const SkString* path) SK_OVERRIDE; + virtual bool render(const SkString* path, SkBitmap** out = NULL) SK_OVERRIDE; virtual void end() SK_OVERRIDE; @@ -435,7 +435,7 @@ class PlaybackCreationRenderer : public PictureRenderer { public: virtual void setup() SK_OVERRIDE; - virtual bool render(const SkString*) SK_OVERRIDE; + virtual bool render(const SkString*, SkBitmap** out = NULL) SK_OVERRIDE; virtual SkString getPerIterTimeFormat() SK_OVERRIDE { return SkString("%.4f"); } diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp index 3a58eeaaf9..fce4055139 100644 --- a/tools/render_pictures_main.cpp +++ b/tools/render_pictures_main.cpp @@ -11,6 +11,7 @@ #include "SkDevice.h" #include "SkGraphics.h" #include "SkImageDecoder.h" +#include "SkImageEncoder.h" #include "SkMath.h" #include "SkOSFile.h" #include "SkPicture.h" @@ -29,7 +30,11 @@ static void usage(const char* argv0) { " [--mode pow2tile minWidth height | copyTile width height | simple\n" " | tile width height]\n" " [--pipe]\n" +" [--bbh bbhType]\n" " [--multi count]\n" +" [--validate]\n" +" [--writeWholeImage]\n" +" [--clone n]\n" " [--viewport width height][--scale sf]\n" " [--device bitmap" #if SK_SUPPORT_GPU @@ -79,6 +84,20 @@ static void usage(const char* argv0) { " --scale sf : Scale drawing by sf.\n" " --pipe: Benchmark SkGPipe rendering. Currently incompatible with \"mode\".\n"); SkDebugf( +" --validate: Verify that the rendered image contains the same pixels as " +"the picture rendered in simple mode.\n" +" --writeWholeImage: In tile mode, write the entire rendered image to a " +"file, instead of an image for each tile.\n"); + SkDebugf( +" --clone n: Clone the picture n times before rendering.\n"); + SkDebugf( +" --bbh bbhType [width height]: Set the bounding box hierarchy type to\n" +" be used. Accepted values are: none, rtree, grid. Default\n" +" value is none. Not compatible with --pipe. With value\n" +" 'grid', width and height must be specified. 'grid' can\n" +" only be used with modes tile, record, and\n" +" playbackCreation."); + SkDebugf( " --device bitmap" #if SK_SUPPORT_GPU " | gpu" @@ -100,7 +119,9 @@ static void make_output_filepath(SkString* path, const SkString& dir, } static bool render_picture(const SkString& inputPath, const SkString* outputDir, - sk_tools::PictureRenderer& renderer) { + sk_tools::PictureRenderer& renderer, + SkBitmap** out, + int clones) { SkString inputFilename; sk_tools::get_basename(&inputFilename, inputPath); @@ -112,16 +133,23 @@ static bool render_picture(const SkString& inputPath, const SkString* outputDir, } bool success = false; - SkPicture picture(&inputStream, &success, &SkImageDecoder::DecodeStream); + SkPicture* picture = SkNEW_ARGS(SkPicture, + (&inputStream, &success, &SkImageDecoder::DecodeStream)); if (!success) { SkDebugf("Could not read an SkPicture from %s\n", inputPath.c_str()); return false; } - SkDebugf("drawing... [%i %i] %s\n", picture.width(), picture.height(), + for (int i = 0; i < clones; ++i) { + SkPicture* clone = picture->clone(); + SkDELETE(picture); + picture = clone; + } + + SkDebugf("drawing... [%i %i] %s\n", picture->width(), picture->height(), inputPath.c_str()); - renderer.init(&picture); + renderer.init(picture); renderer.setup(); SkString* outputPath = NULL; @@ -129,7 +157,8 @@ static bool render_picture(const SkString& inputPath, const SkString* outputDir, outputPath = SkNEW(SkString); make_output_filepath(outputPath, *outputDir, inputFilename); } - success = renderer.render(outputPath); + + success = renderer.render(outputPath, out); if (outputPath) { if (!success) { SkDebugf("Could not write to file %s\n", outputPath->c_str()); @@ -140,11 +169,96 @@ static bool render_picture(const SkString& inputPath, const SkString* outputDir, renderer.resetState(); renderer.end(); + + SkDELETE(picture); return success; } +static bool render_picture(const SkString& inputPath, const SkString* outputDir, + sk_tools::PictureRenderer& renderer, + bool validate, + bool writeWholeImage, + int clones) { + SkBitmap* bitmap = NULL; + bool success = render_picture(inputPath, + writeWholeImage ? NULL : outputDir, + renderer, + validate || writeWholeImage ? &bitmap : NULL, clones); + + if (!success || ((validate || writeWholeImage) && bitmap == NULL)) { + SkDebugf("Failed to draw the picture.\n"); + SkDELETE(bitmap); + return false; + } + + if (validate) { + SkBitmap* referenceBitmap = NULL; + sk_tools::SimplePictureRenderer referenceRenderer; + success = render_picture(inputPath, NULL, referenceRenderer, + &referenceBitmap, 0); + + if (!success || !referenceBitmap) { + SkDebugf("Failed to draw the reference picture.\n"); + SkDELETE(bitmap); + SkDELETE(referenceBitmap); + return false; + } + + if (success && (bitmap->width() != referenceBitmap->width())) { + SkDebugf("Expected image width: %i, actual image width %i.\n", + referenceBitmap->width(), bitmap->width()); + SkDELETE(bitmap); + SkDELETE(referenceBitmap); + return false; + } + if (success && (bitmap->height() != referenceBitmap->height())) { + SkDebugf("Expected image height: %i, actual image height %i", + referenceBitmap->height(), bitmap->height()); + SkDELETE(bitmap); + SkDELETE(referenceBitmap); + return false; + } + + for (int y = 0; success && y < bitmap->height(); y++) { + for (int x = 0; success && x < bitmap->width(); x++) { + if (*referenceBitmap->getAddr32(x, y) != *bitmap->getAddr32(x, y)) { + SkDebugf("Expected pixel at (%i %i): 0x%x, actual 0x%x\n", + x, y, + referenceBitmap->getAddr32(x, y), + *bitmap->getAddr32(x, y)); + SkDELETE(bitmap); + SkDELETE(referenceBitmap); + return false; + } + } + } + SkDELETE(referenceBitmap); + } + + if (writeWholeImage) { + sk_tools::force_all_opaque(*bitmap); + if (NULL != outputDir && writeWholeImage) { + SkString inputFilename; + sk_tools::get_basename(&inputFilename, inputPath); + SkString outputPath; + make_output_filepath(&outputPath, *outputDir, inputFilename); + outputPath.append(".png"); + if (!SkImageEncoder::EncodeFile(outputPath.c_str(), *bitmap, + SkImageEncoder::kPNG_Type, 100)) { + SkDebugf("Failed to draw the picture.\n"); + success = false; + } + } + } + SkDELETE(bitmap); + + return success; +} + + static int process_input(const SkString& input, const SkString* outputDir, - sk_tools::PictureRenderer& renderer) { + sk_tools::PictureRenderer& renderer, + bool validate, bool writeWholeImage, int clones) { SkOSFile::Iter iter(input.c_str(), "skp"); SkString inputFilename; int failures = 0; @@ -153,13 +267,15 @@ static int process_input(const SkString& input, const SkString* outputDir, do { SkString inputPath; sk_tools::make_filepath(&inputPath, input, inputFilename); - if (!render_picture(inputPath, outputDir, renderer)) { + if (!render_picture(inputPath, outputDir, renderer, + validate, writeWholeImage, clones)) { ++failures; } } while(iter.next(&inputFilename)); } else if (SkStrEndsWith(input.c_str(), ".skp")) { SkString inputPath(input); - if (!render_picture(inputPath, outputDir, renderer)) { + if (!render_picture(inputPath, outputDir, renderer, + validate, writeWholeImage, clones)) { ++failures; } } else { @@ -171,7 +287,9 @@ static int process_input(const SkString& input, const SkString* outputDir, } static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs, - sk_tools::PictureRenderer*& renderer, SkString*& outputDir){ + sk_tools::PictureRenderer*& renderer, SkString*& outputDir, + bool* validate, bool* writeWholeImage, + int* clones){ const char* argv0 = argv[0]; char* const* stop = argv + argc; @@ -183,14 +301,23 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* bool useTiles = false; const char* widthString = NULL; const char* heightString = NULL; + int gridWidth = 0; + int gridHeight = 0; bool isPowerOf2Mode = false; bool isCopyMode = false; const char* xTilesString = NULL; const char* yTilesString = NULL; const char* mode = NULL; + bool gridSupported = false; + sk_tools::PictureRenderer::BBoxHierarchyType bbhType = + sk_tools::PictureRenderer::kNone_BBoxHierarchyType; + *validate = false; + *writeWholeImage = false; + *clones = 0; SkISize viewport; viewport.setEmpty(); SkScalar scaleFactor = SK_Scalar1; + for (++argv; argv < stop; ++argv) { if (0 == strcmp(*argv, "--mode")) { if (renderer != NULL) { @@ -218,6 +345,8 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* isPowerOf2Mode = true; } else if (0 == strcmp(*argv, "copyTile")) { isCopyMode = true; + } else { + gridSupported = true; } ++argv; @@ -242,6 +371,38 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* usage(argv0); exit(-1); } + } else if (0 == strcmp(*argv, "--bbh")) { + ++argv; + if (argv >= stop) { + SkDebugf("Missing value for --bbh\n"); + usage(argv0); + exit(-1); + } + if (0 == strcmp(*argv, "none")) { + bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType; + } else if (0 == strcmp(*argv, "rtree")) { + bbhType = sk_tools::PictureRenderer::kRTree_BBoxHierarchyType; + } else if (0 == strcmp(*argv, "grid")) { + bbhType = sk_tools::PictureRenderer::kTileGrid_BBoxHierarchyType; + ++argv; + if (argv >= stop) { + SkDebugf("Missing width for --bbh grid\n"); + usage(argv0); + exit(-1); + } + gridWidth = atoi(*argv); + ++argv; + if (argv >= stop) { + SkDebugf("Missing height for --bbh grid\n"); + usage(argv0); + exit(-1); + } + gridHeight = atoi(*argv); + } else { + SkDebugf("%s is not a valid value for --bbhType\n", *argv); + usage(argv0); + exit(-1);; + } } else if (0 == strcmp(*argv, "--viewport")) { ++argv; if (argv >= stop) { @@ -297,6 +458,21 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* usage(argv0); exit(-1); } + } else if (0 == strcmp(*argv, "--clone")) { + ++argv; + if (argv >= stop) { + SkSafeUnref(renderer); + SkDebugf("Missing arg for --clone\n"); + usage(argv0); + exit(-1); + } + *clones = atoi(*argv); + if (*clones < 0) { + SkSafeUnref(renderer); + SkDebugf("Number of clones must be at least 0.\n"); + usage(argv0); + exit(-1); + } } else if (0 == strcmp(*argv, "--device")) { ++argv; if (argv >= stop) { @@ -333,6 +509,10 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* exit(-1); } outputDir = SkNEW_ARGS(SkString, (*argv)); + } else if (0 == strcmp(*argv, "--validate")) { + *validate = true; + } else if (0 == strcmp(*argv, "--writeWholeImage")) { + *writeWholeImage = true; } else { inputs->push_back(SkString(*argv)); } @@ -345,6 +525,19 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* exit(-1); } + if (usePipe && sk_tools::PictureRenderer::kNone_BBoxHierarchyType != bbhType) { + SkDebugf("--pipe and --bbh cannot be used together\n"); + usage(argv0); + exit(-1); + } + + if (sk_tools::PictureRenderer::kTileGrid_BBoxHierarchyType == bbhType && + !gridSupported) { + SkDebugf("'--bbh grid' is not compatible with specified --mode.\n"); + usage(argv0); + exit(-1); + } + if (useTiles) { SkASSERT(NULL == renderer); sk_tools::TiledPictureRenderer* tiledRenderer; @@ -469,6 +662,8 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* renderer = SkNEW(sk_tools::SimplePictureRenderer); } + renderer->setBBoxHierarchyType(bbhType); + renderer->setGridSize(gridWidth, gridHeight); renderer->setViewport(viewport); renderer->setScaleFactor(scaleFactor); renderer->setDeviceType(deviceType); @@ -480,12 +675,17 @@ int tool_main(int argc, char** argv) { SkTArray<SkString> inputs; sk_tools::PictureRenderer* renderer = NULL; SkString* outputDir = NULL; - parse_commandline(argc, argv, &inputs, renderer, outputDir); + bool validate = false; + bool writeWholeImage = false; + int clones = 0; + parse_commandline(argc, argv, &inputs, renderer, outputDir, + &validate, &writeWholeImage, &clones); SkASSERT(renderer); int failures = 0; for (int i = 0; i < inputs.count(); i ++) { - failures += process_input(inputs[i], outputDir, *renderer); + failures += process_input(inputs[i], outputDir, *renderer, + validate, writeWholeImage, clones); } if (failures != 0) { SkDebugf("Failed to render %i pictures.\n", failures); |