blob: e0d02f2b97c259980ff9a1e53eb4ee848ec04364 [file] [log] [blame]
joshualitt962cc982015-06-30 07:43:14 -07001/*
2 * Copyright 2015 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
9#include <VisualBench/VisualBenchmarkStream.h>
joshualittc9dd93c2015-10-15 09:49:31 -070010#include <VisualBench/WrappedBenchmark.h>
joshualitt962cc982015-06-30 07:43:14 -070011#include "GMBench.h"
12#include "SkOSFile.h"
joshualitt98d2e2f2015-10-05 07:23:30 -070013#include "SkPath.h"
joshualitt962cc982015-06-30 07:43:14 -070014#include "SkPictureRecorder.h"
15#include "SkStream.h"
joshualitt98d2e2f2015-10-05 07:23:30 -070016#include "sk_tool_utils.h"
joshualittc9dd93c2015-10-15 09:49:31 -070017#include "VisualFlags.h"
joshualitt962cc982015-06-30 07:43:14 -070018#include "VisualSKPBench.h"
19
cdaltone6d20242015-10-26 13:45:29 -070020#if SK_SUPPORT_GPU
21#include "GrContext.h"
22#endif
23
halcanary96fcdcc2015-08-27 07:41:13 -070024DEFINE_string2(match, m, nullptr,
joshualitt962cc982015-06-30 07:43:14 -070025 "[~][^]substring[$] [...] of bench name to run.\n"
26 "Multiple matches may be separated by spaces.\n"
27 "~ causes a matching bench to always be skipped\n"
28 "^ requires the start of the bench to match\n"
29 "$ requires the end of the bench to match\n"
30 "^ and $ requires an exact match\n"
31 "If a bench does not match any list entry,\n"
32 "it is skipped unless some list entry starts with ~");
33DEFINE_string(skps, "skps", "Directory to read skps from.");
cdalton78f915e2015-12-10 14:20:06 -080034DEFINE_bool(warmup, true, "Include a warmup bench? (Excluding the warmup may compromise results)");
joshualitt962cc982015-06-30 07:43:14 -070035
joshualitt98d2e2f2015-10-05 07:23:30 -070036// We draw a big nonAA path to warmup the gpu / cpu
37#include "SkPerlinNoiseShader.h"
38class WarmupBench : public Benchmark {
39public:
40 WarmupBench() {
41 sk_tool_utils::make_big_path(fPath);
cdalton0f6cca82015-11-24 08:54:29 -080042 fPerlinRect = SkRect::MakeLTRB(0., 0., 400., 400.);
joshualitt98d2e2f2015-10-05 07:23:30 -070043 }
44private:
45 const char* onGetName() override { return "warmupbench"; }
cdalton0f6cca82015-11-24 08:54:29 -080046 SkIPoint onGetSize() override {
47 int w = SkScalarCeilToInt(SkTMax(fPath.getBounds().right(), fPerlinRect.right()));
48 int h = SkScalarCeilToInt(SkTMax(fPath.getBounds().bottom(), fPerlinRect.bottom()));
49 return SkIPoint::Make(w, h);
50 }
joshualitt98d2e2f2015-10-05 07:23:30 -070051 void onDraw(int loops, SkCanvas* canvas) override {
52 // We draw a big path to warm up the cpu, and then use perlin noise shader to warm up the
53 // gpu
54 SkPaint paint;
55 paint.setStyle(SkPaint::kStroke_Style);
56 paint.setStrokeWidth(2);
57
58 SkPaint perlinPaint;
59 perlinPaint.setShader(SkPerlinNoiseShader::CreateTurbulence(0.1f, 0.1f, 1, 0,
60 nullptr))->unref();
joshualitt98d2e2f2015-10-05 07:23:30 -070061 for (int i = 0; i < loops; i++) {
62 canvas->drawPath(fPath, paint);
cdalton0f6cca82015-11-24 08:54:29 -080063 canvas->drawRect(fPerlinRect, perlinPaint);
cdaltone6d20242015-10-26 13:45:29 -070064#if SK_SUPPORT_GPU
65 // Ensure the GrContext doesn't batch across draw loops.
66 if (GrContext* context = canvas->getGrContext()) {
67 context->flush();
68 }
69#endif
joshualitt98d2e2f2015-10-05 07:23:30 -070070 }
71 }
72 SkPath fPath;
cdalton0f6cca82015-11-24 08:54:29 -080073 SkRect fPerlinRect;
joshualitt98d2e2f2015-10-05 07:23:30 -070074};
75
joshualitt6ebd4232015-12-04 09:02:34 -080076VisualBenchmarkStream::VisualBenchmarkStream(const SkSurfaceProps& surfaceProps, bool justSKP)
cdaltonc70483f2015-10-26 13:14:36 -070077 : fSurfaceProps(surfaceProps)
78 , fBenches(BenchRegistry::Head())
joshualitt962cc982015-06-30 07:43:14 -070079 , fGMs(skiagm::GMRegistry::Head())
halcanary96fcdcc2015-08-27 07:41:13 -070080 , fSourceType(nullptr)
81 , fBenchType(nullptr)
joshualitt98d2e2f2015-10-05 07:23:30 -070082 , fCurrentSKP(0)
83 , fIsWarmedUp(false) {
joshualitt962cc982015-06-30 07:43:14 -070084 for (int i = 0; i < FLAGS_skps.count(); i++) {
85 if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
86 fSKPs.push_back() = FLAGS_skps[i];
87 } else {
88 SkOSFile::Iter it(FLAGS_skps[i], ".skp");
89 SkString path;
90 while (it.next(&path)) {
91 fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str());
92 }
93 }
94 }
joshualittc603c142015-10-15 07:18:29 -070095
joshualitt6ebd4232015-12-04 09:02:34 -080096 if (justSKP) {
97 fGMs = nullptr;
98 fBenches = nullptr;
99 }
100
joshualittc603c142015-10-15 07:18:29 -0700101 // seed with an initial benchmark
102 // NOTE the initial benchmark will not have preTimingHooks called, but that is okay because
103 // it is the warmupbench
104 this->next();
joshualitt962cc982015-06-30 07:43:14 -0700105}
106
107bool VisualBenchmarkStream::ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) {
108 // Not strictly necessary, as it will be checked again later,
109 // but helps to avoid a lot of pointless work if we're going to skip it.
110 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) {
111 return false;
112 }
113
114 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
halcanary96fcdcc2015-08-27 07:41:13 -0700115 if (stream.get() == nullptr) {
joshualitt962cc982015-06-30 07:43:14 -0700116 SkDebugf("Could not read %s.\n", path);
117 return false;
118 }
119
120 pic->reset(SkPicture::CreateFromStream(stream.get()));
halcanary96fcdcc2015-08-27 07:41:13 -0700121 if (pic->get() == nullptr) {
joshualitt962cc982015-06-30 07:43:14 -0700122 SkDebugf("Could not read %s as an SkPicture.\n", path);
123 return false;
124 }
125 return true;
126}
127
128Benchmark* VisualBenchmarkStream::next() {
joshualittc603c142015-10-15 07:18:29 -0700129 Benchmark* bench;
cdalton78f915e2015-12-10 14:20:06 -0800130 if (FLAGS_warmup && !fIsWarmedUp) {
joshualitt98d2e2f2015-10-05 07:23:30 -0700131 fIsWarmedUp = true;
joshualittc603c142015-10-15 07:18:29 -0700132 bench = new WarmupBench;
133 } else {
134 // skips non matching benches
135 while ((bench = this->innerNext()) &&
136 (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName()) ||
137 !bench->isSuitableFor(Benchmark::kGPU_Backend))) {
138 bench->unref();
139 }
140 }
joshualittc9dd93c2015-10-15 09:49:31 -0700141
142 // TODO move this all to --config
joshualittc603c142015-10-15 07:18:29 -0700143 if (bench && FLAGS_cpu) {
cdaltonc70483f2015-10-26 13:14:36 -0700144 bench = new CpuWrappedBenchmark(fSurfaceProps, bench);
cdaltonbaf8fcb2015-11-24 09:20:24 -0800145 } else if (bench && FLAGS_offscreen) {
146 bench = new GpuWrappedBenchmark(fSurfaceProps, bench, FLAGS_msaa);
joshualitt98d2e2f2015-10-05 07:23:30 -0700147 }
148
joshualittc603c142015-10-15 07:18:29 -0700149 fBenchmark.reset(bench);
150 return fBenchmark;
joshualitt82874f82015-07-15 08:38:02 -0700151}
152
153Benchmark* VisualBenchmarkStream::innerNext() {
joshualitt962cc982015-06-30 07:43:14 -0700154 while (fBenches) {
halcanary96fcdcc2015-08-27 07:41:13 -0700155 Benchmark* bench = fBenches->factory()(nullptr);
joshualitt962cc982015-06-30 07:43:14 -0700156 fBenches = fBenches->next();
157 if (bench->isVisual()) {
158 fSourceType = "bench";
159 fBenchType = "micro";
160 return bench;
161 }
joshualitt47d280d2015-07-16 14:23:22 -0700162 bench->unref();
joshualitt962cc982015-06-30 07:43:14 -0700163 }
164
165 while (fGMs) {
halcanary96fcdcc2015-08-27 07:41:13 -0700166 SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr));
joshualitt962cc982015-06-30 07:43:14 -0700167 fGMs = fGMs->next();
168 if (gm->runAsBench()) {
169 fSourceType = "gm";
170 fBenchType = "micro";
mtklein18300a32016-03-16 13:53:35 -0700171 return new GMBench(gm.release());
joshualitt962cc982015-06-30 07:43:14 -0700172 }
173 }
174
175 // Render skps
176 while (fCurrentSKP < fSKPs.count()) {
177 const SkString& path = fSKPs[fCurrentSKP++];
178 SkAutoTUnref<SkPicture> pic;
179 if (!ReadPicture(path.c_str(), &pic)) {
180 continue;
181 }
182
183 SkString name = SkOSPath::Basename(path.c_str());
184 fSourceType = "skp";
185 fBenchType = "playback";
halcanary385fe4d2015-08-26 13:07:48 -0700186 return new VisualSKPBench(name.c_str(), pic.get());
joshualitt962cc982015-06-30 07:43:14 -0700187 }
188
halcanary96fcdcc2015-08-27 07:41:13 -0700189 return nullptr;
joshualitt962cc982015-06-30 07:43:14 -0700190}