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

Side by Side Diff: tools/PictureRenderer.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/PictureRenderer.h ('k') | tools/bbh_shootout.cpp » ('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 "PictureRenderer.h" 8 #include "PictureRenderer.h"
9 #include "picture_utils.h" 9 #include "picture_utils.h"
10 #include "SamplePipeControllers.h" 10 #include "SamplePipeControllers.h"
(...skipping 30 matching lines...) Expand all
41 return SkScalarLog(x) * log2_conversion_factor; 41 return SkScalarLog(x) * log2_conversion_factor;
42 } 42 }
43 43
44 namespace sk_tools { 44 namespace sk_tools {
45 45
46 enum { 46 enum {
47 kDefaultTileWidth = 256, 47 kDefaultTileWidth = 256,
48 kDefaultTileHeight = 256 48 kDefaultTileHeight = 256
49 }; 49 };
50 50
51 void PictureRenderer::init(SkPicture* pict, const SkString* outputDir, 51 void PictureRenderer::init(SkPicture* pict, const SkString* writePath, const SkS tring* mismatchPath,
52 const SkString* inputFilename, bool useChecksumBasedF ilenames) { 52 const SkString* inputFilename, bool useChecksumBasedF ilenames) {
53 this->CopyString(&fOutputDir, outputDir); 53 this->CopyString(&fWritePath, writePath);
54 this->CopyString(&fMismatchPath, mismatchPath);
54 this->CopyString(&fInputFilename, inputFilename); 55 this->CopyString(&fInputFilename, inputFilename);
55 fUseChecksumBasedFilenames = useChecksumBasedFilenames; 56 fUseChecksumBasedFilenames = useChecksumBasedFilenames;
56 57
57 SkASSERT(NULL == fPicture); 58 SkASSERT(NULL == fPicture);
58 SkASSERT(NULL == fCanvas.get()); 59 SkASSERT(NULL == fCanvas.get());
59 if (NULL != fPicture || NULL != fCanvas.get()) { 60 if (NULL != fPicture || NULL != fCanvas.get()) {
60 return; 61 return;
61 } 62 }
62 63
63 SkASSERT(pict != NULL); 64 SkASSERT(pict != NULL);
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 uint32_t PictureRenderer::recordFlags() { 259 uint32_t PictureRenderer::recordFlags() {
259 return (kNone_BBoxHierarchyType == fBBoxHierarchyType) 260 return (kNone_BBoxHierarchyType == fBBoxHierarchyType)
260 ? 0 261 ? 0
261 : SkPicture::kUsePathBoundsForClip_RecordingFlag; 262 : SkPicture::kUsePathBoundsForClip_RecordingFlag;
262 } 263 }
263 264
264 /** 265 /**
265 * Write the canvas to an image file and/or JSON summary. 266 * Write the canvas to an image file and/or JSON summary.
266 * 267 *
267 * @param canvas Must be non-null. Canvas to be written to a file. 268 * @param canvas Must be non-null. Canvas to be written to a file.
268 * @param outputDir If nonempty, write the binary image to a file within this di rectory; 269 * @param writePath If nonempty, write the binary image to a file within this di rectory.
269 * if empty, don't write out the image at all. 270 * @param mismatchPath If nonempty, write the binary image to a file within this directory,
271 * but only if the image does not match expectations.
270 * @param inputFilename If we are writing out a binary image, use this to build its filename. 272 * @param inputFilename If we are writing out a binary image, use this to build its filename.
271 * @param jsonSummaryPtr If not null, add image results (checksum) to this summa ry. 273 * @param jsonSummaryPtr If not null, add image results (checksum) to this summa ry.
272 * @param useChecksumBasedFilenames If true, use checksum-based filenames when w riting to disk. 274 * @param useChecksumBasedFilenames If true, use checksum-based filenames when w riting to disk.
273 * @param tileNumberPtr If not null, which tile number this image contains. 275 * @param tileNumberPtr If not null, which tile number this image contains.
274 * 276 *
275 * @return bool True if the operation completed successfully. 277 * @return bool True if the operation completed successfully.
276 */ 278 */
277 static bool write(SkCanvas* canvas, const SkString& outputDir, const SkString& i nputFilename, 279 static bool write(SkCanvas* canvas, const SkString& writePath, const SkString& m ismatchPath,
278 ImageResultsAndExpectations *jsonSummaryPtr, bool useChecksumB asedFilenames, 280 const SkString& inputFilename, ImageResultsAndExpectations *js onSummaryPtr,
279 const int* tileNumberPtr=NULL) { 281 bool useChecksumBasedFilenames, const int* tileNumberPtr=NULL) {
280 SkASSERT(canvas != NULL); 282 SkASSERT(canvas != NULL);
281 if (NULL == canvas) { 283 if (NULL == canvas) {
282 return false; 284 return false;
283 } 285 }
284 286
285 SkBitmap bitmap; 287 SkBitmap bitmap;
286 SkISize size = canvas->getDeviceSize(); 288 SkISize size = canvas->getDeviceSize();
287 setup_bitmap(&bitmap, size.width(), size.height()); 289 setup_bitmap(&bitmap, size.width(), size.height());
288 290
289 canvas->readPixels(&bitmap, 0, 0); 291 canvas->readPixels(&bitmap, 0, 0);
(...skipping 28 matching lines...) Expand all
318 if (outputSubdirPtr) { 320 if (outputSubdirPtr) {
319 outputRelativePath.set(outputSubdirPtr); 321 outputRelativePath.set(outputSubdirPtr);
320 outputRelativePath.append("/"); // always use "/", even on Windows 322 outputRelativePath.append("/"); // always use "/", even on Windows
321 outputRelativePath.append(outputFilename); 323 outputRelativePath.append(outputFilename);
322 } else { 324 } else {
323 outputRelativePath.set(outputFilename); 325 outputRelativePath.set(outputFilename);
324 } 326 }
325 327
326 jsonSummaryPtr->add(inputFilename.c_str(), outputRelativePath.c_str(), 328 jsonSummaryPtr->add(inputFilename.c_str(), outputRelativePath.c_str(),
327 *imageDigestPtr, tileNumberPtr); 329 *imageDigestPtr, tileNumberPtr);
330 if (!mismatchPath.isEmpty() &&
331 !jsonSummaryPtr->matchesExpectation(inputFilename.c_str(), *imageDig estPtr,
332 tileNumberPtr)) {
333 if (!write_bitmap_to_disk(bitmap, mismatchPath, outputSubdirPtr, out putFilename)) {
334 return false;
335 }
336 }
328 } 337 }
329 338
330 if (outputDir.isEmpty()) { 339 if (writePath.isEmpty()) {
331 return true; 340 return true;
341 } else {
342 return write_bitmap_to_disk(bitmap, writePath, outputSubdirPtr, outputFi lename);
332 } 343 }
333
334 SkString dirPath;
335 if (outputSubdirPtr) {
336 dirPath = SkOSPath::SkPathJoin(outputDir.c_str(), outputSubdirPtr);
337 sk_mkdir(dirPath.c_str());
338 } else {
339 dirPath.set(outputDir);
340 }
341 SkString fullPath = SkOSPath::SkPathJoin(dirPath.c_str(), outputFilename.c_s tr());
342 return SkImageEncoder::EncodeFile(fullPath.c_str(), bitmap, SkImageEncoder:: kPNG_Type, 100);
343 } 344 }
344 345
345 //////////////////////////////////////////////////////////////////////////////// /////////////// 346 //////////////////////////////////////////////////////////////////////////////// ///////////////
346 347
347 SkCanvas* RecordPictureRenderer::setupCanvas(int width, int height) { 348 SkCanvas* RecordPictureRenderer::setupCanvas(int width, int height) {
348 // defer the canvas setup until the render step 349 // defer the canvas setup until the render step
349 return NULL; 350 return NULL;
350 } 351 }
351 352
352 // the size_t* parameter is deprecated, so we ignore it 353 // the size_t* parameter is deprecated, so we ignore it
353 static SkData* encode_bitmap_to_data(size_t*, const SkBitmap& bm) { 354 static SkData* encode_bitmap_to_data(size_t*, const SkBitmap& bm) {
354 return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100); 355 return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100);
355 } 356 }
356 357
357 bool RecordPictureRenderer::render(SkBitmap** out) { 358 bool RecordPictureRenderer::render(SkBitmap** out) {
358 SkAutoTDelete<SkBBHFactory> factory(this->getFactory()); 359 SkAutoTDelete<SkBBHFactory> factory(this->getFactory());
359 SkPictureRecorder recorder; 360 SkPictureRecorder recorder;
360 SkCanvas* canvas = recorder.beginRecording(this->getViewWidth(), this->getVi ewHeight(), 361 SkCanvas* canvas = recorder.beginRecording(this->getViewWidth(), this->getVi ewHeight(),
361 factory.get(), 362 factory.get(),
362 this->recordFlags()); 363 this->recordFlags());
363 this->scaleToScaleFactor(canvas); 364 this->scaleToScaleFactor(canvas);
364 fPicture->draw(canvas); 365 fPicture->draw(canvas);
365 SkAutoTUnref<SkPicture> picture(recorder.endRecording()); 366 SkAutoTUnref<SkPicture> picture(recorder.endRecording());
366 if (!fOutputDir.isEmpty()) { 367 if (!fWritePath.isEmpty()) {
367 // Record the new picture as a new SKP with PNG encoded bitmaps. 368 // Record the new picture as a new SKP with PNG encoded bitmaps.
368 SkString skpPath = SkOSPath::SkPathJoin(fOutputDir.c_str(), fInputFilena me.c_str()); 369 SkString skpPath = SkOSPath::SkPathJoin(fWritePath.c_str(), fInputFilena me.c_str());
369 SkFILEWStream stream(skpPath.c_str()); 370 SkFILEWStream stream(skpPath.c_str());
370 picture->serialize(&stream, &encode_bitmap_to_data); 371 picture->serialize(&stream, &encode_bitmap_to_data);
371 return true; 372 return true;
372 } 373 }
373 return false; 374 return false;
374 } 375 }
375 376
376 SkString RecordPictureRenderer::getConfigNameInternal() { 377 SkString RecordPictureRenderer::getConfigNameInternal() {
377 return SkString("record"); 378 return SkString("record");
378 } 379 }
(...skipping 11 matching lines...) Expand all
390 SkGPipeWriter writer; 391 SkGPipeWriter writer;
391 SkCanvas* pipeCanvas = writer.startRecording(&pipeController); 392 SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
392 pipeCanvas->drawPicture(*fPicture); 393 pipeCanvas->drawPicture(*fPicture);
393 writer.endRecording(); 394 writer.endRecording();
394 fCanvas->flush(); 395 fCanvas->flush();
395 if (NULL != out) { 396 if (NULL != out) {
396 *out = SkNEW(SkBitmap); 397 *out = SkNEW(SkBitmap);
397 setup_bitmap(*out, fPicture->width(), fPicture->height()); 398 setup_bitmap(*out, fPicture->width(), fPicture->height());
398 fCanvas->readPixels(*out, 0, 0); 399 fCanvas->readPixels(*out, 0, 0);
399 } 400 }
400 return write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr, 401 return write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummar yPtr,
401 fUseChecksumBasedFilenames); 402 fUseChecksumBasedFilenames);
402 } 403 }
403 404
404 SkString PipePictureRenderer::getConfigNameInternal() { 405 SkString PipePictureRenderer::getConfigNameInternal() {
405 return SkString("pipe"); 406 return SkString("pipe");
406 } 407 }
407 408
408 //////////////////////////////////////////////////////////////////////////////// /////////////// 409 //////////////////////////////////////////////////////////////////////////////// ///////////////
409 410
410 void SimplePictureRenderer::init(SkPicture* picture, const SkString* outputDir, 411 void SimplePictureRenderer::init(SkPicture* picture, const SkString* writePath,
411 const SkString* inputFilename, bool useChecksum BasedFilenames) { 412 const SkString* mismatchPath, const SkString* i nputFilename,
412 INHERITED::init(picture, outputDir, inputFilename, useChecksumBasedFilenames ); 413 bool useChecksumBasedFilenames) {
414 INHERITED::init(picture, writePath, mismatchPath, inputFilename, useChecksum BasedFilenames);
413 this->buildBBoxHierarchy(); 415 this->buildBBoxHierarchy();
414 } 416 }
415 417
416 bool SimplePictureRenderer::render(SkBitmap** out) { 418 bool SimplePictureRenderer::render(SkBitmap** out) {
417 SkASSERT(fCanvas.get() != NULL); 419 SkASSERT(fCanvas.get() != NULL);
418 SkASSERT(NULL != fPicture); 420 SkASSERT(NULL != fPicture);
419 if (NULL == fCanvas.get() || NULL == fPicture) { 421 if (NULL == fCanvas.get() || NULL == fPicture) {
420 return false; 422 return false;
421 } 423 }
422 424
423 fCanvas->drawPicture(*fPicture); 425 fCanvas->drawPicture(*fPicture);
424 fCanvas->flush(); 426 fCanvas->flush();
425 if (NULL != out) { 427 if (NULL != out) {
426 *out = SkNEW(SkBitmap); 428 *out = SkNEW(SkBitmap);
427 setup_bitmap(*out, fPicture->width(), fPicture->height()); 429 setup_bitmap(*out, fPicture->width(), fPicture->height());
428 fCanvas->readPixels(*out, 0, 0); 430 fCanvas->readPixels(*out, 0, 0);
429 } 431 }
430 return write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr, 432 return write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJsonSummar yPtr,
431 fUseChecksumBasedFilenames); 433 fUseChecksumBasedFilenames);
432 } 434 }
433 435
434 SkString SimplePictureRenderer::getConfigNameInternal() { 436 SkString SimplePictureRenderer::getConfigNameInternal() {
435 return SkString("simple"); 437 return SkString("simple");
436 } 438 }
437 439
438 //////////////////////////////////////////////////////////////////////////////// /////////////// 440 //////////////////////////////////////////////////////////////////////////////// ///////////////
439 441
440 TiledPictureRenderer::TiledPictureRenderer() 442 TiledPictureRenderer::TiledPictureRenderer()
441 : fTileWidth(kDefaultTileWidth) 443 : fTileWidth(kDefaultTileWidth)
442 , fTileHeight(kDefaultTileHeight) 444 , fTileHeight(kDefaultTileHeight)
443 , fTileWidthPercentage(0.0) 445 , fTileWidthPercentage(0.0)
444 , fTileHeightPercentage(0.0) 446 , fTileHeightPercentage(0.0)
445 , fTileMinPowerOf2Width(0) 447 , fTileMinPowerOf2Width(0)
446 , fCurrentTileOffset(-1) 448 , fCurrentTileOffset(-1)
447 , fTilesX(0) 449 , fTilesX(0)
448 , fTilesY(0) { } 450 , fTilesY(0) { }
449 451
450 void TiledPictureRenderer::init(SkPicture* pict, const SkString* outputDir, 452 void TiledPictureRenderer::init(SkPicture* pict, const SkString* writePath,
451 const SkString* inputFilename, bool useChecksumB asedFilenames) { 453 const SkString* mismatchPath, const SkString* in putFilename,
454 bool useChecksumBasedFilenames) {
452 SkASSERT(NULL != pict); 455 SkASSERT(NULL != pict);
453 SkASSERT(0 == fTileRects.count()); 456 SkASSERT(0 == fTileRects.count());
454 if (NULL == pict || fTileRects.count() != 0) { 457 if (NULL == pict || fTileRects.count() != 0) {
455 return; 458 return;
456 } 459 }
457 460
458 // Do not call INHERITED::init(), which would create a (potentially large) c anvas which is not 461 // Do not call INHERITED::init(), which would create a (potentially large) c anvas which is not
459 // used by bench_pictures. 462 // used by bench_pictures.
460 fPicture.reset(pict)->ref(); 463 fPicture.reset(pict)->ref();
461 this->CopyString(&fOutputDir, outputDir); 464 this->CopyString(&fWritePath, writePath);
465 this->CopyString(&fMismatchPath, mismatchPath);
462 this->CopyString(&fInputFilename, inputFilename); 466 this->CopyString(&fInputFilename, inputFilename);
463 fUseChecksumBasedFilenames = useChecksumBasedFilenames; 467 fUseChecksumBasedFilenames = useChecksumBasedFilenames;
464 this->buildBBoxHierarchy(); 468 this->buildBBoxHierarchy();
465 469
466 if (fTileWidthPercentage > 0) { 470 if (fTileWidthPercentage > 0) {
467 fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->wi dth() / 100)); 471 fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->wi dth() / 100));
468 } 472 }
469 if (fTileHeightPercentage > 0) { 473 if (fTileHeightPercentage > 0) {
470 fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture-> height() / 100)); 474 fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture-> height() / 100));
471 } 475 }
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 633
630 SkBitmap bitmap; 634 SkBitmap bitmap;
631 if (out){ 635 if (out){
632 *out = SkNEW(SkBitmap); 636 *out = SkNEW(SkBitmap);
633 setup_bitmap(*out, fPicture->width(), fPicture->height()); 637 setup_bitmap(*out, fPicture->width(), fPicture->height());
634 setup_bitmap(&bitmap, fTileWidth, fTileHeight); 638 setup_bitmap(&bitmap, fTileWidth, fTileHeight);
635 } 639 }
636 bool success = true; 640 bool success = true;
637 for (int i = 0; i < fTileRects.count(); ++i) { 641 for (int i = 0; i < fTileRects.count(); ++i) {
638 draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture); 642 draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture);
639 success &= write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr, 643 success &= write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJs onSummaryPtr,
640 fUseChecksumBasedFilenames, &i); 644 fUseChecksumBasedFilenames, &i);
641 if (NULL != out) { 645 if (NULL != out) {
642 if (fCanvas->readPixels(&bitmap, 0, 0)) { 646 if (fCanvas->readPixels(&bitmap, 0, 0)) {
643 // Add this tile to the entire bitmap. 647 // Add this tile to the entire bitmap.
644 bitmapCopyAtOffset(bitmap, *out, SkScalarFloorToInt(fTileRects[i ].left()), 648 bitmapCopyAtOffset(bitmap, *out, SkScalarFloorToInt(fTileRects[i ].left()),
645 SkScalarFloorToInt(fTileRects[i].top())); 649 SkScalarFloorToInt(fTileRects[i].top()));
646 } else { 650 } else {
647 success = false; 651 success = false;
648 } 652 }
649 } 653 }
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
713 SkGraphics::SetTLSFontCacheLimit(1024 * 1024); 717 SkGraphics::SetTLSFontCacheLimit(1024 * 1024);
714 718
715 SkBitmap bitmap; 719 SkBitmap bitmap;
716 if (fBitmap != NULL) { 720 if (fBitmap != NULL) {
717 // All tiles are the same size. 721 // All tiles are the same size.
718 setup_bitmap(&bitmap, SkScalarFloorToInt(fRects[0].width()), SkScala rFloorToInt(fRects[0].height())); 722 setup_bitmap(&bitmap, SkScalarFloorToInt(fRects[0].width()), SkScala rFloorToInt(fRects[0].height()));
719 } 723 }
720 724
721 for (int i = fStart; i < fEnd; i++) { 725 for (int i = fStart; i < fEnd; i++) {
722 draw_tile_to_canvas(fCanvas, fRects[i], fClone); 726 draw_tile_to_canvas(fCanvas, fRects[i], fClone);
723 if (!write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr, 727 if (!write(fCanvas, fWritePath, fMismatchPath, fInputFilename, fJson SummaryPtr,
724 fUseChecksumBasedFilenames, &i) 728 fUseChecksumBasedFilenames, &i)
725 && fSuccess != NULL) { 729 && fSuccess != NULL) {
726 *fSuccess = false; 730 *fSuccess = false;
727 // If one tile fails to write to a file, do not continue drawing the rest. 731 // If one tile fails to write to a file, do not continue drawing the rest.
728 break; 732 break;
729 } 733 }
730 if (fBitmap != NULL) { 734 if (fBitmap != NULL) {
731 if (fCanvas->readPixels(&bitmap, 0, 0)) { 735 if (fCanvas->readPixels(&bitmap, 0, 0)) {
732 SkAutoLockPixels alp(*fBitmap); 736 SkAutoLockPixels alp(*fBitmap);
733 bitmapCopyAtOffset(bitmap, fBitmap, SkScalarFloorToInt(fRect s[i].left()), 737 bitmapCopyAtOffset(bitmap, fBitmap, SkScalarFloorToInt(fRect s[i].left()),
734 SkScalarFloorToInt(fRects[i].top())); 738 SkScalarFloorToInt(fRects[i].top()));
735 } else { 739 } else {
736 *fSuccess = false; 740 *fSuccess = false;
737 // If one tile fails to read pixels, do not continue drawing the rest. 741 // If one tile fails to read pixels, do not continue drawing the rest.
738 break; 742 break;
739 } 743 }
740 } 744 }
741 } 745 }
742 fDone->run(); 746 fDone->run();
743 } 747 }
744 748
745 void setPathsAndSuccess(const SkString& outputDir, const SkString& inputFile name, 749 void setPathsAndSuccess(const SkString& writePath, const SkString& mismatchP ath,
746 bool* success) { 750 const SkString& inputFilename, bool* success) {
747 fOutputDir.set(outputDir); 751 fWritePath.set(writePath);
752 fMismatchPath.set(mismatchPath);
748 fInputFilename.set(inputFilename); 753 fInputFilename.set(inputFilename);
749 fSuccess = success; 754 fSuccess = success;
750 } 755 }
751 756
752 void setBitmap(SkBitmap* bitmap) { 757 void setBitmap(SkBitmap* bitmap) {
753 fBitmap = bitmap; 758 fBitmap = bitmap;
754 } 759 }
755 760
756 private: 761 private:
757 // All pointers unowned. 762 // All pointers unowned.
758 SkPicture* fClone; // Picture to draw from. Each CloneData has a unique one which 763 SkPicture* fClone; // Picture to draw from. Each CloneData has a unique one which
759 // is threadsafe. 764 // is threadsafe.
760 SkCanvas* fCanvas; // Canvas to draw to. Reused for each tile. 765 SkCanvas* fCanvas; // Canvas to draw to. Reused for each tile.
761 SkString fOutputDir; // If not empty, write results into this dir ectory. 766 SkString fWritePath; // If not empty, write all results into this directory.
767 SkString fMismatchPath; // If not empty, write all unexpected res ults into this dir.
762 SkString fInputFilename; // Filename of input SkPicture file. 768 SkString fInputFilename; // Filename of input SkPicture file.
763 SkTDArray<SkRect>& fRects; // All tiles of the picture. 769 SkTDArray<SkRect>& fRects; // All tiles of the picture.
764 const int fStart; // Range of tiles drawn by this thread. 770 const int fStart; // Range of tiles drawn by this thread.
765 const int fEnd; 771 const int fEnd;
766 bool* fSuccess; // Only meaningful if path is non-null. Shar ed by all threads, 772 bool* fSuccess; // Only meaningful if path is non-null. Shar ed by all threads,
767 // and only set to false upon failure to wri te to a PNG. 773 // and only set to false upon failure to wri te to a PNG.
768 SkRunnable* fDone; 774 SkRunnable* fDone;
769 SkBitmap* fBitmap; 775 SkBitmap* fBitmap;
770 ImageResultsAndExpectations* fJsonSummaryPtr; 776 ImageResultsAndExpectations* fJsonSummaryPtr;
771 bool fUseChecksumBasedFilenames; 777 bool fUseChecksumBasedFilenames;
772 }; 778 };
773 779
774 MultiCorePictureRenderer::MultiCorePictureRenderer(int threadCount) 780 MultiCorePictureRenderer::MultiCorePictureRenderer(int threadCount)
775 : fNumThreads(threadCount) 781 : fNumThreads(threadCount)
776 , fThreadPool(threadCount) 782 , fThreadPool(threadCount)
777 , fCountdown(threadCount) { 783 , fCountdown(threadCount) {
778 // Only need to create fNumThreads - 1 clones, since one thread will use the base 784 // Only need to create fNumThreads - 1 clones, since one thread will use the base
779 // picture. 785 // picture.
780 fPictureClones = SkNEW_ARRAY(SkPicture, fNumThreads - 1); 786 fPictureClones = SkNEW_ARRAY(SkPicture, fNumThreads - 1);
781 fCloneData = SkNEW_ARRAY(CloneData*, fNumThreads); 787 fCloneData = SkNEW_ARRAY(CloneData*, fNumThreads);
782 } 788 }
783 789
784 void MultiCorePictureRenderer::init(SkPicture *pict, const SkString* outputDir, 790 void MultiCorePictureRenderer::init(SkPicture *pict, const SkString* writePath,
785 const SkString* inputFilename, bool useCheck sumBasedFilenames) { 791 const SkString* mismatchPath, const SkString * inputFilename,
792 bool useChecksumBasedFilenames) {
786 // Set fPicture and the tiles. 793 // Set fPicture and the tiles.
787 this->INHERITED::init(pict, outputDir, inputFilename, useChecksumBasedFilena mes); 794 this->INHERITED::init(pict, writePath, mismatchPath, inputFilename, useCheck sumBasedFilenames);
788 for (int i = 0; i < fNumThreads; ++i) { 795 for (int i = 0; i < fNumThreads; ++i) {
789 *fCanvasPool.append() = this->setupCanvas(this->getTileWidth(), this->ge tTileHeight()); 796 *fCanvasPool.append() = this->setupCanvas(this->getTileWidth(), this->ge tTileHeight());
790 } 797 }
791 // Only need to create fNumThreads - 1 clones, since one thread will use the base picture. 798 // Only need to create fNumThreads - 1 clones, since one thread will use the base picture.
792 fPicture->clone(fPictureClones, fNumThreads - 1); 799 fPicture->clone(fPictureClones, fNumThreads - 1);
793 // Populate each thread with the appropriate data. 800 // Populate each thread with the appropriate data.
794 // Group the tiles into nearly equal size chunks, rounding up so we're sure to cover them all. 801 // Group the tiles into nearly equal size chunks, rounding up so we're sure to cover them all.
795 const int chunkSize = (fTileRects.count() + fNumThreads - 1) / fNumThreads; 802 const int chunkSize = (fTileRects.count() + fNumThreads - 1) / fNumThreads;
796 803
797 for (int i = 0; i < fNumThreads; i++) { 804 for (int i = 0; i < fNumThreads; i++) {
798 SkPicture* pic; 805 SkPicture* pic;
799 if (i == fNumThreads-1) { 806 if (i == fNumThreads-1) {
800 // The last set will use the original SkPicture. 807 // The last set will use the original SkPicture.
801 pic = fPicture; 808 pic = fPicture;
802 } else { 809 } else {
803 pic = &fPictureClones[i]; 810 pic = &fPictureClones[i];
804 } 811 }
805 const int start = i * chunkSize; 812 const int start = i * chunkSize;
806 const int end = SkMin32(start + chunkSize, fTileRects.count()); 813 const int end = SkMin32(start + chunkSize, fTileRects.count());
807 fCloneData[i] = SkNEW_ARGS(CloneData, 814 fCloneData[i] = SkNEW_ARGS(CloneData,
808 (pic, fCanvasPool[i], fTileRects, start, end, &fCountdown, 815 (pic, fCanvasPool[i], fTileRects, start, end, &fCountdown,
809 fJsonSummaryPtr, useChecksumBasedFilenames)) ; 816 fJsonSummaryPtr, useChecksumBasedFilenames)) ;
810 } 817 }
811 } 818 }
812 819
813 bool MultiCorePictureRenderer::render(SkBitmap** out) { 820 bool MultiCorePictureRenderer::render(SkBitmap** out) {
814 bool success = true; 821 bool success = true;
815 if (!fOutputDir.isEmpty()) { 822 if (!fWritePath.isEmpty() || !fMismatchPath.isEmpty()) {
816 for (int i = 0; i < fNumThreads-1; i++) { 823 for (int i = 0; i < fNumThreads-1; i++) {
817 fCloneData[i]->setPathsAndSuccess(fOutputDir, fInputFilename, &succe ss); 824 fCloneData[i]->setPathsAndSuccess(fWritePath, fMismatchPath, fInputF ilename, &success);
818 } 825 }
819 } 826 }
820 827
821 if (NULL != out) { 828 if (NULL != out) {
822 *out = SkNEW(SkBitmap); 829 *out = SkNEW(SkBitmap);
823 setup_bitmap(*out, fPicture->width(), fPicture->height()); 830 setup_bitmap(*out, fPicture->width(), fPicture->height());
824 for (int i = 0; i < fNumThreads; i++) { 831 for (int i = 0; i < fNumThreads; i++) {
825 fCloneData[i]->setBitmap(*out); 832 fCloneData[i]->setBitmap(*out);
826 } 833 }
827 } else { 834 } else {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
905 /////////////////////////////////////////////////////////////////////////////// 912 ///////////////////////////////////////////////////////////////////////////////
906 913
907 class GatherRenderer : public PictureRenderer { 914 class GatherRenderer : public PictureRenderer {
908 public: 915 public:
909 virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE { 916 virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE {
910 SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->width()), 917 SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
911 SkIntToScalar(fPicture->height())); 918 SkIntToScalar(fPicture->height()));
912 SkData* data = SkPictureUtils::GatherPixelRefs(fPicture, bounds); 919 SkData* data = SkPictureUtils::GatherPixelRefs(fPicture, bounds);
913 SkSafeUnref(data); 920 SkSafeUnref(data);
914 921
915 return (fOutputDir.isEmpty()); // we don't have anything to write 922 return (fWritePath.isEmpty()); // we don't have anything to write
916 } 923 }
917 924
918 private: 925 private:
919 virtual SkString getConfigNameInternal() SK_OVERRIDE { 926 virtual SkString getConfigNameInternal() SK_OVERRIDE {
920 return SkString("gather_pixelrefs"); 927 return SkString("gather_pixelrefs");
921 } 928 }
922 }; 929 };
923 930
924 PictureRenderer* CreateGatherPixelRefsRenderer() { 931 PictureRenderer* CreateGatherPixelRefsRenderer() {
925 return SkNEW(GatherRenderer); 932 return SkNEW(GatherRenderer);
926 } 933 }
927 934
928 /////////////////////////////////////////////////////////////////////////////// 935 ///////////////////////////////////////////////////////////////////////////////
929 936
930 class PictureCloneRenderer : public PictureRenderer { 937 class PictureCloneRenderer : public PictureRenderer {
931 public: 938 public:
932 virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE { 939 virtual bool render(SkBitmap** out = NULL) SK_OVERRIDE {
933 for (int i = 0; i < 100; ++i) { 940 for (int i = 0; i < 100; ++i) {
934 SkPicture* clone = fPicture->clone(); 941 SkPicture* clone = fPicture->clone();
935 SkSafeUnref(clone); 942 SkSafeUnref(clone);
936 } 943 }
937 944
938 return (fOutputDir.isEmpty()); // we don't have anything to write 945 return (fWritePath.isEmpty()); // we don't have anything to write
939 } 946 }
940 947
941 private: 948 private:
942 virtual SkString getConfigNameInternal() SK_OVERRIDE { 949 virtual SkString getConfigNameInternal() SK_OVERRIDE {
943 return SkString("picture_clone"); 950 return SkString("picture_clone");
944 } 951 }
945 }; 952 };
946 953
947 PictureRenderer* CreatePictureCloneRenderer() { 954 PictureRenderer* CreatePictureCloneRenderer() {
948 return SkNEW(PictureCloneRenderer); 955 return SkNEW(PictureCloneRenderer);
949 } 956 }
950 957
951 } // namespace sk_tools 958 } // namespace sk_tools
OLDNEW
« no previous file with comments | « tools/PictureRenderer.h ('k') | tools/bbh_shootout.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698