blob: 906aab27886d44d9fbbaaf6bb6954595b3c33e6d [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
mtkleinc6f5cac2015-10-01 11:56:56 -070020DEFINE_bool(cpu, false, "Run in CPU mode?");
halcanary96fcdcc2015-08-27 07:41:13 -070021DEFINE_string2(match, m, nullptr,
joshualitt962cc982015-06-30 07:43:14 -070022 "[~][^]substring[$] [...] of bench name to run.\n"
23 "Multiple matches may be separated by spaces.\n"
24 "~ causes a matching bench to always be skipped\n"
25 "^ requires the start of the bench to match\n"
26 "$ requires the end of the bench to match\n"
27 "^ and $ requires an exact match\n"
28 "If a bench does not match any list entry,\n"
29 "it is skipped unless some list entry starts with ~");
30DEFINE_string(skps, "skps", "Directory to read skps from.");
31
joshualitt98d2e2f2015-10-05 07:23:30 -070032// We draw a big nonAA path to warmup the gpu / cpu
33#include "SkPerlinNoiseShader.h"
34class WarmupBench : public Benchmark {
35public:
36 WarmupBench() {
37 sk_tool_utils::make_big_path(fPath);
38 }
39private:
40 const char* onGetName() override { return "warmupbench"; }
41 void onDraw(int loops, SkCanvas* canvas) override {
42 // We draw a big path to warm up the cpu, and then use perlin noise shader to warm up the
43 // gpu
44 SkPaint paint;
45 paint.setStyle(SkPaint::kStroke_Style);
46 paint.setStrokeWidth(2);
47
48 SkPaint perlinPaint;
49 perlinPaint.setShader(SkPerlinNoiseShader::CreateTurbulence(0.1f, 0.1f, 1, 0,
50 nullptr))->unref();
51 SkRect rect = SkRect::MakeLTRB(0., 0., 400., 400.);
52 for (int i = 0; i < loops; i++) {
53 canvas->drawPath(fPath, paint);
54 canvas->drawRect(rect, perlinPaint);
55 }
56 }
57 SkPath fPath;
58};
59
joshualitt962cc982015-06-30 07:43:14 -070060VisualBenchmarkStream::VisualBenchmarkStream()
61 : fBenches(BenchRegistry::Head())
62 , fGMs(skiagm::GMRegistry::Head())
halcanary96fcdcc2015-08-27 07:41:13 -070063 , fSourceType(nullptr)
64 , fBenchType(nullptr)
joshualitt98d2e2f2015-10-05 07:23:30 -070065 , fCurrentSKP(0)
66 , fIsWarmedUp(false) {
joshualitt962cc982015-06-30 07:43:14 -070067 for (int i = 0; i < FLAGS_skps.count(); i++) {
68 if (SkStrEndsWith(FLAGS_skps[i], ".skp")) {
69 fSKPs.push_back() = FLAGS_skps[i];
70 } else {
71 SkOSFile::Iter it(FLAGS_skps[i], ".skp");
72 SkString path;
73 while (it.next(&path)) {
74 fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str());
75 }
76 }
77 }
joshualittc603c142015-10-15 07:18:29 -070078
79 // seed with an initial benchmark
80 // NOTE the initial benchmark will not have preTimingHooks called, but that is okay because
81 // it is the warmupbench
82 this->next();
joshualitt962cc982015-06-30 07:43:14 -070083}
84
85bool VisualBenchmarkStream::ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) {
86 // Not strictly necessary, as it will be checked again later,
87 // but helps to avoid a lot of pointless work if we're going to skip it.
88 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) {
89 return false;
90 }
91
92 SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path));
halcanary96fcdcc2015-08-27 07:41:13 -070093 if (stream.get() == nullptr) {
joshualitt962cc982015-06-30 07:43:14 -070094 SkDebugf("Could not read %s.\n", path);
95 return false;
96 }
97
98 pic->reset(SkPicture::CreateFromStream(stream.get()));
halcanary96fcdcc2015-08-27 07:41:13 -070099 if (pic->get() == nullptr) {
joshualitt962cc982015-06-30 07:43:14 -0700100 SkDebugf("Could not read %s as an SkPicture.\n", path);
101 return false;
102 }
103 return true;
104}
105
106Benchmark* VisualBenchmarkStream::next() {
joshualittc603c142015-10-15 07:18:29 -0700107 Benchmark* bench;
joshualitt98d2e2f2015-10-05 07:23:30 -0700108 if (!fIsWarmedUp) {
109 fIsWarmedUp = true;
joshualittc603c142015-10-15 07:18:29 -0700110 bench = new WarmupBench;
111 } else {
112 // skips non matching benches
113 while ((bench = this->innerNext()) &&
114 (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName()) ||
115 !bench->isSuitableFor(Benchmark::kGPU_Backend))) {
116 bench->unref();
117 }
118 }
joshualittc9dd93c2015-10-15 09:49:31 -0700119
120 // TODO move this all to --config
joshualittc603c142015-10-15 07:18:29 -0700121 if (bench && FLAGS_cpu) {
122 bench = new CpuWrappedBenchmark(bench);
joshualittc9dd93c2015-10-15 09:49:31 -0700123 } else if (bench && FLAGS_nvpr) {
124 bench = new NvprWrappedBenchmark(bench, 4);
joshualitt98d2e2f2015-10-05 07:23:30 -0700125 }
126
joshualittc603c142015-10-15 07:18:29 -0700127 fBenchmark.reset(bench);
128 return fBenchmark;
joshualitt82874f82015-07-15 08:38:02 -0700129}
130
131Benchmark* VisualBenchmarkStream::innerNext() {
joshualitt962cc982015-06-30 07:43:14 -0700132 while (fBenches) {
halcanary96fcdcc2015-08-27 07:41:13 -0700133 Benchmark* bench = fBenches->factory()(nullptr);
joshualitt962cc982015-06-30 07:43:14 -0700134 fBenches = fBenches->next();
135 if (bench->isVisual()) {
136 fSourceType = "bench";
137 fBenchType = "micro";
138 return bench;
139 }
joshualitt47d280d2015-07-16 14:23:22 -0700140 bench->unref();
joshualitt962cc982015-06-30 07:43:14 -0700141 }
142
143 while (fGMs) {
halcanary96fcdcc2015-08-27 07:41:13 -0700144 SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr));
joshualitt962cc982015-06-30 07:43:14 -0700145 fGMs = fGMs->next();
146 if (gm->runAsBench()) {
147 fSourceType = "gm";
148 fBenchType = "micro";
halcanary385fe4d2015-08-26 13:07:48 -0700149 return new GMBench(gm.detach());
joshualitt962cc982015-06-30 07:43:14 -0700150 }
151 }
152
153 // Render skps
154 while (fCurrentSKP < fSKPs.count()) {
155 const SkString& path = fSKPs[fCurrentSKP++];
156 SkAutoTUnref<SkPicture> pic;
157 if (!ReadPicture(path.c_str(), &pic)) {
158 continue;
159 }
160
161 SkString name = SkOSPath::Basename(path.c_str());
162 fSourceType = "skp";
163 fBenchType = "playback";
halcanary385fe4d2015-08-26 13:07:48 -0700164 return new VisualSKPBench(name.c_str(), pic.get());
joshualitt962cc982015-06-30 07:43:14 -0700165 }
166
halcanary96fcdcc2015-08-27 07:41:13 -0700167 return nullptr;
joshualitt962cc982015-06-30 07:43:14 -0700168}