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

Side by Side Diff: tools/PictureRenderer.cpp

Issue 202983003: add --writeChecksumBasedFilenames flag to render_pictures (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix SkDebugger build Created 6 years, 9 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
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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 }; 51 };
52 52
53 /* TODO(epoger): These constants are already maintained in 2 other places: 53 /* TODO(epoger): These constants are already maintained in 2 other places:
54 * gm/gm_json.py and gm/gm_expectations.cpp. We shouldn't add yet a third place . 54 * gm/gm_json.py and gm/gm_expectations.cpp. We shouldn't add yet a third place .
55 * Figure out a way to share the definitions instead. 55 * Figure out a way to share the definitions instead.
56 */ 56 */
57 const static char kJsonKey_ActualResults[] = "actual-results"; 57 const static char kJsonKey_ActualResults[] = "actual-results";
58 const static char kJsonKey_ActualResults_NoComparison[] = "no-comparison"; 58 const static char kJsonKey_ActualResults_NoComparison[] = "no-comparison";
59 const static char kJsonKey_Hashtype_Bitmap_64bitMD5[] = "bitmap-64bitMD5"; 59 const static char kJsonKey_Hashtype_Bitmap_64bitMD5[] = "bitmap-64bitMD5";
60 60
61 void ImageResultsSummary::add(const char *testName, const SkBitmap& bitmap) { 61 void ImageResultsSummary::add(const char *testName, uint64_t hash) {
62 uint64_t hash;
63 SkAssertResult(SkBitmapHasher::ComputeDigest(bitmap, &hash));
64 Json::Value jsonTypeValuePair; 62 Json::Value jsonTypeValuePair;
65 jsonTypeValuePair.append(Json::Value(kJsonKey_Hashtype_Bitmap_64bitMD5)); 63 jsonTypeValuePair.append(Json::Value(kJsonKey_Hashtype_Bitmap_64bitMD5));
66 jsonTypeValuePair.append(Json::UInt64(hash)); 64 jsonTypeValuePair.append(Json::UInt64(hash));
67 fActualResultsNoComparison[testName] = jsonTypeValuePair; 65 fActualResultsNoComparison[testName] = jsonTypeValuePair;
68 } 66 }
69 67
68 void ImageResultsSummary::add(const char *testName, const SkBitmap& bitmap) {
69 uint64_t hash;
70 SkAssertResult(SkBitmapHasher::ComputeDigest(bitmap, &hash));
robertphillips 2014/03/19 14:42:36 this->
robertphillips1 2014/03/19 14:44:15 this->
epoger 2014/03/19 15:20:29 Done.
71 add(testName, hash);
72 }
73
70 void ImageResultsSummary::writeToFile(const char *filename) { 74 void ImageResultsSummary::writeToFile(const char *filename) {
71 Json::Value actualResults; 75 Json::Value actualResults;
72 actualResults[kJsonKey_ActualResults_NoComparison] = fActualResultsNoCompari son; 76 actualResults[kJsonKey_ActualResults_NoComparison] = fActualResultsNoCompari son;
73 Json::Value root; 77 Json::Value root;
74 root[kJsonKey_ActualResults] = actualResults; 78 root[kJsonKey_ActualResults] = actualResults;
75 std::string jsonStdString = root.toStyledString(); 79 std::string jsonStdString = root.toStyledString();
76 SkFILEWStream stream(filename); 80 SkFILEWStream stream(filename);
77 stream.write(jsonStdString.c_str(), jsonStdString.length()); 81 stream.write(jsonStdString.c_str(), jsonStdString.length());
78 } 82 }
79 83
80 void PictureRenderer::init(SkPicture* pict) { 84 void PictureRenderer::init(SkPicture* pict, const SkString& outputDir,
85 const SkString& inputFilename, bool useChecksumBasedF ilenames) {
86 fOutputDir.set(outputDir);
87 fInputFilename.set(inputFilename);
88 fUseChecksumBasedFilenames = useChecksumBasedFilenames;
89
81 SkASSERT(NULL == fPicture); 90 SkASSERT(NULL == fPicture);
82 SkASSERT(NULL == fCanvas.get()); 91 SkASSERT(NULL == fCanvas.get());
83 if (fPicture != NULL || NULL != fCanvas.get()) { 92 if (fPicture != NULL || NULL != fCanvas.get()) {
84 return; 93 return;
85 } 94 }
86 95
87 SkASSERT(pict != NULL); 96 SkASSERT(pict != NULL);
88 if (NULL == pict) { 97 if (NULL == pict) {
89 return; 98 return;
90 } 99 }
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 } 283 }
275 284
276 uint32_t PictureRenderer::recordFlags() { 285 uint32_t PictureRenderer::recordFlags() {
277 return ((kNone_BBoxHierarchyType == fBBoxHierarchyType) ? 0 : 286 return ((kNone_BBoxHierarchyType == fBBoxHierarchyType) ? 0 :
278 SkPicture::kOptimizeForClippedPlayback_RecordingFlag) | 287 SkPicture::kOptimizeForClippedPlayback_RecordingFlag) |
279 SkPicture::kUsePathBoundsForClip_RecordingFlag; 288 SkPicture::kUsePathBoundsForClip_RecordingFlag;
280 } 289 }
281 290
282 /** 291 /**
283 * Write the canvas to the specified path. 292 * Write the canvas to the specified path.
293 *
284 * @param canvas Must be non-null. Canvas to be written to a file. 294 * @param canvas Must be non-null. Canvas to be written to a file.
285 * @param path Path for the file to be written. Should have no extension; write( ) will append 295 * @param outputDir If nonempty, write the binary image to a file within this di rectory.
286 * an appropriate one. Passed in by value so it can be modified. 296 * @param inputFilename If we are writing out a binary image, use this to build its filename.
287 * @param jsonSummaryPtr If not null, add image results to this summary. 297 * @param jsonSummaryPtr If not null, add image results to this summary.
298 * @param useChecksumBasedFilenames If true, use checksum-based filenames when w riting to disk.
299 * @param numberToAppend If not null, append this number to the filename.
288 * @return bool True if the Canvas is written to a file. 300 * @return bool True if the Canvas is written to a file.
289 * 301 *
290 * TODO(epoger): Right now, all canvases must pass through this function in orde r to be appended 302 * TODO(epoger): Right now, all canvases must pass through this function in orde r to be appended
291 * to the ImageResultsSummary. We need some way to add bitmaps to the ImageResu ltsSummary 303 * to the ImageResultsSummary. We need some way to add bitmaps to the ImageResu ltsSummary
292 * even if --writePath has not been specified (and thus this function is not cal led). 304 * even if --writePath has not been specified (and thus this function is not cal led).
293 * 305 *
294 * One fix would be to pass in these path elements separately, and allow this fu nction to be 306 * One fix would be to pass in these path elements separately, and allow this fu nction to be
295 * called even if --writePath was not specified... 307 * called even if --writePath was not specified...
296 * const char *outputDir // NULL if we don't want to write image files to dis k 308 * const char *outputDir // NULL if we don't want to write image files to dis k
297 * const char *filename // name we use within JSON summary, and as the filen ame within outputDir 309 * const char *filename // name we use within JSON summary, and as the filen ame within outputDir
310 *
311 * UPDATE: Now that outputDir and inputFilename are passed separately, we should be able to do that.
298 */ 312 */
robertphillips1 2014/03/19 14:44:15 Write
epoger 2014/03/19 15:20:29 I think the function name is already consistent wi
robertphillips 2014/03/19 16:06:50 Ah yes (thought it was class scoped for no good re
299 static bool write(SkCanvas* canvas, const SkString* path, ImageResultsSummary *j sonSummaryPtr) { 313 static bool write(SkCanvas* canvas, const SkString& outputDir, const SkString& i nputFilename,
314 ImageResultsSummary *jsonSummaryPtr, bool useChecksumBasedFile names,
315 const int* numberToAppend=NULL) {
300 SkASSERT(canvas != NULL); 316 SkASSERT(canvas != NULL);
301 if (NULL == canvas) { 317 if (NULL == canvas) {
302 return false; 318 return false;
303 } 319 }
304 320
305 SkASSERT(path != NULL); // TODO(epoger): we want to remove this constraint, as noted above
306 SkString fullPathname(*path);
307 fullPathname.append(".png");
308
309 SkBitmap bitmap; 321 SkBitmap bitmap;
310 SkISize size = canvas->getDeviceSize(); 322 SkISize size = canvas->getDeviceSize();
311 sk_tools::setup_bitmap(&bitmap, size.width(), size.height()); 323 sk_tools::setup_bitmap(&bitmap, size.width(), size.height());
312 324
325 // Make sure we only compute the bitmap hash once (at most).
326 uint64_t hash;
327 bool generatedHash = false;
328
313 canvas->readPixels(&bitmap, 0, 0); 329 canvas->readPixels(&bitmap, 0, 0);
314 sk_tools::force_all_opaque(bitmap); 330 sk_tools::force_all_opaque(bitmap);
315 331
332 SkString outputFilename(inputFilename);
333 outputFilename.remove(outputFilename.size() - 4, 4);
334 if (NULL != numberToAppend) {
335 outputFilename.appendf("%i", *numberToAppend);
336 }
337 outputFilename.append(".png");
338 // TODO(epoger): what about including the config type within outputFilename? That way,
339 // we could combine results of different config types without conflicting fi lenames.
340
316 if (NULL != jsonSummaryPtr) { 341 if (NULL != jsonSummaryPtr) {
317 // EPOGER: This is a hacky way of constructing the filename associated w ith the 342 if (!generatedHash) {
318 // image checksum; we assume that outputDir is not NULL, and we remove o utputDir 343 SkAssertResult(SkBitmapHasher::ComputeDigest(bitmap, &hash));
319 // from fullPathname. 344 generatedHash = true;
320 // 345 }
321 // EPOGER: what about including the config type within hashFilename? Th at way, 346 jsonSummaryPtr->add(outputFilename.c_str(), hash);
322 // we could combine results of different config types without conflictin g filenames.
323 SkString hashFilename;
324 sk_tools::get_basename(&hashFilename, fullPathname);
325 jsonSummaryPtr->add(hashFilename.c_str(), bitmap);
326 } 347 }
327 348
349 // Update outputFilename AFTER adding to JSON summary, but BEFORE writing ou t the image file.
350 if (useChecksumBasedFilenames) {
351 if (!generatedHash) {
352 SkAssertResult(SkBitmapHasher::ComputeDigest(bitmap, &hash));
353 generatedHash = true;
354 }
355 outputFilename.set(kJsonKey_Hashtype_Bitmap_64bitMD5);
356 outputFilename.append("_");
357 outputFilename.appendU64(hash);
358 outputFilename.append(".png");
359 }
360
361 SkASSERT(!outputDir.isEmpty()); // TODO(epoger): we want to remove this cons traint,
362 // as noted above
363 SkString fullPathname;
364 make_filepath(&fullPathname, outputDir, outputFilename);
328 return SkImageEncoder::EncodeFile(fullPathname.c_str(), bitmap, SkImageEncod er::kPNG_Type, 100); 365 return SkImageEncoder::EncodeFile(fullPathname.c_str(), bitmap, SkImageEncod er::kPNG_Type, 100);
329 } 366 }
330 367
331 /**
332 * If path is non NULL, append number to it, and call write() to write the
333 * provided canvas to a file. Returns true if path is NULL or if write() succeed s.
334 */
335 static bool writeAppendNumber(SkCanvas* canvas, const SkString* path, int number ,
336 ImageResultsSummary *jsonSummaryPtr) {
337 if (NULL == path) {
338 return true;
339 }
340 SkString pathWithNumber(*path);
341 pathWithNumber.appendf("%i", number);
342 return write(canvas, &pathWithNumber, jsonSummaryPtr);
343 }
344
345 //////////////////////////////////////////////////////////////////////////////// /////////////// 368 //////////////////////////////////////////////////////////////////////////////// ///////////////
346 369
347 SkCanvas* RecordPictureRenderer::setupCanvas(int width, int height) { 370 SkCanvas* RecordPictureRenderer::setupCanvas(int width, int height) {
348 // defer the canvas setup until the render step 371 // defer the canvas setup until the render step
349 return NULL; 372 return NULL;
350 } 373 }
351 374
352 // the size_t* parameter is deprecated, so we ignore it 375 // the size_t* parameter is deprecated, so we ignore it
353 static SkData* encode_bitmap_to_data(size_t*, const SkBitmap& bm) { 376 static SkData* encode_bitmap_to_data(size_t*, const SkBitmap& bm) {
354 return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100); 377 return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100);
355 } 378 }
356 379
357 bool RecordPictureRenderer::render(const SkString* path, SkBitmap** out) { 380 bool RecordPictureRenderer::render(SkBitmap** out) {
358 SkAutoTUnref<SkPicture> replayer(this->createPicture()); 381 SkAutoTUnref<SkPicture> replayer(this->createPicture());
359 SkCanvas* recorder = replayer->beginRecording(this->getViewWidth(), this->ge tViewHeight(), 382 SkCanvas* recorder = replayer->beginRecording(this->getViewWidth(), this->ge tViewHeight(),
360 this->recordFlags()); 383 this->recordFlags());
361 this->scaleToScaleFactor(recorder); 384 this->scaleToScaleFactor(recorder);
362 fPicture->draw(recorder); 385 fPicture->draw(recorder);
363 replayer->endRecording(); 386 replayer->endRecording();
364 if (path != NULL) { 387 if (!fOutputDir.isEmpty()) {
365 // Record the new picture as a new SKP with PNG encoded bitmaps. 388 // Record the new picture as a new SKP with PNG encoded bitmaps.
366 SkString skpPath(*path); 389 SkString skpPath;
367 // ".skp" was removed from 'path' before being passed in here. 390 make_filepath(&skpPath, fOutputDir, fInputFilename);
368 skpPath.append(".skp");
369 SkFILEWStream stream(skpPath.c_str()); 391 SkFILEWStream stream(skpPath.c_str());
370 replayer->serialize(&stream, &encode_bitmap_to_data); 392 replayer->serialize(&stream, &encode_bitmap_to_data);
371 return true; 393 return true;
372 } 394 }
373 return false; 395 return false;
374 } 396 }
375 397
376 SkString RecordPictureRenderer::getConfigNameInternal() { 398 SkString RecordPictureRenderer::getConfigNameInternal() {
377 return SkString("record"); 399 return SkString("record");
378 } 400 }
379 401
380 //////////////////////////////////////////////////////////////////////////////// /////////////// 402 //////////////////////////////////////////////////////////////////////////////// ///////////////
381 403
382 bool PipePictureRenderer::render(const SkString* path, SkBitmap** out) { 404 bool PipePictureRenderer::render(SkBitmap** out) {
383 SkASSERT(fCanvas.get() != NULL); 405 SkASSERT(fCanvas.get() != NULL);
384 SkASSERT(fPicture != NULL); 406 SkASSERT(fPicture != NULL);
385 if (NULL == fCanvas.get() || NULL == fPicture) { 407 if (NULL == fCanvas.get() || NULL == fPicture) {
386 return false; 408 return false;
387 } 409 }
388 410
389 PipeController pipeController(fCanvas.get()); 411 PipeController pipeController(fCanvas.get());
390 SkGPipeWriter writer; 412 SkGPipeWriter writer;
391 SkCanvas* pipeCanvas = writer.startRecording(&pipeController); 413 SkCanvas* pipeCanvas = writer.startRecording(&pipeController);
392 pipeCanvas->drawPicture(*fPicture); 414 pipeCanvas->drawPicture(*fPicture);
393 writer.endRecording(); 415 writer.endRecording();
394 fCanvas->flush(); 416 fCanvas->flush();
395 if (NULL != path) { 417 if (!fOutputDir.isEmpty()) {
396 return write(fCanvas, path, fJsonSummaryPtr); 418 return write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr,
419 fUseChecksumBasedFilenames);
397 } 420 }
398 if (NULL != out) { 421 if (NULL != out) {
399 *out = SkNEW(SkBitmap); 422 *out = SkNEW(SkBitmap);
400 setup_bitmap(*out, fPicture->width(), fPicture->height()); 423 setup_bitmap(*out, fPicture->width(), fPicture->height());
401 fCanvas->readPixels(*out, 0, 0); 424 fCanvas->readPixels(*out, 0, 0);
402 } 425 }
403 return true; 426 return true;
404 } 427 }
405 428
406 SkString PipePictureRenderer::getConfigNameInternal() { 429 SkString PipePictureRenderer::getConfigNameInternal() {
407 return SkString("pipe"); 430 return SkString("pipe");
408 } 431 }
409 432
410 //////////////////////////////////////////////////////////////////////////////// /////////////// 433 //////////////////////////////////////////////////////////////////////////////// ///////////////
411 434
412 void SimplePictureRenderer::init(SkPicture* picture) { 435 void SimplePictureRenderer::init(SkPicture* picture, const SkString& outputDir,
413 INHERITED::init(picture); 436 const SkString& inputFilename, bool useChecksum BasedFilenames) {
437 INHERITED::init(picture, outputDir, inputFilename, useChecksumBasedFilenames );
414 this->buildBBoxHierarchy(); 438 this->buildBBoxHierarchy();
415 } 439 }
416 440
417 bool SimplePictureRenderer::render(const SkString* path, SkBitmap** out) { 441 bool SimplePictureRenderer::render(SkBitmap** out) {
418 SkASSERT(fCanvas.get() != NULL); 442 SkASSERT(fCanvas.get() != NULL);
419 SkASSERT(fPicture != NULL); 443 SkASSERT(fPicture != NULL);
420 if (NULL == fCanvas.get() || NULL == fPicture) { 444 if (NULL == fCanvas.get() || NULL == fPicture) {
421 return false; 445 return false;
422 } 446 }
423 447
424 fCanvas->drawPicture(*fPicture); 448 fCanvas->drawPicture(*fPicture);
425 fCanvas->flush(); 449 fCanvas->flush();
426 if (NULL != path) { 450 if (!fOutputDir.isEmpty()) {
427 return write(fCanvas, path, fJsonSummaryPtr); 451 return write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr,
452 fUseChecksumBasedFilenames);
428 } 453 }
429 454
430 if (NULL != out) { 455 if (NULL != out) {
431 *out = SkNEW(SkBitmap); 456 *out = SkNEW(SkBitmap);
432 setup_bitmap(*out, fPicture->width(), fPicture->height()); 457 setup_bitmap(*out, fPicture->width(), fPicture->height());
433 fCanvas->readPixels(*out, 0, 0); 458 fCanvas->readPixels(*out, 0, 0);
434 } 459 }
435 460
436 return true; 461 return true;
437 } 462 }
438 463
439 SkString SimplePictureRenderer::getConfigNameInternal() { 464 SkString SimplePictureRenderer::getConfigNameInternal() {
440 return SkString("simple"); 465 return SkString("simple");
441 } 466 }
442 467
443 //////////////////////////////////////////////////////////////////////////////// /////////////// 468 //////////////////////////////////////////////////////////////////////////////// ///////////////
444 469
445 TiledPictureRenderer::TiledPictureRenderer() 470 TiledPictureRenderer::TiledPictureRenderer()
446 : fTileWidth(kDefaultTileWidth) 471 : fTileWidth(kDefaultTileWidth)
447 , fTileHeight(kDefaultTileHeight) 472 , fTileHeight(kDefaultTileHeight)
448 , fTileWidthPercentage(0.0) 473 , fTileWidthPercentage(0.0)
449 , fTileHeightPercentage(0.0) 474 , fTileHeightPercentage(0.0)
450 , fTileMinPowerOf2Width(0) 475 , fTileMinPowerOf2Width(0)
451 , fCurrentTileOffset(-1) 476 , fCurrentTileOffset(-1)
452 , fTilesX(0) 477 , fTilesX(0)
453 , fTilesY(0) { } 478 , fTilesY(0) { }
454 479
455 void TiledPictureRenderer::init(SkPicture* pict) { 480 void TiledPictureRenderer::init(SkPicture* pict, const SkString& outputDir,
481 const SkString& inputFilename, bool useChecksumB asedFilenames) {
456 SkASSERT(pict != NULL); 482 SkASSERT(pict != NULL);
457 SkASSERT(0 == fTileRects.count()); 483 SkASSERT(0 == fTileRects.count());
458 if (NULL == pict || fTileRects.count() != 0) { 484 if (NULL == pict || fTileRects.count() != 0) {
459 return; 485 return;
460 } 486 }
461 487
462 // Do not call INHERITED::init(), which would create a (potentially large) c anvas which is not 488 // Do not call INHERITED::init(), which would create a (potentially large) c anvas which is not
463 // used by bench_pictures. 489 // used by bench_pictures.
464 fPicture = pict; 490 fPicture = pict;
491 fOutputDir.set(outputDir);
492 fInputFilename.set(inputFilename);
493 fUseChecksumBasedFilenames = useChecksumBasedFilenames;
465 fPicture->ref(); 494 fPicture->ref();
466 this->buildBBoxHierarchy(); 495 this->buildBBoxHierarchy();
467 496
468 if (fTileWidthPercentage > 0) { 497 if (fTileWidthPercentage > 0) {
469 fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->wi dth() / 100)); 498 fTileWidth = sk_float_ceil2int(float(fTileWidthPercentage * fPicture->wi dth() / 100));
470 } 499 }
471 if (fTileHeightPercentage > 0) { 500 if (fTileHeightPercentage > 0) {
472 fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture-> height() / 100)); 501 fTileHeight = sk_float_ceil2int(float(fTileHeightPercentage * fPicture-> height() / 100));
473 } 502 }
474 503
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
616 return true; 645 return true;
617 } 646 }
618 return false; 647 return false;
619 } 648 }
620 649
621 void TiledPictureRenderer::drawCurrentTile() { 650 void TiledPictureRenderer::drawCurrentTile() {
622 SkASSERT(fCurrentTileOffset >= 0 && fCurrentTileOffset < fTileRects.count()) ; 651 SkASSERT(fCurrentTileOffset >= 0 && fCurrentTileOffset < fTileRects.count()) ;
623 draw_tile_to_canvas(fCanvas, fTileRects[fCurrentTileOffset], fPicture); 652 draw_tile_to_canvas(fCanvas, fTileRects[fCurrentTileOffset], fPicture);
624 } 653 }
625 654
626 bool TiledPictureRenderer::render(const SkString* path, SkBitmap** out) { 655 bool TiledPictureRenderer::render(SkBitmap** out) {
627 SkASSERT(fPicture != NULL); 656 SkASSERT(fPicture != NULL);
628 if (NULL == fPicture) { 657 if (NULL == fPicture) {
629 return false; 658 return false;
630 } 659 }
631 660
632 SkBitmap bitmap; 661 SkBitmap bitmap;
633 if (out){ 662 if (out){
634 *out = SkNEW(SkBitmap); 663 *out = SkNEW(SkBitmap);
635 setup_bitmap(*out, fPicture->width(), fPicture->height()); 664 setup_bitmap(*out, fPicture->width(), fPicture->height());
636 setup_bitmap(&bitmap, fTileWidth, fTileHeight); 665 setup_bitmap(&bitmap, fTileWidth, fTileHeight);
637 } 666 }
638 bool success = true; 667 bool success = true;
639 for (int i = 0; i < fTileRects.count(); ++i) { 668 for (int i = 0; i < fTileRects.count(); ++i) {
640 draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture); 669 draw_tile_to_canvas(fCanvas, fTileRects[i], fPicture);
641 if (NULL != path) { 670 if (!fOutputDir.isEmpty()) {
642 success &= writeAppendNumber(fCanvas, path, i, fJsonSummaryPtr); 671 success &= write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPt r,
672 fUseChecksumBasedFilenames, &i);
643 } 673 }
644 if (NULL != out) { 674 if (NULL != out) {
645 if (fCanvas->readPixels(&bitmap, 0, 0)) { 675 if (fCanvas->readPixels(&bitmap, 0, 0)) {
646 // Add this tile to the entire bitmap. 676 // Add this tile to the entire bitmap.
647 bitmapCopyAtOffset(bitmap, *out, SkScalarFloorToInt(fTileRects[i ].left()), 677 bitmapCopyAtOffset(bitmap, *out, SkScalarFloorToInt(fTileRects[i ].left()),
648 SkScalarFloorToInt(fTileRects[i].top())); 678 SkScalarFloorToInt(fTileRects[i].top()));
649 } else { 679 } else {
650 success = false; 680 success = false;
651 } 681 }
652 } 682 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 return name; 721 return name;
692 } 722 }
693 723
694 //////////////////////////////////////////////////////////////////////////////// /////////////// 724 //////////////////////////////////////////////////////////////////////////////// ///////////////
695 725
696 // Holds all of the information needed to draw a set of tiles. 726 // Holds all of the information needed to draw a set of tiles.
697 class CloneData : public SkRunnable { 727 class CloneData : public SkRunnable {
698 728
699 public: 729 public:
700 CloneData(SkPicture* clone, SkCanvas* canvas, SkTDArray<SkRect>& rects, int start, int end, 730 CloneData(SkPicture* clone, SkCanvas* canvas, SkTDArray<SkRect>& rects, int start, int end,
701 SkRunnable* done, ImageResultsSummary* jsonSummaryPtr) 731 SkRunnable* done, ImageResultsSummary* jsonSummaryPtr, bool useChe cksumBasedFilenames)
702 : fClone(clone) 732 : fClone(clone)
703 , fCanvas(canvas) 733 , fCanvas(canvas)
704 , fPath(NULL)
705 , fRects(rects) 734 , fRects(rects)
706 , fStart(start) 735 , fStart(start)
707 , fEnd(end) 736 , fEnd(end)
708 , fSuccess(NULL) 737 , fSuccess(NULL)
709 , fDone(done) 738 , fDone(done)
710 , fJsonSummaryPtr(jsonSummaryPtr) { 739 , fJsonSummaryPtr(jsonSummaryPtr)
740 , fUseChecksumBasedFilenames(useChecksumBasedFilenames) {
711 SkASSERT(fDone != NULL); 741 SkASSERT(fDone != NULL);
712 } 742 }
713 743
714 virtual void run() SK_OVERRIDE { 744 virtual void run() SK_OVERRIDE {
715 SkGraphics::SetTLSFontCacheLimit(1024 * 1024); 745 SkGraphics::SetTLSFontCacheLimit(1024 * 1024);
716 746
717 SkBitmap bitmap; 747 SkBitmap bitmap;
718 if (fBitmap != NULL) { 748 if (fBitmap != NULL) {
719 // All tiles are the same size. 749 // All tiles are the same size.
720 setup_bitmap(&bitmap, SkScalarFloorToInt(fRects[0].width()), SkScala rFloorToInt(fRects[0].height())); 750 setup_bitmap(&bitmap, SkScalarFloorToInt(fRects[0].width()), SkScala rFloorToInt(fRects[0].height()));
721 } 751 }
722 752
723 for (int i = fStart; i < fEnd; i++) { 753 for (int i = fStart; i < fEnd; i++) {
724 draw_tile_to_canvas(fCanvas, fRects[i], fClone); 754 draw_tile_to_canvas(fCanvas, fRects[i], fClone);
725 if ((fPath != NULL) && !writeAppendNumber(fCanvas, fPath, i, fJsonSu mmaryPtr) 755 if ((!fOutputDir.isEmpty())
756 && !write(fCanvas, fOutputDir, fInputFilename, fJsonSummaryPtr,
757 fUseChecksumBasedFilenames, &i)
726 && fSuccess != NULL) { 758 && fSuccess != NULL) {
727 *fSuccess = false; 759 *fSuccess = false;
728 // If one tile fails to write to a file, do not continue drawing the rest. 760 // If one tile fails to write to a file, do not continue drawing the rest.
729 break; 761 break;
730 } 762 }
731 if (fBitmap != NULL) { 763 if (fBitmap != NULL) {
732 if (fCanvas->readPixels(&bitmap, 0, 0)) { 764 if (fCanvas->readPixels(&bitmap, 0, 0)) {
733 SkAutoLockPixels alp(*fBitmap); 765 SkAutoLockPixels alp(*fBitmap);
734 bitmapCopyAtOffset(bitmap, fBitmap, SkScalarFloorToInt(fRect s[i].left()), 766 bitmapCopyAtOffset(bitmap, fBitmap, SkScalarFloorToInt(fRect s[i].left()),
735 SkScalarFloorToInt(fRects[i].top())); 767 SkScalarFloorToInt(fRects[i].top()));
736 } else { 768 } else {
737 *fSuccess = false; 769 *fSuccess = false;
738 // If one tile fails to read pixels, do not continue drawing the rest. 770 // If one tile fails to read pixels, do not continue drawing the rest.
739 break; 771 break;
740 } 772 }
741 } 773 }
742 } 774 }
743 fDone->run(); 775 fDone->run();
744 } 776 }
745 777
746 void setPathAndSuccess(const SkString* path, bool* success) { 778 void setPathsAndSuccess(const SkString& outputDir, const SkString& inputFile name,
747 fPath = path; 779 bool* success) {
780 fOutputDir.set(outputDir);
781 fInputFilename.set(inputFilename);
748 fSuccess = success; 782 fSuccess = success;
749 } 783 }
750 784
751 void setBitmap(SkBitmap* bitmap) { 785 void setBitmap(SkBitmap* bitmap) {
752 fBitmap = bitmap; 786 fBitmap = bitmap;
753 } 787 }
754 788
755 private: 789 private:
756 // All pointers unowned. 790 // All pointers unowned.
757 SkPicture* fClone; // Picture to draw from. Each CloneData has a unique one which 791 SkPicture* fClone; // Picture to draw from. Each CloneData has a unique one which
758 // is threadsafe. 792 // is threadsafe.
759 SkCanvas* fCanvas; // Canvas to draw to. Reused for each tile. 793 SkCanvas* fCanvas; // Canvas to draw to. Reused for each tile.
760 const SkString* fPath; // If non-null, path to write the result to as a PNG. 794 SkString fOutputDir; // If not empty, write results into this dir ectory.
795 SkString fInputFilename; // Filename of input SkPicture file.
761 SkTDArray<SkRect>& fRects; // All tiles of the picture. 796 SkTDArray<SkRect>& fRects; // All tiles of the picture.
762 const int fStart; // Range of tiles drawn by this thread. 797 const int fStart; // Range of tiles drawn by this thread.
763 const int fEnd; 798 const int fEnd;
764 bool* fSuccess; // Only meaningful if path is non-null. Shar ed by all threads, 799 bool* fSuccess; // Only meaningful if path is non-null. Shar ed by all threads,
765 // and only set to false upon failure to wri te to a PNG. 800 // and only set to false upon failure to wri te to a PNG.
766 SkRunnable* fDone; 801 SkRunnable* fDone;
767 SkBitmap* fBitmap; 802 SkBitmap* fBitmap;
768 ImageResultsSummary* fJsonSummaryPtr; 803 ImageResultsSummary* fJsonSummaryPtr;
804 bool fUseChecksumBasedFilenames;
769 }; 805 };
770 806
771 MultiCorePictureRenderer::MultiCorePictureRenderer(int threadCount) 807 MultiCorePictureRenderer::MultiCorePictureRenderer(int threadCount)
772 : fNumThreads(threadCount) 808 : fNumThreads(threadCount)
773 , fThreadPool(threadCount) 809 , fThreadPool(threadCount)
774 , fCountdown(threadCount) { 810 , fCountdown(threadCount) {
775 // Only need to create fNumThreads - 1 clones, since one thread will use the base 811 // Only need to create fNumThreads - 1 clones, since one thread will use the base
776 // picture. 812 // picture.
777 fPictureClones = SkNEW_ARRAY(SkPicture, fNumThreads - 1); 813 fPictureClones = SkNEW_ARRAY(SkPicture, fNumThreads - 1);
778 fCloneData = SkNEW_ARRAY(CloneData*, fNumThreads); 814 fCloneData = SkNEW_ARRAY(CloneData*, fNumThreads);
779 } 815 }
780 816
781 void MultiCorePictureRenderer::init(SkPicture *pict) { 817 void MultiCorePictureRenderer::init(SkPicture *pict, const SkString& outputDir,
818 const SkString& inputFilename, bool useCheck sumBasedFilenames) {
782 // Set fPicture and the tiles. 819 // Set fPicture and the tiles.
783 this->INHERITED::init(pict); 820 this->INHERITED::init(pict, outputDir, inputFilename, useChecksumBasedFilena mes);
784 for (int i = 0; i < fNumThreads; ++i) { 821 for (int i = 0; i < fNumThreads; ++i) {
785 *fCanvasPool.append() = this->setupCanvas(this->getTileWidth(), this->ge tTileHeight()); 822 *fCanvasPool.append() = this->setupCanvas(this->getTileWidth(), this->ge tTileHeight());
786 } 823 }
787 // Only need to create fNumThreads - 1 clones, since one thread will use the base picture. 824 // Only need to create fNumThreads - 1 clones, since one thread will use the base picture.
788 fPicture->clone(fPictureClones, fNumThreads - 1); 825 fPicture->clone(fPictureClones, fNumThreads - 1);
789 // Populate each thread with the appropriate data. 826 // Populate each thread with the appropriate data.
790 // Group the tiles into nearly equal size chunks, rounding up so we're sure to cover them all. 827 // Group the tiles into nearly equal size chunks, rounding up so we're sure to cover them all.
791 const int chunkSize = (fTileRects.count() + fNumThreads - 1) / fNumThreads; 828 const int chunkSize = (fTileRects.count() + fNumThreads - 1) / fNumThreads;
792 829
793 for (int i = 0; i < fNumThreads; i++) { 830 for (int i = 0; i < fNumThreads; i++) {
794 SkPicture* pic; 831 SkPicture* pic;
795 if (i == fNumThreads-1) { 832 if (i == fNumThreads-1) {
796 // The last set will use the original SkPicture. 833 // The last set will use the original SkPicture.
797 pic = fPicture; 834 pic = fPicture;
798 } else { 835 } else {
799 pic = &fPictureClones[i]; 836 pic = &fPictureClones[i];
800 } 837 }
801 const int start = i * chunkSize; 838 const int start = i * chunkSize;
802 const int end = SkMin32(start + chunkSize, fTileRects.count()); 839 const int end = SkMin32(start + chunkSize, fTileRects.count());
803 fCloneData[i] = SkNEW_ARGS(CloneData, 840 fCloneData[i] = SkNEW_ARGS(CloneData,
804 (pic, fCanvasPool[i], fTileRects, start, end, &fCountdown, 841 (pic, fCanvasPool[i], fTileRects, start, end, &fCountdown,
805 fJsonSummaryPtr)); 842 fJsonSummaryPtr, useChecksumBasedFilenames)) ;
806 } 843 }
807 } 844 }
808 845
809 bool MultiCorePictureRenderer::render(const SkString *path, SkBitmap** out) { 846 bool MultiCorePictureRenderer::render(SkBitmap** out) {
810 bool success = true; 847 bool success = true;
811 if (path != NULL) { 848 if (!fOutputDir.isEmpty()) {
812 for (int i = 0; i < fNumThreads-1; i++) { 849 for (int i = 0; i < fNumThreads-1; i++) {
813 fCloneData[i]->setPathAndSuccess(path, &success); 850 fCloneData[i]->setPathsAndSuccess(fOutputDir, fInputFilename, &succe ss);
814 } 851 }
815 } 852 }
816 853
817 if (NULL != out) { 854 if (NULL != out) {
818 *out = SkNEW(SkBitmap); 855 *out = SkNEW(SkBitmap);
819 setup_bitmap(*out, fPicture->width(), fPicture->height()); 856 setup_bitmap(*out, fPicture->width(), fPicture->height());
820 for (int i = 0; i < fNumThreads; i++) { 857 for (int i = 0; i < fNumThreads; i++) {
821 fCloneData[i]->setBitmap(*out); 858 fCloneData[i]->setBitmap(*out);
822 } 859 }
823 } else { 860 } else {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
861 //////////////////////////////////////////////////////////////////////////////// /////////////// 898 //////////////////////////////////////////////////////////////////////////////// ///////////////
862 899
863 void PlaybackCreationRenderer::setup() { 900 void PlaybackCreationRenderer::setup() {
864 fReplayer.reset(this->createPicture()); 901 fReplayer.reset(this->createPicture());
865 SkCanvas* recorder = fReplayer->beginRecording(this->getViewWidth(), this->g etViewHeight(), 902 SkCanvas* recorder = fReplayer->beginRecording(this->getViewWidth(), this->g etViewHeight(),
866 this->recordFlags()); 903 this->recordFlags());
867 this->scaleToScaleFactor(recorder); 904 this->scaleToScaleFactor(recorder);
868 fPicture->draw(recorder); 905 fPicture->draw(recorder);
869 } 906 }
870 907
871 bool PlaybackCreationRenderer::render(const SkString*, SkBitmap** out) { 908 bool PlaybackCreationRenderer::render(SkBitmap** out) {
872 fReplayer->endRecording(); 909 fReplayer->endRecording();
873 // Since this class does not actually render, return false. 910 // Since this class does not actually render, return false.
874 return false; 911 return false;
875 } 912 }
876 913
877 SkString PlaybackCreationRenderer::getConfigNameInternal() { 914 SkString PlaybackCreationRenderer::getConfigNameInternal() {
878 return SkString("playback_creation"); 915 return SkString("playback_creation");
879 } 916 }
880 917
881 //////////////////////////////////////////////////////////////////////////////// /////////////// 918 //////////////////////////////////////////////////////////////////////////////// ///////////////
(...skipping 26 matching lines...) Expand all
908 fPicture->height(), fGridInfo)); 945 fPicture->height(), fGridInfo));
909 } 946 }
910 SkASSERT(0); // invalid bbhType 947 SkASSERT(0); // invalid bbhType
911 return NULL; 948 return NULL;
912 } 949 }
913 950
914 /////////////////////////////////////////////////////////////////////////////// 951 ///////////////////////////////////////////////////////////////////////////////
915 952
916 class GatherRenderer : public PictureRenderer { 953 class GatherRenderer : public PictureRenderer {
917 public: 954 public:
918 virtual bool render(const SkString* path, SkBitmap** out = NULL) 955 virtual bool render(SkBitmap** out = NULL)
919 SK_OVERRIDE { 956 SK_OVERRIDE {
920 SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->width()), 957 SkRect bounds = SkRect::MakeWH(SkIntToScalar(fPicture->width()),
921 SkIntToScalar(fPicture->height())); 958 SkIntToScalar(fPicture->height()));
922 SkData* data = SkPictureUtils::GatherPixelRefs(fPicture, bounds); 959 SkData* data = SkPictureUtils::GatherPixelRefs(fPicture, bounds);
923 SkSafeUnref(data); 960 SkSafeUnref(data);
924 961
925 return NULL == path; // we don't have anything to write 962 return (fOutputDir.isEmpty()); // we don't have anything to write
926 } 963 }
927 964
928 private: 965 private:
929 virtual SkString getConfigNameInternal() SK_OVERRIDE { 966 virtual SkString getConfigNameInternal() SK_OVERRIDE {
930 return SkString("gather_pixelrefs"); 967 return SkString("gather_pixelrefs");
931 } 968 }
932 }; 969 };
933 970
934 PictureRenderer* CreateGatherPixelRefsRenderer() { 971 PictureRenderer* CreateGatherPixelRefsRenderer() {
935 return SkNEW(GatherRenderer); 972 return SkNEW(GatherRenderer);
936 } 973 }
937 974
938 /////////////////////////////////////////////////////////////////////////////// 975 ///////////////////////////////////////////////////////////////////////////////
939 976
940 class PictureCloneRenderer : public PictureRenderer { 977 class PictureCloneRenderer : public PictureRenderer {
941 public: 978 public:
942 virtual bool render(const SkString* path, SkBitmap** out = NULL) 979 virtual bool render(SkBitmap** out = NULL)
943 SK_OVERRIDE { 980 SK_OVERRIDE {
944 for (int i = 0; i < 100; ++i) { 981 for (int i = 0; i < 100; ++i) {
945 SkPicture* clone = fPicture->clone(); 982 SkPicture* clone = fPicture->clone();
946 SkSafeUnref(clone); 983 SkSafeUnref(clone);
947 } 984 }
948 985
949 return NULL == path; // we don't have anything to write 986 return (fOutputDir.isEmpty()); // we don't have anything to write
950 } 987 }
951 988
952 private: 989 private:
953 virtual SkString getConfigNameInternal() SK_OVERRIDE { 990 virtual SkString getConfigNameInternal() SK_OVERRIDE {
954 return SkString("picture_clone"); 991 return SkString("picture_clone");
955 } 992 }
956 }; 993 };
957 994
958 PictureRenderer* CreatePictureCloneRenderer() { 995 PictureRenderer* CreatePictureCloneRenderer() {
959 return SkNEW(PictureCloneRenderer); 996 return SkNEW(PictureCloneRenderer);
960 } 997 }
961 998
962 } // namespace sk_tools 999 } // namespace sk_tools
OLDNEW
« tools/PictureRenderer.h ('K') | « tools/PictureRenderer.h ('k') | tools/bbh_shootout.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698