| 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 470 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 break; | 481 break; |
| 482 } | 482 } |
| 483 | 483 |
| 484 if (!target->init(info, bench)) { | 484 if (!target->init(info, bench)) { |
| 485 delete target; | 485 delete target; |
| 486 return NULL; | 486 return NULL; |
| 487 } | 487 } |
| 488 return target; | 488 return target; |
| 489 } | 489 } |
| 490 | 490 |
| 491 // Creates targets for a benchmark and a set of configs. | |
| 492 static void create_targets(SkTDArray<Target*>* targets, Benchmark* b, | |
| 493 const SkTDArray<Config>& configs) { | |
| 494 for (int i = 0; i < configs.count(); ++i) { | |
| 495 if (Target* t = is_enabled(b, configs[i])) { | |
| 496 targets->push(t); | |
| 497 } | |
| 498 | |
| 499 } | |
| 500 } | |
| 501 | |
| 502 /* | 491 /* |
| 503 * Returns true if set up for a subset decode succeeds, false otherwise | 492 * Returns true if set up for a subset decode succeeds, false otherwise |
| 504 * If the set-up succeeds, the width and height parameters will be set | 493 * If the set-up succeeds, the width and height parameters will be set |
| 505 */ | 494 */ |
| 506 static bool valid_subset_bench(const SkString& path, SkColorType colorType, bool
useCodec, | 495 static bool valid_subset_bench(const SkString& path, SkColorType colorType, bool
useCodec, |
| 507 int* width, int* height) { | 496 int* width, int* height) { |
| 508 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); | 497 SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); |
| 509 SkAutoTDelete<SkMemoryStream> stream(new SkMemoryStream(encoded)); | 498 SkAutoTDelete<SkMemoryStream> stream(new SkMemoryStream(encoded)); |
| 510 | 499 |
| 511 // Check that we can create a codec or image decoder. | 500 // Check that we can create a codec or image decoder. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 551 | 540 |
| 552 // Check if the image is large enough for a meaningful subset benchmark. | 541 // Check if the image is large enough for a meaningful subset benchmark. |
| 553 if (*width <= 512 && *height <= 512) { | 542 if (*width <= 512 && *height <= 512) { |
| 554 // This should not print a message since it is not an error. | 543 // This should not print a message since it is not an error. |
| 555 return false; | 544 return false; |
| 556 } | 545 } |
| 557 | 546 |
| 558 return true; | 547 return true; |
| 559 } | 548 } |
| 560 | 549 |
| 550 static void cleanup_run(Target* target) { |
| 551 SkDELETE(target); |
| 552 #if SK_SUPPORT_GPU |
| 553 if (FLAGS_abandonGpuContext) { |
| 554 gGrFactory->abandonContexts(); |
| 555 } |
| 556 if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { |
| 557 gGrFactory->destroyContexts(); |
| 558 } |
| 559 #endif |
| 560 } |
| 561 |
| 561 class BenchmarkStream { | 562 class BenchmarkStream { |
| 562 public: | 563 public: |
| 563 BenchmarkStream() : fBenches(BenchRegistry::Head()) | 564 BenchmarkStream() : fBenches(BenchRegistry::Head()) |
| 564 , fGMs(skiagm::GMRegistry::Head()) | 565 , fGMs(skiagm::GMRegistry::Head()) |
| 565 , fCurrentRecording(0) | 566 , fCurrentRecording(0) |
| 566 , fCurrentScale(0) | 567 , fCurrentScale(0) |
| 567 , fCurrentSKP(0) | 568 , fCurrentSKP(0) |
| 568 , fCurrentUseMPD(0) | 569 , fCurrentUseMPD(0) |
| 569 , fCurrentCodec(0) | 570 , fCurrentCodec(0) |
| 570 , fCurrentImage(0) | 571 , fCurrentImage(0) |
| (...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1019 create_configs(&configs); | 1020 create_configs(&configs); |
| 1020 | 1021 |
| 1021 int runs = 0; | 1022 int runs = 0; |
| 1022 BenchmarkStream benchStream; | 1023 BenchmarkStream benchStream; |
| 1023 while (Benchmark* b = benchStream.next()) { | 1024 while (Benchmark* b = benchStream.next()) { |
| 1024 SkAutoTDelete<Benchmark> bench(b); | 1025 SkAutoTDelete<Benchmark> bench(b); |
| 1025 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName()))
{ | 1026 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName()))
{ |
| 1026 continue; | 1027 continue; |
| 1027 } | 1028 } |
| 1028 | 1029 |
| 1029 SkTDArray<Target*> targets; | 1030 if (!configs.isEmpty()) { |
| 1030 create_targets(&targets, bench.get(), configs); | |
| 1031 | |
| 1032 if (!targets.isEmpty()) { | |
| 1033 log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSi
ze().fY); | 1031 log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSi
ze().fY); |
| 1034 bench->preDraw(); | 1032 bench->preDraw(); |
| 1035 } | 1033 } |
| 1036 for (int j = 0; j < targets.count(); j++) { | 1034 for (int i = 0; i < configs.count(); ++i) { |
| 1035 Target* target = is_enabled(b, configs[i]); |
| 1036 if (!target) { |
| 1037 continue; |
| 1038 } |
| 1039 |
| 1037 // During HWUI output this canvas may be NULL. | 1040 // During HWUI output this canvas may be NULL. |
| 1038 SkCanvas* canvas = targets[j]->getCanvas(); | 1041 SkCanvas* canvas = target->getCanvas(); |
| 1039 const char* config = targets[j]->config.name; | 1042 const char* config = target->config.name; |
| 1040 | 1043 |
| 1041 targets[j]->setup(); | 1044 target->setup(); |
| 1042 bench->perCanvasPreDraw(canvas); | 1045 bench->perCanvasPreDraw(canvas); |
| 1043 | 1046 |
| 1044 int maxFrameLag; | 1047 int maxFrameLag; |
| 1045 const int loops = targets[j]->needsFrameTiming(&maxFrameLag) | 1048 const int loops = target->needsFrameTiming(&maxFrameLag) |
| 1046 ? setup_gpu_bench(targets[j], bench.get(), maxFrameLag) | 1049 ? setup_gpu_bench(target, bench.get(), maxFrameLag) |
| 1047 : setup_cpu_bench(overhead, targets[j], bench.get()); | 1050 : setup_cpu_bench(overhead, target, bench.get()); |
| 1048 | 1051 |
| 1049 if (kTimedSampling != FLAGS_samples) { | 1052 if (kTimedSampling != FLAGS_samples) { |
| 1050 samples.reset(FLAGS_samples); | 1053 samples.reset(FLAGS_samples); |
| 1051 for (int s = 0; s < FLAGS_samples; s++) { | 1054 for (int s = 0; s < FLAGS_samples; s++) { |
| 1052 samples[s] = time(loops, bench, targets[j]) / loops; | 1055 samples[s] = time(loops, bench, target) / loops; |
| 1053 } | 1056 } |
| 1054 } else if (samplingTimeMs) { | 1057 } else if (samplingTimeMs) { |
| 1055 samples.reset(); | 1058 samples.reset(); |
| 1056 if (FLAGS_verbose) { | 1059 if (FLAGS_verbose) { |
| 1057 SkDebugf("Begin sampling %s for %ims\n", | 1060 SkDebugf("Begin sampling %s for %ims\n", |
| 1058 bench->getUniqueName(), static_cast<int>(samplingTi
meMs)); | 1061 bench->getUniqueName(), static_cast<int>(samplingTi
meMs)); |
| 1059 } | 1062 } |
| 1060 WallTimer timer; | 1063 WallTimer timer; |
| 1061 timer.start(); | 1064 timer.start(); |
| 1062 do { | 1065 do { |
| 1063 samples.push_back(time(loops, bench, targets[j]) / loops); | 1066 samples.push_back(time(loops, bench, target) / loops); |
| 1064 timer.end(); | 1067 timer.end(); |
| 1065 } while (timer.fWall < samplingTimeMs); | 1068 } while (timer.fWall < samplingTimeMs); |
| 1066 } | 1069 } |
| 1067 | 1070 |
| 1068 bench->perCanvasPostDraw(canvas); | 1071 bench->perCanvasPostDraw(canvas); |
| 1069 | 1072 |
| 1070 if (Benchmark::kNonRendering_Backend != targets[j]->config.backend &
& | 1073 if (Benchmark::kNonRendering_Backend != target->config.backend && |
| 1071 !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { | 1074 !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { |
| 1072 SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config
); | 1075 SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config
); |
| 1073 pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniq
ueName()); | 1076 pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniq
ueName()); |
| 1074 pngFilename.append(".png"); | 1077 pngFilename.append(".png"); |
| 1075 write_canvas_png(targets[j], pngFilename); | 1078 write_canvas_png(target, pngFilename); |
| 1076 } | 1079 } |
| 1077 | 1080 |
| 1078 if (kFailedLoops == loops) { | 1081 if (kFailedLoops == loops) { |
| 1079 // Can't be timed. A warning note has already been printed. | 1082 // Can't be timed. A warning note has already been printed. |
| 1083 cleanup_run(target); |
| 1080 continue; | 1084 continue; |
| 1081 } | 1085 } |
| 1082 | 1086 |
| 1083 Stats stats(samples); | 1087 Stats stats(samples); |
| 1084 log->config(config); | 1088 log->config(config); |
| 1085 log->configOption("name", bench->getName()); | 1089 log->configOption("name", bench->getName()); |
| 1086 benchStream.fillCurrentOptions(log.get()); | 1090 benchStream.fillCurrentOptions(log.get()); |
| 1087 targets[j]->fillOptions(log.get()); | 1091 target->fillOptions(log.get()); |
| 1088 log->metric("min_ms", stats.min); | 1092 log->metric("min_ms", stats.min); |
| 1089 if (runs++ % FLAGS_flushEvery == 0) { | 1093 if (runs++ % FLAGS_flushEvery == 0) { |
| 1090 log->flush(); | 1094 log->flush(); |
| 1091 } | 1095 } |
| 1092 | 1096 |
| 1093 if (kAutoTuneLoops != FLAGS_loops) { | 1097 if (kAutoTuneLoops != FLAGS_loops) { |
| 1094 if (targets.count() == 1) { | 1098 if (configs.count() == 1) { |
| 1095 config = ""; // Only print the config if we run the same ben
ch on more than one. | 1099 config = ""; // Only print the config if we run the same ben
ch on more than one. |
| 1096 } | 1100 } |
| 1097 SkDebugf("%4d/%-4dMB\t%s\t%s\n" | 1101 SkDebugf("%4d/%-4dMB\t%s\t%s\n" |
| 1098 , sk_tools::getCurrResidentSetSizeMB() | 1102 , sk_tools::getCurrResidentSetSizeMB() |
| 1099 , sk_tools::getMaxResidentSetSizeMB() | 1103 , sk_tools::getMaxResidentSetSizeMB() |
| 1100 , bench->getUniqueName() | 1104 , bench->getUniqueName() |
| 1101 , config); | 1105 , config); |
| 1102 } else if (FLAGS_verbose) { | 1106 } else if (FLAGS_verbose) { |
| 1103 for (int i = 0; i < samples.count(); i++) { | 1107 for (int i = 0; i < samples.count(); i++) { |
| 1104 SkDebugf("%s ", HUMANIZE(samples[i])); | 1108 SkDebugf("%s ", HUMANIZE(samples[i])); |
| 1105 } | 1109 } |
| 1106 SkDebugf("%s\n", bench->getUniqueName()); | 1110 SkDebugf("%s\n", bench->getUniqueName()); |
| 1107 } else if (FLAGS_quiet) { | 1111 } else if (FLAGS_quiet) { |
| 1108 if (targets.count() == 1) { | 1112 if (configs.count() == 1) { |
| 1109 config = ""; // Only print the config if we run the same ben
ch on more than one. | 1113 config = ""; // Only print the config if we run the same ben
ch on more than one. |
| 1110 } | 1114 } |
| 1111 SkDebugf("%s\t%s\t%s\n", HUMANIZE(stats.median), bench->getUniqu
eName(), config); | 1115 SkDebugf("%s\t%s\t%s\n", HUMANIZE(stats.median), bench->getUniqu
eName(), config); |
| 1112 } else { | 1116 } else { |
| 1113 const double stddev_percent = 100 * sqrt(stats.var) / stats.mean
; | 1117 const double stddev_percent = 100 * sqrt(stats.var) / stats.mean
; |
| 1114 SkDebugf("%4d/%-4dMB\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" | 1118 SkDebugf("%4d/%-4dMB\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" |
| 1115 , sk_tools::getCurrResidentSetSizeMB() | 1119 , sk_tools::getCurrResidentSetSizeMB() |
| 1116 , sk_tools::getMaxResidentSetSizeMB() | 1120 , sk_tools::getMaxResidentSetSizeMB() |
| 1117 , loops | 1121 , loops |
| 1118 , HUMANIZE(stats.min) | 1122 , HUMANIZE(stats.min) |
| 1119 , HUMANIZE(stats.median) | 1123 , HUMANIZE(stats.median) |
| 1120 , HUMANIZE(stats.mean) | 1124 , HUMANIZE(stats.mean) |
| 1121 , HUMANIZE(stats.max) | 1125 , HUMANIZE(stats.max) |
| 1122 , stddev_percent | 1126 , stddev_percent |
| 1123 , kTimedSampling != FLAGS_samples ? stats.plot.c_str() | 1127 , kTimedSampling != FLAGS_samples ? stats.plot.c_str() |
| 1124 : to_string(samples.co
unt()).c_str() | 1128 : to_string(samples.co
unt()).c_str() |
| 1125 , config | 1129 , config |
| 1126 , bench->getUniqueName() | 1130 , bench->getUniqueName() |
| 1127 ); | 1131 ); |
| 1128 } | 1132 } |
| 1129 #if SK_SUPPORT_GPU | 1133 #if SK_SUPPORT_GPU |
| 1130 if (FLAGS_gpuStats && | 1134 if (FLAGS_gpuStats && |
| 1131 Benchmark::kGPU_Backend == targets[j]->config.backend) { | 1135 Benchmark::kGPU_Backend == configs[i].backend) { |
| 1132 gGrFactory->get(targets[j]->config.ctxType)->printCacheStats(); | 1136 gGrFactory->get(configs[i].ctxType)->printCacheStats(); |
| 1133 gGrFactory->get(targets[j]->config.ctxType)->printGpuStats(); | 1137 gGrFactory->get(configs[i].ctxType)->printGpuStats(); |
| 1134 } | 1138 } |
| 1135 #endif | 1139 #endif |
| 1140 cleanup_run(target); |
| 1136 } | 1141 } |
| 1137 targets.deleteAll(); | |
| 1138 | |
| 1139 #if SK_SUPPORT_GPU | |
| 1140 if (FLAGS_abandonGpuContext) { | |
| 1141 gGrFactory->abandonContexts(); | |
| 1142 } | |
| 1143 if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { | |
| 1144 gGrFactory->destroyContexts(); | |
| 1145 } | |
| 1146 #endif | |
| 1147 } | 1142 } |
| 1148 | 1143 |
| 1149 log->bench("memory_usage", 0,0); | 1144 log->bench("memory_usage", 0,0); |
| 1150 log->config("meta"); | 1145 log->config("meta"); |
| 1151 log->metric("max_rss_mb", sk_tools::getMaxResidentSetSizeMB()); | 1146 log->metric("max_rss_mb", sk_tools::getMaxResidentSetSizeMB()); |
| 1152 | 1147 |
| 1153 #if SK_SUPPORT_GPU | 1148 #if SK_SUPPORT_GPU |
| 1154 // Make sure we clean up the global GrContextFactory here, otherwise we migh
t race with the | 1149 // Make sure we clean up the global GrContextFactory here, otherwise we migh
t race with the |
| 1155 // SkEventTracer destructor | 1150 // SkEventTracer destructor |
| 1156 gGrFactory.reset(NULL); | 1151 gGrFactory.reset(NULL); |
| 1157 #endif | 1152 #endif |
| 1158 | 1153 |
| 1159 return 0; | 1154 return 0; |
| 1160 } | 1155 } |
| 1161 | 1156 |
| 1162 #if !defined SK_BUILD_FOR_IOS | 1157 #if !defined SK_BUILD_FOR_IOS |
| 1163 int main(int argc, char** argv) { | 1158 int main(int argc, char** argv) { |
| 1164 SkCommandLineFlags::Parse(argc, argv); | 1159 SkCommandLineFlags::Parse(argc, argv); |
| 1165 return nanobench_main(); | 1160 return nanobench_main(); |
| 1166 } | 1161 } |
| 1167 #endif | 1162 #endif |
| OLD | NEW |