render_pictures_main.cpp revision 163c84ba5026907fea7b4f4bdcf8b16c13103adc
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 "SkBitmap.h" 9#include "SkCanvas.h" 10#include "SkDevice.h" 11#include "SkGraphics.h" 12#include "SkMath.h" 13#include "SkOSFile.h" 14#include "SkPicture.h" 15#include "SkStream.h" 16#include "SkString.h" 17#include "SkTArray.h" 18#include "PictureRenderer.h" 19#include "picture_utils.h" 20 21static void usage(const char* argv0) { 22 SkDebugf("SkPicture rendering tool\n"); 23 SkDebugf("\n" 24"Usage: \n" 25" %s <input>... <outputDir> \n" 26" [--mode pipe | pow2tile minWidth height[%] | simple\n" 27" | tile width[%] height[%]]\n" 28" [--device bitmap" 29#if SK_SUPPORT_GPU 30" | gpu" 31#endif 32"]" 33, argv0); 34 SkDebugf("\n\n"); 35 SkDebugf( 36" input: 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" outputDir: directory to write the rendered images.\n\n"); 40 SkDebugf( 41" --mode pipe | pow2tile minWidth height[%] | simple\n" 42" | tile width[%] height[%]: Run in the corresponding mode.\n" 43" Default is simple.\n"); 44 SkDebugf( 45" pipe, Render using a SkGPipe.\n"); 46 SkDebugf( 47" pow2tile minWidth height[%], Creates tiles with widths\n" 48" that are all a power of two\n" 49" such that they minimize the\n" 50" amount of wasted tile space.\n" 51" minWidth is the minimum width\n" 52" of these tiles and must be a\n" 53" power of two. A simple render\n" 54" is done with these tiles.\n"); 55 SkDebugf( 56" simple, Render using the default rendering method.\n"); 57 SkDebugf( 58" tile width[%] height[%], Do a simple render using tiles\n" 59" with the given dimensions.\n"); 60 SkDebugf("\n"); 61 SkDebugf( 62" --device bitmap" 63#if SK_SUPPORT_GPU 64" | gpu" 65#endif 66": Use the corresponding device. Default is bitmap.\n"); 67 SkDebugf( 68" bitmap, Render to a bitmap.\n"); 69#if SK_SUPPORT_GPU 70 SkDebugf( 71" gpu, Render to the GPU.\n"); 72#endif 73} 74 75static void make_output_filepath(SkString* path, const SkString& dir, 76 const SkString& name) { 77 sk_tools::make_filepath(path, dir, name); 78 path->remove(path->size() - 3, 3); 79 path->append("png"); 80} 81 82static void write_output(const SkString& outputDir, const SkString& inputFilename, 83 const sk_tools::PictureRenderer& renderer) { 84 SkString outputPath; 85 make_output_filepath(&outputPath, outputDir, inputFilename); 86 bool isWritten = renderer.write(outputPath); 87 if (!isWritten) { 88 SkDebugf("Could not write to file %s\n", outputPath.c_str()); 89 } 90} 91 92static void render_picture(const SkString& inputPath, const SkString& outputDir, 93 sk_tools::PictureRenderer& renderer) { 94 SkString inputFilename; 95 sk_tools::get_basename(&inputFilename, inputPath); 96 97 SkFILEStream inputStream; 98 inputStream.setPath(inputPath.c_str()); 99 if (!inputStream.isValid()) { 100 SkDebugf("Could not open file %s\n", inputPath.c_str()); 101 return; 102 } 103 104 SkPicture picture(&inputStream); 105 106 SkDebugf("drawing... [%i %i] %s\n", picture.width(), picture.height(), 107 inputPath.c_str()); 108 renderer.init(&picture); 109 110 renderer.render(true); 111 112 renderer.resetState(); 113 114 write_output(outputDir, inputFilename, renderer); 115 116 renderer.end(); 117} 118 119static void process_input(const SkString& input, const SkString& outputDir, 120 sk_tools::PictureRenderer& renderer) { 121 SkOSFile::Iter iter(input.c_str(), "skp"); 122 SkString inputFilename; 123 124 if (iter.next(&inputFilename)) { 125 do { 126 SkString inputPath; 127 sk_tools::make_filepath(&inputPath, input, inputFilename); 128 render_picture(inputPath, outputDir, renderer); 129 } while(iter.next(&inputFilename)); 130 } else { 131 SkString inputPath(input); 132 render_picture(inputPath, outputDir, renderer); 133 } 134} 135 136static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs, 137 sk_tools::PictureRenderer*& renderer){ 138 const char* argv0 = argv[0]; 139 char* const* stop = argv + argc; 140 141 sk_tools::PictureRenderer::SkDeviceTypes deviceType = 142 sk_tools::PictureRenderer::kBitmap_DeviceType; 143 144 for (++argv; argv < stop; ++argv) { 145 if (0 == strcmp(*argv, "--mode")) { 146 SkDELETE(renderer); 147 148 ++argv; 149 if (argv >= stop) { 150 SkDebugf("Missing mode for --mode\n"); 151 usage(argv0); 152 exit(-1); 153 } 154 155 if (0 == strcmp(*argv, "pipe")) { 156 renderer = SkNEW(sk_tools::PipePictureRenderer); 157 } else if (0 == strcmp(*argv, "simple")) { 158 renderer = SkNEW(sk_tools::SimplePictureRenderer); 159 } else if ((0 == strcmp(*argv, "tile")) || (0 == strcmp(*argv, "pow2tile"))) { 160 char* mode = *argv; 161 bool isPowerOf2Mode = false; 162 163 if (0 == strcmp(*argv, "pow2tile")) { 164 isPowerOf2Mode = true; 165 } 166 167 sk_tools::TiledPictureRenderer* tileRenderer = 168 SkNEW(sk_tools::TiledPictureRenderer); 169 ++argv; 170 if (argv >= stop) { 171 SkDELETE(tileRenderer); 172 SkDebugf("Missing width for --mode %s\n", mode); 173 usage(argv0); 174 exit(-1); 175 } 176 177 if (isPowerOf2Mode) { 178 int minWidth = atoi(*argv); 179 180 if (!SkIsPow2(minWidth) || minWidth <= 0) { 181 SkDELETE(tileRenderer); 182 SkDebugf("--mode %s must be given a width" 183 " value that is a power of two\n", mode); 184 exit(-1); 185 } 186 187 tileRenderer->setTileMinPowerOf2Width(minWidth); 188 } else if (sk_tools::is_percentage(*argv)) { 189 tileRenderer->setTileWidthPercentage(atof(*argv)); 190 if (!(tileRenderer->getTileWidthPercentage() > 0)) { 191 SkDELETE(tileRenderer); 192 SkDebugf("--mode %s must be given a width percentage > 0\n", mode); 193 exit(-1); 194 } 195 } else { 196 tileRenderer->setTileWidth(atoi(*argv)); 197 if (!(tileRenderer->getTileWidth() > 0)) { 198 SkDELETE(tileRenderer); 199 SkDebugf("--mode %s must be given a width > 0\n", mode); 200 exit(-1); 201 } 202 } 203 204 ++argv; 205 if (argv >= stop) { 206 SkDELETE(tileRenderer); 207 SkDebugf("Missing height for --mode %s\n", mode); 208 usage(argv0); 209 exit(-1); 210 } 211 212 if (sk_tools::is_percentage(*argv)) { 213 tileRenderer->setTileHeightPercentage(atof(*argv)); 214 if (!(tileRenderer->getTileHeightPercentage() > 0)) { 215 SkDELETE(tileRenderer); 216 SkDebugf( 217 "--mode %s must be given a height percentage > 0\n", mode); 218 exit(-1); 219 } 220 } else { 221 tileRenderer->setTileHeight(atoi(*argv)); 222 if (!(tileRenderer->getTileHeight() > 0)) { 223 SkDELETE(tileRenderer); 224 SkDebugf("--mode %s must be given a height > 0\n", mode); 225 exit(-1); 226 } 227 } 228 229 renderer = tileRenderer; 230 } else { 231 SkDebugf("%s is not a valid mode for --mode\n", *argv); 232 usage(argv0); 233 exit(-1); 234 } 235 } else if (0 == strcmp(*argv, "--device")) { 236 ++argv; 237 if (argv >= stop) { 238 SkDebugf("Missing mode for --deivce\n"); 239 usage(argv0); 240 exit(-1); 241 } 242 243 if (0 == strcmp(*argv, "bitmap")) { 244 deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType; 245 } 246#if SK_SUPPORT_GPU 247 else if (0 == strcmp(*argv, "gpu")) { 248 deviceType = sk_tools::PictureRenderer::kGPU_DeviceType; 249 } 250#endif 251 else { 252 SkDebugf("%s is not a valid mode for --device\n", *argv); 253 usage(argv0); 254 exit(-1); 255 } 256 257 } else if ((0 == strcmp(*argv, "-h")) || (0 == strcmp(*argv, "--help"))) { 258 SkDELETE(renderer); 259 usage(argv0); 260 exit(-1); 261 } else { 262 inputs->push_back(SkString(*argv)); 263 } 264 } 265 266 if (inputs->count() < 2) { 267 SkDELETE(renderer); 268 usage(argv0); 269 exit(-1); 270 } 271 272 if (NULL == renderer) { 273 renderer = SkNEW(sk_tools::SimplePictureRenderer); 274 } 275 276 renderer->setDeviceType(deviceType); 277} 278 279int main(int argc, char* const argv[]) { 280 SkGraphics::Init(); 281 SkTArray<SkString> inputs; 282 sk_tools::PictureRenderer* renderer = NULL; 283 284 parse_commandline(argc, argv, &inputs, renderer); 285 SkString outputDir = inputs[inputs.count() - 1]; 286 SkASSERT(renderer); 287 288 for (int i = 0; i < inputs.count() - 1; i ++) { 289 process_input(inputs[i], outputDir, *renderer); 290 } 291 292#if SK_SUPPORT_GPU 293#if GR_CACHE_STATS 294 if (renderer->isUsingGpuDevice()) { 295 GrContext* ctx = renderer->getGrContext(); 296 297 ctx->printCacheStats(); 298 } 299#endif 300#endif 301 302 SkDELETE(renderer); 303 SkGraphics::Term(); 304} 305