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

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: Test on a few more scales Created 5 years, 2 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 2 scalin g, so we will test
928 // on power of 2 sample sizes. The output tile is always 512x512, so, w hen a
929 // sampleSize is used, the size of the subset that is decoded is always
930 // (sampleSize*512)x(sampleSize*512).
931 // Note that we also test on scales that are not powers of 2. These tes ts are useful
932 // to compare various implementations of BRD, but are not relevant to th e use case
933 // described above.
934 const uint32_t sampleSizes[] = { 1, 2, 3, 4, 5, 6, 7, 8, 16 };
935 const uint32_t minOutputSize = 512;
936 while (fCurrentBRDImage < fImages.count()) {
937 while (fCurrentBRDStrategy < (int) SK_ARRAY_COUNT(strategies)) {
938 while (fCurrentColorType < fColorTypes.count()) {
939 while (fCurrentBRDSampleSize < (int) SK_ARRAY_COUNT(sampleSi zes)) {
940 // JPEG decodes using kOriginal_Strategy are broken for non-power of 2
941 // sample sizes.
942 // skbug.com/4319
943 const SkString& path = fImages[fCurrentBRDImage];
944 const SkBitmapRegionDecoderInterface::Strategy strategy =
945 strategies[fCurrentBRDStrategy];
946 uint32_t sampleSize = sampleSizes[fCurrentBRDSampleSize] ;
947 if (SkBitmapRegionDecoderInterface::kOriginal_Strategy = = strategy &&
948 (path.endsWith(".jpg") || path.endsWith(".JPG") ||
949 path.endsWith(".jpeg") || path.endsWith(".JPEG") ) &&
950 !SkIsPow2(sampleSize)) {
951 fCurrentBRDSampleSize++;
952 continue;
953 }
954
955 while (fCurrentSubsetType <= kLastSingle_SubsetType) {
956 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName (path.c_str()));
957 const SkColorType colorType = fColorTypes[fCurrentCo lorType];
958 int currentSubsetType = fCurrentSubsetType++;
959
960 int width = 0;
961 int height = 0;
962 if (!valid_brd_bench(encoded.get(), strategy, colorT ype, sampleSize,
963 minOutputSize, &width, &height)) {
964 break;
965 } else {
scroggo 2015/09/22 16:57:35 nit: Part of the beauty of handling the break firs
msarett 2015/09/22 17:53:38 Ah yes of course
966 SkString basename = SkOSPath::Basename(path.c_st r());
967 SkIRect subset;
968 const uint32_t subsetSize = sampleSize * minOutp utSize;
969 switch (currentSubsetType) {
970 case kTopLeft_SubsetType:
971 basename.append("_TopLeft");
972 subset = SkIRect::MakeXYWH(0, 0, subsetS ize, subsetSize);
973 break;
974 case kTopRight_SubsetType:
975 basename.append("_TopRight");
976 subset = SkIRect::MakeXYWH(width - subse tSize, 0,
977 subsetSize, subsetSize);
978 break;
979 case kMiddle_SubsetType:
980 basename.append("_Middle");
981 subset = SkIRect::MakeXYWH((width - subs etSize) / 2,
982 (height - subsetSize) / 2, subse tSize, subsetSize);
983 break;
984 case kBottomLeft_SubsetType:
985 basename.append("_BottomLeft");
986 subset = SkIRect::MakeXYWH(0, height - s ubsetSize,
987 subsetSize, subsetSize);
988 break;
989 case kBottomRight_SubsetType:
990 basename.append("_BottomRight");
991 subset = SkIRect::MakeXYWH(width - subse tSize,
992 height - subsetSize, subsetSize, subsetSize);
993 break;
994 default:
995 SkASSERT(false);
996 }
997
998 return new BitmapRegionDecoderBench(basename.c_s tr(), encoded.get(),
999 strategy, colorType, sampleSize, subset) ;
1000 }
1001 }
1002 fCurrentSubsetType = 0;
1003 fCurrentBRDSampleSize++;
1004 }
1005 fCurrentBRDSampleSize = 0;
1006 fCurrentColorType++;
1007 }
1008 fCurrentColorType = 0;
1009 fCurrentBRDStrategy++;
1010 }
1011 fCurrentBRDStrategy = 0;
1012 fCurrentBRDImage++;
1013 }
1014
879 return nullptr; 1015 return nullptr;
880 } 1016 }
881 1017
882 void fillCurrentOptions(ResultsWriter* log) const { 1018 void fillCurrentOptions(ResultsWriter* log) const {
883 log->configOption("source_type", fSourceType); 1019 log->configOption("source_type", fSourceType);
884 log->configOption("bench_type", fBenchType); 1020 log->configOption("bench_type", fBenchType);
885 if (0 == strcmp(fSourceType, "skp")) { 1021 if (0 == strcmp(fSourceType, "skp")) {
886 log->configOption("clip", 1022 log->configOption("clip",
887 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, 1023 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop,
888 fClip.fRight, fClip.fBottom).c _str()); 1024 fClip.fRight, fClip.fBottom).c _str());
(...skipping 11 matching lines...) Expand all
900 1036
901 private: 1037 private:
902 enum SubsetType { 1038 enum SubsetType {
903 kTopLeft_SubsetType = 0, 1039 kTopLeft_SubsetType = 0,
904 kTopRight_SubsetType = 1, 1040 kTopRight_SubsetType = 1,
905 kMiddle_SubsetType = 2, 1041 kMiddle_SubsetType = 2,
906 kBottomLeft_SubsetType = 3, 1042 kBottomLeft_SubsetType = 3,
907 kBottomRight_SubsetType = 4, 1043 kBottomRight_SubsetType = 4,
908 kTranslate_SubsetType = 5, 1044 kTranslate_SubsetType = 5,
909 kZoom_SubsetType = 6, 1045 kZoom_SubsetType = 6,
910 kLast_SubsetType = kZoom_SubsetType 1046 kLast_SubsetType = kZoom_SubsetType,
1047 kLastSingle_SubsetType = kBottomRight_SubsetType,
911 }; 1048 };
912 1049
913 const BenchRegistry* fBenches; 1050 const BenchRegistry* fBenches;
914 const skiagm::GMRegistry* fGMs; 1051 const skiagm::GMRegistry* fGMs;
915 SkIRect fClip; 1052 SkIRect fClip;
916 SkTArray<SkScalar> fScales; 1053 SkTArray<SkScalar> fScales;
917 SkTArray<SkString> fSKPs; 1054 SkTArray<SkString> fSKPs;
918 SkTArray<bool> fUseMPDs; 1055 SkTArray<bool> fUseMPDs;
919 SkTArray<SkString> fImages; 1056 SkTArray<SkString> fImages;
920 SkTArray<SkColorType> fColorTypes; 1057 SkTArray<SkColorType> fColorTypes;
921 SkScalar fZoomMax; 1058 SkScalar fZoomMax;
922 double fZoomPeriodMs; 1059 double fZoomPeriodMs;
923 1060
924 double fSKPBytes, fSKPOps; 1061 double fSKPBytes, fSKPOps;
925 1062
926 const char* fSourceType; // What we're benching: bench, GM, SKP, ... 1063 const char* fSourceType; // What we're benching: bench, GM, SKP, ...
927 const char* fBenchType; // How we bench it: micro, recording, playback, .. . 1064 const char* fBenchType; // How we bench it: micro, recording, playback, .. .
928 int fCurrentRecording; 1065 int fCurrentRecording;
929 int fCurrentScale; 1066 int fCurrentScale;
930 int fCurrentSKP; 1067 int fCurrentSKP;
931 int fCurrentUseMPD; 1068 int fCurrentUseMPD;
932 int fCurrentCodec; 1069 int fCurrentCodec;
933 int fCurrentImage; 1070 int fCurrentImage;
934 int fCurrentSubsetImage; 1071 int fCurrentSubsetImage;
1072 int fCurrentBRDImage;
935 int fCurrentColorType; 1073 int fCurrentColorType;
936 int fCurrentSubsetType; 1074 int fCurrentSubsetType;
937 int fUseCodec; 1075 int fUseCodec;
1076 int fCurrentBRDStrategy;
1077 int fCurrentBRDSampleSize;
938 int fCurrentAnimSKP; 1078 int fCurrentAnimSKP;
939 }; 1079 };
940 1080
941 int nanobench_main(); 1081 int nanobench_main();
942 int nanobench_main() { 1082 int nanobench_main() {
943 SetupCrashHandler(); 1083 SetupCrashHandler();
944 SkAutoGraphics ag; 1084 SkAutoGraphics ag;
945 SkTaskGroup::Enabler enabled(FLAGS_threads); 1085 SkTaskGroup::Enabler enabled(FLAGS_threads);
946 1086
947 #if SK_SUPPORT_GPU 1087 #if SK_SUPPORT_GPU
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 1301
1162 return 0; 1302 return 0;
1163 } 1303 }
1164 1304
1165 #if !defined SK_BUILD_FOR_IOS 1305 #if !defined SK_BUILD_FOR_IOS
1166 int main(int argc, char** argv) { 1306 int main(int argc, char** argv) {
1167 SkCommandLineFlags::Parse(argc, argv); 1307 SkCommandLineFlags::Parse(argc, argv);
1168 return nanobench_main(); 1308 return nanobench_main();
1169 } 1309 }
1170 #endif 1310 #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