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

Side by Side Diff: bench/nanobench.cpp

Issue 1160953002: Subset decoding benchmarks (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Tested for multiple images and multiple color types on both codec and image decoder Created 5 years, 6 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 "nanobench.h" 10 #include "nanobench.h"
11 11
12 #include "Benchmark.h" 12 #include "Benchmark.h"
13 #include "CodecBench.h" 13 #include "CodecBench.h"
14 #include "CrashHandler.h" 14 #include "CrashHandler.h"
15 #include "DecodingBench.h" 15 #include "DecodingBench.h"
16 #include "DecodingSubsetBench.h"
17 #include "GMBench.h" 16 #include "GMBench.h"
18 #include "ProcStats.h" 17 #include "ProcStats.h"
19 #include "ResultsWriter.h" 18 #include "ResultsWriter.h"
20 #include "RecordingBench.h" 19 #include "RecordingBench.h"
21 #include "SKPAnimationBench.h" 20 #include "SKPAnimationBench.h"
22 #include "SKPBench.h" 21 #include "SKPBench.h"
22 #include "SubsetBenchPriv.h"
23 #include "SubsetDivisorBench.h"
24 #include "SubsetSingleBench.h"
25 #include "SubsetTranslateBench.h"
26 #include "SubsetZoomBench.h"
23 #include "Stats.h" 27 #include "Stats.h"
24 #include "Timer.h" 28 #include "Timer.h"
25 29
26 #include "SkBBoxHierarchy.h" 30 #include "SkBBoxHierarchy.h"
27 #include "SkCanvas.h" 31 #include "SkCanvas.h"
28 #include "SkCodec.h" 32 #include "SkCodec.h"
29 #include "SkCommonFlags.h" 33 #include "SkCommonFlags.h"
30 #include "SkData.h" 34 #include "SkData.h"
31 #include "SkForceLinking.h" 35 #include "SkForceLinking.h"
32 #include "SkGraphics.h" 36 #include "SkGraphics.h"
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 static void create_targets(SkTDArray<Target*>* targets, Benchmark* b, 479 static void create_targets(SkTDArray<Target*>* targets, Benchmark* b,
476 const SkTDArray<Config>& configs) { 480 const SkTDArray<Config>& configs) {
477 for (int i = 0; i < configs.count(); ++i) { 481 for (int i = 0; i < configs.count(); ++i) {
478 if (Target* t = is_enabled(b, configs[i])) { 482 if (Target* t = is_enabled(b, configs[i])) {
479 targets->push(t); 483 targets->push(t);
480 } 484 }
481 485
482 } 486 }
483 } 487 }
484 488
489 /*
490 * Returns true if set up for a subset decode succeeds, false otherwise
491 * If the set-up succeeds, the width and height parameters will be set
492 */
493 static bool valid_subset_bench(const SkString& path, SkColorType colorType, bool useCodec,
494 int* width, int* height) {
495 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str()));
496 SkAutoTDelete<SkMemoryStream> stream(new SkMemoryStream(encoded));
497
498 if (useCodec) {
499 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach()));
500 if (NULL == codec) {
501 SkDebugf("Could not create codec for %s. Skipping bench.\n", path.c _str());
502 return false;
503 }
504
505 const SkImageInfo info = codec->getInfo().makeColorType(colorType);
506 SkAutoTDeleteArray<uint8_t> row(SkNEW_ARRAY(uint8_t, info.minRowBytes()) );
507 SkScanlineDecoder* scanlineDecoder = codec->getScanlineDecoder(info);
scroggo 2015/06/04 13:50:04 If colortype is Index8, this will always fail, rig
msarett 2015/06/08 16:28:33 Umm yeah it returns NULL in Release mode. But the
508 if (NULL == scanlineDecoder) {
509 SkDebugf("Could not create scanline decoder for %s with color type % s. "
510 "Skipping bench.\n", path.c_str(), get_color_name(colorType) );
511 return false;
512 }
513 *width = info.width();
514 *height = info.height();
515 } else {
516 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
517 if (NULL == decoder) {
518 SkDebugf("Could not create decoder for %s. Skipping bench.\n", path .c_str());
519 return false;
520 }
521 if (!decoder->buildTileIndex(stream.detach(), width, height)) {
522 SkDebugf("Could not build tile index for %s. Skipping bench.\n", pa th.c_str());
523 return false;
524 }
525 }
526 return true;
527 }
485 528
486 class BenchmarkStream { 529 class BenchmarkStream {
487 public: 530 public:
488 BenchmarkStream() : fBenches(BenchRegistry::Head()) 531 BenchmarkStream() : fBenches(BenchRegistry::Head())
489 , fGMs(skiagm::GMRegistry::Head()) 532 , fGMs(skiagm::GMRegistry::Head())
490 , fCurrentRecording(0) 533 , fCurrentRecording(0)
491 , fCurrentScale(0) 534 , fCurrentScale(0)
492 , fCurrentSKP(0) 535 , fCurrentSKP(0)
493 , fCurrentUseMPD(0) 536 , fCurrentUseMPD(0)
494 , fCurrentCodec(0) 537 , fCurrentCodec(0)
495 , fCurrentImage(0) 538 , fCurrentImage(0)
496 , fCurrentSubsetImage(0) 539 , fCurrentSubsetImage(0)
497 , fCurrentColorType(0) 540 , fCurrentColorType(0)
498 , fCurrentAnimSKP(0) 541 , fCurrentSubsetType(0)
499 , fDivisor(2) { 542 , fUseCodec(0)
543 , fCurrentAnimSKP(0) {
500 for (int i = 0; i < FLAGS_skps.count(); i++) { 544 for (int i = 0; i < FLAGS_skps.count(); i++) {
501 if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { 545 if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
502 fSKPs.push_back() = FLAGS_skps[i]; 546 fSKPs.push_back() = FLAGS_skps[i];
503 } else { 547 } else {
504 SkOSFile::Iter it(FLAGS_skps[i], ".skp"); 548 SkOSFile::Iter it(FLAGS_skps[i], ".skp");
505 SkString path; 549 SkString path;
506 while (it.next(&path)) { 550 while (it.next(&path)) {
507 fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str ()); 551 fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str ());
508 } 552 }
509 } 553 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 fImages.push_back() = SkOSPath::Join(flag, file.c_str()); 587 fImages.push_back() = SkOSPath::Join(flag, file.c_str());
544 } 588 }
545 } else if (sk_exists(flag)) { 589 } else if (sk_exists(flag)) {
546 // Also add the value if it is a single image 590 // Also add the value if it is a single image
547 fImages.push_back() = flag; 591 fImages.push_back() = flag;
548 } 592 }
549 } 593 }
550 594
551 // Choose the candidate color types for image decoding 595 // Choose the candidate color types for image decoding
552 const SkColorType colorTypes[] = 596 const SkColorType colorTypes[] =
553 { kN32_SkColorType, kRGB_565_SkColorType, kAlpha_8_SkColorType, kInd ex_8_SkColorType }; 597 { kN32_SkColorType,
598 kRGB_565_SkColorType,
599 kAlpha_8_SkColorType,
600 kIndex_8_SkColorType,
601 kGray_8_SkColorType };
554 fColorTypes.push_back_n(SK_ARRAY_COUNT(colorTypes), colorTypes); 602 fColorTypes.push_back_n(SK_ARRAY_COUNT(colorTypes), colorTypes);
555 } 603 }
556 604
557 static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) { 605 static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) {
558 // Not strictly necessary, as it will be checked again later, 606 // Not strictly necessary, as it will be checked again later,
559 // but helps to avoid a lot of pointless work if we're going to skip it. 607 // but helps to avoid a lot of pointless work if we're going to skip it.
560 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) { 608 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) {
561 return false; 609 return false;
562 } 610 }
563 611
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
730 if (SkImageDecoder::DecodeFile(path.c_str(), &bitmap, 778 if (SkImageDecoder::DecodeFile(path.c_str(), &bitmap,
731 colorType, SkImageDecoder::kDecodePixels_Mode) 779 colorType, SkImageDecoder::kDecodePixels_Mode)
732 && bitmap.colorType() == colorType) { 780 && bitmap.colorType() == colorType) {
733 return new DecodingBench(path, colorType); 781 return new DecodingBench(path, colorType);
734 } 782 }
735 } 783 }
736 fCurrentColorType = 0; 784 fCurrentColorType = 0;
737 fCurrentImage++; 785 fCurrentImage++;
738 } 786 }
739 787
740 // Run the DecodingSubsetBenches 788 // Run the SubsetBenches
741 while (fCurrentSubsetImage < fImages.count()) { 789 bool useCodecOpts[] = { true, false };
742 while (fCurrentColorType < fColorTypes.count()) { 790 while (fUseCodec < 2) {
743 const SkString& path = fImages[fCurrentSubsetImage]; 791 bool useCodec = useCodecOpts[fUseCodec];
744 SkColorType colorType = fColorTypes[fCurrentColorType]; 792 while (fCurrentSubsetImage < fImages.count()) {
745 fCurrentColorType++; 793 while (fCurrentColorType < fColorTypes.count()) {
746 // Check if the image decodes before creating the benchmark 794 const SkString& path = fImages[fCurrentSubsetImage];
747 SkAutoTUnref<SkData> encoded( 795 SkColorType colorType = fColorTypes[fCurrentColorType];
748 SkData::NewFromFileName(path.c_str())); 796 while (fCurrentSubsetType <= kLast_SubsetType) {
749 SkAutoTDelete<SkMemoryStream> stream( 797 int width = 0;
750 new SkMemoryStream(encoded)); 798 int height = 0;
751 SkAutoTDelete<SkImageDecoder> 799 int currentSubsetType = fCurrentSubsetType++;
752 decoder(SkImageDecoder::Factory(stream.get())); 800 if (valid_subset_bench(path, colorType, useCodec, &width , &height)) {
753 if (!decoder) { 801 switch (currentSubsetType) {
754 SkDebugf("Cannot find decoder for %s\n", path.c_str()); 802 case kTopLeft_SubsetType:
755 } else { 803 return new SubsetSingleBench(path, colorType , width/2,
756 stream->rewind(); 804 height/2, 0, 0, useCodec);
757 int w, h; 805 case kTopRight_SubsetType:
758 bool success; 806 return new SubsetSingleBench(path, colorType , width/2,
759 if (!decoder->buildTileIndex(stream.detach(), &w, &h) 807 height/2, width/2, 0, useCodec);
760 || w*h == 1) { 808 case kBottomLeft_SubsetType:
761 // This is not an error, but in this case we still 809 return new SubsetSingleBench(path, colorType , width/2,
762 // do not want to run the benchmark. 810 height/2, 0, height/2, useCodec);
763 success = false; 811 case kBottomRight_SubsetType:
764 } else if (fDivisor > w || fDivisor > h) { 812 return new SubsetSingleBench(path, colorType , width/2,
765 SkDebugf("Divisor %d is too big for %s %dx%d\n", 813 height/2, width/2, height/2, useCode c);
766 fDivisor, path.c_str(), w, h); 814 case k2x2_SubsetType:
767 success = false; 815 return new SubsetDivisorBench(path, colorTyp e, 2, useCodec);
768 } else { 816 case k3x3_SubsetType:
769 const int sW = w / fDivisor; 817 return new SubsetDivisorBench(path, colorTyp e, 3, useCodec);
770 const int sH = h / fDivisor; 818 case kTranslate_SubsetType:
771 SkBitmap bitmap; 819 return new SubsetTranslateBench(path, colorT ype, 512, 512,
772 success = true; 820 useCodec);
773 for (int y = 0; y < h; y += sH) { 821 case kZoom_SubsetType:
774 for (int x = 0; x < w; x += sW) { 822 return new SubsetZoomBench(path, colorType, 512, 512,
775 SkIRect rect = SkIRect::MakeXYWH(x, y, sW, sH); 823 useCodec);
776 success &= decoder->decodeSubset(&bitmap, rect,
777 colorType);
778 } 824 }
825 } else {
826 fCurrentSubsetType = 0;
scroggo 2015/06/04 13:50:04 Is this necessary? Won't we break out of this loop
msarett 2015/06/08 16:28:33 Yes we will!
827 break;
779 } 828 }
780 } 829 }
781 // Create the benchmark if successful 830 fCurrentSubsetType = 0;
782 if (success) { 831 fCurrentColorType++;
783 return new DecodingSubsetBench(path, colorType,
784 fDivisor);
785 }
786 } 832 }
833 fCurrentColorType = 0;
834 fCurrentSubsetImage++;
787 } 835 }
788 fCurrentColorType = 0; 836 fCurrentSubsetImage = 0;
789 fCurrentSubsetImage++; 837 fUseCodec++;
790 } 838 }
791 839
792 return NULL; 840 return NULL;
793 } 841 }
794 842
795 void fillCurrentOptions(ResultsWriter* log) const { 843 void fillCurrentOptions(ResultsWriter* log) const {
796 log->configOption("source_type", fSourceType); 844 log->configOption("source_type", fSourceType);
797 log->configOption("bench_type", fBenchType); 845 log->configOption("bench_type", fBenchType);
798 if (0 == strcmp(fSourceType, "skp")) { 846 if (0 == strcmp(fSourceType, "skp")) {
799 log->configOption("clip", 847 log->configOption("clip",
800 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, 848 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop,
801 fClip.fRight, fClip.fBottom).c _str()); 849 fClip.fRight, fClip.fBottom).c _str());
802 log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentSc ale]).c_str()); 850 log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentSc ale]).c_str());
803 if (fCurrentUseMPD > 0) { 851 if (fCurrentUseMPD > 0) {
804 SkASSERT(1 == fCurrentUseMPD || 2 == fCurrentUseMPD); 852 SkASSERT(1 == fCurrentUseMPD || 2 == fCurrentUseMPD);
805 log->configOption("multi_picture_draw", fUseMPDs[fCurrentUseMPD- 1] ? "true" : "false"); 853 log->configOption("multi_picture_draw", fUseMPDs[fCurrentUseMPD- 1] ? "true" : "false");
806 } 854 }
807 } 855 }
808 if (0 == strcmp(fBenchType, "recording")) { 856 if (0 == strcmp(fBenchType, "recording")) {
809 log->metric("bytes", fSKPBytes); 857 log->metric("bytes", fSKPBytes);
810 log->metric("ops", fSKPOps); 858 log->metric("ops", fSKPOps);
811 } 859 }
812 } 860 }
813 861
814 private: 862 private:
863 enum SubsetType {
864 kTopLeft_SubsetType = 0,
865 kTopRight_SubsetType = 1,
866 kBottomLeft_SubsetType = 2,
867 kBottomRight_SubsetType = 3,
868 k2x2_SubsetType = 4,
869 k3x3_SubsetType = 5,
870 kTranslate_SubsetType = 6,
871 kZoom_SubsetType = 7,
872 kLast_SubsetType = kZoom_SubsetType
873 };
874
815 const BenchRegistry* fBenches; 875 const BenchRegistry* fBenches;
816 const skiagm::GMRegistry* fGMs; 876 const skiagm::GMRegistry* fGMs;
817 SkIRect fClip; 877 SkIRect fClip;
818 SkTArray<SkScalar> fScales; 878 SkTArray<SkScalar> fScales;
819 SkTArray<SkString> fSKPs; 879 SkTArray<SkString> fSKPs;
820 SkTArray<bool> fUseMPDs; 880 SkTArray<bool> fUseMPDs;
821 SkTArray<SkString> fImages; 881 SkTArray<SkString> fImages;
822 SkTArray<SkColorType> fColorTypes; 882 SkTArray<SkColorType> fColorTypes;
823 SkScalar fZoomScale; 883 SkScalar fZoomScale;
824 int fZoomSteps; 884 int fZoomSteps;
825 885
826 double fSKPBytes, fSKPOps; 886 double fSKPBytes, fSKPOps;
827 887
828 const char* fSourceType; // What we're benching: bench, GM, SKP, ... 888 const char* fSourceType; // What we're benching: bench, GM, SKP, ...
829 const char* fBenchType; // How we bench it: micro, recording, playback, .. . 889 const char* fBenchType; // How we bench it: micro, recording, playback, .. .
830 int fCurrentRecording; 890 int fCurrentRecording;
831 int fCurrentScale; 891 int fCurrentScale;
832 int fCurrentSKP; 892 int fCurrentSKP;
833 int fCurrentUseMPD; 893 int fCurrentUseMPD;
834 int fCurrentCodec; 894 int fCurrentCodec;
835 int fCurrentImage; 895 int fCurrentImage;
836 int fCurrentSubsetImage; 896 int fCurrentSubsetImage;
837 int fCurrentColorType; 897 int fCurrentColorType;
898 int fCurrentSubsetType;
899 int fUseCodec;
838 int fCurrentAnimSKP; 900 int fCurrentAnimSKP;
839 const int fDivisor;
840 }; 901 };
841 902
842 int nanobench_main(); 903 int nanobench_main();
843 int nanobench_main() { 904 int nanobench_main() {
844 SetupCrashHandler(); 905 SetupCrashHandler();
845 SkAutoGraphics ag; 906 SkAutoGraphics ag;
846 SkTaskGroup::Enabler enabled; 907 SkTaskGroup::Enabler enabled;
847 908
848 #if SK_SUPPORT_GPU 909 #if SK_SUPPORT_GPU
849 GrContextOptions grContextOpts; 910 GrContextOptions grContextOpts;
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 1089
1029 return 0; 1090 return 0;
1030 } 1091 }
1031 1092
1032 #if !defined SK_BUILD_FOR_IOS 1093 #if !defined SK_BUILD_FOR_IOS
1033 int main(int argc, char** argv) { 1094 int main(int argc, char** argv) {
1034 SkCommandLineFlags::Parse(argc, argv); 1095 SkCommandLineFlags::Parse(argc, argv);
1035 return nanobench_main(); 1096 return nanobench_main();
1036 } 1097 }
1037 #endif 1098 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698