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

Side by Side Diff: bench/nanobench.cpp

Issue 1344993003: Add nanobench tests for BitmapRegionDecoder (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 3 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 | « bench/DecodingBench.cpp ('k') | bench/subset/SubsetBenchPriv.h » ('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 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 "BitmapRegionDecoderBench.h"
13 #include "CodecBench.h" 14 #include "CodecBench.h"
15 #include "CodecBenchPriv.h"
14 #include "CrashHandler.h" 16 #include "CrashHandler.h"
15 #include "DecodingBench.h" 17 #include "DecodingBench.h"
16 #include "GMBench.h" 18 #include "GMBench.h"
17 #include "ProcStats.h" 19 #include "ProcStats.h"
18 #include "ResultsWriter.h" 20 #include "ResultsWriter.h"
19 #include "RecordingBench.h" 21 #include "RecordingBench.h"
20 #include "SKPAnimationBench.h" 22 #include "SKPAnimationBench.h"
21 #include "SKPBench.h" 23 #include "SKPBench.h"
22 #include "SubsetBenchPriv.h"
23 #include "SubsetSingleBench.h" 24 #include "SubsetSingleBench.h"
24 #include "SubsetTranslateBench.h" 25 #include "SubsetTranslateBench.h"
25 #include "SubsetZoomBench.h" 26 #include "SubsetZoomBench.h"
26 #include "Stats.h" 27 #include "Stats.h"
27 #include "Timer.h" 28 #include "Timer.h"
28 29
30 #include "SkBitmapRegionDecoderInterface.h"
29 #include "SkBBoxHierarchy.h" 31 #include "SkBBoxHierarchy.h"
30 #include "SkCanvas.h" 32 #include "SkCanvas.h"
31 #include "SkCodec.h" 33 #include "SkCodec.h"
32 #include "SkCommonFlags.h" 34 #include "SkCommonFlags.h"
33 #include "SkData.h" 35 #include "SkData.h"
34 #include "SkForceLinking.h" 36 #include "SkForceLinking.h"
35 #include "SkGraphics.h" 37 #include "SkGraphics.h"
36 #include "SkOSFile.h" 38 #include "SkOSFile.h"
37 #include "SkPictureRecorder.h" 39 #include "SkPictureRecorder.h"
38 #include "SkPictureUtils.h" 40 #include "SkPictureUtils.h"
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 // unused otherwise. 520 // unused otherwise.
519 SkPMColor colors[256]; 521 SkPMColor colors[256];
520 int colorCount; 522 int colorCount;
521 const SkImageInfo info = codec->getInfo().makeColorType(colorType); 523 const SkImageInfo info = codec->getInfo().makeColorType(colorType);
522 SkAutoTDeleteArray<uint8_t> row(new uint8_t[info.minRowBytes()]); 524 SkAutoTDeleteArray<uint8_t> row(new uint8_t[info.minRowBytes()]);
523 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(SkScanlineDecoder::NewF romData(encoded)); 525 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(SkScanlineDecoder::NewF romData(encoded));
524 if (nullptr == scanlineDecoder || scanlineDecoder->start(info, nullptr, 526 if (nullptr == scanlineDecoder || scanlineDecoder->start(info, nullptr,
525 colors, &colorCount) != SkCodec::kSuccess) 527 colors, &colorCount) != SkCodec::kSuccess)
526 { 528 {
527 SkDebugf("Could not create scanline decoder for %s with color type % s. " 529 SkDebugf("Could not create scanline decoder for %s with color type % s. "
528 "Skipping bench.\n", path.c_str(), get_color_name(colorType) ); 530 "Skipping bench.\n", path.c_str(), color_type_to_str(colorTy pe));
529 return false; 531 return false;
530 } 532 }
531 *width = info.width(); 533 *width = info.width();
532 *height = info.height(); 534 *height = info.height();
533 } else { 535 } else {
534 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); 536 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
535 if (nullptr == decoder) { 537 if (nullptr == decoder) {
536 SkDebugf("Could not create decoder for %s. Skipping bench.\n", path .c_str()); 538 SkDebugf("Could not create decoder for %s. Skipping bench.\n", path .c_str());
537 return false; 539 return false;
538 } 540 }
539 //FIXME: See skbug.com/3921 541 //FIXME: See skbug.com/3921
540 if (kIndex_8_SkColorType == colorType || kGray_8_SkColorType == colorTyp e) { 542 if (kIndex_8_SkColorType == colorType || kGray_8_SkColorType == colorTyp e) {
541 SkDebugf("Cannot use image subset decoder for %s with color type %s. " 543 SkDebugf("Cannot use image subset decoder for %s with color type %s. "
542 "Skipping bench.\n", path.c_str(), get_color_name(colorType) ); 544 "Skipping bench.\n", path.c_str(), color_type_to_str(colorTy pe));
543 return false; 545 return false;
544 } 546 }
545 if (!decoder->buildTileIndex(stream.detach(), width, height)) { 547 if (!decoder->buildTileIndex(stream.detach(), width, height)) {
546 SkDebugf("Could not build tile index for %s. Skipping bench.\n", pa th.c_str()); 548 SkDebugf("Could not build tile index for %s. Skipping bench.\n", pa th.c_str());
547 return false; 549 return false;
548 } 550 }
549 } 551 }
550 552
551 // Check if the image is large enough for a meaningful subset benchmark. 553 // Check if the image is large enough for a meaningful subset benchmark.
552 if (*width <= 512 && *height <= 512) { 554 if (*width <= 512 && *height <= 512) {
553 // This should not print a message since it is not an error. 555 // This should not print a message since it is not an error.
554 return false; 556 return false;
555 } 557 }
556 558
557 return true; 559 return true;
558 } 560 }
559 561
562 static bool valid_brd_bench(SkData* encoded, SkBitmapRegionDecoderInterface::Str ategy strategy,
563 SkColorType colorType, uint32_t sampleSize, uint32_t minOutputSize, int* width,
564 int* height) {
565 SkStreamRewindable* stream = new SkMemoryStream(encoded);
566 SkAutoTDelete<SkBitmapRegionDecoderInterface> brd(
567 SkBitmapRegionDecoderInterface::CreateBitmapRegionDecoder(stream, st rategy));
568 if (nullptr == brd.get()) {
569 // This is indicates that subset decoding is not supported for a particu lar image format.
570 return false;
571 }
572
573 SkAutoTDelete<SkBitmap> bitmap(brd->decodeRegion(0, 0, brd->width(), brd->he ight(), 1,
574 colorType));
575 if (nullptr == bitmap.get() || colorType != bitmap->colorType()) {
576 // This indicates that conversion to the requested color type is not sup ported for the
577 // particular image.
578 return false;
579 }
580
581 if (sampleSize * minOutputSize > (uint32_t) brd->width() || sampleSize * min OutputSize >
582 (uint32_t) brd->height()) {
583 // This indicates that the image is not large enough to decode a
584 // minOutputSize x minOutputSize subset at the given sampleSize.
585 return false;
586 }
587
588 // Set the image width and height. The calling code will use this to choose subsets to decode.
589 *width = brd->width();
590 *height = brd->height();
591 return true;
592 }
593
560 static void cleanup_run(Target* target) { 594 static void cleanup_run(Target* target) {
561 delete target; 595 delete target;
562 #if SK_SUPPORT_GPU 596 #if SK_SUPPORT_GPU
563 if (FLAGS_abandonGpuContext) { 597 if (FLAGS_abandonGpuContext) {
564 gGrFactory->abandonContexts(); 598 gGrFactory->abandonContexts();
565 } 599 }
566 if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { 600 if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) {
567 gGrFactory->destroyContexts(); 601 gGrFactory->destroyContexts();
568 } 602 }
569 #endif 603 #endif
570 } 604 }
571 605
572 class BenchmarkStream { 606 class BenchmarkStream {
573 public: 607 public:
574 BenchmarkStream() : fBenches(BenchRegistry::Head()) 608 BenchmarkStream() : fBenches(BenchRegistry::Head())
575 , fGMs(skiagm::GMRegistry::Head()) 609 , fGMs(skiagm::GMRegistry::Head())
576 , fCurrentRecording(0) 610 , fCurrentRecording(0)
577 , fCurrentScale(0) 611 , fCurrentScale(0)
578 , fCurrentSKP(0) 612 , fCurrentSKP(0)
579 , fCurrentUseMPD(0) 613 , fCurrentUseMPD(0)
580 , fCurrentCodec(0) 614 , fCurrentCodec(0)
581 , fCurrentImage(0) 615 , fCurrentImage(0)
582 , fCurrentSubsetImage(0) 616 , fCurrentSubsetImage(0)
617 , fCurrentBRDImage(0)
583 , fCurrentColorType(0) 618 , fCurrentColorType(0)
584 , fCurrentSubsetType(0) 619 , fCurrentSubsetType(0)
585 , fUseCodec(0) 620 , fUseCodec(0)
621 , fCurrentBRDStrategy(0)
622 , fCurrentBRDSampleSize(0)
586 , fCurrentAnimSKP(0) { 623 , fCurrentAnimSKP(0) {
587 for (int i = 0; i < FLAGS_skps.count(); i++) { 624 for (int i = 0; i < FLAGS_skps.count(); i++) {
588 if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { 625 if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
589 fSKPs.push_back() = FLAGS_skps[i]; 626 fSKPs.push_back() = FLAGS_skps[i];
590 } else { 627 } else {
591 SkOSFile::Iter it(FLAGS_skps[i], ".skp"); 628 SkOSFile::Iter it(FLAGS_skps[i], ".skp");
592 SkString path; 629 SkString path;
593 while (it.next(&path)) { 630 while (it.next(&path)) {
594 fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str ()); 631 fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str ());
595 } 632 }
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
869 fCurrentSubsetType = 0; 906 fCurrentSubsetType = 0;
870 fCurrentColorType++; 907 fCurrentColorType++;
871 } 908 }
872 fCurrentColorType = 0; 909 fCurrentColorType = 0;
873 fCurrentSubsetImage++; 910 fCurrentSubsetImage++;
874 } 911 }
875 fCurrentSubsetImage = 0; 912 fCurrentSubsetImage = 0;
876 fUseCodec++; 913 fUseCodec++;
877 } 914 }
878 915
916 // Run the BRDBenches
917 // We will benchmark multiple BRD strategies.
918 const SkBitmapRegionDecoderInterface::Strategy strategies[] = {
919 SkBitmapRegionDecoderInterface::kOriginal_Strategy,
920 SkBitmapRegionDecoderInterface::kCanvas_Strategy,
921 };
922
923 // We intend to create benchmarks that model the use cases in
924 // android/libraries/social/tiledimage. In this library, an image is de coded in 512x512
925 // tiles. The image can be translated freely, so the location of a tile may be anywhere in
926 // the image. For that reason, we will benchmark decodes in five repres entative locations
927 // in the image. Additionally, this use case utilizes power of two scal ing, so we will
928 // test on power of two sample sizes. The output tile is always 512x512 , so, when a
929 // sampleSize is used, the size of the subset that is decoded is always
930 // (sampleSize*512)x(sampleSize*512).
931 // There are a few good reasons to only test on power of two sample size s at this time:
932 // JPEG decodes using kOriginal_Strategy are broken for non-powers o f two.
933 // skbug.com/4319
934 // All use cases we are aware of only scale by powers of two.
935 // PNG decodes use the indicated sampling strategy regardless of the sample size, so
936 // these tests are sufficient to provide good coverage of our sc aling options.
937 const uint32_t sampleSizes[] = { 1, 2, 4, 8, 16 };
938 const uint32_t minOutputSize = 512;
939 while (fCurrentBRDImage < fImages.count()) {
940 while (fCurrentBRDStrategy < (int) SK_ARRAY_COUNT(strategies)) {
941 while (fCurrentColorType < fColorTypes.count()) {
942 while (fCurrentBRDSampleSize < (int) SK_ARRAY_COUNT(sampleSi zes)) {
943 while (fCurrentSubsetType <= kLastSingle_SubsetType) {
944 const SkString& path = fImages[fCurrentBRDImage];
945 const SkBitmapRegionDecoderInterface::Strategy strat egy =
946 strategies[fCurrentBRDStrategy];
947 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName (path.c_str()));
948 const SkColorType colorType = fColorTypes[fCurrentCo lorType];
949 uint32_t sampleSize = sampleSizes[fCurrentBRDSampleS ize];
950 int currentSubsetType = fCurrentSubsetType++;
951
952 int width = 0;
953 int height = 0;
954 if (!valid_brd_bench(encoded.get(), strategy, colorT ype, sampleSize,
955 minOutputSize, &width, &height)) {
956 break;
957 }
958
959 SkString basename = SkOSPath::Basename(path.c_str()) ;
960 SkIRect subset;
961 const uint32_t subsetSize = sampleSize * minOutputSi ze;
962 switch (currentSubsetType) {
963 case kTopLeft_SubsetType:
964 basename.append("_TopLeft");
965 subset = SkIRect::MakeXYWH(0, 0, subsetSize, subsetSize);
966 break;
967 case kTopRight_SubsetType:
968 basename.append("_TopRight");
969 subset = SkIRect::MakeXYWH(width - subsetSiz e, 0, subsetSize,
970 subsetSize);
971 break;
972 case kMiddle_SubsetType:
973 basename.append("_Middle");
974 subset = SkIRect::MakeXYWH((width - subsetSi ze) / 2,
975 (height - subsetSize) / 2, subsetSiz e, subsetSize);
976 break;
977 case kBottomLeft_SubsetType:
978 basename.append("_BottomLeft");
979 subset = SkIRect::MakeXYWH(0, height - subse tSize, subsetSize,
980 subsetSize);
981 break;
982 case kBottomRight_SubsetType:
983 basename.append("_BottomRight");
984 subset = SkIRect::MakeXYWH(width - subsetSiz e,
985 height - subsetSize, subsetSize, sub setSize);
986 break;
987 default:
988 SkASSERT(false);
989 }
990
991 return new BitmapRegionDecoderBench(basename.c_str() , encoded.get(),
992 strategy, colorType, sampleSize, subset);
993 }
994 fCurrentSubsetType = 0;
995 fCurrentBRDSampleSize++;
996 }
997 fCurrentBRDSampleSize = 0;
998 fCurrentColorType++;
999 }
1000 fCurrentColorType = 0;
1001 fCurrentBRDStrategy++;
1002 }
1003 fCurrentBRDStrategy = 0;
1004 fCurrentBRDImage++;
1005 }
1006
879 return nullptr; 1007 return nullptr;
880 } 1008 }
881 1009
882 void fillCurrentOptions(ResultsWriter* log) const { 1010 void fillCurrentOptions(ResultsWriter* log) const {
883 log->configOption("source_type", fSourceType); 1011 log->configOption("source_type", fSourceType);
884 log->configOption("bench_type", fBenchType); 1012 log->configOption("bench_type", fBenchType);
885 if (0 == strcmp(fSourceType, "skp")) { 1013 if (0 == strcmp(fSourceType, "skp")) {
886 log->configOption("clip", 1014 log->configOption("clip",
887 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, 1015 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop,
888 fClip.fRight, fClip.fBottom).c _str()); 1016 fClip.fRight, fClip.fBottom).c _str());
(...skipping 11 matching lines...) Expand all
900 1028
901 private: 1029 private:
902 enum SubsetType { 1030 enum SubsetType {
903 kTopLeft_SubsetType = 0, 1031 kTopLeft_SubsetType = 0,
904 kTopRight_SubsetType = 1, 1032 kTopRight_SubsetType = 1,
905 kMiddle_SubsetType = 2, 1033 kMiddle_SubsetType = 2,
906 kBottomLeft_SubsetType = 3, 1034 kBottomLeft_SubsetType = 3,
907 kBottomRight_SubsetType = 4, 1035 kBottomRight_SubsetType = 4,
908 kTranslate_SubsetType = 5, 1036 kTranslate_SubsetType = 5,
909 kZoom_SubsetType = 6, 1037 kZoom_SubsetType = 6,
910 kLast_SubsetType = kZoom_SubsetType 1038 kLast_SubsetType = kZoom_SubsetType,
1039 kLastSingle_SubsetType = kBottomRight_SubsetType,
911 }; 1040 };
912 1041
913 const BenchRegistry* fBenches; 1042 const BenchRegistry* fBenches;
914 const skiagm::GMRegistry* fGMs; 1043 const skiagm::GMRegistry* fGMs;
915 SkIRect fClip; 1044 SkIRect fClip;
916 SkTArray<SkScalar> fScales; 1045 SkTArray<SkScalar> fScales;
917 SkTArray<SkString> fSKPs; 1046 SkTArray<SkString> fSKPs;
918 SkTArray<bool> fUseMPDs; 1047 SkTArray<bool> fUseMPDs;
919 SkTArray<SkString> fImages; 1048 SkTArray<SkString> fImages;
920 SkTArray<SkColorType> fColorTypes; 1049 SkTArray<SkColorType> fColorTypes;
921 SkScalar fZoomMax; 1050 SkScalar fZoomMax;
922 double fZoomPeriodMs; 1051 double fZoomPeriodMs;
923 1052
924 double fSKPBytes, fSKPOps; 1053 double fSKPBytes, fSKPOps;
925 1054
926 const char* fSourceType; // What we're benching: bench, GM, SKP, ... 1055 const char* fSourceType; // What we're benching: bench, GM, SKP, ...
927 const char* fBenchType; // How we bench it: micro, recording, playback, .. . 1056 const char* fBenchType; // How we bench it: micro, recording, playback, .. .
928 int fCurrentRecording; 1057 int fCurrentRecording;
929 int fCurrentScale; 1058 int fCurrentScale;
930 int fCurrentSKP; 1059 int fCurrentSKP;
931 int fCurrentUseMPD; 1060 int fCurrentUseMPD;
932 int fCurrentCodec; 1061 int fCurrentCodec;
933 int fCurrentImage; 1062 int fCurrentImage;
934 int fCurrentSubsetImage; 1063 int fCurrentSubsetImage;
1064 int fCurrentBRDImage;
935 int fCurrentColorType; 1065 int fCurrentColorType;
936 int fCurrentSubsetType; 1066 int fCurrentSubsetType;
937 int fUseCodec; 1067 int fUseCodec;
1068 int fCurrentBRDStrategy;
1069 int fCurrentBRDSampleSize;
938 int fCurrentAnimSKP; 1070 int fCurrentAnimSKP;
939 }; 1071 };
940 1072
941 int nanobench_main(); 1073 int nanobench_main();
942 int nanobench_main() { 1074 int nanobench_main() {
943 SetupCrashHandler(); 1075 SetupCrashHandler();
944 SkAutoGraphics ag; 1076 SkAutoGraphics ag;
945 SkTaskGroup::Enabler enabled(FLAGS_threads); 1077 SkTaskGroup::Enabler enabled(FLAGS_threads);
946 1078
947 #if SK_SUPPORT_GPU 1079 #if SK_SUPPORT_GPU
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 1293
1162 return 0; 1294 return 0;
1163 } 1295 }
1164 1296
1165 #if !defined SK_BUILD_FOR_IOS 1297 #if !defined SK_BUILD_FOR_IOS
1166 int main(int argc, char** argv) { 1298 int main(int argc, char** argv) {
1167 SkCommandLineFlags::Parse(argc, argv); 1299 SkCommandLineFlags::Parse(argc, argv);
1168 return nanobench_main(); 1300 return nanobench_main();
1169 } 1301 }
1170 #endif 1302 #endif
OLDNEW
« no previous file with comments | « bench/DecodingBench.cpp ('k') | bench/subset/SubsetBenchPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698