blob: f0f908dfd08f2533e970c4328efb4e98aeb87580 [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"
scroggo@google.com9a412522012-09-07 15:21:18 +000010#include "SkBenchLogger.h"
reed@google.com006db0f2012-06-27 19:33:29 +000011#include "SkCanvas.h"
scroggo@google.com0a36f432012-09-10 20:29:13 +000012#include "SkGraphics.h"
scroggo@google.com5a7c6be2012-10-04 21:46:08 +000013#include "SkImageDecoder.h"
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000014#include "SkMath.h"
reed@google.com006db0f2012-06-27 19:33:29 +000015#include "SkOSFile.h"
16#include "SkPicture.h"
17#include "SkStream.h"
18#include "SkTArray.h"
19#include "picture_utils.h"
20
borenet@google.com13fd5a12012-09-17 21:10:05 +000021const int DEFAULT_REPEATS = 1;
reed@google.com006db0f2012-06-27 19:33:29 +000022
23static void usage(const char* argv0) {
24 SkDebugf("SkPicture benchmarking tool\n");
25 SkDebugf("\n"
26"Usage: \n"
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +000027" %s <inputDir>...\n"
scroggo@google.com5239c322012-09-11 19:15:32 +000028" [--logFile filename][--timers [wcgWC]*][--logPerIter 1|0][--min]\n"
keyar@chromium.org795cd472012-08-02 18:57:53 +000029" [--repeat] \n"
scroggo@google.combcdf2ec2012-09-20 14:42:33 +000030" [--mode pow2tile minWidth height[] | record | simple\n"
31" | tile width[] height[] | playbackCreation]\n"
scroggo@google.com58b4ead2012-08-31 16:15:22 +000032" [--pipe]\n"
junov@chromium.org9313ca42012-11-02 18:11:49 +000033" [--bbh bbhType]\n"
scroggo@google.combcdf2ec2012-09-20 14:42:33 +000034" [--multi numThreads]\n"
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000035" [--device bitmap"
36#if SK_SUPPORT_GPU
37" | gpu"
38#endif
39"]"
reed@google.com006db0f2012-06-27 19:33:29 +000040, argv0);
41 SkDebugf("\n\n");
42 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000043" inputDir: A list of directories and files to use as input. Files are\n"
scroggo@google.com9a412522012-09-07 15:21:18 +000044" expected to have the .skp extension.\n\n"
45" --logFile filename : destination for writing log output, in addition to stdout.\n");
scroggo@google.com5239c322012-09-11 19:15:32 +000046 SkDebugf(" --logPerIter 1|0 : "
47 "Log each repeat timer instead of mean, default is disabled.\n");
48 SkDebugf(" --min : Print the minimum times (instead of average).\n");
49 SkDebugf(" --timers [wcgWC]* : "
50 "Display wall, cpu, gpu, truncated wall or truncated cpu time for each picture.\n");
reed@google.com006db0f2012-06-27 19:33:29 +000051 SkDebugf(
scroggo@google.combcdf2ec2012-09-20 14:42:33 +000052" --mode pow2tile minWidht height[] | record | simple\n"
53" | tile width[] height[] | playbackCreation:\n"
scroggo@google.com58b4ead2012-08-31 16:15:22 +000054" Run in the corresponding mode.\n"
55" Default is simple.\n");
keyar@chromium.orgcf6c44c2012-07-09 19:37:40 +000056 SkDebugf(
scroggo@google.com58b4ead2012-08-31 16:15:22 +000057" pow2tile minWidth height[], Creates tiles with widths\n"
58" that are all a power of two\n"
59" such that they minimize the\n"
60" amount of wasted tile space.\n"
61" minWidth is the minimum width\n"
62" of these tiles and must be a\n"
63" power of two. Simple\n"
64" rendering using these tiles\n"
scroggo@google.combcdf2ec2012-09-20 14:42:33 +000065" is benchmarked.\n");
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000066 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000067" record, Benchmark picture to picture recording.\n");
68 SkDebugf(
69" simple, Benchmark a simple rendering.\n");
70 SkDebugf(
scroggo@google.com58b4ead2012-08-31 16:15:22 +000071" tile width[] height[], Benchmark simple rendering using\n"
scroggo@google.combcdf2ec2012-09-20 14:42:33 +000072" tiles with the given dimensions.\n");
keyar@chromium.org795cd472012-08-02 18:57:53 +000073 SkDebugf(
scroggo@google.com9a412522012-09-07 15:21:18 +000074" playbackCreation, Benchmark creation of the SkPicturePlayback.\n");
keyar@chromium.org795cd472012-08-02 18:57:53 +000075 SkDebugf("\n");
76 SkDebugf(
scroggo@google.combcdf2ec2012-09-20 14:42:33 +000077" --multi numThreads : Set the number of threads for multi threaded drawing. Must be greater\n"
78" than 1. Only works with tiled rendering.\n"
scroggo@google.coma62da2f2012-11-02 21:28:12 +000079" --pipe: Benchmark SkGPipe rendering. Currently incompatible with \"mode\".\n");
scroggo@google.com58b4ead2012-08-31 16:15:22 +000080 SkDebugf(
junov@chromium.org7b537062012-11-06 18:58:43 +000081" --bbh bbhType [width height]: Set the bounding box hierarchy type to\n"
82" be used. Accepted values are: none, rtree, grid. Default\n"
83" value is none. Not compatible with --pipe. With value\n"
84" 'grid', width and height must be specified. 'grid' can\n"
85" only be used with modes tile, record, and\n"
86" playbackCreation.");
junov@chromium.org9313ca42012-11-02 18:11:49 +000087 SkDebugf(
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000088" --device bitmap"
89#if SK_SUPPORT_GPU
90" | gpu"
91#endif
92": Use the corresponding device. Default is bitmap.\n");
93 SkDebugf(
94" bitmap, Render to a bitmap.\n");
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000095#if SK_SUPPORT_GPU
keyar@chromium.orga40c20d2012-08-20 15:04:12 +000096 SkDebugf(
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000097" gpu, Render to the GPU.\n");
98#endif
99 SkDebugf("\n");
100 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +0000101" --repeat: "
reed@google.com006db0f2012-06-27 19:33:29 +0000102"Set the number of times to repeat each test."
103" Default is %i.\n", DEFAULT_REPEATS);
reed@google.com006db0f2012-06-27 19:33:29 +0000104}
105
scroggo@google.com9a412522012-09-07 15:21:18 +0000106SkBenchLogger gLogger;
107
borenet@google.com66bcbd12012-09-17 18:26:06 +0000108static bool run_single_benchmark(const SkString& inputPath,
keyar@chromium.org163b5672012-08-01 17:53:29 +0000109 sk_tools::PictureBenchmark& benchmark) {
reed@google.com006db0f2012-06-27 19:33:29 +0000110 SkFILEStream inputStream;
111
reed@google.com006db0f2012-06-27 19:33:29 +0000112 inputStream.setPath(inputPath.c_str());
113 if (!inputStream.isValid()) {
scroggo@google.com9a412522012-09-07 15:21:18 +0000114 SkString err;
115 err.printf("Could not open file %s\n", inputPath.c_str());
116 gLogger.logError(err);
borenet@google.com66bcbd12012-09-17 18:26:06 +0000117 return false;
reed@google.com006db0f2012-06-27 19:33:29 +0000118 }
119
borenet@google.com66bcbd12012-09-17 18:26:06 +0000120 bool success = false;
scroggo@google.com5a7c6be2012-10-04 21:46:08 +0000121 SkPicture picture(&inputStream, &success, &SkImageDecoder::DecodeStream);
borenet@google.com66bcbd12012-09-17 18:26:06 +0000122 if (!success) {
123 SkString err;
124 err.printf("Could not read an SkPicture from %s\n", inputPath.c_str());
125 gLogger.logError(err);
126 return false;
127 }
reed@google.com006db0f2012-06-27 19:33:29 +0000128
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000129 SkString filename;
130 sk_tools::get_basename(&filename, inputPath);
keyar@chromium.orgdb9a5fb2012-08-21 17:57:59 +0000131
132 SkString result;
borenet@google.com2d2b9a02012-09-20 18:54:04 +0000133 result.printf("running bench [%i %i] %s ", picture.width(),
134 picture.height(), filename.c_str());
scroggo@google.com9a412522012-09-07 15:21:18 +0000135 gLogger.logProgress(result);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000136
borenet@google.com2d2b9a02012-09-20 18:54:04 +0000137 benchmark.run(&picture);
borenet@google.com66bcbd12012-09-17 18:26:06 +0000138 return true;
keyar@chromium.org0665f252012-07-10 18:30:18 +0000139}
140
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000141#define PRINT_USAGE_AND_EXIT \
142 do { \
143 usage(argv0); \
144 exit(-1); \
145 } while (0)
146
keyar@chromium.org163b5672012-08-01 17:53:29 +0000147static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs,
scroggo@google.com5239c322012-09-11 19:15:32 +0000148 sk_tools::PictureBenchmark* benchmark) {
reed@google.com006db0f2012-06-27 19:33:29 +0000149 const char* argv0 = argv[0];
150 char* const* stop = argv + argc;
151
keyar@chromium.org163b5672012-08-01 17:53:29 +0000152 int repeats = DEFAULT_REPEATS;
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000153 sk_tools::PictureRenderer::SkDeviceTypes deviceType =
154 sk_tools::PictureRenderer::kBitmap_DeviceType;
keyar@chromium.org163b5672012-08-01 17:53:29 +0000155
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000156 SkAutoTUnref<sk_tools::PictureRenderer> renderer(NULL);
scroggo@google.com5239c322012-09-11 19:15:32 +0000157
scroggo@google.com9a412522012-09-07 15:21:18 +0000158 // Create a string to show our current settings.
159 // TODO: Make it prettier. Currently it just repeats the command line.
160 SkString commandLine("bench_pictures:");
161 for (int i = 1; i < argc; i++) {
162 commandLine.appendf(" %s", *(argv+i));
163 }
164 commandLine.append("\n");
165
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000166 bool usePipe = false;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000167 int numThreads = 1;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000168 bool useTiles = false;
169 const char* widthString = NULL;
170 const char* heightString = NULL;
junov@chromium.org7b537062012-11-06 18:58:43 +0000171 int gridWidth = 0;
172 int gridHeight = 0;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000173 bool isPowerOf2Mode = false;
174 const char* mode = NULL;
junov@chromium.org7b537062012-11-06 18:58:43 +0000175 bool gridSupported = false;
skia.committer@gmail.com1aa90cf2012-11-06 13:18:25 +0000176 sk_tools::PictureRenderer::BBoxHierarchyType bbhType =
junov@chromium.org9313ca42012-11-02 18:11:49 +0000177 sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
reed@google.com006db0f2012-06-27 19:33:29 +0000178 for (++argv; argv < stop; ++argv) {
179 if (0 == strcmp(*argv, "--repeat")) {
180 ++argv;
181 if (argv < stop) {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000182 repeats = atoi(*argv);
183 if (repeats < 1) {
scroggo@google.com9a412522012-09-07 15:21:18 +0000184 gLogger.logError("--repeat must be given a value > 0\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000185 PRINT_USAGE_AND_EXIT;
reed@google.com006db0f2012-06-27 19:33:29 +0000186 }
187 } else {
scroggo@google.com9a412522012-09-07 15:21:18 +0000188 gLogger.logError("Missing arg for --repeat\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000189 PRINT_USAGE_AND_EXIT;
reed@google.com006db0f2012-06-27 19:33:29 +0000190 }
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000191 } else if (0 == strcmp(*argv, "--pipe")) {
192 usePipe = true;
scroggo@google.com9a412522012-09-07 15:21:18 +0000193 } else if (0 == strcmp(*argv, "--logFile")) {
194 argv++;
195 if (argv < stop) {
196 if (!gLogger.SetLogFile(*argv)) {
197 SkString str;
198 str.printf("Could not open %s for writing.", *argv);
199 gLogger.logError(str);
200 usage(argv0);
borenet@google.coma49bffd2012-09-13 18:54:48 +0000201 // TODO(borenet): We're disabling this for now, due to
202 // write-protected Android devices. The very short-term
203 // solution is to ignore the fact that we have no log file.
204 //exit(-1);
scroggo@google.com9a412522012-09-07 15:21:18 +0000205 }
206 } else {
207 gLogger.logError("Missing arg for --logFile\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000208 PRINT_USAGE_AND_EXIT;
scroggo@google.com9a412522012-09-07 15:21:18 +0000209 }
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000210 } else if (0 == strcmp(*argv, "--multi")) {
211 ++argv;
212 if (argv >= stop) {
213 gLogger.logError("Missing arg for --multi\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000214 PRINT_USAGE_AND_EXIT;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000215 }
216 numThreads = atoi(*argv);
217 if (numThreads < 2) {
218 gLogger.logError("Number of threads must be at least 2.\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000219 PRINT_USAGE_AND_EXIT;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000220 }
junov@chromium.org9313ca42012-11-02 18:11:49 +0000221 } else if (0 == strcmp(*argv, "--bbh")) {
222 ++argv;
223 if (argv >= stop) {
224 gLogger.logError("Missing value for --bbh\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000225 PRINT_USAGE_AND_EXIT;
junov@chromium.org9313ca42012-11-02 18:11:49 +0000226 }
227 if (0 == strcmp(*argv, "none")) {
228 bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
229 } else if (0 == strcmp(*argv, "rtree")) {
230 bbhType = sk_tools::PictureRenderer::kRTree_BBoxHierarchyType;
junov@chromium.org7b537062012-11-06 18:58:43 +0000231 } else if (0 == strcmp(*argv, "grid")) {
232 bbhType = sk_tools::PictureRenderer::kTileGrid_BBoxHierarchyType;
233 ++argv;
234 if (argv >= stop) {
235 gLogger.logError("Missing width for --bbh grid\n");
236 PRINT_USAGE_AND_EXIT;
237 }
238 gridWidth = atoi(*argv);
239 ++argv;
240 if (argv >= stop) {
241 gLogger.logError("Missing height for --bbh grid\n");
242 PRINT_USAGE_AND_EXIT;
243 }
244 gridHeight = atoi(*argv);
junov@chromium.org9313ca42012-11-02 18:11:49 +0000245 } else {
246 SkString err;
247 err.printf("%s is not a valid value for --bbhType\n", *argv);
248 gLogger.logError(err);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000249 PRINT_USAGE_AND_EXIT;
junov@chromium.org9313ca42012-11-02 18:11:49 +0000250 }
251
keyar@chromium.org795cd472012-08-02 18:57:53 +0000252 } else if (0 == strcmp(*argv, "--mode")) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000253 if (renderer.get() != NULL) {
254 SkDebugf("Cannot combine modes.\n");
255 PRINT_USAGE_AND_EXIT;
256 }
keyar@chromium.org795cd472012-08-02 18:57:53 +0000257
reed@google.com006db0f2012-06-27 19:33:29 +0000258 ++argv;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000259 if (argv >= stop) {
scroggo@google.com9a412522012-09-07 15:21:18 +0000260 gLogger.logError("Missing mode for --mode\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000261 PRINT_USAGE_AND_EXIT;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000262 }
263
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000264 if (0 == strcmp(*argv, "record")) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000265 renderer.reset(SkNEW(sk_tools::RecordPictureRenderer));
junov@chromium.org7b537062012-11-06 18:58:43 +0000266 gridSupported = true;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000267 } else if (0 == strcmp(*argv, "simple")) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000268 renderer.reset(SkNEW(sk_tools::SimplePictureRenderer));
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000269 } else if ((0 == strcmp(*argv, "tile")) || (0 == strcmp(*argv, "pow2tile"))) {
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000270 useTiles = true;
271 mode = *argv;
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000272
273 if (0 == strcmp(*argv, "pow2tile")) {
274 isPowerOf2Mode = true;
junov@chromium.org7b537062012-11-06 18:58:43 +0000275 } else {
276 gridSupported = true;
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000277 }
278
keyar@chromium.org795cd472012-08-02 18:57:53 +0000279 ++argv;
280 if (argv >= stop) {
scroggo@google.com9a412522012-09-07 15:21:18 +0000281 SkString err;
282 err.printf("Missing width for --mode %s\n", mode);
283 gLogger.logError(err);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000284 PRINT_USAGE_AND_EXIT;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000285 }
286
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000287 widthString = *argv;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000288 ++argv;
289 if (argv >= stop) {
scroggo@google.com9a412522012-09-07 15:21:18 +0000290 gLogger.logError("Missing height for --mode tile\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000291 PRINT_USAGE_AND_EXIT;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000292 }
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000293 heightString = *argv;
scroggo@google.com9a412522012-09-07 15:21:18 +0000294 } else if (0 == strcmp(*argv, "playbackCreation")) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000295 renderer.reset(SkNEW(sk_tools::PlaybackCreationRenderer));
junov@chromium.org7b537062012-11-06 18:58:43 +0000296 gridSupported = true;
reed@google.com006db0f2012-06-27 19:33:29 +0000297 } else {
scroggo@google.com9a412522012-09-07 15:21:18 +0000298 SkString err;
299 err.printf("%s is not a valid mode for --mode\n", *argv);
300 gLogger.logError(err);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000301 PRINT_USAGE_AND_EXIT;
reed@google.com006db0f2012-06-27 19:33:29 +0000302 }
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000303 } else if (0 == strcmp(*argv, "--device")) {
304 ++argv;
305 if (argv >= stop) {
borenet@google.coma49bffd2012-09-13 18:54:48 +0000306 gLogger.logError("Missing mode for --device\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000307 PRINT_USAGE_AND_EXIT;
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000308 }
309
310 if (0 == strcmp(*argv, "bitmap")) {
311 deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType;
312 }
313#if SK_SUPPORT_GPU
314 else if (0 == strcmp(*argv, "gpu")) {
315 deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
316 }
317#endif
318 else {
scroggo@google.com9a412522012-09-07 15:21:18 +0000319 SkString err;
320 err.printf("%s is not a valid mode for --device\n", *argv);
321 gLogger.logError(err);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000322 PRINT_USAGE_AND_EXIT;
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000323 }
scroggo@google.com5239c322012-09-11 19:15:32 +0000324 } else if (0 == strcmp(*argv, "--timers")) {
325 ++argv;
326 if (argv < stop) {
327 bool timerWall = false;
328 bool truncatedTimerWall = false;
329 bool timerCpu = false;
330 bool truncatedTimerCpu = false;
331 bool timerGpu = false;
332 for (char* t = *argv; *t; ++t) {
333 switch (*t) {
334 case 'w':
335 timerWall = true;
336 break;
337 case 'c':
338 timerCpu = true;
339 break;
340 case 'W':
341 truncatedTimerWall = true;
342 break;
343 case 'C':
344 truncatedTimerCpu = true;
345 break;
346 case 'g':
347 timerGpu = true;
348 break;
349 default: {
350 break;
351 }
352 }
353 }
354 benchmark->setTimersToShow(timerWall, truncatedTimerWall, timerCpu,
355 truncatedTimerCpu, timerGpu);
356 } else {
357 gLogger.logError("Missing arg for --timers\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000358 PRINT_USAGE_AND_EXIT;
scroggo@google.com5239c322012-09-11 19:15:32 +0000359 }
360 } else if (0 == strcmp(*argv, "--min")) {
361 benchmark->setPrintMin(true);
362 } else if (0 == strcmp(*argv, "--logPerIter")) {
363 ++argv;
364 if (argv < stop) {
365 bool log = atoi(*argv) != 0;
366 benchmark->setLogPerIter(log);
367 } else {
368 gLogger.logError("Missing arg for --logPerIter\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000369 PRINT_USAGE_AND_EXIT;
scroggo@google.com5239c322012-09-11 19:15:32 +0000370 }
reed@google.com006db0f2012-06-27 19:33:29 +0000371 } else if (0 == strcmp(*argv, "--help") || 0 == strcmp(*argv, "-h")) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000372 PRINT_USAGE_AND_EXIT;
reed@google.com006db0f2012-06-27 19:33:29 +0000373 } else {
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000374 inputs->push_back(SkString(*argv));
reed@google.com006db0f2012-06-27 19:33:29 +0000375 }
376 }
377
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000378 if (numThreads > 1 && !useTiles) {
379 gLogger.logError("Multithreaded drawing requires tiled rendering.\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000380 PRINT_USAGE_AND_EXIT;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000381 }
382
junov@chromium.org9313ca42012-11-02 18:11:49 +0000383 if (usePipe && sk_tools::PictureRenderer::kNone_BBoxHierarchyType != bbhType) {
384 gLogger.logError("--pipe and --bbh cannot be used together\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000385 PRINT_USAGE_AND_EXIT;
junov@chromium.org9313ca42012-11-02 18:11:49 +0000386 }
387
junov@chromium.org7b537062012-11-06 18:58:43 +0000388 if (sk_tools::PictureRenderer::kTileGrid_BBoxHierarchyType == bbhType &&
389 !gridSupported) {
390 gLogger.logError("'--bbh grid' is not compatible with specified --mode.\n");
391 PRINT_USAGE_AND_EXIT;
392 }
393
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000394 if (useTiles) {
scroggo@google.com5239c322012-09-11 19:15:32 +0000395 SkASSERT(NULL == renderer);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000396 sk_tools::TiledPictureRenderer* tiledRenderer;
397 if (numThreads > 1) {
398 tiledRenderer = SkNEW_ARGS(sk_tools::MultiCorePictureRenderer, (numThreads));
399 } else {
400 tiledRenderer = SkNEW(sk_tools::TiledPictureRenderer);
401 }
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000402 if (isPowerOf2Mode) {
403 int minWidth = atoi(widthString);
404 if (!SkIsPow2(minWidth) || minWidth < 0) {
scroggo@google.com5239c322012-09-11 19:15:32 +0000405 tiledRenderer->unref();
scroggo@google.com9a412522012-09-07 15:21:18 +0000406 SkString err;
scroggo@google.com5239c322012-09-11 19:15:32 +0000407 err.printf("-mode %s must be given a width"
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000408 " value that is a power of two\n", mode);
scroggo@google.com9a412522012-09-07 15:21:18 +0000409 gLogger.logError(err);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000410 PRINT_USAGE_AND_EXIT;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000411 }
scroggo@google.com5239c322012-09-11 19:15:32 +0000412 tiledRenderer->setTileMinPowerOf2Width(minWidth);
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000413 } else if (sk_tools::is_percentage(widthString)) {
scroggo@google.com5239c322012-09-11 19:15:32 +0000414 tiledRenderer->setTileWidthPercentage(atof(widthString));
415 if (!(tiledRenderer->getTileWidthPercentage() > 0)) {
416 tiledRenderer->unref();
scroggo@google.com9a412522012-09-07 15:21:18 +0000417 gLogger.logError("--mode tile must be given a width percentage > 0\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000418 PRINT_USAGE_AND_EXIT;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000419 }
420 } else {
scroggo@google.com5239c322012-09-11 19:15:32 +0000421 tiledRenderer->setTileWidth(atoi(widthString));
422 if (!(tiledRenderer->getTileWidth() > 0)) {
423 tiledRenderer->unref();
scroggo@google.com9a412522012-09-07 15:21:18 +0000424 gLogger.logError("--mode tile must be given a width > 0\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000425 PRINT_USAGE_AND_EXIT;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000426 }
427 }
428
429 if (sk_tools::is_percentage(heightString)) {
scroggo@google.com5239c322012-09-11 19:15:32 +0000430 tiledRenderer->setTileHeightPercentage(atof(heightString));
431 if (!(tiledRenderer->getTileHeightPercentage() > 0)) {
432 tiledRenderer->unref();
scroggo@google.com9a412522012-09-07 15:21:18 +0000433 gLogger.logError("--mode tile must be given a height percentage > 0\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000434 PRINT_USAGE_AND_EXIT;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000435 }
436 } else {
scroggo@google.com5239c322012-09-11 19:15:32 +0000437 tiledRenderer->setTileHeight(atoi(heightString));
438 if (!(tiledRenderer->getTileHeight() > 0)) {
439 tiledRenderer->unref();
scroggo@google.com9a412522012-09-07 15:21:18 +0000440 gLogger.logError("--mode tile must be given a height > 0\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000441 PRINT_USAGE_AND_EXIT;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000442 }
443 }
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000444 if (numThreads > 1) {
445#if SK_SUPPORT_GPU
446 if (sk_tools::PictureRenderer::kGPU_DeviceType == deviceType) {
447 tiledRenderer->unref();
448 gLogger.logError("GPU not compatible with multithreaded tiling.\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000449 PRINT_USAGE_AND_EXIT;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000450 }
451#endif
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000452 }
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000453 renderer.reset(tiledRenderer);
454 if (usePipe) {
455 SkDebugf("Pipe rendering is currently not compatible with tiling.\n"
456 "Turning off pipe.\n");
457 }
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000458 } else if (usePipe) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000459 if (renderer.get() != NULL) {
460 SkDebugf("Pipe is incompatible with other modes.\n");
461 PRINT_USAGE_AND_EXIT;
462 }
463 renderer.reset(SkNEW(sk_tools::PipePictureRenderer));
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000464 }
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000465 if (inputs->count() < 1) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000466 PRINT_USAGE_AND_EXIT;
reed@google.com006db0f2012-06-27 19:33:29 +0000467 }
keyar@chromium.org163b5672012-08-01 17:53:29 +0000468
scroggo@google.com5239c322012-09-11 19:15:32 +0000469 if (NULL == renderer) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000470 renderer.reset(SkNEW(sk_tools::SimplePictureRenderer));
keyar@chromium.org163b5672012-08-01 17:53:29 +0000471 }
junov@chromium.org9313ca42012-11-02 18:11:49 +0000472
473 renderer->setBBoxHierarchyType(bbhType);
junov@chromium.org7b537062012-11-06 18:58:43 +0000474 renderer->setGridSize(gridWidth, gridHeight);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000475 benchmark->setRenderer(renderer);
keyar@chromium.org163b5672012-08-01 17:53:29 +0000476 benchmark->setRepeats(repeats);
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000477 benchmark->setDeviceType(deviceType);
scroggo@google.com9a412522012-09-07 15:21:18 +0000478 benchmark->setLogger(&gLogger);
479 // Report current settings:
480 gLogger.logProgress(commandLine);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000481}
reed@google.com006db0f2012-06-27 19:33:29 +0000482
borenet@google.com66bcbd12012-09-17 18:26:06 +0000483static int process_input(const SkString& input,
484 sk_tools::PictureBenchmark& benchmark) {
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000485 SkOSFile::Iter iter(input.c_str(), "skp");
486 SkString inputFilename;
borenet@google.com66bcbd12012-09-17 18:26:06 +0000487 int failures = 0;
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000488 if (iter.next(&inputFilename)) {
489 do {
490 SkString inputPath;
keyar@chromium.org163b5672012-08-01 17:53:29 +0000491 sk_tools::make_filepath(&inputPath, input, inputFilename);
borenet@google.com57837bf2012-09-19 17:28:29 +0000492 if (!run_single_benchmark(inputPath, benchmark)) {
borenet@google.com66bcbd12012-09-17 18:26:06 +0000493 ++failures;
borenet@google.com57837bf2012-09-19 17:28:29 +0000494 }
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000495 } while(iter.next(&inputFilename));
borenet@google.com57837bf2012-09-19 17:28:29 +0000496 } else if (SkStrEndsWith(input.c_str(), ".skp")) {
497 if (!run_single_benchmark(input, benchmark)) {
borenet@google.com66bcbd12012-09-17 18:26:06 +0000498 ++failures;
borenet@google.com57837bf2012-09-19 17:28:29 +0000499 }
500 } else {
501 SkString warning;
502 warning.printf("Warning: skipping %s\n", input.c_str());
503 gLogger.logError(warning);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000504 }
borenet@google.com66bcbd12012-09-17 18:26:06 +0000505 return failures;
reed@google.com006db0f2012-06-27 19:33:29 +0000506}
507
caryclark@google.com5987f582012-10-02 18:33:14 +0000508int tool_main(int argc, char** argv);
509int tool_main(int argc, char** argv) {
scroggo@google.com5239c322012-09-11 19:15:32 +0000510#ifdef SK_ENABLE_INST_COUNT
511 gPrintInstCount = true;
512#endif
scroggo@google.com0a36f432012-09-10 20:29:13 +0000513 SkAutoGraphics ag;
reed@google.com006db0f2012-06-27 19:33:29 +0000514
scroggo@google.com5239c322012-09-11 19:15:32 +0000515 SkTArray<SkString> inputs;
516 sk_tools::PictureBenchmark benchmark;
517
518 parse_commandline(argc, argv, &inputs, &benchmark);
reed@google.com006db0f2012-06-27 19:33:29 +0000519
borenet@google.com66bcbd12012-09-17 18:26:06 +0000520 int failures = 0;
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000521 for (int i = 0; i < inputs.count(); ++i) {
borenet@google.com66bcbd12012-09-17 18:26:06 +0000522 failures += process_input(inputs[i], benchmark);
523 }
524
525 if (failures != 0) {
526 SkString err;
527 err.printf("Failed to run %i benchmarks.\n", failures);
528 gLogger.logError(err);
529 return 1;
reed@google.com006db0f2012-06-27 19:33:29 +0000530 }
caryclark@google.com868e1f62012-10-02 20:00:03 +0000531 return 0;
reed@google.com006db0f2012-06-27 19:33:29 +0000532}
caryclark@google.com5987f582012-10-02 18:33:14 +0000533
534#if !defined SK_BUILD_FOR_IOS
535int main(int argc, char * const argv[]) {
536 return tool_main(argc, (char**) argv);
537}
538#endif