OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |