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

Side by Side Diff: bench/nanobench.cpp

Issue 918673002: Adding new benchmark to test image decoding performance. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Missed a few minor comments (sorry!) Created 5 years, 10 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 2014 Google Inc. 2 * Copyright 2014 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 <ctype.h> 8 #include <ctype.h>
9 9
10 #include "Benchmark.h" 10 #include "Benchmark.h"
11 #include "CrashHandler.h" 11 #include "CrashHandler.h"
12 #include "DecodingBench.h"
13 #include "DecodingSubsetBench.h"
12 #include "GMBench.h" 14 #include "GMBench.h"
13 #include "ProcStats.h" 15 #include "ProcStats.h"
14 #include "ResultsWriter.h" 16 #include "ResultsWriter.h"
15 #include "RecordingBench.h" 17 #include "RecordingBench.h"
18 #include "Resources.h"
16 #include "SKPBench.h" 19 #include "SKPBench.h"
17 #include "Stats.h" 20 #include "Stats.h"
18 #include "Timer.h" 21 #include "Timer.h"
19 22
20 #include "SkBBoxHierarchy.h" 23 #include "SkBBoxHierarchy.h"
21 #include "SkCanvas.h" 24 #include "SkCanvas.h"
22 #include "SkCommonFlags.h" 25 #include "SkCommonFlags.h"
23 #include "SkForceLinking.h" 26 #include "SkForceLinking.h"
24 #include "SkGraphics.h" 27 #include "SkGraphics.h"
25 #include "SkOSFile.h" 28 #include "SkOSFile.h"
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 } 435 }
433 #endif 436 #endif
434 437
435 class BenchmarkStream { 438 class BenchmarkStream {
436 public: 439 public:
437 BenchmarkStream() : fBenches(BenchRegistry::Head()) 440 BenchmarkStream() : fBenches(BenchRegistry::Head())
438 , fGMs(skiagm::GMRegistry::Head()) 441 , fGMs(skiagm::GMRegistry::Head())
439 , fCurrentRecording(0) 442 , fCurrentRecording(0)
440 , fCurrentScale(0) 443 , fCurrentScale(0)
441 , fCurrentSKP(0) 444 , fCurrentSKP(0)
442 , fCurrentUseMPD(0) { 445 , fCurrentUseMPD(0)
446 , fCurrentImage(0)
447 , fCurrentSubsetImage(0)
448 , fCurrentColorType(0)
449 , fDivisor(2) {
443 for (int i = 0; i < FLAGS_skps.count(); i++) { 450 for (int i = 0; i < FLAGS_skps.count(); i++) {
444 if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { 451 if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
445 fSKPs.push_back() = FLAGS_skps[i]; 452 fSKPs.push_back() = FLAGS_skps[i];
446 } else { 453 } else {
447 SkOSFile::Iter it(FLAGS_skps[i], ".skp"); 454 SkOSFile::Iter it(FLAGS_skps[i], ".skp");
448 SkString path; 455 SkString path;
449 while (it.next(&path)) { 456 while (it.next(&path)) {
450 fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str ()); 457 fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str ());
451 } 458 }
452 } 459 }
453 } 460 }
454 461
455 if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d", 462 if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d",
456 &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom )) { 463 &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom )) {
457 SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0 ]); 464 SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0 ]);
458 exit(1); 465 exit(1);
459 } 466 }
460 467
461 for (int i = 0; i < FLAGS_scales.count(); i++) { 468 for (int i = 0; i < FLAGS_scales.count(); i++) {
462 if (1 != sscanf(FLAGS_scales[i], "%f", &fScales.push_back())) { 469 if (1 != sscanf(FLAGS_scales[i], "%f", &fScales.push_back())) {
463 SkDebugf("Can't parse %s from --scales as an SkScalar.\n", FLAGS _scales[i]); 470 SkDebugf("Can't parse %s from --scales as an SkScalar.\n", FLAGS _scales[i]);
464 exit(1); 471 exit(1);
465 } 472 }
466 } 473 }
467 474
468 fUseMPDs.push_back() = false; 475 fUseMPDs.push_back() = false;
469 if (FLAGS_mpd) { 476 if (FLAGS_mpd) {
470 fUseMPDs.push_back() = true; 477 fUseMPDs.push_back() = true;
471 } 478 }
479
480 // Prepare the images for decoding
481 for (int i = 0; i < FLAGS_images.count(); i++) {
482 const char* flag = FLAGS_images[i];
483 if (sk_isdir(flag)) {
484 // If the value passed in is a directory, add all the images
485 SkOSFile::Iter it(flag);
486 SkString file;
487 while (it.next(&file)) {
488 fImages.push_back() = SkOSPath::Join(flag, file.c_str());
489 }
490 } else if (sk_exists(flag)) {
491 // Also add the value if it is a single image
492 fImages.push_back() = flag;
493 }
494 }
495
496 // Choose the candidate color types for image decoding
497 const SkColorType colorTypes[] =
498 { kN32_SkColorType, kRGB_565_SkColorType, kAlpha_8_SkColorType };
499 fColorTypes.push_back_n(SK_ARRAY_COUNT(colorTypes), colorTypes);
472 } 500 }
473 501
474 static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) { 502 static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) {
475 // Not strictly necessary, as it will be checked again later, 503 // Not strictly necessary, as it will be checked again later,
476 // but helps to avoid a lot of pointless work if we're going to skip it. 504 // but helps to avoid a lot of pointless work if we're going to skip it.
477 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) { 505 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) {
478 return false; 506 return false;
479 } 507 }
480 508
481 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path)); 509 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 (name.c_str(), pic.get(), fClip, 583 (name.c_str(), pic.get(), fClip,
556 fScales[fCurrentScale], fUseMPDs[fCurrentUseMPD++]) ); 584 fScales[fCurrentScale], fUseMPDs[fCurrentUseMPD++]) );
557 } 585 }
558 fCurrentUseMPD = 0; 586 fCurrentUseMPD = 0;
559 fCurrentSKP++; 587 fCurrentSKP++;
560 } 588 }
561 fCurrentSKP = 0; 589 fCurrentSKP = 0;
562 fCurrentScale++; 590 fCurrentScale++;
563 } 591 }
564 592
593 // Run the DecodingBenches
594 SkString file;
595 while (fCurrentImage < fImages.count()) {
596 while (fCurrentColorType < fColorTypes.count()) {
597 const SkString& path = fImages[fCurrentImage];
598 SkColorType colorType = fColorTypes[fCurrentColorType];
599 fCurrentColorType++;
600 // Check if the image decodes before creating the benchmark
601 SkBitmap bitmap;
602 if (SkImageDecoder::DecodeFile(path.c_str(), &bitmap,
603 colorType, SkImageDecoder::kDecodePixels_Mode)) {
604 return SkNEW_ARGS(DecodingBench, (path, colorType));
605 }
606 }
607 fCurrentColorType = 0;
608 fCurrentImage++;
609 }
610
611 // Run the DecodingSubsetBenches
612 while (fCurrentSubsetImage < fImages.count()) {
613 while (fCurrentColorType < fColorTypes.count()) {
614 const SkString& path = fImages[fCurrentSubsetImage];
615 SkColorType colorType = fColorTypes[fCurrentColorType];
616 fCurrentColorType++;
617 // Check if the image decodes before creating the benchmark
618 SkAutoTUnref<SkData> encoded(
619 SkData::NewFromFileName(path.c_str()));
620 SkAutoTDelete<SkMemoryStream> stream(
621 new SkMemoryStream(encoded));
622 SkAutoTDelete<SkImageDecoder>
623 decoder(SkImageDecoder::Factory(stream.get()));
624 if (!decoder) {
625 SkDebugf("Cannot find decoder for %s\n", path.c_str());
scroggo 2015/02/12 19:53:28 Why do we make sure decoding succeeds for subset i
msarett 2015/02/12 22:05:45 We do in fact make the check for both. The check
626 } else {
627 stream->rewind();
628 int w, h;
629 bool success;
630 if (!decoder->buildTileIndex(stream.detach(), &w, &h)
631 || w*h == 1) {
632 SkDebugf("Subset decoding is not supported for %s\n",
msarett 2015/02/12 18:57:06 Forgot to mention: We may want to consider failing
mtklein 2015/02/12 19:28:56 Ah. We can certainly fail less loudly. Maybe onl
msarett 2015/02/12 19:42:51 Done.
633 path.c_str());
634 success = false;
635 } else if (fDivisor > w || fDivisor > h) {
636 SkDebugf("Divisor %d is too big for %s %dx%d\n",
637 fDivisor, path.c_str(), w, h);
638 success = false;
639 } else {
640 const int sW = w / fDivisor;
641 const int sH = h / fDivisor;
642 SkBitmap bitmap;
643 success = true;
644 for (int y = 0; y < h; y += sH) {
scroggo 2015/02/12 19:53:28 At first it seemed odd to me that we make sure all
msarett 2015/02/12 22:05:45 It is true that we have similar code in 3 places
645 for (int x = 0; x < w; x += sW) {
646 SkIRect rect = SkIRect::MakeXYWH(x, y, sW, sH);
647 success &= decoder->decodeSubset(&bitmap, rect,
648 colorType);
649 }
650 }
651 }
652 // Create the benchmark if successful
653 if (success) {
654 return SkNEW_ARGS(DecodingSubsetBench,
scroggo 2015/02/12 19:53:28 Any reason you're going back and forth on "new" ve
msarett 2015/02/12 22:05:45 I am happy to not use SkNew!
655 (path, colorType, fDivisor));
656 }
657 }
658 }
659 fCurrentColorType = 0;
660 fCurrentSubsetImage++;
661 }
662
565 return NULL; 663 return NULL;
566 } 664 }
567 665
568 void fillCurrentOptions(ResultsWriter* log) const { 666 void fillCurrentOptions(ResultsWriter* log) const {
569 log->configOption("source_type", fSourceType); 667 log->configOption("source_type", fSourceType);
570 log->configOption("bench_type", fBenchType); 668 log->configOption("bench_type", fBenchType);
571 if (0 == strcmp(fSourceType, "skp")) { 669 if (0 == strcmp(fSourceType, "skp")) {
572 log->configOption("clip", 670 log->configOption("clip",
573 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, 671 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop,
574 fClip.fRight, fClip.fBottom).c _str()); 672 fClip.fRight, fClip.fBottom).c _str());
575 log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentSc ale]).c_str()); 673 log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentSc ale]).c_str());
576 if (fCurrentUseMPD > 0) { 674 if (fCurrentUseMPD > 0) {
577 SkASSERT(1 == fCurrentUseMPD || 2 == fCurrentUseMPD); 675 SkASSERT(1 == fCurrentUseMPD || 2 == fCurrentUseMPD);
578 log->configOption("multi_picture_draw", fUseMPDs[fCurrentUseMPD- 1] ? "true" : "false"); 676 log->configOption("multi_picture_draw", fUseMPDs[fCurrentUseMPD- 1] ? "true" : "false");
579 } 677 }
580 } 678 }
581 if (0 == strcmp(fBenchType, "recording")) { 679 if (0 == strcmp(fBenchType, "recording")) {
582 log->metric("bytes", fSKPBytes); 680 log->metric("bytes", fSKPBytes);
583 log->metric("ops", fSKPOps); 681 log->metric("ops", fSKPOps);
584 } 682 }
585 } 683 }
586 684
587 private: 685 private:
588 const BenchRegistry* fBenches; 686 const BenchRegistry* fBenches;
589 const skiagm::GMRegistry* fGMs; 687 const skiagm::GMRegistry* fGMs;
590 SkIRect fClip; 688 SkIRect fClip;
591 SkTArray<SkScalar> fScales; 689 SkTArray<SkScalar> fScales;
592 SkTArray<SkString> fSKPs; 690 SkTArray<SkString> fSKPs;
593 SkTArray<bool> fUseMPDs; 691 SkTArray<bool> fUseMPDs;
692 SkTArray<SkString> fImages;
693 SkTArray<SkColorType> fColorTypes;
594 694
595 double fSKPBytes, fSKPOps; 695 double fSKPBytes, fSKPOps;
596 696
597 const char* fSourceType; // What we're benching: bench, GM, SKP, ... 697 const char* fSourceType; // What we're benching: bench, GM, SKP, ...
598 const char* fBenchType; // How we bench it: micro, recording, playback, .. . 698 const char* fBenchType; // How we bench it: micro, recording, playback, .. .
599 int fCurrentRecording; 699 int fCurrentRecording;
600 int fCurrentScale; 700 int fCurrentScale;
601 int fCurrentSKP; 701 int fCurrentSKP;
602 int fCurrentUseMPD; 702 int fCurrentUseMPD;
703 int fCurrentImage;
704 int fCurrentSubsetImage;
705 int fCurrentColorType;
706 const int fDivisor;
603 }; 707 };
604 708
605 int nanobench_main(); 709 int nanobench_main();
606 int nanobench_main() { 710 int nanobench_main() {
607 SetupCrashHandler(); 711 SetupCrashHandler();
608 SkAutoGraphics ag; 712 SkAutoGraphics ag;
609 SkTaskGroup::Enabler enabled; 713 SkTaskGroup::Enabler enabled;
610 714
611 #if SK_SUPPORT_GPU 715 #if SK_SUPPORT_GPU
612 GrContext::Options grContextOpts; 716 GrContext::Options grContextOpts;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
793 897
794 return 0; 898 return 0;
795 } 899 }
796 900
797 #if !defined SK_BUILD_FOR_IOS 901 #if !defined SK_BUILD_FOR_IOS
798 int main(int argc, char** argv) { 902 int main(int argc, char** argv) {
799 SkCommandLineFlags::Parse(argc, argv); 903 SkCommandLineFlags::Parse(argc, argv);
800 return nanobench_main(); 904 return nanobench_main();
801 } 905 }
802 #endif 906 #endif
OLDNEW
« bench/DecodingBench.cpp ('K') | « bench/ImageDecodeBench.cpp ('k') | dm/DM.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698