| 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" |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 bmp->setInfo(canvas->imageInfo()); | 134 bmp->setInfo(canvas->imageInfo()); |
| 135 if (!canvas->readPixels(bmp, 0, 0)) { | 135 if (!canvas->readPixels(bmp, 0, 0)) { |
| 136 SkDebugf("Can't read canvas pixels.\n"); | 136 SkDebugf("Can't read canvas pixels.\n"); |
| 137 return false; | 137 return false; |
| 138 } | 138 } |
| 139 return true; | 139 return true; |
| 140 } | 140 } |
| 141 | 141 |
| 142 #if SK_SUPPORT_GPU | 142 #if SK_SUPPORT_GPU |
| 143 struct GPUTarget : public Target { | 143 struct GPUTarget : public Target { |
| 144 explicit GPUTarget(const Config& c) : Target(c), gl(NULL) { } | 144 explicit GPUTarget(const Config& c) : Target(c), gl(nullptr) { } |
| 145 SkGLContext* gl; | 145 SkGLContext* gl; |
| 146 | 146 |
| 147 void setup() override { | 147 void setup() override { |
| 148 this->gl->makeCurrent(); | 148 this->gl->makeCurrent(); |
| 149 // Make sure we're done with whatever came before. | 149 // Make sure we're done with whatever came before. |
| 150 SK_GL(*this->gl, Finish()); | 150 SK_GL(*this->gl, Finish()); |
| 151 } | 151 } |
| 152 void endTiming() override { | 152 void endTiming() override { |
| 153 if (this->gl) { | 153 if (this->gl) { |
| 154 SK_GL(*this->gl, Flush()); | 154 SK_GL(*this->gl, Flush()); |
| (...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 | 451 |
| 452 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK | 452 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK |
| 453 if (is_cpu_config_allowed("hwui")) { | 453 if (is_cpu_config_allowed("hwui")) { |
| 454 Config config = { "hwui", Benchmark::kHWUI_Backend, kRGBA_8888_SkColorTy
pe, | 454 Config config = { "hwui", Benchmark::kHWUI_Backend, kRGBA_8888_SkColorTy
pe, |
| 455 kPremul_SkAlphaType, 0, kBogusGLContextType, false }; | 455 kPremul_SkAlphaType, 0, kBogusGLContextType, false }; |
| 456 configs->push(config); | 456 configs->push(config); |
| 457 } | 457 } |
| 458 #endif | 458 #endif |
| 459 } | 459 } |
| 460 | 460 |
| 461 // If bench is enabled for config, returns a Target* for it, otherwise NULL. | 461 // If bench is enabled for config, returns a Target* for it, otherwise nullptr. |
| 462 static Target* is_enabled(Benchmark* bench, const Config& config) { | 462 static Target* is_enabled(Benchmark* bench, const Config& config) { |
| 463 if (!bench->isSuitableFor(config.backend)) { | 463 if (!bench->isSuitableFor(config.backend)) { |
| 464 return NULL; | 464 return nullptr; |
| 465 } | 465 } |
| 466 | 466 |
| 467 SkImageInfo info = SkImageInfo::Make(bench->getSize().fX, bench->getSize().f
Y, | 467 SkImageInfo info = SkImageInfo::Make(bench->getSize().fX, bench->getSize().f
Y, |
| 468 config.color, config.alpha); | 468 config.color, config.alpha); |
| 469 | 469 |
| 470 Target* target = NULL; | 470 Target* target = nullptr; |
| 471 | 471 |
| 472 switch (config.backend) { | 472 switch (config.backend) { |
| 473 #if SK_SUPPORT_GPU | 473 #if SK_SUPPORT_GPU |
| 474 case Benchmark::kGPU_Backend: | 474 case Benchmark::kGPU_Backend: |
| 475 target = new GPUTarget(config); | 475 target = new GPUTarget(config); |
| 476 break; | 476 break; |
| 477 #endif | 477 #endif |
| 478 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK | 478 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK |
| 479 case Benchmark::kHWUI_Backend: | 479 case Benchmark::kHWUI_Backend: |
| 480 target = new HWUITarget(config, bench); | 480 target = new HWUITarget(config, bench); |
| 481 break; | 481 break; |
| 482 #endif | 482 #endif |
| 483 default: | 483 default: |
| 484 target = new Target(config); | 484 target = new Target(config); |
| 485 break; | 485 break; |
| 486 } | 486 } |
| 487 | 487 |
| 488 if (!target->init(info, bench)) { | 488 if (!target->init(info, bench)) { |
| 489 delete target; | 489 delete target; |
| 490 return NULL; | 490 return nullptr; |
| 491 } | 491 } |
| 492 return target; | 492 return target; |
| 493 } | 493 } |
| 494 | 494 |
| 495 /* | 495 /* |
| 496 * Returns true if set up for a subset decode succeeds, false otherwise | 496 * Returns true if set up for a subset decode succeeds, false otherwise |
| 497 * If the set-up succeeds, the width and height parameters will be set | 497 * If the set-up succeeds, the width and height parameters will be set |
| 498 */ | 498 */ |
| 499 static bool valid_subset_bench(const SkString& path, SkColorType colorType, bool
useCodec, | 499 static bool valid_subset_bench(const SkString& path, SkColorType colorType, bool
useCodec, |
| 500 int* width, int* height) { | 500 int* width, int* height) { |
| 501 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); | 501 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); |
| 502 SkAutoTDelete<SkMemoryStream> stream(new SkMemoryStream(encoded)); | 502 SkAutoTDelete<SkMemoryStream> stream(new SkMemoryStream(encoded)); |
| 503 | 503 |
| 504 // Check that we can create a codec or image decoder. | 504 // Check that we can create a codec or image decoder. |
| 505 if (useCodec) { | 505 if (useCodec) { |
| 506 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); | 506 SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); |
| 507 if (NULL == codec) { | 507 if (nullptr == codec) { |
| 508 SkDebugf("Could not create codec for %s. Skipping bench.\n", path.c
_str()); | 508 SkDebugf("Could not create codec for %s. Skipping bench.\n", path.c
_str()); |
| 509 return false; | 509 return false; |
| 510 } | 510 } |
| 511 | 511 |
| 512 // These will be initialized by SkCodec if the color type is kIndex8 and | 512 // These will be initialized by SkCodec if the color type is kIndex8 and |
| 513 // unused otherwise. | 513 // unused otherwise. |
| 514 SkPMColor colors[256]; | 514 SkPMColor colors[256]; |
| 515 int colorCount; | 515 int colorCount; |
| 516 const SkImageInfo info = codec->getInfo().makeColorType(colorType); | 516 const SkImageInfo info = codec->getInfo().makeColorType(colorType); |
| 517 SkAutoTDeleteArray<uint8_t> row(new uint8_t[info.minRowBytes()]); | 517 SkAutoTDeleteArray<uint8_t> row(new uint8_t[info.minRowBytes()]); |
| 518 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(SkScanlineDecoder::NewF
romData(encoded)); | 518 SkAutoTDelete<SkScanlineDecoder> scanlineDecoder(SkScanlineDecoder::NewF
romData(encoded)); |
| 519 if (NULL == scanlineDecoder || scanlineDecoder->start(info, NULL, | 519 if (nullptr == scanlineDecoder || scanlineDecoder->start(info, nullptr, |
| 520 colors, &colorCount) != SkCodec::kSuccess) | 520 colors, &colorCount) != SkCodec::kSuccess) |
| 521 { | 521 { |
| 522 SkDebugf("Could not create scanline decoder for %s with color type %
s. " | 522 SkDebugf("Could not create scanline decoder for %s with color type %
s. " |
| 523 "Skipping bench.\n", path.c_str(), get_color_name(colorType)
); | 523 "Skipping bench.\n", path.c_str(), get_color_name(colorType)
); |
| 524 return false; | 524 return false; |
| 525 } | 525 } |
| 526 *width = info.width(); | 526 *width = info.width(); |
| 527 *height = info.height(); | 527 *height = info.height(); |
| 528 } else { | 528 } else { |
| 529 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); | 529 SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); |
| 530 if (NULL == decoder) { | 530 if (nullptr == decoder) { |
| 531 SkDebugf("Could not create decoder for %s. Skipping bench.\n", path
.c_str()); | 531 SkDebugf("Could not create decoder for %s. Skipping bench.\n", path
.c_str()); |
| 532 return false; | 532 return false; |
| 533 } | 533 } |
| 534 //FIXME: See skbug.com/3921 | 534 //FIXME: See skbug.com/3921 |
| 535 if (kIndex_8_SkColorType == colorType || kGray_8_SkColorType == colorTyp
e) { | 535 if (kIndex_8_SkColorType == colorType || kGray_8_SkColorType == colorTyp
e) { |
| 536 SkDebugf("Cannot use image subset decoder for %s with color type %s.
" | 536 SkDebugf("Cannot use image subset decoder for %s with color type %s.
" |
| 537 "Skipping bench.\n", path.c_str(), get_color_name(colorType)
); | 537 "Skipping bench.\n", path.c_str(), get_color_name(colorType)
); |
| 538 return false; | 538 return false; |
| 539 } | 539 } |
| 540 if (!decoder->buildTileIndex(stream.detach(), width, height)) { | 540 if (!decoder->buildTileIndex(stream.detach(), width, height)) { |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 641 } | 641 } |
| 642 | 642 |
| 643 static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) { | 643 static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) { |
| 644 // Not strictly necessary, as it will be checked again later, | 644 // Not strictly necessary, as it will be checked again later, |
| 645 // but helps to avoid a lot of pointless work if we're going to skip it. | 645 // but helps to avoid a lot of pointless work if we're going to skip it. |
| 646 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) { | 646 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) { |
| 647 return false; | 647 return false; |
| 648 } | 648 } |
| 649 | 649 |
| 650 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path)); | 650 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path)); |
| 651 if (stream.get() == NULL) { | 651 if (stream.get() == nullptr) { |
| 652 SkDebugf("Could not read %s.\n", path); | 652 SkDebugf("Could not read %s.\n", path); |
| 653 return false; | 653 return false; |
| 654 } | 654 } |
| 655 | 655 |
| 656 pic->reset(SkPicture::CreateFromStream(stream.get())); | 656 pic->reset(SkPicture::CreateFromStream(stream.get())); |
| 657 if (pic->get() == NULL) { | 657 if (pic->get() == nullptr) { |
| 658 SkDebugf("Could not read %s as an SkPicture.\n", path); | 658 SkDebugf("Could not read %s as an SkPicture.\n", path); |
| 659 return false; | 659 return false; |
| 660 } | 660 } |
| 661 return true; | 661 return true; |
| 662 } | 662 } |
| 663 | 663 |
| 664 Benchmark* next() { | 664 Benchmark* next() { |
| 665 if (fBenches) { | 665 if (fBenches) { |
| 666 Benchmark* bench = fBenches->factory()(NULL); | 666 Benchmark* bench = fBenches->factory()(nullptr); |
| 667 fBenches = fBenches->next(); | 667 fBenches = fBenches->next(); |
| 668 fSourceType = "bench"; | 668 fSourceType = "bench"; |
| 669 fBenchType = "micro"; | 669 fBenchType = "micro"; |
| 670 return bench; | 670 return bench; |
| 671 } | 671 } |
| 672 | 672 |
| 673 while (fGMs) { | 673 while (fGMs) { |
| 674 SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(NULL)); | 674 SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr)); |
| 675 fGMs = fGMs->next(); | 675 fGMs = fGMs->next(); |
| 676 if (gm->runAsBench()) { | 676 if (gm->runAsBench()) { |
| 677 fSourceType = "gm"; | 677 fSourceType = "gm"; |
| 678 fBenchType = "micro"; | 678 fBenchType = "micro"; |
| 679 return new GMBench(gm.detach()); | 679 return new GMBench(gm.detach()); |
| 680 } | 680 } |
| 681 } | 681 } |
| 682 | 682 |
| 683 // First add all .skps as RecordingBenches. | 683 // First add all .skps as RecordingBenches. |
| 684 while (fCurrentRecording < fSKPs.count()) { | 684 while (fCurrentRecording < fSKPs.count()) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 776 } | 776 } |
| 777 | 777 |
| 778 const size_t rowBytes = info.minRowBytes(); | 778 const size_t rowBytes = info.minRowBytes(); |
| 779 SkAutoMalloc storage(info.getSafeSize(rowBytes)); | 779 SkAutoMalloc storage(info.getSafeSize(rowBytes)); |
| 780 | 780 |
| 781 // Used if fCurrentColorType is kIndex_8_SkColorType | 781 // Used if fCurrentColorType is kIndex_8_SkColorType |
| 782 int colorCount = 256; | 782 int colorCount = 256; |
| 783 SkPMColor colors[256]; | 783 SkPMColor colors[256]; |
| 784 | 784 |
| 785 const SkCodec::Result result = codec->getPixels( | 785 const SkCodec::Result result = codec->getPixels( |
| 786 info, storage.get(), rowBytes, NULL, colors, | 786 info, storage.get(), rowBytes, nullptr, colors, |
| 787 &colorCount); | 787 &colorCount); |
| 788 switch (result) { | 788 switch (result) { |
| 789 case SkCodec::kSuccess: | 789 case SkCodec::kSuccess: |
| 790 case SkCodec::kIncompleteInput: | 790 case SkCodec::kIncompleteInput: |
| 791 return new CodecBench(SkOSPath::Basename(path.c_str()), | 791 return new CodecBench(SkOSPath::Basename(path.c_str()), |
| 792 encoded, colorType); | 792 encoded, colorType); |
| 793 case SkCodec::kInvalidConversion: | 793 case SkCodec::kInvalidConversion: |
| 794 // This is okay. Not all conversions are valid. | 794 // This is okay. Not all conversions are valid. |
| 795 break; | 795 break; |
| 796 default: | 796 default: |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 864 fCurrentSubsetType = 0; | 864 fCurrentSubsetType = 0; |
| 865 fCurrentColorType++; | 865 fCurrentColorType++; |
| 866 } | 866 } |
| 867 fCurrentColorType = 0; | 867 fCurrentColorType = 0; |
| 868 fCurrentSubsetImage++; | 868 fCurrentSubsetImage++; |
| 869 } | 869 } |
| 870 fCurrentSubsetImage = 0; | 870 fCurrentSubsetImage = 0; |
| 871 fUseCodec++; | 871 fUseCodec++; |
| 872 } | 872 } |
| 873 | 873 |
| 874 return NULL; | 874 return nullptr; |
| 875 } | 875 } |
| 876 | 876 |
| 877 void fillCurrentOptions(ResultsWriter* log) const { | 877 void fillCurrentOptions(ResultsWriter* log) const { |
| 878 log->configOption("source_type", fSourceType); | 878 log->configOption("source_type", fSourceType); |
| 879 log->configOption("bench_type", fBenchType); | 879 log->configOption("bench_type", fBenchType); |
| 880 if (0 == strcmp(fSourceType, "skp")) { | 880 if (0 == strcmp(fSourceType, "skp")) { |
| 881 log->configOption("clip", | 881 log->configOption("clip", |
| 882 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, | 882 SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, |
| 883 fClip.fRight, fClip.fBottom).c
_str()); | 883 fClip.fRight, fClip.fBottom).c
_str()); |
| 884 log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentSc
ale]).c_str()); | 884 log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentSc
ale]).c_str()); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 | 969 |
| 970 if (kAutoTuneLoops != FLAGS_loops) { | 970 if (kAutoTuneLoops != FLAGS_loops) { |
| 971 FLAGS_samples = 1; | 971 FLAGS_samples = 1; |
| 972 FLAGS_gpuFrameLag = 0; | 972 FLAGS_gpuFrameLag = 0; |
| 973 } | 973 } |
| 974 | 974 |
| 975 if (!FLAGS_writePath.isEmpty()) { | 975 if (!FLAGS_writePath.isEmpty()) { |
| 976 SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); | 976 SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); |
| 977 if (!sk_mkdir(FLAGS_writePath[0])) { | 977 if (!sk_mkdir(FLAGS_writePath[0])) { |
| 978 SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_wri
tePath[0]); | 978 SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_wri
tePath[0]); |
| 979 FLAGS_writePath.set(0, NULL); | 979 FLAGS_writePath.set(0, nullptr); |
| 980 } | 980 } |
| 981 } | 981 } |
| 982 | 982 |
| 983 SkAutoTDelete<ResultsWriter> log(new ResultsWriter); | 983 SkAutoTDelete<ResultsWriter> log(new ResultsWriter); |
| 984 if (!FLAGS_outResultsFile.isEmpty()) { | 984 if (!FLAGS_outResultsFile.isEmpty()) { |
| 985 log.reset(new NanoJSONResultsWriter(FLAGS_outResultsFile[0])); | 985 log.reset(new NanoJSONResultsWriter(FLAGS_outResultsFile[0])); |
| 986 } | 986 } |
| 987 | 987 |
| 988 if (1 == FLAGS_properties.count() % 2) { | 988 if (1 == FLAGS_properties.count() % 2) { |
| 989 SkDebugf("ERROR: --properties must be passed with an even number of argu
ments.\n"); | 989 SkDebugf("ERROR: --properties must be passed with an even number of argu
ments.\n"); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1031 if (!configs.isEmpty()) { | 1031 if (!configs.isEmpty()) { |
| 1032 log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSi
ze().fY); | 1032 log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSi
ze().fY); |
| 1033 bench->preDraw(); | 1033 bench->preDraw(); |
| 1034 } | 1034 } |
| 1035 for (int i = 0; i < configs.count(); ++i) { | 1035 for (int i = 0; i < configs.count(); ++i) { |
| 1036 Target* target = is_enabled(b, configs[i]); | 1036 Target* target = is_enabled(b, configs[i]); |
| 1037 if (!target) { | 1037 if (!target) { |
| 1038 continue; | 1038 continue; |
| 1039 } | 1039 } |
| 1040 | 1040 |
| 1041 // During HWUI output this canvas may be NULL. | 1041 // During HWUI output this canvas may be nullptr. |
| 1042 SkCanvas* canvas = target->getCanvas(); | 1042 SkCanvas* canvas = target->getCanvas(); |
| 1043 const char* config = target->config.name; | 1043 const char* config = target->config.name; |
| 1044 | 1044 |
| 1045 target->setup(); | 1045 target->setup(); |
| 1046 bench->perCanvasPreDraw(canvas); | 1046 bench->perCanvasPreDraw(canvas); |
| 1047 | 1047 |
| 1048 int maxFrameLag; | 1048 int maxFrameLag; |
| 1049 const int loops = target->needsFrameTiming(&maxFrameLag) | 1049 const int loops = target->needsFrameTiming(&maxFrameLag) |
| 1050 ? setup_gpu_bench(target, bench.get(), maxFrameLag) | 1050 ? setup_gpu_bench(target, bench.get(), maxFrameLag) |
| 1051 : setup_cpu_bench(overhead, target, bench.get()); | 1051 : setup_cpu_bench(overhead, target, bench.get()); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1144 } | 1144 } |
| 1145 } | 1145 } |
| 1146 | 1146 |
| 1147 log->bench("memory_usage", 0,0); | 1147 log->bench("memory_usage", 0,0); |
| 1148 log->config("meta"); | 1148 log->config("meta"); |
| 1149 log->metric("max_rss_mb", sk_tools::getMaxResidentSetSizeMB()); | 1149 log->metric("max_rss_mb", sk_tools::getMaxResidentSetSizeMB()); |
| 1150 | 1150 |
| 1151 #if SK_SUPPORT_GPU | 1151 #if SK_SUPPORT_GPU |
| 1152 // Make sure we clean up the global GrContextFactory here, otherwise we migh
t race with the | 1152 // Make sure we clean up the global GrContextFactory here, otherwise we migh
t race with the |
| 1153 // SkEventTracer destructor | 1153 // SkEventTracer destructor |
| 1154 gGrFactory.reset(NULL); | 1154 gGrFactory.reset(nullptr); |
| 1155 #endif | 1155 #endif |
| 1156 | 1156 |
| 1157 return 0; | 1157 return 0; |
| 1158 } | 1158 } |
| 1159 | 1159 |
| 1160 #if !defined SK_BUILD_FOR_IOS | 1160 #if !defined SK_BUILD_FOR_IOS |
| 1161 int main(int argc, char** argv) { | 1161 int main(int argc, char** argv) { |
| 1162 SkCommandLineFlags::Parse(argc, argv); | 1162 SkCommandLineFlags::Parse(argc, argv); |
| 1163 return nanobench_main(); | 1163 return nanobench_main(); |
| 1164 } | 1164 } |
| 1165 #endif | 1165 #endif |
| OLD | NEW |