render_pictures: add --mismatchPath flag
When set, it will only write out images that don't match expectations.
BUG=skia:1942
R=rmistry@google.com
Author: epoger@google.com
Review URL: https://codereview.chromium.org/283123002
git-svn-id: http://skia.googlecode.com/svn/trunk@14748 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp
index 7456700..12f0afa 100644
--- a/tools/PictureRenderer.cpp
+++ b/tools/PictureRenderer.cpp
@@ -48,9 +48,10 @@
kDefaultTileHeight = 256
};
-void PictureRenderer::init(SkPicture* pict, const SkString* outputDir,
+void PictureRenderer::init(SkPicture* pict, const SkString* writePath, const SkString* mismatchPath,
const SkString* inputFilename, bool useChecksumBasedFilenames) {
- this->CopyString(&fOutputDir, outputDir);
+ this->CopyString(&fWritePath, writePath);
+ this->CopyString(&fMismatchPath, mismatchPath);
this->CopyString(&fInputFilename, inputFilename);
fUseChecksumBasedFilenames = useChecksumBasedFilenames;
@@ -265,8 +266,9 @@
* Write the canvas to an image file and/or JSON summary.
*
* @param canvas Must be non-null. Canvas to be written to a file.
- * @param outputDir If nonempty, write the binary image to a file within this directory;
- * if empty, don't write out the image at all.
+ * @param writePath If nonempty, write the binary image to a file within this directory.
+ * @param mismatchPath If nonempty, write the binary image to a file within this directory,
+ * but only if the image does not match expectations.
* @param inputFilename If we are writing out a binary image, use this to build its filename.
* @param jsonSummaryPtr If not null, add image results (checksum) to this summary.
* @param useChecksumBasedFilenames If true, use checksum-based filenames when writing to disk.
@@ -274,9 +276,9 @@
*
* @return bool True if the operation completed successfully.
*/
-static bool write(SkCanvas* canvas, const SkString& outputDir, const SkString& inputFilename,
- ImageResultsAndExpectations *jsonSummaryPtr, bool useChecksumBasedFilenames,
- const int* tileNumberPtr=NULL) {
+static bool write(SkCanvas* canvas, const SkString& writePath, const SkString& mismatchPath,
+ const SkString& inputFilename, ImageResultsAndExpectations *jsonSummaryPtr,
+ bool useChecksumBasedFilenames, const int* tileNumberPtr=NULL) {
SkASSERT(canvas != NULL);
if (NULL == canvas) {
return false;
@@ -325,21 +327,20 @@
jsonSummaryPtr->add(inputFilename.c_str(), outputRelativePath.c_str(),
*imageDigestPtr, tileNumberPtr);
+ if (!mismatchPath.isEmpty() &&
+ !jsonSummaryPtr->matchesExpectation(inputFilename.c_str(), *imageDigestPtr,
+ tileNumberPtr)) {
+ if (!write_bitmap_to_disk(bitmap, mismatchPath, outputSubdirPtr, outputFilename)) {
+ return false;
+ }
+ }
}
- if (outputDir.isEmpty()) {
+ if (writePath.isEmpty()) {
return true;
- }
-
- SkString dirPath;
- if (outputSubdirPtr) {
- dirPath = SkOSPath::SkPathJoin(outputDir.c_str(), outputSubdirPtr);
- sk_mkdir(dirPath.c_str());
} else {
- dirPath.set(outputDir);
+ return write_bitmap_to_disk(bitmap, writePath, outputSubdirPtr, outputFilename);
}
- SkString fullPath = SkOSPath::SkPathJoin(dirPath.c_str(), outputFilename.c_str());
- return SkImageEncoder::EncodeFile(fullPath.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100);
}
///////////////////////////////////////////////////////////////////////////////////////////////
@@ -363,9 +364,9 @@
this->scaleToScaleFactor(canvas);
fPicture->draw(canvas);
SkAutoTUnref<SkPicture> picture(recorder.endRecording());
- if (!fOutputDir.isEmpty()) {
+ if (!fWritePath.isEmpty()) {
// Record the new picture as a new SKP with PNG encoded bitmaps.
- SkString skpPath = SkOSPath::SkPathJoin(fOutputDir.c_str(), fInputFilename.c_str());
+ SkString skpPath = SkOSPath::SkPathJoin(fWritePath.c_str(), fInputFilename.c_str());
SkFILEWStream stream(skpPath.c_str());
picture->serialize(&stream, &encode_bitmap_to_data);
return true;
@@ -397,7 +398,7 @@
setup_bitmap(*out, fPicture->width(), fPicture->height());
fCanvas->readPixels(*out, 0, 0);
}
- return write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr,
+ return write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr,
fUseChecksumBasedFilenames);
}
@@ -407,9 +408,10 @@
///////////////////////////////////////////////////////////////////////////////////////////////
-void SimplePictureRenderer::init(SkPicture* picture, const SkString* outputDir,
- const SkString* inputFilename, bool useChecksumBasedFilenames) {
- INHERITED::init(picture, outputDir, inputFilename, useChecksumBasedFilenames);
+void SimplePictureRenderer::init(SkPicture* picture, const SkString* writePath,
+ const SkString* mismatchPath, const SkString* inputFilename,
+ bool useChecksumBasedFilenames) {
+ INHERITED::init(picture, writePath, mismatchPath, inputFilename, useChecksumBasedFilenames);
this->buildBBoxHierarchy();
}
@@ -427,7 +429,7 @@
setup_bitmap(*out, fPicture->width(), fPicture->height());
fCanvas->readPixels(*out, 0, 0);
}
- return write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr,
+ return write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr,
fUseChecksumBasedFilenames);
}
@@ -447,8 +449,9 @@
, fTilesX(0)
, fTilesY(0) { }
-void TiledPictureRenderer::init(SkPicture* pict, const SkString* outputDir,
- const SkString* inputFilename, bool useChecksumBasedFilenames) {
+void TiledPictureRenderer::init(SkPicture* pict, const SkString* writePath,
+ const SkString* mismatchPath, const SkString* inputFilename,
+ bool useChecksumBasedFilenames) {
SkASSERT(NULL != pict);
SkASSERT(0 == fTileRects.count());
if (NULL == pict || fTileRects.count() != 0) {
@@ -458,7 +461,8 @@
// Do not call INHERITED::init(), which would create a (potentially large) canvas which is not
// used by bench_pictures.
fPicture.reset(pict)->ref();
- this->CopyString(&fOutputDir, outputDir);
+ this->CopyString(&fWritePath, writePath);
+ this->CopyString(&fMismatchPath, mismatchPath);
this->CopyString(&fInputFilename, inputFilename);
fUseChecksumBasedFilenames = useChecksumBasedFilenames;
this->buildBBoxHierarchy();
@@ -636,7 +640,7 @@
bool success = true;
for (int i = 0; i < fTileRects.count(); ++i) {
draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture);
- success &= write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr,
+ success &= write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr,
fUseChecksumBasedFilenames, &i);
if (NULL != out) {
if (fCanvas->readPixels(&bitmap, 0, 0)) {
@@ -720,7 +724,7 @@
for (int i = fStart; i < fEnd; i++) {
draw_tile_to_canvas(fCanvas, fRects[i], fClone);
- if (!write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr,
+ if (!write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummaryPtr,
fUseChecksumBasedFilenames, &i)
&& fSuccess != NULL) {
*fSuccess = false;
@@ -742,9 +746,10 @@
fDone->run();
}
- void setPathsAndSuccess(const SkString& outputDir, const SkString& inputFilename,
- bool* success) {
- fOutputDir.set(outputDir);
+ void setPathsAndSuccess(const SkString& writePath, const SkString& mismatchPath,
+ const SkString& inputFilename, bool* success) {
+ fWritePath.set(writePath);
+ fMismatchPath.set(mismatchPath);
fInputFilename.set(inputFilename);
fSuccess = success;
}
@@ -758,7 +763,8 @@
SkPicture* fClone; // Picture to draw from. Each CloneData has a unique one which
// is threadsafe.
SkCanvas* fCanvas; // Canvas to draw to. Reused for each tile.
- SkString fOutputDir; // If not empty, write results into this directory.
+ SkString fWritePath; // If not empty, write all results into this directory.
+ SkString fMismatchPath; // If not empty, write all unexpected results into this dir.
SkString fInputFilename; // Filename of input SkPicture file.
SkTDArray<SkRect>& fRects; // All tiles of the picture.
const int fStart; // Range of tiles drawn by this thread.
@@ -781,10 +787,11 @@
fCloneData = SkNEW_ARRAY(CloneData*, fNumThreads);
}
-void MultiCorePictureRenderer::init(SkPicture *pict, const SkString* outputDir,
- const SkString* inputFilename, bool useChecksumBasedFilenames) {
+void MultiCorePictureRenderer::init(SkPicture *pict, const SkString* writePath,
+ const SkString* mismatchPath, const SkString* inputFilename,
+ bool useChecksumBasedFilenames) {
// Set fPicture and the tiles.
- this->INHERITED::init(pict, outputDir, inputFilename, useChecksumBasedFilenames);
+ this->INHERITED::init(pict, writePath, mismatchPath, inputFilename, useChecksumBasedFilenames);
for (int i = 0; i < fNumThreads; ++i) {
*fCanvasPool.append() = this->setupCanvas(this->getTileWidth(), this->getTileHeight());
}
@@ -812,9 +819,9 @@
bool MultiCorePictureRenderer::render(SkBitmap** out) {
bool success = true;
- if (!fOutputDir.isEmpty()) {
+ if (!fWritePath.isEmpty() || !fMismatchPath.isEmpty()) {
for (int i = 0; i < fNumThreads-1; i++) {
- fCloneData[i]->setPathsAndSuccess(fOutputDir, fInputFilename, &success);
+ fCloneData[i]->setPathsAndSuccess(fWritePath, fMismatchPath, fInputFilename, &success);
}
}
@@ -912,7 +919,7 @@
SkData* data = SkPictureUtils::GatherPixelRefs(fPicture, bounds);
SkSafeUnref(data);
- return (fOutputDir.isEmpty()); // we don't have anything to write
+ return (fWritePath.isEmpty()); // we don't have anything to write
}
private:
@@ -935,7 +942,7 @@
SkSafeUnref(clone);
}
- return (fOutputDir.isEmpty()); // we don't have anything to write
+ return (fWritePath.isEmpty()); // we don't have anything to write
}
private: