Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(162)

Side by Side Diff: tools/render_pictures_main.cpp

Issue 283123002: render_pictures: add --mismatchPath flag (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix SkDebuggerGUI Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « tools/picture_utils.cpp ('k') | tools/tests/base_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2012 Google Inc. 2 * Copyright 2012 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 #include "LazyDecodeBitmap.h" 8 #include "LazyDecodeBitmap.h"
9 #include "CopyTilesRenderer.h" 9 #include "CopyTilesRenderer.h"
10 #include "SkBitmap.h" 10 #include "SkBitmap.h"
(...skipping 13 matching lines...) Expand all
24 #include "PictureRenderer.h" 24 #include "PictureRenderer.h"
25 #include "PictureRenderingFlags.h" 25 #include "PictureRenderingFlags.h"
26 #include "picture_utils.h" 26 #include "picture_utils.h"
27 27
28 // Flags used by this file, alphabetically: 28 // Flags used by this file, alphabetically:
29 DEFINE_int32(clone, 0, "Clone the picture n times before rendering."); 29 DEFINE_int32(clone, 0, "Clone the picture n times before rendering.");
30 DECLARE_bool(deferImageDecoding); 30 DECLARE_bool(deferImageDecoding);
31 DEFINE_int32(maxComponentDiff, 256, "Maximum diff on a component, 0 - 256. Compo nents that differ " 31 DEFINE_int32(maxComponentDiff, 256, "Maximum diff on a component, 0 - 256. Compo nents that differ "
32 "by more than this amount are considered errors, though all diffs a re reported. " 32 "by more than this amount are considered errors, though all diffs a re reported. "
33 "Requires --validate."); 33 "Requires --validate.");
34 DEFINE_string(mismatchPath, "", "Write images for tests that failed due to "
35 "pixel mismatches into this directory.");
34 DEFINE_string(readJsonSummaryPath, "", "JSON file to read image expectations fro m."); 36 DEFINE_string(readJsonSummaryPath, "", "JSON file to read image expectations fro m.");
35 DECLARE_string(readPath); 37 DECLARE_string(readPath);
36 DEFINE_bool(writeChecksumBasedFilenames, false, 38 DEFINE_bool(writeChecksumBasedFilenames, false,
37 "When writing out images, use checksum-based filenames."); 39 "When writing out images, use checksum-based filenames.");
38 DEFINE_bool(writeEncodedImages, false, "Any time the skp contains an encoded ima ge, write it to a " 40 DEFINE_bool(writeEncodedImages, false, "Any time the skp contains an encoded ima ge, write it to a "
39 "file rather than decoding it. Requires writePath to be set. Skips d rawing the full " 41 "file rather than decoding it. Requires writePath to be set. Skips d rawing the full "
40 "skp to a file. Not compatible with deferImageDecoding."); 42 "skp to a file. Not compatible with deferImageDecoding.");
41 DEFINE_string(writeJsonSummaryPath, "", "File to write a JSON summary of image r esults to."); 43 DEFINE_string(writeJsonSummaryPath, "", "File to write a JSON summary of image r esults to.");
42 DEFINE_string2(writePath, w, "", "Directory to write the rendered images into.") ; 44 DEFINE_string2(writePath, w, "", "Directory to write the rendered images into.") ;
43 DEFINE_bool(writeWholeImage, false, "In tile mode, write the entire rendered ima ge to a " 45 DEFINE_bool(writeWholeImage, false, "In tile mode, write the entire rendered ima ge to a "
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 // Put in a dummy bitmap. 132 // Put in a dummy bitmap.
131 return SkImageDecoder::DecodeStream(&memStream, bitmap, SkBitmap::kNo_Config , 133 return SkImageDecoder::DecodeStream(&memStream, bitmap, SkBitmap::kNo_Config ,
132 SkImageDecoder::kDecodeBounds_Mode); 134 SkImageDecoder::kDecodeBounds_Mode);
133 } 135 }
134 136
135 //////////////////////////////////////////////////////////////////////////////// //////////////////// 137 //////////////////////////////////////////////////////////////////////////////// ////////////////////
136 138
137 /** 139 /**
138 * Called only by render_picture(). 140 * Called only by render_picture().
139 */ 141 */
140 static bool render_picture_internal(const SkString& inputPath, const SkString* o utputDir, 142 static bool render_picture_internal(const SkString& inputPath, const SkString* w ritePath,
143 const SkString* mismatchPath,
141 sk_tools::PictureRenderer& renderer, 144 sk_tools::PictureRenderer& renderer,
142 SkBitmap** out) { 145 SkBitmap** out) {
143 SkString inputFilename; 146 SkString inputFilename;
144 sk_tools::get_basename(&inputFilename, inputPath); 147 sk_tools::get_basename(&inputFilename, inputPath);
145 SkString outputDirString; 148 SkString writePathString;
146 if (NULL != outputDir && outputDir->size() > 0 && !FLAGS_writeEncodedImages) { 149 if (NULL != writePath && writePath->size() > 0 && !FLAGS_writeEncodedImages) {
147 outputDirString.set(*outputDir); 150 writePathString.set(*writePath);
151 }
152 SkString mismatchPathString;
153 if (NULL != mismatchPath && mismatchPath->size() > 0) {
154 mismatchPathString.set(*mismatchPath);
148 } 155 }
149 156
150 SkFILEStream inputStream; 157 SkFILEStream inputStream;
151 inputStream.setPath(inputPath.c_str()); 158 inputStream.setPath(inputPath.c_str());
152 if (!inputStream.isValid()) { 159 if (!inputStream.isValid()) {
153 SkDebugf("Could not open file %s\n", inputPath.c_str()); 160 SkDebugf("Could not open file %s\n", inputPath.c_str());
154 return false; 161 return false;
155 } 162 }
156 163
157 SkPicture::InstallPixelRefProc proc; 164 SkPicture::InstallPixelRefProc proc;
(...skipping 24 matching lines...) Expand all
182 189
183 for (int i = 0; i < FLAGS_clone; ++i) { 190 for (int i = 0; i < FLAGS_clone; ++i) {
184 SkPicture* clone = picture->clone(); 191 SkPicture* clone = picture->clone();
185 SkDELETE(picture); 192 SkDELETE(picture);
186 picture = clone; 193 picture = clone;
187 } 194 }
188 195
189 SkDebugf("drawing... [%i %i] %s\n", picture->width(), picture->height(), 196 SkDebugf("drawing... [%i %i] %s\n", picture->width(), picture->height(),
190 inputPath.c_str()); 197 inputPath.c_str());
191 198
192 renderer.init(picture, &outputDirString, &inputFilename, FLAGS_writeChecksum BasedFilenames); 199 renderer.init(picture, &writePathString, &mismatchPathString, &inputFilename ,
200 FLAGS_writeChecksumBasedFilenames);
193 201
194 if (FLAGS_preprocess) { 202 if (FLAGS_preprocess) {
195 if (NULL != renderer.getCanvas()) { 203 if (NULL != renderer.getCanvas()) {
196 renderer.getCanvas()->EXPERIMENTAL_optimize(renderer.getPicture()); 204 renderer.getCanvas()->EXPERIMENTAL_optimize(renderer.getPicture());
197 } 205 }
198 } 206 }
199 207
200 renderer.setup(); 208 renderer.setup();
201 209
202 bool success = renderer.render(out); 210 bool success = renderer.render(out);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
239 fRenderer->setBBoxHierarchyType(fSavedBbhType); 247 fRenderer->setBBoxHierarchyType(fSavedBbhType);
240 } 248 }
241 } 249 }
242 250
243 private: 251 private:
244 sk_tools::PictureRenderer* fRenderer; 252 sk_tools::PictureRenderer* fRenderer;
245 sk_tools::PictureRenderer::BBoxHierarchyType fSavedBbhType; 253 sk_tools::PictureRenderer::BBoxHierarchyType fSavedBbhType;
246 }; 254 };
247 255
248 /** 256 /**
249 * Render the SKP file(s) within inputPath, writing their bitmap images into out putDir. 257 * Render the SKP file(s) within inputPath.
250 * 258 *
251 * @param inputPath path to an individual SKP file, or a directory of SKP files 259 * @param inputPath path to an individual SKP file, or a directory of SKP files
252 * @param outputDir if not NULL, write the image(s) generated into this director y 260 * @param writePath if not NULL, write all image(s) generated into this director y
261 * @param mismatchPath if not NULL, write any image(s) not matching expectations into this directory
253 * @param renderer PictureRenderer to use to render the SKPs 262 * @param renderer PictureRenderer to use to render the SKPs
254 * @param jsonSummaryPtr if not NULL, add the image(s) generated to this summary 263 * @param jsonSummaryPtr if not NULL, add the image(s) generated to this summary
255 */ 264 */
256 static bool render_picture(const SkString& inputPath, const SkString* outputDir, 265 static bool render_picture(const SkString& inputPath, const SkString* writePath,
257 sk_tools::PictureRenderer& renderer, 266 const SkString* mismatchPath, sk_tools::PictureRender er& renderer,
258 sk_tools::ImageResultsAndExpectations *jsonSummaryPtr ) { 267 sk_tools::ImageResultsAndExpectations *jsonSummaryPtr ) {
259 int diffs[256] = {0}; 268 int diffs[256] = {0};
260 SkBitmap* bitmap = NULL; 269 SkBitmap* bitmap = NULL;
261 renderer.setJsonSummaryPtr(jsonSummaryPtr); 270 renderer.setJsonSummaryPtr(jsonSummaryPtr);
262 bool success = render_picture_internal(inputPath, 271 bool success = render_picture_internal(inputPath,
263 FLAGS_writeWholeImage ? NULL : outputDir, 272 FLAGS_writeWholeImage ? NULL : writePath,
273 FLAGS_writeWholeImage ? NULL : mismatchPath,
264 renderer, 274 renderer,
265 FLAGS_validate || FLAGS_writeWholeImage ? &bitmap : NULL); 275 FLAGS_validate || FLAGS_writeWholeImage ? &bitmap : NULL);
266 276
267 if (!success || ((FLAGS_validate || FLAGS_writeWholeImage) && bitmap == NULL )) { 277 if (!success || ((FLAGS_validate || FLAGS_writeWholeImage) && bitmap == NULL )) {
268 SkDebugf("Failed to draw the picture.\n"); 278 SkDebugf("Failed to draw the picture.\n");
269 SkDELETE(bitmap); 279 SkDELETE(bitmap);
270 return false; 280 return false;
271 } 281 }
272 282
273 if (FLAGS_validate) { 283 if (FLAGS_validate) {
274 SkBitmap* referenceBitmap = NULL; 284 SkBitmap* referenceBitmap = NULL;
275 sk_tools::PictureRenderer* referenceRenderer; 285 sk_tools::PictureRenderer* referenceRenderer;
276 // If the renderer uses a BBoxHierarchy, then the reference renderer 286 // If the renderer uses a BBoxHierarchy, then the reference renderer
277 // will be the same renderer, without the bbh. 287 // will be the same renderer, without the bbh.
278 AutoRestoreBbhType arbbh; 288 AutoRestoreBbhType arbbh;
279 if (sk_tools::PictureRenderer::kNone_BBoxHierarchyType != 289 if (sk_tools::PictureRenderer::kNone_BBoxHierarchyType !=
280 renderer.getBBoxHierarchyType()) { 290 renderer.getBBoxHierarchyType()) {
281 referenceRenderer = &renderer; 291 referenceRenderer = &renderer;
282 referenceRenderer->ref(); // to match auto unref below 292 referenceRenderer->ref(); // to match auto unref below
283 arbbh.set(referenceRenderer, sk_tools::PictureRenderer::kNone_BBoxHi erarchyType); 293 arbbh.set(referenceRenderer, sk_tools::PictureRenderer::kNone_BBoxHi erarchyType);
284 } else { 294 } else {
285 referenceRenderer = SkNEW(sk_tools::SimplePictureRenderer); 295 referenceRenderer = SkNEW(sk_tools::SimplePictureRenderer);
286 } 296 }
287 SkAutoTUnref<sk_tools::PictureRenderer> aurReferenceRenderer(referenceRe nderer); 297 SkAutoTUnref<sk_tools::PictureRenderer> aurReferenceRenderer(referenceRe nderer);
288 298
289 success = render_picture_internal(inputPath, NULL, *referenceRenderer, 299 success = render_picture_internal(inputPath, NULL, NULL, *referenceRende rer,
290 &referenceBitmap); 300 &referenceBitmap);
291 301
292 if (!success || NULL == referenceBitmap || NULL == referenceBitmap->getP ixels()) { 302 if (!success || NULL == referenceBitmap || NULL == referenceBitmap->getP ixels()) {
293 SkDebugf("Failed to draw the reference picture.\n"); 303 SkDebugf("Failed to draw the reference picture.\n");
294 SkDELETE(bitmap); 304 SkDELETE(bitmap);
295 SkDELETE(referenceBitmap); 305 SkDELETE(referenceBitmap);
296 return false; 306 return false;
297 } 307 }
298 308
299 if (success && (bitmap->width() != referenceBitmap->width())) { 309 if (success && (bitmap->width() != referenceBitmap->width())) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
335 for (int i = 1; i <= 255; ++i) { 345 for (int i = 1; i <= 255; ++i) {
336 if(diffs[i] > 0) { 346 if(diffs[i] > 0) {
337 SkDebugf("Number of pixels with max diff of %i is %i\n", i, diff s[i]); 347 SkDebugf("Number of pixels with max diff of %i is %i\n", i, diff s[i]);
338 } 348 }
339 } 349 }
340 } 350 }
341 351
342 if (FLAGS_writeWholeImage) { 352 if (FLAGS_writeWholeImage) {
343 sk_tools::force_all_opaque(*bitmap); 353 sk_tools::force_all_opaque(*bitmap);
344 354
345 SkString inputFilename, outputPath; 355 SkString inputFilename;
346 sk_tools::get_basename(&inputFilename, inputPath); 356 sk_tools::get_basename(&inputFilename, inputPath);
347 sk_tools::make_filepath(&outputPath, *outputDir, inputFilename); 357 SkString outputFilename(inputFilename);
348 sk_tools::replace_char(&outputPath, '.', '_'); 358 sk_tools::replace_char(&outputFilename, '.', '_');
349 outputPath.append(".png"); 359 outputFilename.append(".png");
350 360
351 if (NULL != jsonSummaryPtr) { 361 if (NULL != jsonSummaryPtr) {
352 sk_tools::ImageDigest imageDigest(*bitmap); 362 sk_tools::ImageDigest imageDigest(*bitmap);
353 SkString outputFileBasename; 363 jsonSummaryPtr->add(inputFilename.c_str(), outputFilename.c_str(), i mageDigest);
354 sk_tools::get_basename(&outputFileBasename, outputPath); 364 if ((NULL != mismatchPath) && !mismatchPath->isEmpty() &&
355 jsonSummaryPtr->add(inputFilename.c_str(), outputFileBasename.c_str( ), imageDigest); 365 !jsonSummaryPtr->matchesExpectation(inputFilename.c_str(), image Digest)) {
366 success &= sk_tools::write_bitmap_to_disk(*bitmap, *mismatchPath , NULL,
367 outputFilename);
368 }
356 } 369 }
357 370
358 if (NULL != outputDir) { 371 if ((NULL != writePath) && !writePath->isEmpty()) {
359 if (!SkImageEncoder::EncodeFile(outputPath.c_str(), *bitmap, 372 success &= sk_tools::write_bitmap_to_disk(*bitmap, *writePath, NULL, outputFilename);
360 SkImageEncoder::kPNG_Type, 100)) {
361 SkDebugf("Failed to draw the picture.\n");
362 success = false;
363 }
364 } 373 }
365 } 374 }
366 SkDELETE(bitmap); 375 SkDELETE(bitmap);
367 376
368 return success; 377 return success;
369 } 378 }
370 379
371 380
372 static int process_input(const char* input, const SkString* outputDir, 381 static int process_input(const char* input, const SkString* writePath,
373 sk_tools::PictureRenderer& renderer, 382 const SkString* mismatchPath, sk_tools::PictureRenderer & renderer,
374 sk_tools::ImageResultsAndExpectations *jsonSummaryPtr) { 383 sk_tools::ImageResultsAndExpectations *jsonSummaryPtr) {
375 SkOSFile::Iter iter(input, "skp"); 384 SkOSFile::Iter iter(input, "skp");
376 SkString inputFilename; 385 SkString inputFilename;
377 int failures = 0; 386 int failures = 0;
378 SkDebugf("process_input, %s\n", input); 387 SkDebugf("process_input, %s\n", input);
379 if (iter.next(&inputFilename)) { 388 if (iter.next(&inputFilename)) {
380 do { 389 do {
381 SkString inputPath; 390 SkString inputPath;
382 SkString inputAsSkString(input); 391 SkString inputAsSkString(input);
383 sk_tools::make_filepath(&inputPath, inputAsSkString, inputFilename); 392 sk_tools::make_filepath(&inputPath, inputAsSkString, inputFilename);
384 if (!render_picture(inputPath, outputDir, renderer, jsonSummaryPtr)) { 393 if (!render_picture(inputPath, writePath, mismatchPath, renderer, js onSummaryPtr)) {
385 ++failures; 394 ++failures;
386 } 395 }
387 } while(iter.next(&inputFilename)); 396 } while(iter.next(&inputFilename));
388 } else if (SkStrEndsWith(input, ".skp")) { 397 } else if (SkStrEndsWith(input, ".skp")) {
389 SkString inputPath(input); 398 SkString inputPath(input);
390 if (!render_picture(inputPath, outputDir, renderer, jsonSummaryPtr)) { 399 if (!render_picture(inputPath, writePath, mismatchPath, renderer, jsonSu mmaryPtr)) {
391 ++failures; 400 ++failures;
392 } 401 }
393 } else { 402 } else {
394 SkString warning; 403 SkString warning;
395 warning.printf("Warning: skipping %s\n", input); 404 warning.printf("Warning: skipping %s\n", input);
396 SkDebugf(warning.c_str()); 405 SkDebugf(warning.c_str());
397 } 406 }
398 return failures; 407 return failures;
399 } 408 }
400 409
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 if (errorString.size() > 0) { 449 if (errorString.size() > 0) {
441 SkDebugf("%s\n", errorString.c_str()); 450 SkDebugf("%s\n", errorString.c_str());
442 } 451 }
443 452
444 if (renderer.get() == NULL) { 453 if (renderer.get() == NULL) {
445 exit(-1); 454 exit(-1);
446 } 455 }
447 456
448 SkAutoGraphics ag; 457 SkAutoGraphics ag;
449 458
450 SkString outputDir; 459 SkString writePath;
451 if (FLAGS_writePath.count() == 1) { 460 if (FLAGS_writePath.count() == 1) {
452 outputDir.set(FLAGS_writePath[0]); 461 writePath.set(FLAGS_writePath[0]);
462 }
463 SkString mismatchPath;
464 if (FLAGS_mismatchPath.count() == 1) {
465 mismatchPath.set(FLAGS_mismatchPath[0]);
453 } 466 }
454 sk_tools::ImageResultsAndExpectations jsonSummary; 467 sk_tools::ImageResultsAndExpectations jsonSummary;
455 sk_tools::ImageResultsAndExpectations* jsonSummaryPtr = NULL; 468 sk_tools::ImageResultsAndExpectations* jsonSummaryPtr = NULL;
456 if (FLAGS_writeJsonSummaryPath.count() == 1) { 469 if (FLAGS_writeJsonSummaryPath.count() == 1) {
457 jsonSummaryPtr = &jsonSummary; 470 jsonSummaryPtr = &jsonSummary;
458 if (FLAGS_readJsonSummaryPath.count() == 1) { 471 if (FLAGS_readJsonSummaryPath.count() == 1) {
459 SkASSERT(jsonSummary.readExpectationsFile(FLAGS_readJsonSummaryPath[ 0])); 472 SkASSERT(jsonSummary.readExpectationsFile(FLAGS_readJsonSummaryPath[ 0]));
460 } 473 }
461 } 474 }
462 475
463 int failures = 0; 476 int failures = 0;
464 for (int i = 0; i < FLAGS_readPath.count(); i ++) { 477 for (int i = 0; i < FLAGS_readPath.count(); i ++) {
465 failures += process_input(FLAGS_readPath[i], &outputDir, *renderer.get() , jsonSummaryPtr); 478 failures += process_input(FLAGS_readPath[i], &writePath, &mismatchPath, *renderer.get(),
479 jsonSummaryPtr);
466 } 480 }
467 if (failures != 0) { 481 if (failures != 0) {
468 SkDebugf("Failed to render %i pictures.\n", failures); 482 SkDebugf("Failed to render %i pictures.\n", failures);
469 return 1; 483 return 1;
470 } 484 }
471 #if SK_SUPPORT_GPU 485 #if SK_SUPPORT_GPU
472 #if GR_CACHE_STATS 486 #if GR_CACHE_STATS
473 if (renderer->isUsingGpuDevice()) { 487 if (renderer->isUsingGpuDevice()) {
474 GrContext* ctx = renderer->getGrContext(); 488 GrContext* ctx = renderer->getGrContext();
475 ctx->printCacheStats(); 489 ctx->printCacheStats();
476 #ifdef SK_DEVELOPER 490 #ifdef SK_DEVELOPER
477 ctx->dumpFontCache(); 491 ctx->dumpFontCache();
478 #endif 492 #endif
479 } 493 }
480 #endif 494 #endif
481 #endif 495 #endif
482 if (FLAGS_writeJsonSummaryPath.count() == 1) { 496 if (FLAGS_writeJsonSummaryPath.count() == 1) {
483 jsonSummary.writeToFile(FLAGS_writeJsonSummaryPath[0]); 497 jsonSummary.writeToFile(FLAGS_writeJsonSummaryPath[0]);
484 } 498 }
485 return 0; 499 return 0;
486 } 500 }
487 501
488 #if !defined SK_BUILD_FOR_IOS 502 #if !defined SK_BUILD_FOR_IOS
489 int main(int argc, char * const argv[]) { 503 int main(int argc, char * const argv[]) {
490 return tool_main(argc, (char**) argv); 504 return tool_main(argc, (char**) argv);
491 } 505 }
492 #endif 506 #endif
OLDNEW
« no previous file with comments | « tools/picture_utils.cpp ('k') | tools/tests/base_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698