blob: 569a0a50066152bafd9f6eeb24fb7050a132d65b [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
caryclark@google.coma3622372012-11-06 21:26:13 +000023static char const * const gFilterTypes[] = {
24 "paint",
25 "point",
26 "line",
27 "bitmap",
28 "rect",
29 "path",
30 "text",
31 "all",
32};
33
34static const size_t kFilterTypesCount = sizeof(gFilterTypes) / sizeof(gFilterTypes[0]);
35
36static char const * const gFilterFlags[] = {
37 "antiAlias",
38 "filterBitmap",
39 "dither",
40 "underlineText",
41 "strikeThruText",
42 "fakeBoldText",
43 "linearText",
44 "subpixelText",
45 "devKernText",
46 "LCDRenderText",
47 "embeddedBitmapText",
48 "autoHinting",
49 "verticalText",
50 "genA8FromLCD",
51 "blur",
52 "hinting",
53 "slightHinting",
54};
55
56static const size_t kFilterFlagsCount = sizeof(gFilterFlags) / sizeof(gFilterFlags[0]);
57
58static SkString filtersName(sk_tools::PictureRenderer::DrawFilterFlags* drawFilters) {
59 int all = drawFilters[0];
60 size_t tIndex;
61 for (tIndex = 1; tIndex < SkDrawFilter::kTypeCount; ++tIndex) {
62 all &= drawFilters[tIndex];
63 }
64 SkString result;
65 for (size_t fIndex = 0; fIndex < kFilterFlagsCount; ++fIndex) {
66 SkString types;
67 if (all & (1 << fIndex)) {
68 types = gFilterTypes[SkDrawFilter::kTypeCount];
69 } else {
70 for (tIndex = 0; tIndex < SkDrawFilter::kTypeCount; ++tIndex) {
71 if (drawFilters[tIndex] & (1 << fIndex)) {
72 types += gFilterTypes[tIndex];
73 }
74 }
75 }
76 if (!types.size()) {
77 continue;
78 }
79 result += "_";
80 result += types;
81 result += ".";
82 result += gFilterFlags[fIndex];
83 }
84 return result;
85}
86
87static SkString filterTypesUsage() {
88 SkString result;
89 for (size_t index = 0; index < kFilterTypesCount; ++index) {
90 result += gFilterTypes[index];
91 if (index < kFilterTypesCount - 1) {
92 result += " | ";
93 }
94 }
95 return result;
96}
97
98static SkString filterFlagsUsage() {
99 SkString result;
100 size_t len = 0;
101 for (size_t index = 0; index < kFilterFlagsCount; ++index) {
102 result += gFilterFlags[index];
103 if (result.size() - len >= 72) {
104 result += "\n ";
105 len = result.size();
106 }
107 if (index < kFilterFlagsCount - 1) {
108 result += " | ";
109 }
110 }
111 return result;
112}
113
reed@google.com006db0f2012-06-27 19:33:29 +0000114static void usage(const char* argv0) {
115 SkDebugf("SkPicture benchmarking tool\n");
116 SkDebugf("\n"
117"Usage: \n"
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000118" %s <inputDir>...\n"
scroggo@google.com5239c322012-09-11 19:15:32 +0000119" [--logFile filename][--timers [wcgWC]*][--logPerIter 1|0][--min]\n"
keyar@chromium.org795cd472012-08-02 18:57:53 +0000120" [--repeat] \n"
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000121" [--mode pow2tile minWidth height[] | record | simple\n"
122" | tile width[] height[] | playbackCreation]\n"
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000123" [--pipe]\n"
junov@chromium.org9313ca42012-11-02 18:11:49 +0000124" [--bbh bbhType]\n"
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000125" [--multi numThreads]\n"
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000126" [--device bitmap"
127#if SK_SUPPORT_GPU
128" | gpu"
129#endif
caryclark@google.coma3622372012-11-06 21:26:13 +0000130"]\n"
131" [--filter [%s]:\n [%s]]\n"
132, argv0, filterTypesUsage().c_str(), filterFlagsUsage().c_str());
133 SkDebugf("\n");
reed@google.com006db0f2012-06-27 19:33:29 +0000134 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +0000135" inputDir: A list of directories and files to use as input. Files are\n"
scroggo@google.com9a412522012-09-07 15:21:18 +0000136" expected to have the .skp extension.\n\n"
137" --logFile filename : destination for writing log output, in addition to stdout.\n");
scroggo@google.com5239c322012-09-11 19:15:32 +0000138 SkDebugf(" --logPerIter 1|0 : "
139 "Log each repeat timer instead of mean, default is disabled.\n");
140 SkDebugf(" --min : Print the minimum times (instead of average).\n");
141 SkDebugf(" --timers [wcgWC]* : "
142 "Display wall, cpu, gpu, truncated wall or truncated cpu time for each picture.\n");
reed@google.com006db0f2012-06-27 19:33:29 +0000143 SkDebugf(
caryclark@google.coma3622372012-11-06 21:26:13 +0000144" --mode pow2tile minWidth height[] | record | simple\n"
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000145" | tile width[] height[] | playbackCreation:\n"
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000146" Run in the corresponding mode.\n"
147" Default is simple.\n");
keyar@chromium.orgcf6c44c2012-07-09 19:37:40 +0000148 SkDebugf(
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000149" pow2tile minWidth height[], Creates tiles with widths\n"
150" that are all a power of two\n"
151" such that they minimize the\n"
152" amount of wasted tile space.\n"
153" minWidth is the minimum width\n"
154" of these tiles and must be a\n"
155" power of two. Simple\n"
156" rendering using these tiles\n"
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000157" is benchmarked.\n");
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000158 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +0000159" record, Benchmark picture to picture recording.\n");
160 SkDebugf(
161" simple, Benchmark a simple rendering.\n");
162 SkDebugf(
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000163" tile width[] height[], Benchmark simple rendering using\n"
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000164" tiles with the given dimensions.\n");
keyar@chromium.org795cd472012-08-02 18:57:53 +0000165 SkDebugf(
scroggo@google.com9a412522012-09-07 15:21:18 +0000166" playbackCreation, Benchmark creation of the SkPicturePlayback.\n");
keyar@chromium.org795cd472012-08-02 18:57:53 +0000167 SkDebugf("\n");
168 SkDebugf(
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000169" --multi numThreads : Set the number of threads for multi threaded drawing. Must be greater\n"
170" than 1. Only works with tiled rendering.\n"
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000171" --pipe: Benchmark SkGPipe rendering. Currently incompatible with \"mode\".\n");
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000172 SkDebugf(
junov@chromium.org7b537062012-11-06 18:58:43 +0000173" --bbh bbhType [width height]: Set the bounding box hierarchy type to\n"
174" be used. Accepted values are: none, rtree, grid. Default\n"
175" value is none. Not compatible with --pipe. With value\n"
176" 'grid', width and height must be specified. 'grid' can\n"
177" only be used with modes tile, record, and\n"
178" playbackCreation.");
junov@chromium.org9313ca42012-11-02 18:11:49 +0000179 SkDebugf(
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000180" --device bitmap"
181#if SK_SUPPORT_GPU
182" | gpu"
183#endif
184": Use the corresponding device. Default is bitmap.\n");
185 SkDebugf(
186" bitmap, Render to a bitmap.\n");
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000187#if SK_SUPPORT_GPU
keyar@chromium.orga40c20d2012-08-20 15:04:12 +0000188 SkDebugf(
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000189" gpu, Render to the GPU.\n");
190#endif
191 SkDebugf("\n");
192 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +0000193" --repeat: "
reed@google.com006db0f2012-06-27 19:33:29 +0000194"Set the number of times to repeat each test."
195" Default is %i.\n", DEFAULT_REPEATS);
caryclark@google.coma3622372012-11-06 21:26:13 +0000196 SkDebugf(
197" --filter type:flag : ");
198 SkDebugf(
199"Enable canvas filtering to disable a paint flag,\n"
200" disable blur, or use less hinting.\n");
reed@google.com006db0f2012-06-27 19:33:29 +0000201}
202
scroggo@google.com9a412522012-09-07 15:21:18 +0000203SkBenchLogger gLogger;
204
borenet@google.com66bcbd12012-09-17 18:26:06 +0000205static bool run_single_benchmark(const SkString& inputPath,
keyar@chromium.org163b5672012-08-01 17:53:29 +0000206 sk_tools::PictureBenchmark& benchmark) {
reed@google.com006db0f2012-06-27 19:33:29 +0000207 SkFILEStream inputStream;
208
reed@google.com006db0f2012-06-27 19:33:29 +0000209 inputStream.setPath(inputPath.c_str());
210 if (!inputStream.isValid()) {
scroggo@google.com9a412522012-09-07 15:21:18 +0000211 SkString err;
212 err.printf("Could not open file %s\n", inputPath.c_str());
213 gLogger.logError(err);
borenet@google.com66bcbd12012-09-17 18:26:06 +0000214 return false;
reed@google.com006db0f2012-06-27 19:33:29 +0000215 }
216
borenet@google.com66bcbd12012-09-17 18:26:06 +0000217 bool success = false;
scroggo@google.com5a7c6be2012-10-04 21:46:08 +0000218 SkPicture picture(&inputStream, &success, &SkImageDecoder::DecodeStream);
borenet@google.com66bcbd12012-09-17 18:26:06 +0000219 if (!success) {
220 SkString err;
221 err.printf("Could not read an SkPicture from %s\n", inputPath.c_str());
222 gLogger.logError(err);
223 return false;
224 }
reed@google.com006db0f2012-06-27 19:33:29 +0000225
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000226 SkString filename;
227 sk_tools::get_basename(&filename, inputPath);
keyar@chromium.orgdb9a5fb2012-08-21 17:57:59 +0000228
229 SkString result;
borenet@google.com2d2b9a02012-09-20 18:54:04 +0000230 result.printf("running bench [%i %i] %s ", picture.width(),
231 picture.height(), filename.c_str());
scroggo@google.com9a412522012-09-07 15:21:18 +0000232 gLogger.logProgress(result);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000233
borenet@google.com2d2b9a02012-09-20 18:54:04 +0000234 benchmark.run(&picture);
borenet@google.com66bcbd12012-09-17 18:26:06 +0000235 return true;
keyar@chromium.org0665f252012-07-10 18:30:18 +0000236}
237
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000238#define PRINT_USAGE_AND_EXIT \
239 do { \
240 usage(argv0); \
241 exit(-1); \
242 } while (0)
243
keyar@chromium.org163b5672012-08-01 17:53:29 +0000244static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs,
scroggo@google.com5239c322012-09-11 19:15:32 +0000245 sk_tools::PictureBenchmark* benchmark) {
reed@google.com006db0f2012-06-27 19:33:29 +0000246 const char* argv0 = argv[0];
247 char* const* stop = argv + argc;
248
keyar@chromium.org163b5672012-08-01 17:53:29 +0000249 int repeats = DEFAULT_REPEATS;
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000250 sk_tools::PictureRenderer::SkDeviceTypes deviceType =
251 sk_tools::PictureRenderer::kBitmap_DeviceType;
keyar@chromium.org163b5672012-08-01 17:53:29 +0000252
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000253 SkAutoTUnref<sk_tools::PictureRenderer> renderer(NULL);
scroggo@google.com5239c322012-09-11 19:15:32 +0000254
scroggo@google.com9a412522012-09-07 15:21:18 +0000255 // Create a string to show our current settings.
256 // TODO: Make it prettier. Currently it just repeats the command line.
257 SkString commandLine("bench_pictures:");
258 for (int i = 1; i < argc; i++) {
259 commandLine.appendf(" %s", *(argv+i));
260 }
261 commandLine.append("\n");
262
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000263 bool usePipe = false;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000264 int numThreads = 1;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000265 bool useTiles = false;
266 const char* widthString = NULL;
267 const char* heightString = NULL;
junov@chromium.org7b537062012-11-06 18:58:43 +0000268 int gridWidth = 0;
269 int gridHeight = 0;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000270 bool isPowerOf2Mode = false;
271 const char* mode = NULL;
junov@chromium.org7b537062012-11-06 18:58:43 +0000272 bool gridSupported = false;
skia.committer@gmail.com1aa90cf2012-11-06 13:18:25 +0000273 sk_tools::PictureRenderer::BBoxHierarchyType bbhType =
junov@chromium.org9313ca42012-11-02 18:11:49 +0000274 sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
caryclark@google.coma3622372012-11-06 21:26:13 +0000275 sk_tools::PictureRenderer::DrawFilterFlags drawFilters[SkDrawFilter::kTypeCount];
276 sk_bzero(drawFilters, sizeof(drawFilters));
reed@google.com006db0f2012-06-27 19:33:29 +0000277 for (++argv; argv < stop; ++argv) {
278 if (0 == strcmp(*argv, "--repeat")) {
279 ++argv;
280 if (argv < stop) {
keyar@chromium.org163b5672012-08-01 17:53:29 +0000281 repeats = atoi(*argv);
282 if (repeats < 1) {
scroggo@google.com9a412522012-09-07 15:21:18 +0000283 gLogger.logError("--repeat must be given a value > 0\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000284 PRINT_USAGE_AND_EXIT;
reed@google.com006db0f2012-06-27 19:33:29 +0000285 }
286 } else {
scroggo@google.com9a412522012-09-07 15:21:18 +0000287 gLogger.logError("Missing arg for --repeat\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000288 PRINT_USAGE_AND_EXIT;
reed@google.com006db0f2012-06-27 19:33:29 +0000289 }
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000290 } else if (0 == strcmp(*argv, "--pipe")) {
291 usePipe = true;
scroggo@google.com9a412522012-09-07 15:21:18 +0000292 } else if (0 == strcmp(*argv, "--logFile")) {
293 argv++;
294 if (argv < stop) {
295 if (!gLogger.SetLogFile(*argv)) {
296 SkString str;
297 str.printf("Could not open %s for writing.", *argv);
298 gLogger.logError(str);
299 usage(argv0);
borenet@google.coma49bffd2012-09-13 18:54:48 +0000300 // TODO(borenet): We're disabling this for now, due to
301 // write-protected Android devices. The very short-term
302 // solution is to ignore the fact that we have no log file.
303 //exit(-1);
scroggo@google.com9a412522012-09-07 15:21:18 +0000304 }
305 } else {
306 gLogger.logError("Missing arg for --logFile\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000307 PRINT_USAGE_AND_EXIT;
scroggo@google.com9a412522012-09-07 15:21:18 +0000308 }
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000309 } else if (0 == strcmp(*argv, "--multi")) {
310 ++argv;
311 if (argv >= stop) {
312 gLogger.logError("Missing arg for --multi\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000313 PRINT_USAGE_AND_EXIT;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000314 }
315 numThreads = atoi(*argv);
316 if (numThreads < 2) {
317 gLogger.logError("Number of threads must be at least 2.\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000318 PRINT_USAGE_AND_EXIT;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000319 }
junov@chromium.org9313ca42012-11-02 18:11:49 +0000320 } else if (0 == strcmp(*argv, "--bbh")) {
321 ++argv;
322 if (argv >= stop) {
323 gLogger.logError("Missing value for --bbh\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000324 PRINT_USAGE_AND_EXIT;
junov@chromium.org9313ca42012-11-02 18:11:49 +0000325 }
326 if (0 == strcmp(*argv, "none")) {
327 bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
328 } else if (0 == strcmp(*argv, "rtree")) {
329 bbhType = sk_tools::PictureRenderer::kRTree_BBoxHierarchyType;
junov@chromium.org7b537062012-11-06 18:58:43 +0000330 } else if (0 == strcmp(*argv, "grid")) {
331 bbhType = sk_tools::PictureRenderer::kTileGrid_BBoxHierarchyType;
332 ++argv;
333 if (argv >= stop) {
334 gLogger.logError("Missing width for --bbh grid\n");
335 PRINT_USAGE_AND_EXIT;
336 }
337 gridWidth = atoi(*argv);
338 ++argv;
339 if (argv >= stop) {
340 gLogger.logError("Missing height for --bbh grid\n");
341 PRINT_USAGE_AND_EXIT;
342 }
343 gridHeight = atoi(*argv);
junov@chromium.org9313ca42012-11-02 18:11:49 +0000344 } else {
345 SkString err;
346 err.printf("%s is not a valid value for --bbhType\n", *argv);
347 gLogger.logError(err);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000348 PRINT_USAGE_AND_EXIT;
junov@chromium.org9313ca42012-11-02 18:11:49 +0000349 }
350
keyar@chromium.org795cd472012-08-02 18:57:53 +0000351 } else if (0 == strcmp(*argv, "--mode")) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000352 if (renderer.get() != NULL) {
353 SkDebugf("Cannot combine modes.\n");
354 PRINT_USAGE_AND_EXIT;
355 }
keyar@chromium.org795cd472012-08-02 18:57:53 +0000356
reed@google.com006db0f2012-06-27 19:33:29 +0000357 ++argv;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000358 if (argv >= stop) {
scroggo@google.com9a412522012-09-07 15:21:18 +0000359 gLogger.logError("Missing mode for --mode\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000360 PRINT_USAGE_AND_EXIT;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000361 }
362
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000363 if (0 == strcmp(*argv, "record")) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000364 renderer.reset(SkNEW(sk_tools::RecordPictureRenderer));
junov@chromium.org7b537062012-11-06 18:58:43 +0000365 gridSupported = true;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000366 } else if (0 == strcmp(*argv, "simple")) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000367 renderer.reset(SkNEW(sk_tools::SimplePictureRenderer));
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000368 } else if ((0 == strcmp(*argv, "tile")) || (0 == strcmp(*argv, "pow2tile"))) {
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000369 useTiles = true;
370 mode = *argv;
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000371
372 if (0 == strcmp(*argv, "pow2tile")) {
373 isPowerOf2Mode = true;
junov@chromium.org7b537062012-11-06 18:58:43 +0000374 } else {
375 gridSupported = true;
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000376 }
377
keyar@chromium.org795cd472012-08-02 18:57:53 +0000378 ++argv;
379 if (argv >= stop) {
scroggo@google.com9a412522012-09-07 15:21:18 +0000380 SkString err;
381 err.printf("Missing width for --mode %s\n", mode);
382 gLogger.logError(err);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000383 PRINT_USAGE_AND_EXIT;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000384 }
385
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000386 widthString = *argv;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000387 ++argv;
388 if (argv >= stop) {
scroggo@google.com9a412522012-09-07 15:21:18 +0000389 gLogger.logError("Missing height for --mode tile\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000390 PRINT_USAGE_AND_EXIT;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000391 }
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000392 heightString = *argv;
scroggo@google.com9a412522012-09-07 15:21:18 +0000393 } else if (0 == strcmp(*argv, "playbackCreation")) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000394 renderer.reset(SkNEW(sk_tools::PlaybackCreationRenderer));
junov@chromium.org7b537062012-11-06 18:58:43 +0000395 gridSupported = true;
reed@google.com006db0f2012-06-27 19:33:29 +0000396 } else {
scroggo@google.com9a412522012-09-07 15:21:18 +0000397 SkString err;
398 err.printf("%s is not a valid mode for --mode\n", *argv);
399 gLogger.logError(err);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000400 PRINT_USAGE_AND_EXIT;
reed@google.com006db0f2012-06-27 19:33:29 +0000401 }
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000402 } else if (0 == strcmp(*argv, "--device")) {
403 ++argv;
404 if (argv >= stop) {
borenet@google.coma49bffd2012-09-13 18:54:48 +0000405 gLogger.logError("Missing mode for --device\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000406 PRINT_USAGE_AND_EXIT;
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000407 }
408
409 if (0 == strcmp(*argv, "bitmap")) {
410 deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType;
411 }
412#if SK_SUPPORT_GPU
413 else if (0 == strcmp(*argv, "gpu")) {
414 deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
415 }
416#endif
417 else {
scroggo@google.com9a412522012-09-07 15:21:18 +0000418 SkString err;
419 err.printf("%s is not a valid mode for --device\n", *argv);
420 gLogger.logError(err);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000421 PRINT_USAGE_AND_EXIT;
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000422 }
scroggo@google.com5239c322012-09-11 19:15:32 +0000423 } else if (0 == strcmp(*argv, "--timers")) {
424 ++argv;
425 if (argv < stop) {
426 bool timerWall = false;
427 bool truncatedTimerWall = false;
428 bool timerCpu = false;
429 bool truncatedTimerCpu = false;
430 bool timerGpu = false;
431 for (char* t = *argv; *t; ++t) {
432 switch (*t) {
433 case 'w':
434 timerWall = true;
435 break;
436 case 'c':
437 timerCpu = true;
438 break;
439 case 'W':
440 truncatedTimerWall = true;
441 break;
442 case 'C':
443 truncatedTimerCpu = true;
444 break;
445 case 'g':
446 timerGpu = true;
447 break;
448 default: {
449 break;
450 }
451 }
452 }
453 benchmark->setTimersToShow(timerWall, truncatedTimerWall, timerCpu,
454 truncatedTimerCpu, timerGpu);
455 } else {
456 gLogger.logError("Missing arg for --timers\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000457 PRINT_USAGE_AND_EXIT;
scroggo@google.com5239c322012-09-11 19:15:32 +0000458 }
459 } else if (0 == strcmp(*argv, "--min")) {
460 benchmark->setPrintMin(true);
461 } else if (0 == strcmp(*argv, "--logPerIter")) {
462 ++argv;
463 if (argv < stop) {
464 bool log = atoi(*argv) != 0;
465 benchmark->setLogPerIter(log);
466 } else {
467 gLogger.logError("Missing arg for --logPerIter\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000468 PRINT_USAGE_AND_EXIT;
scroggo@google.com5239c322012-09-11 19:15:32 +0000469 }
caryclark@google.coma3622372012-11-06 21:26:13 +0000470 } else if (0 == strcmp(*argv, "--filter")) {
471 ++argv;
472 if (argv < stop) {
473 const char* colon = strchr(*argv, ':');
474 if (colon) {
475 int type = -1;
476 size_t typeLen = colon - *argv;
477 for (size_t tIndex = 0; tIndex < kFilterTypesCount; ++tIndex) {
478 if (typeLen == strlen(gFilterTypes[tIndex])
479 && !strncmp(*argv, gFilterTypes[tIndex], typeLen)) {
480 type = tIndex;
481 break;
482 }
483 }
484 if (type < 0) {
485 SkString err;
486 err.printf("Unknown type for --filter %s\n", *argv);
487 gLogger.logError(err);
488 PRINT_USAGE_AND_EXIT;
489 }
490 int flag = -1;
491 size_t flagLen = strlen(*argv) - typeLen - 1;
492 for (size_t fIndex = 0; fIndex < kFilterFlagsCount; ++fIndex) {
493 if (flagLen == strlen(gFilterFlags[fIndex])
494 && !strncmp(colon + 1, gFilterFlags[fIndex], flagLen)) {
495 flag = 1 << fIndex;
496 break;
497 }
498 }
499 if (flag < 0) {
500 SkString err;
501 err.printf("Unknown flag for --filter %s\n", *argv);
502 gLogger.logError(err);
503 PRINT_USAGE_AND_EXIT;
504 }
505 for (int index = 0; index < SkDrawFilter::kTypeCount; ++index) {
506 if (type != SkDrawFilter::kTypeCount && index != type) {
507 continue;
508 }
509 drawFilters[index] = (sk_tools::PictureRenderer::DrawFilterFlags)
510 (drawFilters[index] | flag);
511 }
512 } else {
513 SkString err;
514 err.printf("Unknown arg for --filter %s : missing colon\n", *argv);
515 gLogger.logError(err);
516 PRINT_USAGE_AND_EXIT;
517 }
518 } else {
519 gLogger.logError("Missing arg for --filter\n");
520 PRINT_USAGE_AND_EXIT;
521 }
reed@google.com006db0f2012-06-27 19:33:29 +0000522 } else if (0 == strcmp(*argv, "--help") || 0 == strcmp(*argv, "-h")) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000523 PRINT_USAGE_AND_EXIT;
reed@google.com006db0f2012-06-27 19:33:29 +0000524 } else {
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000525 inputs->push_back(SkString(*argv));
reed@google.com006db0f2012-06-27 19:33:29 +0000526 }
527 }
528
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000529 if (numThreads > 1 && !useTiles) {
530 gLogger.logError("Multithreaded drawing requires tiled rendering.\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000531 PRINT_USAGE_AND_EXIT;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000532 }
533
junov@chromium.org9313ca42012-11-02 18:11:49 +0000534 if (usePipe && sk_tools::PictureRenderer::kNone_BBoxHierarchyType != bbhType) {
535 gLogger.logError("--pipe and --bbh cannot be used together\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000536 PRINT_USAGE_AND_EXIT;
junov@chromium.org9313ca42012-11-02 18:11:49 +0000537 }
538
junov@chromium.org7b537062012-11-06 18:58:43 +0000539 if (sk_tools::PictureRenderer::kTileGrid_BBoxHierarchyType == bbhType &&
540 !gridSupported) {
541 gLogger.logError("'--bbh grid' is not compatible with specified --mode.\n");
542 PRINT_USAGE_AND_EXIT;
543 }
544
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000545 if (useTiles) {
scroggo@google.com5239c322012-09-11 19:15:32 +0000546 SkASSERT(NULL == renderer);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000547 sk_tools::TiledPictureRenderer* tiledRenderer;
548 if (numThreads > 1) {
549 tiledRenderer = SkNEW_ARGS(sk_tools::MultiCorePictureRenderer, (numThreads));
550 } else {
551 tiledRenderer = SkNEW(sk_tools::TiledPictureRenderer);
552 }
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000553 if (isPowerOf2Mode) {
554 int minWidth = atoi(widthString);
555 if (!SkIsPow2(minWidth) || minWidth < 0) {
scroggo@google.com5239c322012-09-11 19:15:32 +0000556 tiledRenderer->unref();
scroggo@google.com9a412522012-09-07 15:21:18 +0000557 SkString err;
scroggo@google.com5239c322012-09-11 19:15:32 +0000558 err.printf("-mode %s must be given a width"
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000559 " value that is a power of two\n", mode);
scroggo@google.com9a412522012-09-07 15:21:18 +0000560 gLogger.logError(err);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000561 PRINT_USAGE_AND_EXIT;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000562 }
scroggo@google.com5239c322012-09-11 19:15:32 +0000563 tiledRenderer->setTileMinPowerOf2Width(minWidth);
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000564 } else if (sk_tools::is_percentage(widthString)) {
scroggo@google.com5239c322012-09-11 19:15:32 +0000565 tiledRenderer->setTileWidthPercentage(atof(widthString));
566 if (!(tiledRenderer->getTileWidthPercentage() > 0)) {
567 tiledRenderer->unref();
scroggo@google.com9a412522012-09-07 15:21:18 +0000568 gLogger.logError("--mode tile must be given a width percentage > 0\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000569 PRINT_USAGE_AND_EXIT;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000570 }
571 } else {
scroggo@google.com5239c322012-09-11 19:15:32 +0000572 tiledRenderer->setTileWidth(atoi(widthString));
573 if (!(tiledRenderer->getTileWidth() > 0)) {
574 tiledRenderer->unref();
scroggo@google.com9a412522012-09-07 15:21:18 +0000575 gLogger.logError("--mode tile must be given a width > 0\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000576 PRINT_USAGE_AND_EXIT;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000577 }
578 }
579
580 if (sk_tools::is_percentage(heightString)) {
scroggo@google.com5239c322012-09-11 19:15:32 +0000581 tiledRenderer->setTileHeightPercentage(atof(heightString));
582 if (!(tiledRenderer->getTileHeightPercentage() > 0)) {
583 tiledRenderer->unref();
scroggo@google.com9a412522012-09-07 15:21:18 +0000584 gLogger.logError("--mode tile must be given a height percentage > 0\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000585 PRINT_USAGE_AND_EXIT;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000586 }
587 } else {
scroggo@google.com5239c322012-09-11 19:15:32 +0000588 tiledRenderer->setTileHeight(atoi(heightString));
589 if (!(tiledRenderer->getTileHeight() > 0)) {
590 tiledRenderer->unref();
scroggo@google.com9a412522012-09-07 15:21:18 +0000591 gLogger.logError("--mode tile must be given a height > 0\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000592 PRINT_USAGE_AND_EXIT;
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000593 }
594 }
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000595 if (numThreads > 1) {
596#if SK_SUPPORT_GPU
597 if (sk_tools::PictureRenderer::kGPU_DeviceType == deviceType) {
598 tiledRenderer->unref();
599 gLogger.logError("GPU not compatible with multithreaded tiling.\n");
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000600 PRINT_USAGE_AND_EXIT;
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000601 }
602#endif
scroggo@google.combcdf2ec2012-09-20 14:42:33 +0000603 }
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000604 renderer.reset(tiledRenderer);
605 if (usePipe) {
606 SkDebugf("Pipe rendering is currently not compatible with tiling.\n"
607 "Turning off pipe.\n");
608 }
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000609 } else if (usePipe) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000610 if (renderer.get() != NULL) {
611 SkDebugf("Pipe is incompatible with other modes.\n");
612 PRINT_USAGE_AND_EXIT;
613 }
614 renderer.reset(SkNEW(sk_tools::PipePictureRenderer));
scroggo@google.com58b4ead2012-08-31 16:15:22 +0000615 }
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000616 if (inputs->count() < 1) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000617 PRINT_USAGE_AND_EXIT;
reed@google.com006db0f2012-06-27 19:33:29 +0000618 }
keyar@chromium.org163b5672012-08-01 17:53:29 +0000619
scroggo@google.com5239c322012-09-11 19:15:32 +0000620 if (NULL == renderer) {
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000621 renderer.reset(SkNEW(sk_tools::SimplePictureRenderer));
keyar@chromium.org163b5672012-08-01 17:53:29 +0000622 }
junov@chromium.org9313ca42012-11-02 18:11:49 +0000623
624 renderer->setBBoxHierarchyType(bbhType);
caryclark@google.coma3622372012-11-06 21:26:13 +0000625 renderer->setDrawFilters(drawFilters, filtersName(drawFilters));
junov@chromium.org7b537062012-11-06 18:58:43 +0000626 renderer->setGridSize(gridWidth, gridHeight);
scroggo@google.coma62da2f2012-11-02 21:28:12 +0000627 benchmark->setRenderer(renderer);
keyar@chromium.org163b5672012-08-01 17:53:29 +0000628 benchmark->setRepeats(repeats);
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000629 benchmark->setDeviceType(deviceType);
scroggo@google.com9a412522012-09-07 15:21:18 +0000630 benchmark->setLogger(&gLogger);
631 // Report current settings:
632 gLogger.logProgress(commandLine);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000633}
reed@google.com006db0f2012-06-27 19:33:29 +0000634
borenet@google.com66bcbd12012-09-17 18:26:06 +0000635static int process_input(const SkString& input,
636 sk_tools::PictureBenchmark& benchmark) {
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000637 SkOSFile::Iter iter(input.c_str(), "skp");
638 SkString inputFilename;
borenet@google.com66bcbd12012-09-17 18:26:06 +0000639 int failures = 0;
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000640 if (iter.next(&inputFilename)) {
641 do {
642 SkString inputPath;
keyar@chromium.org163b5672012-08-01 17:53:29 +0000643 sk_tools::make_filepath(&inputPath, input, inputFilename);
borenet@google.com57837bf2012-09-19 17:28:29 +0000644 if (!run_single_benchmark(inputPath, benchmark)) {
borenet@google.com66bcbd12012-09-17 18:26:06 +0000645 ++failures;
borenet@google.com57837bf2012-09-19 17:28:29 +0000646 }
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000647 } while(iter.next(&inputFilename));
borenet@google.com57837bf2012-09-19 17:28:29 +0000648 } else if (SkStrEndsWith(input.c_str(), ".skp")) {
649 if (!run_single_benchmark(input, benchmark)) {
borenet@google.com66bcbd12012-09-17 18:26:06 +0000650 ++failures;
borenet@google.com57837bf2012-09-19 17:28:29 +0000651 }
652 } else {
653 SkString warning;
654 warning.printf("Warning: skipping %s\n", input.c_str());
655 gLogger.logError(warning);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000656 }
borenet@google.com66bcbd12012-09-17 18:26:06 +0000657 return failures;
reed@google.com006db0f2012-06-27 19:33:29 +0000658}
659
caryclark@google.com5987f582012-10-02 18:33:14 +0000660int tool_main(int argc, char** argv);
661int tool_main(int argc, char** argv) {
scroggo@google.com5239c322012-09-11 19:15:32 +0000662#ifdef SK_ENABLE_INST_COUNT
663 gPrintInstCount = true;
664#endif
scroggo@google.com0a36f432012-09-10 20:29:13 +0000665 SkAutoGraphics ag;
reed@google.com006db0f2012-06-27 19:33:29 +0000666
scroggo@google.com5239c322012-09-11 19:15:32 +0000667 SkTArray<SkString> inputs;
668 sk_tools::PictureBenchmark benchmark;
669
670 parse_commandline(argc, argv, &inputs, &benchmark);
reed@google.com006db0f2012-06-27 19:33:29 +0000671
borenet@google.com66bcbd12012-09-17 18:26:06 +0000672 int failures = 0;
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000673 for (int i = 0; i < inputs.count(); ++i) {
borenet@google.com66bcbd12012-09-17 18:26:06 +0000674 failures += process_input(inputs[i], benchmark);
675 }
676
677 if (failures != 0) {
678 SkString err;
679 err.printf("Failed to run %i benchmarks.\n", failures);
680 gLogger.logError(err);
681 return 1;
reed@google.com006db0f2012-06-27 19:33:29 +0000682 }
caryclark@google.com868e1f62012-10-02 20:00:03 +0000683 return 0;
reed@google.com006db0f2012-06-27 19:33:29 +0000684}
caryclark@google.com5987f582012-10-02 18:33:14 +0000685
686#if !defined SK_BUILD_FOR_IOS
687int main(int argc, char * const argv[]) {
688 return tool_main(argc, (char**) argv);
689}
690#endif