blob: ff0abc265387f9ebc897887f7a3d2bb2045c1595 [file] [log] [blame]
mtklein7e602c22016-07-11 11:27:30 -07001/*
2 * Copyright 2016 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#include "Benchmark.h"
Mike Klein4bc6d8f2016-10-19 13:27:07 -04009#include "OverwriteLine.h"
mtklein7e602c22016-07-11 11:27:30 -070010#include "SkGraphics.h"
Mike Klein0dc6dd02017-05-15 12:19:39 -040011#include "SkSurface.h"
mtklein2052f312016-07-12 14:50:28 -070012#include "SkTaskGroup.h"
mtklein7e602c22016-07-11 11:27:30 -070013#include <algorithm>
14#include <chrono>
Mike Kleincc300a12016-10-12 16:25:27 -040015#include <limits>
mtklein7e602c22016-07-11 11:27:30 -070016#include <regex>
Mike Klein645999f2016-09-28 14:00:51 -040017#include <stdlib.h>
mtklein7e602c22016-07-11 11:27:30 -070018#include <string>
19#include <vector>
20
Mike Klein4bc6d8f2016-10-19 13:27:07 -040021
22#if defined(SK_BUILD_FOR_WIN32)
23static const char* kEllipsis = "...";
24#else
25static const char* kEllipsis = "…";
26#endif
27
mtklein7e602c22016-07-11 11:27:30 -070028int main(int argc, char** argv) {
29 SkGraphics::Init();
mtklein2052f312016-07-12 14:50:28 -070030 SkTaskGroup::Enabler enabled;
mtklein7e602c22016-07-11 11:27:30 -070031
32 using clock = std::chrono::high_resolution_clock;
33 using ns = std::chrono::duration<double, std::nano>;
34
35 std::regex pattern;
Mike Klein645999f2016-09-28 14:00:51 -040036 int limit = 2147483647;
37 if (argc > 1) { pattern = argv[1]; }
38 if (argc > 2) { limit = atoi(argv[2]); }
mtklein7e602c22016-07-11 11:27:30 -070039
40 struct Bench {
41 std::unique_ptr<Benchmark> b;
42 std::string name;
43 ns best;
44 };
45 std::vector<Bench> benches;
46
47 for (auto r = BenchRegistry::Head(); r; r = r->next()) {
48 std::unique_ptr<Benchmark> bench{ r->factory()(nullptr) };
49
50 std::string name = bench->getName();
51 if (std::regex_search(name, pattern) &&
Mike Klein0dc6dd02017-05-15 12:19:39 -040052 (bench->isSuitableFor(Benchmark::kNonRendering_Backend) ||
53 bench->isSuitableFor(Benchmark:: kRaster_Backend))) {
mtklein7e602c22016-07-11 11:27:30 -070054 bench->delayedSetup();
Mike Kleincc300a12016-10-12 16:25:27 -040055 benches.emplace_back(Bench{std::move(bench), name,
56 ns{std::numeric_limits<double>::infinity()}});
mtklein7e602c22016-07-11 11:27:30 -070057 }
58 }
59
Mike Klein645999f2016-09-28 14:00:51 -040060 if (benches.size() == 0) {
Mike Klein4bc6d8f2016-10-19 13:27:07 -040061 SkDebugf("No bench matched.\n");
Mike Klein645999f2016-09-28 14:00:51 -040062 return 1;
63 }
64
mtklein7e602c22016-07-11 11:27:30 -070065 if (benches.size() > 1) {
66 int common_prefix = benches[0].name.size();
67 for (size_t i = 1; i < benches.size(); i++) {
68 int len = std::mismatch(benches[i-1].name.begin(), benches[i-1].name.end(),
69 benches[i-0].name.begin())
70 .first - benches[i-1].name.begin();
71 common_prefix = std::min(common_prefix, len);
72 }
73 std::string prefix = benches[0].name.substr(0, common_prefix);
74 if (common_prefix) {
75 for (auto& bench : benches) {
Mike Klein4bc6d8f2016-10-19 13:27:07 -040076 bench.name.replace(0, common_prefix, kEllipsis);
mtklein7e602c22016-07-11 11:27:30 -070077 }
78 }
79
80 int common_suffix = benches[0].name.size();
81 for (size_t i = 1; i < benches.size(); i++) {
82 int len = std::mismatch(benches[i-1].name.rbegin(), benches[i-1].name.rend(),
83 benches[i-0].name.rbegin())
84 .first - benches[i-1].name.rbegin();
85 common_suffix = std::min(common_suffix, len);
86 }
87 std::string suffix = benches[0].name.substr(benches[0].name.size() - common_suffix);
88 if (common_suffix) {
89 for (auto& bench : benches) {
Mike Klein4bc6d8f2016-10-19 13:27:07 -040090 bench.name.replace(bench.name.size() - common_suffix, common_suffix, kEllipsis);
mtklein7e602c22016-07-11 11:27:30 -070091 }
92 }
93
Mike Klein4bc6d8f2016-10-19 13:27:07 -040094 SkDebugf("%s%s%s\n", prefix.c_str(), kEllipsis, suffix.c_str());
mtklein7e602c22016-07-11 11:27:30 -070095 }
96
97 int samples = 0;
Mike Klein645999f2016-09-28 14:00:51 -040098 while (samples < limit) {
Mike Klein7c6bc462017-01-05 14:08:50 -050099 std::random_shuffle(benches.begin(), benches.end());
mtklein7e602c22016-07-11 11:27:30 -0700100 for (auto& bench : benches) {
Mike Klein0dc6dd02017-05-15 12:19:39 -0400101 sk_sp<SkSurface> dst;
102 SkCanvas* canvas = nullptr;
103 if (!bench.b->isSuitableFor(Benchmark::kNonRendering_Backend)) {
104 dst = SkSurface::MakeRaster(SkImageInfo::MakeS32(bench.b->getSize().x(),
105 bench.b->getSize().y(),
106 kPremul_SkAlphaType));
107 canvas = dst->getCanvas();
108 bench.b->perCanvasPreDraw(canvas);
109 }
mtklein7e602c22016-07-11 11:27:30 -0700110 for (int loops = 1; loops < 1000000000;) {
Mike Klein0dc6dd02017-05-15 12:19:39 -0400111
112 bench.b->preDraw(canvas);
mtklein7e602c22016-07-11 11:27:30 -0700113 auto start = clock::now();
Mike Klein0dc6dd02017-05-15 12:19:39 -0400114 bench.b->draw(loops, canvas);
mtklein7e602c22016-07-11 11:27:30 -0700115 ns elapsed = clock::now() - start;
Mike Klein0dc6dd02017-05-15 12:19:39 -0400116 bench.b->postDraw(canvas);
mtklein7e602c22016-07-11 11:27:30 -0700117
118 if (elapsed < std::chrono::milliseconds{10}) {
119 loops *= 2;
120 continue;
121 }
122
123 bench.best = std::min(bench.best, elapsed / loops);
124 samples++;
125
Mike Kleinef6bbbd2017-01-05 14:23:57 -0500126 struct Result { const char* name; ns best; };
127 std::vector<Result> sorted(benches.size());
128 for (size_t i = 0; i < benches.size(); i++) {
129 sorted[i].name = benches[i].name.c_str();
130 sorted[i].best = benches[i].best;
131 }
132 std::sort(sorted.begin(), sorted.end(), [](const Result& a, const Result& b) {
mtklein7e602c22016-07-11 11:27:30 -0700133 return a.best < b.best;
134 });
Mike Kleinef6bbbd2017-01-05 14:23:57 -0500135
Mike Klein4bc6d8f2016-10-19 13:27:07 -0400136 SkDebugf("%s%d", kSkOverwriteLine, samples);
Mike Kleinef6bbbd2017-01-05 14:23:57 -0500137 for (auto& result : sorted) {
138 if (sorted.size() == 1) {
139 SkDebugf(" %s %gns" , result.name, result.best.count());
mtklein7e602c22016-07-11 11:27:30 -0700140 } else {
Mike Kleinef6bbbd2017-01-05 14:23:57 -0500141 SkDebugf(" %s %.3gx", result.name, result.best / sorted[0].best);
mtklein7e602c22016-07-11 11:27:30 -0700142 }
143 }
mtklein7e602c22016-07-11 11:27:30 -0700144 break;
145 }
Mike Klein0dc6dd02017-05-15 12:19:39 -0400146 if (canvas) {
147 bench.b->perCanvasPostDraw(canvas);
148 }
mtklein7e602c22016-07-11 11:27:30 -0700149 }
150 }
151
152 return 0;
153}