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

Side by Side Diff: tools/PictureRenderer.cpp

Issue 226293002: add explicit filepaths to render_pictures JSON summary (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: unittests now pass Created 6 years, 8 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"
11 #include "SkBitmapHasher.h" 11 #include "SkBitmapHasher.h"
12 #include "SkCanvas.h" 12 #include "SkCanvas.h"
13 #include "SkData.h" 13 #include "SkData.h"
14 #include "SkDevice.h" 14 #include "SkDevice.h"
15 #include "SkDiscardableMemoryPool.h" 15 #include "SkDiscardableMemoryPool.h"
16 #include "SkGPipe.h" 16 #include "SkGPipe.h"
17 #if SK_SUPPORT_GPU 17 #if SK_SUPPORT_GPU
18 #include "gl/GrGLDefines.h" 18 #include "gl/GrGLDefines.h"
19 #include "SkGpuDevice.h" 19 #include "SkGpuDevice.h"
20 #endif 20 #endif
21 #include "SkGraphics.h" 21 #include "SkGraphics.h"
22 #include "SkImageEncoder.h" 22 #include "SkImageEncoder.h"
23 #include "SkMaskFilter.h" 23 #include "SkMaskFilter.h"
24 #include "SkMatrix.h" 24 #include "SkMatrix.h"
25 #include "SkOSFile.h"
25 #include "SkPicture.h" 26 #include "SkPicture.h"
26 #include "SkPictureUtils.h" 27 #include "SkPictureUtils.h"
27 #include "SkPixelRef.h" 28 #include "SkPixelRef.h"
28 #include "SkQuadTree.h" 29 #include "SkQuadTree.h"
29 #include "SkQuadTreePicture.h" 30 #include "SkQuadTreePicture.h"
30 #include "SkRTree.h" 31 #include "SkRTree.h"
31 #include "SkScalar.h" 32 #include "SkScalar.h"
32 #include "SkStream.h" 33 #include "SkStream.h"
33 #include "SkString.h" 34 #include "SkString.h"
34 #include "SkTemplates.h" 35 #include "SkTemplates.h"
35 #include "SkTileGridPicture.h" 36 #include "SkTileGridPicture.h"
36 #include "SkTDArray.h" 37 #include "SkTDArray.h"
37 #include "SkThreadUtils.h" 38 #include "SkThreadUtils.h"
38 #include "SkTypes.h" 39 #include "SkTypes.h"
39 40
40 static inline SkScalar scalar_log2(SkScalar x) { 41 static inline SkScalar scalar_log2(SkScalar x) {
41 static const SkScalar log2_conversion_factor = SkScalarDiv(1, SkScalarLog(2) ); 42 static const SkScalar log2_conversion_factor = SkScalarDiv(1, SkScalarLog(2) );
42 43
43 return SkScalarLog(x) * log2_conversion_factor; 44 return SkScalarLog(x) * log2_conversion_factor;
44 } 45 }
45 46
46 namespace sk_tools { 47 namespace sk_tools {
47 48
48 enum { 49 enum {
49 kDefaultTileWidth = 256, 50 kDefaultTileWidth = 256,
50 kDefaultTileHeight = 256 51 kDefaultTileHeight = 256
51 }; 52 };
52 53
53 /* TODO(epoger): These constants are already maintained in 2 other places: 54 /* TODO(epoger): Similar 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 . 55 * 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. 56 * Figure out a way to share the definitions instead.
57 *
58 * Note that, as of https://codereview.chromium.org/226293002 , the JSON
59 * schema used here has started to differ from the one in gm_expectations.cpp .
60 * TODO(epoger): Consider getting GM and render_pictures to use the same JSON
61 * output module.
56 */ 62 */
57 const static char kJsonKey_ActualResults[] = "actual-results"; 63 const static char kJsonKey_ActualResults[] = "actual-results";
58 const static char kJsonKey_ActualResults_NoComparison[] = "no-comparison"; 64 const static char kJsonKey_ActualResults_NoComparison[] = "no-comparison";
59 const static char kJsonKey_Hashtype_Bitmap_64bitMD5[] = "bitmap-64bitMD5"; 65 const static char kJsonKey_Header[] = "header";
66 const static char kJsonKey_Header_Type[] = "type";
67 const static char kJsonKey_Header_Revision[] = "revision"; // unique within Typ e
60 68
61 void ImageResultsSummary::add(const char *testName, uint64_t hash) { 69 const static char kJsonKey_Image_ChecksumAlgorithm[] = "checksumAlgorithm";
62 Json::Value jsonTypeValuePair; 70 const static char kJsonKey_Image_ChecksumValue[] = "checksumValue";
63 jsonTypeValuePair.append(Json::Value(kJsonKey_Hashtype_Bitmap_64bitMD5)); 71 const static char kJsonKey_Image_Filepath[] = "filepath";
64 jsonTypeValuePair.append(Json::UInt64(hash)); 72 // Values (not keys) that are written out by this JSON generator
65 fActualResultsNoComparison[testName] = jsonTypeValuePair; 73 const static char kJsonValue_Header_Type[] = "ChecksummedImages";
74 const static int kJsonValue_Header_Revision = 1;
75 const static char kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5[] = "bitmap- 64bitMD5";
76
77 void ImageResultsSummary::add(const char *testName, const char *fileName, uint64 _t hash) {
78 Json::Value node;
79 node[kJsonKey_Image_ChecksumAlgorithm] = kJsonValue_Image_ChecksumAlgorithm_ Bitmap64bitMD5;
80 node[kJsonKey_Image_ChecksumValue] = Json::UInt64(hash);
81 node[kJsonKey_Image_Filepath] = fileName;
82 fActualResultsNoComparison[testName] = node;
66 } 83 }
67 84
68 void ImageResultsSummary::add(const char *testName, const SkBitmap& bitmap) { 85 void ImageResultsSummary::add(const char *testName, const char *fileName, const SkBitmap& bitmap) {
69 uint64_t hash; 86 uint64_t hash;
70 SkAssertResult(SkBitmapHasher::ComputeDigest(bitmap, &hash)); 87 SkAssertResult(SkBitmapHasher::ComputeDigest(bitmap, &hash));
71 this->add(testName, hash); 88 this->add(testName, fileName, hash);
72 } 89 }
73 90
74 void ImageResultsSummary::writeToFile(const char *filename) { 91 void ImageResultsSummary::writeToFile(const char *filename) {
92 Json::Value header;
93 header[kJsonKey_Header_Type] = kJsonValue_Header_Type;
94 header[kJsonKey_Header_Revision] = kJsonValue_Header_Revision;
75 Json::Value actualResults; 95 Json::Value actualResults;
76 actualResults[kJsonKey_ActualResults_NoComparison] = fActualResultsNoCompari son; 96 actualResults[kJsonKey_ActualResults_NoComparison] = fActualResultsNoCompari son;
77 Json::Value root; 97 Json::Value root;
98 root[kJsonKey_Header] = header;
78 root[kJsonKey_ActualResults] = actualResults; 99 root[kJsonKey_ActualResults] = actualResults;
79 std::string jsonStdString = root.toStyledString(); 100 std::string jsonStdString = root.toStyledString();
80 SkFILEWStream stream(filename); 101 SkFILEWStream stream(filename);
81 stream.write(jsonStdString.c_str(), jsonStdString.length()); 102 stream.write(jsonStdString.c_str(), jsonStdString.length());
82 } 103 }
83 104
84 void PictureRenderer::init(SkPicture* pict, const SkString* outputDir, 105 void PictureRenderer::init(SkPicture* pict, const SkString* outputDir,
85 const SkString* inputFilename, bool useChecksumBasedF ilenames) { 106 const SkString* inputFilename, bool useChecksumBasedF ilenames) {
86 this->CopyString(&fOutputDir, outputDir); 107 this->CopyString(&fOutputDir, outputDir);
87 this->CopyString(&fInputFilename, inputFilename); 108 this->CopyString(&fInputFilename, inputFilename);
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 SkISize size = canvas->getDeviceSize(); 351 SkISize size = canvas->getDeviceSize();
331 sk_tools::setup_bitmap(&bitmap, size.width(), size.height()); 352 sk_tools::setup_bitmap(&bitmap, size.width(), size.height());
332 353
333 // Make sure we only compute the bitmap hash once (at most). 354 // Make sure we only compute the bitmap hash once (at most).
334 uint64_t hash; 355 uint64_t hash;
335 bool generatedHash = false; 356 bool generatedHash = false;
336 357
337 canvas->readPixels(&bitmap, 0, 0); 358 canvas->readPixels(&bitmap, 0, 0);
338 sk_tools::force_all_opaque(bitmap); 359 sk_tools::force_all_opaque(bitmap);
339 360
340 SkString outputFilename(inputFilename);
341 outputFilename.remove(outputFilename.size() - 4, 4);
342 if (NULL != numberToAppend) {
343 outputFilename.appendf("%i", *numberToAppend);
344 }
345 outputFilename.append(".png");
346 // TODO(epoger): what about including the config type within outputFilename? That way, 361 // TODO(epoger): what about including the config type within outputFilename? That way,
347 // we could combine results of different config types without conflicting fi lenames. 362 // we could combine results of different config types without conflicting fi lenames.
363 SkString inputFilenameWithTileNumber(inputFilename);
364 if (NULL != numberToAppend) {
365 inputFilenameWithTileNumber.append("-tile");
366 inputFilenameWithTileNumber.appendS32(*numberToAppend);
367 }
368 SkString escapedInputFilenameWithTileNumber(inputFilenameWithTileNumber);
369 replace_char(&escapedInputFilenameWithTileNumber, '.', '_');
348 370
349 if (NULL != jsonSummaryPtr) { 371 SkString outputFilename;
372 const char *outputSubdirPtr = NULL;
373 if (useChecksumBasedFilenames) {
350 SkASSERT(!generatedHash); 374 SkASSERT(!generatedHash);
351 SkAssertResult(SkBitmapHasher::ComputeDigest(bitmap, &hash)); 375 SkAssertResult(SkBitmapHasher::ComputeDigest(bitmap, &hash));
352 generatedHash = true; 376 generatedHash = true;
353 377
354 jsonSummaryPtr->add(outputFilename.c_str(), hash); 378 outputSubdirPtr = escapedInputFilenameWithTileNumber.c_str();
379 outputFilename.set(kJsonValue_Image_ChecksumAlgorithm_Bitmap64bitMD5);
380 outputFilename.append("_");
381 outputFilename.appendU64(hash);
382 } else {
383 outputFilename.set(escapedInputFilenameWithTileNumber);
355 } 384 }
385 outputFilename.append(".png");
356 386
357 // Update outputFilename AFTER adding to JSON summary, but BEFORE writing ou t the image file. 387 if (NULL != jsonSummaryPtr) {
358 if (useChecksumBasedFilenames) {
359 if (!generatedHash) { 388 if (!generatedHash) {
360 SkAssertResult(SkBitmapHasher::ComputeDigest(bitmap, &hash)); 389 SkAssertResult(SkBitmapHasher::ComputeDigest(bitmap, &hash));
361 generatedHash = true; 390 generatedHash = true;
362 } 391 }
363 outputFilename.set(kJsonKey_Hashtype_Bitmap_64bitMD5); 392
364 outputFilename.append("_"); 393 SkString outputRelativePath;
365 outputFilename.appendU64(hash); 394 if (outputSubdirPtr) {
366 outputFilename.append(".png"); 395 outputRelativePath.set(outputSubdirPtr);
396 outputRelativePath.append("/"); // always use "/", even on Windows
397 outputRelativePath.append(outputFilename);
398 } else {
399 outputRelativePath.set(outputFilename);
400 }
401 jsonSummaryPtr->add(inputFilenameWithTileNumber.c_str(), outputRelativeP ath.c_str(), hash);
367 } 402 }
368 403
369 SkASSERT(!outputDir.isEmpty()); // TODO(epoger): we want to remove this cons traint, 404 SkASSERT(!outputDir.isEmpty()); // TODO(epoger): we want to remove this cons traint,
370 // as noted above 405 // as noted above
371 SkString fullPathname; 406 SkString dirPath;
372 make_filepath(&fullPathname, outputDir, outputFilename); 407 if (outputSubdirPtr) {
373 return SkImageEncoder::EncodeFile(fullPathname.c_str(), bitmap, SkImageEncod er::kPNG_Type, 100); 408 dirPath = SkOSPath::SkPathJoin(outputDir.c_str(), outputSubdirPtr);
409 sk_mkdir(dirPath.c_str());
410 } else {
411 dirPath.set(outputDir);
412 }
413 SkString fullPath = SkOSPath::SkPathJoin(dirPath.c_str(), outputFilename.c_s tr());
414 return SkImageEncoder::EncodeFile(fullPath.c_str(), bitmap, SkImageEncoder:: kPNG_Type, 100);
374 } 415 }
375 416
376 //////////////////////////////////////////////////////////////////////////////// /////////////// 417 //////////////////////////////////////////////////////////////////////////////// ///////////////
377 418
378 SkCanvas* RecordPictureRenderer::setupCanvas(int width, int height) { 419 SkCanvas* RecordPictureRenderer::setupCanvas(int width, int height) {
379 // defer the canvas setup until the render step 420 // defer the canvas setup until the render step
380 return NULL; 421 return NULL;
381 } 422 }
382 423
383 // the size_t* parameter is deprecated, so we ignore it 424 // the size_t* parameter is deprecated, so we ignore it
384 static SkData* encode_bitmap_to_data(size_t*, const SkBitmap& bm) { 425 static SkData* encode_bitmap_to_data(size_t*, const SkBitmap& bm) {
385 return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100); 426 return SkImageEncoder::EncodeData(bm, SkImageEncoder::kPNG_Type, 100);
386 } 427 }
387 428
388 bool RecordPictureRenderer::render(SkBitmap** out) { 429 bool RecordPictureRenderer::render(SkBitmap** out) {
389 SkAutoTUnref<SkPicture> replayer(this->createPicture()); 430 SkAutoTUnref<SkPicture> replayer(this->createPicture());
390 SkCanvas* recorder = replayer->beginRecording(this->getViewWidth(), this->ge tViewHeight(), 431 SkCanvas* recorder = replayer->beginRecording(this->getViewWidth(), this->ge tViewHeight(),
391 this->recordFlags()); 432 this->recordFlags());
392 this->scaleToScaleFactor(recorder); 433 this->scaleToScaleFactor(recorder);
393 fPicture->draw(recorder); 434 fPicture->draw(recorder);
394 replayer->endRecording(); 435 replayer->endRecording();
395 if (!fOutputDir.isEmpty()) { 436 if (!fOutputDir.isEmpty()) {
396 // Record the new picture as a new SKP with PNG encoded bitmaps. 437 // Record the new picture as a new SKP with PNG encoded bitmaps.
397 SkString skpPath; 438 SkString skpPath = SkOSPath::SkPathJoin(fOutputDir.c_str(), fInputFilena me.c_str());
398 make_filepath(&skpPath, fOutputDir, fInputFilename);
399 SkFILEWStream stream(skpPath.c_str()); 439 SkFILEWStream stream(skpPath.c_str());
400 replayer->serialize(&stream, &encode_bitmap_to_data); 440 replayer->serialize(&stream, &encode_bitmap_to_data);
401 return true; 441 return true;
402 } 442 }
403 return false; 443 return false;
404 } 444 }
405 445
406 SkString RecordPictureRenderer::getConfigNameInternal() { 446 SkString RecordPictureRenderer::getConfigNameInternal() {
407 return SkString("record"); 447 return SkString("record");
408 } 448 }
(...skipping 586 matching lines...) Expand 10 before | Expand all | Expand 10 after
995 virtual SkString getConfigNameInternal() SK_OVERRIDE { 1035 virtual SkString getConfigNameInternal() SK_OVERRIDE {
996 return SkString("picture_clone"); 1036 return SkString("picture_clone");
997 } 1037 }
998 }; 1038 };
999 1039
1000 PictureRenderer* CreatePictureCloneRenderer() { 1040 PictureRenderer* CreatePictureCloneRenderer() {
1001 return SkNEW(PictureCloneRenderer); 1041 return SkNEW(PictureCloneRenderer);
1002 } 1042 }
1003 1043
1004 } // namespace sk_tools 1044 } // namespace sk_tools
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698