bench_pictures_main.cpp revision f4959ab11827bef99e8985031feb457cae1f987a
1/* 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" 9#include "PictureBenchmark.h" 10#include "SkCanvas.h" 11#include "SkMath.h" 12#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; 19 20static void usage(const char* argv0) { 21 SkDebugf("SkPicture benchmarking tool\n"); 22 SkDebugf("\n" 23"Usage: \n" 24" %s <inputDir>...\n" 25" [--repeat] \n" 26" [--mode pipe | pow2tile minWidth height[%] | record | simple\n" 27" | tile width[%] height[%] | unflatten]\n" 28" [--device bitmap" 29#if SK_SUPPORT_GPU 30" | gpu" 31#endif 32"]" 33, argv0); 34 SkDebugf("\n\n"); 35 SkDebugf( 36" inputDir: A list of directories and files to use as input. Files are\n" 37" expected to have the .skp extension.\n\n"); 38 SkDebugf( 39" --mode pipe | pow2tile minWidht height[%] | record | simple\n" 40" | tile width[%] height[%] | unflatten: Run in the corresponding mode.\n" 41" Default is simple.\n"); 42 SkDebugf( 43" pipe, Benchmark SkGPipe rendering.\n"); 44 SkDebugf( 45" 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 SkDebugf( 55" record, Benchmark picture to picture recording.\n"); 56 SkDebugf( 57" simple, Benchmark a simple rendering.\n"); 58 SkDebugf( 59" tile width[%] height[%], Benchmark simple rendering using\n" 60" tiles with the given dimensions.\n"); 61 SkDebugf( 62" unflatten, Benchmark picture unflattening.\n"); 63 SkDebugf("\n"); 64 SkDebugf( 65" --device bitmap" 66#if SK_SUPPORT_GPU 67" | gpu" 68#endif 69": Use the corresponding device. Default is bitmap.\n"); 70 SkDebugf( 71" bitmap, Render to a bitmap.\n"); 72#if SK_SUPPORT_GPU 73 SkDebugf( 74" gpu, Render to the GPU.\n"); 75#endif 76 SkDebugf("\n"); 77 SkDebugf( 78" --repeat: " 79"Set the number of times to repeat each test." 80" Default is %i.\n", DEFAULT_REPEATS); 81} 82 83static void run_single_benchmark(const SkString& inputPath, 84 sk_tools::PictureBenchmark& benchmark) { 85 SkFILEStream inputStream; 86 87 inputStream.setPath(inputPath.c_str()); 88 if (!inputStream.isValid()) { 89 SkDebugf("Could not open file %s\n", inputPath.c_str()); 90 return; 91 } 92 93 SkPicture picture(&inputStream); 94 95 SkString filename; 96 sk_tools::get_basename(&filename, inputPath); 97 98 SkString result; 99 result.printf("running bench [%i %i] %s ", picture.width(), picture.height(), 100 filename.c_str()); 101 sk_tools::print_msg(result.c_str()); 102 103 benchmark.run(&picture); 104} 105 106static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs, 107 sk_tools::PictureBenchmark*& benchmark) { 108 const char* argv0 = argv[0]; 109 char* const* stop = argv + argc; 110 111 int repeats = DEFAULT_REPEATS; 112 sk_tools::PictureRenderer::SkDeviceTypes deviceType = 113 sk_tools::PictureRenderer::kBitmap_DeviceType; 114 115 for (++argv; argv < stop; ++argv) { 116 if (0 == strcmp(*argv, "--repeat")) { 117 ++argv; 118 if (argv < stop) { 119 repeats = atoi(*argv); 120 if (repeats < 1) { 121 SkDELETE(benchmark); 122 SkDebugf("--repeat must be given a value > 0\n"); 123 exit(-1); 124 } 125 } else { 126 SkDELETE(benchmark); 127 SkDebugf("Missing arg for --repeat\n"); 128 usage(argv0); 129 exit(-1); 130 } 131 } else if (0 == strcmp(*argv, "--mode")) { 132 SkDELETE(benchmark); 133 134 ++argv; 135 if (argv >= stop) { 136 SkDebugf("Missing mode for --mode\n"); 137 usage(argv0); 138 exit(-1); 139 } 140 141 if (0 == strcmp(*argv, "pipe")) { 142 benchmark = SkNEW(sk_tools::PipePictureBenchmark); 143 } else if (0 == strcmp(*argv, "record")) { 144 benchmark = SkNEW(sk_tools::RecordPictureBenchmark); 145 } else if (0 == strcmp(*argv, "simple")) { 146 benchmark = SkNEW(sk_tools::SimplePictureBenchmark); 147 } else if ((0 == strcmp(*argv, "tile")) || (0 == strcmp(*argv, "pow2tile"))) { 148 char* mode = *argv; 149 bool isPowerOf2Mode = false; 150 151 if (0 == strcmp(*argv, "pow2tile")) { 152 isPowerOf2Mode = true; 153 } 154 155 sk_tools::TiledPictureBenchmark* tileBenchmark = 156 SkNEW(sk_tools::TiledPictureBenchmark); 157 ++argv; 158 if (argv >= stop) { 159 SkDELETE(tileBenchmark); 160 SkDebugf("Missing width for --mode %s\n", mode); 161 usage(argv0); 162 exit(-1); 163 } 164 165 if (isPowerOf2Mode) { 166 int minWidth = atoi(*argv); 167 168 if (!SkIsPow2(minWidth) || minWidth <= 0) { 169 SkDELETE(tileBenchmark); 170 SkDebugf("--mode %s must be given a width" 171 " value that is a power of two\n", mode); 172 exit(-1); 173 } 174 175 tileBenchmark->setTileMinPowerOf2Width(minWidth); 176 } else if (sk_tools::is_percentage(*argv)) { 177 tileBenchmark->setTileWidthPercentage(atof(*argv)); 178 if (!(tileBenchmark->getTileWidthPercentage() > 0)) { 179 SkDELETE(tileBenchmark); 180 SkDebugf("--mode %s must be given a width percentage > 0\n", mode); 181 exit(-1); 182 } 183 } else { 184 tileBenchmark->setTileWidth(atoi(*argv)); 185 if (!(tileBenchmark->getTileWidth() > 0)) { 186 SkDELETE(tileBenchmark); 187 SkDebugf("--mode %s must be given a width > 0\n", mode); 188 exit(-1); 189 } 190 } 191 192 ++argv; 193 if (argv >= stop) { 194 SkDELETE(tileBenchmark); 195 SkDebugf("Missing height for --mode %s\n", mode); 196 usage(argv0); 197 exit(-1); 198 } 199 200 if (sk_tools::is_percentage(*argv)) { 201 tileBenchmark->setTileHeightPercentage(atof(*argv)); 202 if (!(tileBenchmark->getTileHeightPercentage() > 0)) { 203 SkDELETE(tileBenchmark); 204 SkDebugf("--mode %s must be given a height percentage > 0\n", mode); 205 exit(-1); 206 } 207 } else { 208 tileBenchmark->setTileHeight(atoi(*argv)); 209 if (!(tileBenchmark->getTileHeight() > 0)) { 210 SkDELETE(tileBenchmark); 211 SkDebugf("--mode %s must be given a height > 0\n", mode); 212 exit(-1); 213 } 214 } 215 216 benchmark = tileBenchmark; 217 } else if (0 == strcmp(*argv, "unflatten")) { 218 benchmark = SkNEW(sk_tools::UnflattenPictureBenchmark); 219 } else { 220 SkDebugf("%s is not a valid mode for --mode\n", *argv); 221 usage(argv0); 222 exit(-1); 223 } 224 } else if (0 == strcmp(*argv, "--device")) { 225 ++argv; 226 if (argv >= stop) { 227 SkDebugf("Missing mode for --deivce\n"); 228 usage(argv0); 229 exit(-1); 230 } 231 232 if (0 == strcmp(*argv, "bitmap")) { 233 deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType; 234 } 235#if SK_SUPPORT_GPU 236 else if (0 == strcmp(*argv, "gpu")) { 237 deviceType = sk_tools::PictureRenderer::kGPU_DeviceType; 238 } 239#endif 240 else { 241 SkDebugf("%s is not a valid mode for --device\n", *argv); 242 usage(argv0); 243 exit(-1); 244 } 245 246 } else if (0 == strcmp(*argv, "--help") || 0 == strcmp(*argv, "-h")) { 247 SkDELETE(benchmark); 248 usage(argv0); 249 exit(0); 250 } else { 251 inputs->push_back(SkString(*argv)); 252 } 253 } 254 255 if (inputs->count() < 1) { 256 SkDELETE(benchmark); 257 usage(argv0); 258 exit(-1); 259 } 260 261 if (NULL == benchmark) { 262 benchmark = SkNEW(sk_tools::SimplePictureBenchmark); 263 } 264 265 benchmark->setRepeats(repeats); 266 benchmark->setDeviceType(deviceType); 267} 268 269static void process_input(const SkString& input, sk_tools::PictureBenchmark& benchmark) { 270 SkOSFile::Iter iter(input.c_str(), "skp"); 271 SkString inputFilename; 272 273 if (iter.next(&inputFilename)) { 274 do { 275 SkString inputPath; 276 sk_tools::make_filepath(&inputPath, input, inputFilename); 277 run_single_benchmark(inputPath, benchmark); 278 } while(iter.next(&inputFilename)); 279 } else { 280 run_single_benchmark(input, benchmark); 281 } 282} 283 284int main(int argc, char* const argv[]) { 285 SkTArray<SkString> inputs; 286 sk_tools::PictureBenchmark* benchmark = NULL; 287 288 parse_commandline(argc, argv, &inputs, benchmark); 289 290 for (int i = 0; i < inputs.count(); ++i) { 291 process_input(inputs[i], *benchmark); 292 } 293 294 SkDELETE(benchmark); 295} 296