blob: 084a971acdf7572d8131ead9ca1b8cb5beceb2e9 [file] [log] [blame]
reed@google.com006db0f2012-06-27 19:33:29 +00001/*
2 * Copyright 2012 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 "BenchTimer.h"
keyar@chromium.org163b5672012-08-01 17:53:29 +00009#include "PictureBenchmark.h"
reed@google.com006db0f2012-06-27 19:33:29 +000010#include "SkCanvas.h"
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000011#include "SkMath.h"
reed@google.com006db0f2012-06-27 19:33:29 +000012#include "SkOSFile.h"
13#include "SkPicture.h"
14#include "SkStream.h"
15#include "SkTArray.h"
16#include "picture_utils.h"
17
18const int DEFAULT_REPEATS = 100;
reed@google.com006db0f2012-06-27 19:33:29 +000019
20static void usage(const char* argv0) {
21 SkDebugf("SkPicture benchmarking tool\n");
22 SkDebugf("\n"
23"Usage: \n"
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +000024" %s <inputDir>...\n"
keyar@chromium.org795cd472012-08-02 18:57:53 +000025" [--repeat] \n"
scroggo@google.com58b4ead2012-08-31 16:15:22 +000026" [--mode pow2tile minWidth height[] (multi) | record | simple\n"
27" | tile width[] height[] (multi) | unflatten]\n"
28" [--pipe]\n"
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000029" [--device bitmap"
30#if SK_SUPPORT_GPU
31" | gpu"
32#endif
33"]"
reed@google.com006db0f2012-06-27 19:33:29 +000034, argv0);
35 SkDebugf("\n\n");
36 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000037" inputDir: A list of directories and files to use as input. Files are\n"
38" expected to have the .skp extension.\n\n");
reed@google.com006db0f2012-06-27 19:33:29 +000039 SkDebugf(
scroggo@google.com58b4ead2012-08-31 16:15:22 +000040" --mode pow2tile minWidht height[] (multi) | record | simple\n"
41" | tile width[] height[] (multi) | unflatten:\n"
42" Run in the corresponding mode.\n"
43" Default is simple.\n");
keyar@chromium.orgcf6c44c2012-07-09 19:37:40 +000044 SkDebugf(
scroggo@google.com58b4ead2012-08-31 16:15:22 +000045" pow2tile minWidth height[], Creates tiles with widths\n"
46" that are all a power of two\n"
47" such that they minimize the\n"
48" amount of wasted tile space.\n"
49" minWidth is the minimum width\n"
50" of these tiles and must be a\n"
51" power of two. Simple\n"
52" rendering using these tiles\n"
53" is benchmarked.\n"
54" Append \"multi\" for multithreaded\n"
55" drawing.\n");
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000056 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000057" record, Benchmark picture to picture recording.\n");
58 SkDebugf(
59" simple, Benchmark a simple rendering.\n");
60 SkDebugf(
scroggo@google.com58b4ead2012-08-31 16:15:22 +000061" tile width[] height[], Benchmark simple rendering using\n"
62" tiles with the given dimensions.\n"
63" Append \"multi\" for multithreaded\n"
64" drawing.\n");
keyar@chromium.org795cd472012-08-02 18:57:53 +000065 SkDebugf(
66" unflatten, Benchmark picture unflattening.\n");
67 SkDebugf("\n");
68 SkDebugf(
scroggo@google.com58b4ead2012-08-31 16:15:22 +000069" --pipe: Benchmark SkGPipe rendering. Compatible with tiled, multithreaded rendering.\n");
70 SkDebugf(
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000071" --device bitmap"
72#if SK_SUPPORT_GPU
73" | gpu"
74#endif
75": Use the corresponding device. Default is bitmap.\n");
76 SkDebugf(
77" bitmap, Render to a bitmap.\n");
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000078#if SK_SUPPORT_GPU
keyar@chromium.orga40c20d2012-08-20 15:04:12 +000079 SkDebugf(
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000080" gpu, Render to the GPU.\n");
81#endif
82 SkDebugf("\n");
83 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000084" --repeat: "
reed@google.com006db0f2012-06-27 19:33:29 +000085"Set the number of times to repeat each test."
86" Default is %i.\n", DEFAULT_REPEATS);
reed@google.com006db0f2012-06-27 19:33:29 +000087}
88
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +000089static void run_single_benchmark(const SkString& inputPath,
keyar@chromium.org163b5672012-08-01 17:53:29 +000090 sk_tools::PictureBenchmark& benchmark) {
reed@google.com006db0f2012-06-27 19:33:29 +000091 SkFILEStream inputStream;
92
reed@google.com006db0f2012-06-27 19:33:29 +000093 inputStream.setPath(inputPath.c_str());
94 if (!inputStream.isValid()) {
95 SkDebugf("Could not open file %s\n", inputPath.c_str());
96 return;
97 }
98
99 SkPicture picture(&inputStream);
reed@google.com006db0f2012-06-27 19:33:29 +0000100
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000101 SkString filename;
102 sk_tools::get_basename(&filename, inputPath);
keyar@chromium.orgdb9a5fb2012-08-21 17:57:59 +0000103
104 SkString result;
105 result.printf("running bench [%i %i] %s ", picture.width(), picture.height(),
106 filename.c_str());
107 sk_tools::print_msg(result.c_str());
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000108
keyar@chromium.org163b5672012-08-01 17:53:29 +0000109 benchmark.run(&picture);
keyar@chromium.org0665f252012-07-10 18:30:18 +0000110}
111
keyar@chromium.org163b5672012-08-01 17:53:29 +0000112static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs,
113 sk_tools::PictureBenchmark*& benchmark) {
reed@google.com006db0f2012-06-27 19:33:29 +0000114 const char* argv0 = argv[0];
115 char* const* stop = argv + argc;
116
keyar@chromium.org163b5672012-08-01 17:53:29 +0000117 int repeats = DEFAULT_REPEATS;
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000118 sk_tools::PictureRenderer::SkDeviceTypes deviceType =
119 sk_tools::PictureRenderer::kBitmap_DeviceType;
keyar@chromium.org163b5672012-08-01 17:53:29 +0000120
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000121 bool usePipe = false;
122 bool multiThreaded = false;
123 bool useTiles = false;
124 const char* widthString = NULL;
125 const char* heightString = NULL;
126 bool isPowerOf2Mode = false;
127 const char* mode = NULL;
reed@google.com006db0f2012-06-27 19:33:29 +0000128 for (++argv; argv < stop; ++argv) {
129 if (0 == strcmp(*argv, "--repeat")) {
130 ++argv;
131 if (argv < stop) {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000132 repeats = atoi(*argv);
133 if (repeats < 1) {
keyar@chromium.org795cd472012-08-02 18:57:53 +0000134 SkDELETE(benchmark);
reed@google.com006db0f2012-06-27 19:33:29 +0000135 SkDebugf("--repeat must be given a value > 0\n");
136 exit(-1);
137 }
138 } else {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000139 SkDELETE(benchmark);
reed@google.com006db0f2012-06-27 19:33:29 +0000140 SkDebugf("Missing arg for --repeat\n");
141 usage(argv0);
142 exit(-1);
143 }
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000144 } else if (0 == strcmp(*argv, "--pipe")) {
145 usePipe = true;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000146 } else if (0 == strcmp(*argv, "--mode")) {
147 SkDELETE(benchmark);
148
reed@google.com006db0f2012-06-27 19:33:29 +0000149 ++argv;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000150 if (argv >= stop) {
151 SkDebugf("Missing mode for --mode\n");
152 usage(argv0);
153 exit(-1);
154 }
155
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000156 if (0 == strcmp(*argv, "record")) {
keyar@chromium.org795cd472012-08-02 18:57:53 +0000157 benchmark = SkNEW(sk_tools::RecordPictureBenchmark);
158 } else if (0 == strcmp(*argv, "simple")) {
159 benchmark = SkNEW(sk_tools::SimplePictureBenchmark);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000160 } else if ((0 == strcmp(*argv, "tile")) || (0 == strcmp(*argv, "pow2tile"))) {
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000161 useTiles = true;
162 mode = *argv;
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000163
164 if (0 == strcmp(*argv, "pow2tile")) {
165 isPowerOf2Mode = true;
166 }
167
keyar@chromium.org795cd472012-08-02 18:57:53 +0000168 ++argv;
169 if (argv >= stop) {
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000170 SkDebugf("Missing width for --mode %s\n", mode);
keyar@chromium.org795cd472012-08-02 18:57:53 +0000171 usage(argv0);
172 exit(-1);
173 }
174
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000175 widthString = *argv;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000176 ++argv;
177 if (argv >= stop) {
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000178 SkDebugf("Missing height for --mode tile\n");
keyar@chromium.org795cd472012-08-02 18:57:53 +0000179 usage(argv0);
180 exit(-1);
181 }
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000182 heightString = *argv;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000183
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000184 ++argv;
185 if (argv < stop && 0 == strcmp(*argv, "multi")) {
186 multiThreaded = true;
keyar@chromium.org0665f252012-07-10 18:30:18 +0000187 } else {
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000188 --argv;
reed@google.com006db0f2012-06-27 19:33:29 +0000189 }
keyar@chromium.org795cd472012-08-02 18:57:53 +0000190 } else if (0 == strcmp(*argv, "unflatten")) {
191 benchmark = SkNEW(sk_tools::UnflattenPictureBenchmark);
reed@google.com006db0f2012-06-27 19:33:29 +0000192 } else {
keyar@chromium.org795cd472012-08-02 18:57:53 +0000193 SkDebugf("%s is not a valid mode for --mode\n", *argv);
keyar@chromium.org0665f252012-07-10 18:30:18 +0000194 usage(argv0);
reed@google.com006db0f2012-06-27 19:33:29 +0000195 exit(-1);
196 }
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000197 } else if (0 == strcmp(*argv, "--device")) {
198 ++argv;
199 if (argv >= stop) {
200 SkDebugf("Missing mode for --deivce\n");
201 usage(argv0);
202 exit(-1);
203 }
204
205 if (0 == strcmp(*argv, "bitmap")) {
206 deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType;
207 }
208#if SK_SUPPORT_GPU
209 else if (0 == strcmp(*argv, "gpu")) {
210 deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
211 }
212#endif
213 else {
214 SkDebugf("%s is not a valid mode for --device\n", *argv);
215 usage(argv0);
216 exit(-1);
217 }
218
reed@google.com006db0f2012-06-27 19:33:29 +0000219 } else if (0 == strcmp(*argv, "--help") || 0 == strcmp(*argv, "-h")) {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000220 SkDELETE(benchmark);
reed@google.com006db0f2012-06-27 19:33:29 +0000221 usage(argv0);
222 exit(0);
223 } else {
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000224 inputs->push_back(SkString(*argv));
reed@google.com006db0f2012-06-27 19:33:29 +0000225 }
226 }
227
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000228 if (useTiles) {
229 sk_tools::TiledPictureBenchmark* tileBenchmark = SkNEW(sk_tools::TiledPictureBenchmark);
230 if (isPowerOf2Mode) {
231 int minWidth = atoi(widthString);
232 if (!SkIsPow2(minWidth) || minWidth < 0) {
233 SkDELETE(tileBenchmark);
234 SkDebugf("--mode %s must be given a width"
235 " value that is a power of two\n", mode);
236 exit(-1);
237 }
238 tileBenchmark->setTileMinPowerOf2Width(minWidth);
239 } else if (sk_tools::is_percentage(widthString)) {
240 tileBenchmark->setTileWidthPercentage(atof(widthString));
241 if (!(tileBenchmark->getTileWidthPercentage() > 0)) {
242 SkDELETE(tileBenchmark);
243 SkDebugf("--mode tile must be given a width percentage > 0\n");
244 exit(-1);
245 }
246 } else {
247 tileBenchmark->setTileWidth(atoi(widthString));
248 if (!(tileBenchmark->getTileWidth() > 0)) {
249 SkDELETE(tileBenchmark);
250 SkDebugf("--mode tile must be given a width > 0\n");
251 exit(-1);
252 }
253 }
254
255 if (sk_tools::is_percentage(heightString)) {
256 tileBenchmark->setTileHeightPercentage(atof(heightString));
257 if (!(tileBenchmark->getTileHeightPercentage() > 0)) {
258 SkDELETE(tileBenchmark);
259 SkDebugf("--mode tile must be given a height percentage > 0\n");
260 exit(-1);
261 }
262 } else {
263 tileBenchmark->setTileHeight(atoi(heightString));
264 if (!(tileBenchmark->getTileHeight() > 0)) {
265 SkDELETE(tileBenchmark);
266 SkDebugf("--mode tile must be given a height > 0\n");
267 exit(-1);
268 }
269 }
270 tileBenchmark->setThreading(multiThreaded);
271 tileBenchmark->setUsePipe(usePipe);
272 benchmark = tileBenchmark;
273 } else if (usePipe) {
274 SkDELETE(benchmark);
275 benchmark = SkNEW(sk_tools::PipePictureBenchmark);
276 }
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000277 if (inputs->count() < 1) {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000278 SkDELETE(benchmark);
reed@google.com006db0f2012-06-27 19:33:29 +0000279 usage(argv0);
280 exit(-1);
281 }
keyar@chromium.org163b5672012-08-01 17:53:29 +0000282
keyar@chromium.org78a35c52012-08-20 15:03:44 +0000283 if (NULL == benchmark) {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000284 benchmark = SkNEW(sk_tools::SimplePictureBenchmark);
285 }
286
287 benchmark->setRepeats(repeats);
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000288 benchmark->setDeviceType(deviceType);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000289}
reed@google.com006db0f2012-06-27 19:33:29 +0000290
keyar@chromium.org163b5672012-08-01 17:53:29 +0000291static void process_input(const SkString& input, sk_tools::PictureBenchmark& benchmark) {
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000292 SkOSFile::Iter iter(input.c_str(), "skp");
293 SkString inputFilename;
294
295 if (iter.next(&inputFilename)) {
296 do {
297 SkString inputPath;
keyar@chromium.org163b5672012-08-01 17:53:29 +0000298 sk_tools::make_filepath(&inputPath, input, inputFilename);
299 run_single_benchmark(inputPath, benchmark);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000300 } while(iter.next(&inputFilename));
301 } else {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000302 run_single_benchmark(input, benchmark);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000303 }
reed@google.com006db0f2012-06-27 19:33:29 +0000304}
305
306int main(int argc, char* const argv[]) {
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000307 SkTArray<SkString> inputs;
keyar@chromium.org163b5672012-08-01 17:53:29 +0000308 sk_tools::PictureBenchmark* benchmark = NULL;
reed@google.com006db0f2012-06-27 19:33:29 +0000309
keyar@chromium.org163b5672012-08-01 17:53:29 +0000310 parse_commandline(argc, argv, &inputs, benchmark);
reed@google.com006db0f2012-06-27 19:33:29 +0000311
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000312 for (int i = 0; i < inputs.count(); ++i) {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000313 process_input(inputs[i], *benchmark);
reed@google.com006db0f2012-06-27 19:33:29 +0000314 }
keyar@chromium.org163b5672012-08-01 17:53:29 +0000315
316 SkDELETE(benchmark);
reed@google.com006db0f2012-06-27 19:33:29 +0000317}