blob: ec0969659e40808f796e16ae4071e25b042e4ff6 [file] [log] [blame]
junov@chromium.org777442d2012-06-12 14:56:36 +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
junov@chromium.org777442d2012-06-12 14:56:36 +00008#include "SkBitmap.h"
9#include "SkCanvas.h"
keyar@chromium.org472b3792012-07-20 22:34:27 +000010#include "SkDevice.h"
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000011#include "SkMath.h"
junov@chromium.org777442d2012-06-12 14:56:36 +000012#include "SkOSFile.h"
13#include "SkPicture.h"
14#include "SkStream.h"
15#include "SkString.h"
senorblanco@chromium.org3cbbb542012-07-13 18:55:53 +000016#include "SkTArray.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000017#include "PictureRenderer.h"
twiz@google.coma31b8bb2012-06-22 18:24:56 +000018#include "picture_utils.h"
junov@chromium.org777442d2012-06-12 14:56:36 +000019
junov@chromium.org777442d2012-06-12 14:56:36 +000020static void usage(const char* argv0) {
21 SkDebugf("SkPicture rendering tool\n");
22 SkDebugf("\n"
23"Usage: \n"
keyar@chromium.org472b3792012-07-20 22:34:27 +000024" %s <input>... <outputDir> \n"
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000025" [--mode pipe | pow2tile minWidth height[%] | simple\n"
26" | tile width[%] height[%]]\n"
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000027" [--device bitmap"
28#if SK_SUPPORT_GPU
29" | gpu"
30#endif
31"]"
junov@chromium.org777442d2012-06-12 14:56:36 +000032, argv0);
keyar@chromium.org472b3792012-07-20 22:34:27 +000033 SkDebugf("\n\n");
junov@chromium.org777442d2012-06-12 14:56:36 +000034 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000035" input: A list of directories and files to use as input. Files are\n"
36" expected to have the .skp extension.\n\n");
junov@chromium.org777442d2012-06-12 14:56:36 +000037 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000038" outputDir: directory to write the rendered images.\n\n");
keyar@chromium.org472b3792012-07-20 22:34:27 +000039 SkDebugf(
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000040" --mode pipe | pow2tile minWidth height[%] | simple\n"
41" | tile width[%] height[%]: Run in the corresponding mode.\n"
42" Default is simple.\n");
keyar@chromium.org472b3792012-07-20 22:34:27 +000043 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000044" pipe, Render using a SkGPipe.\n");
45 SkDebugf(
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000046" pow2tile minWidth height[%], Creates tiles with widths\n"
47" that are all a power of two\n"
48" such that they minimize the\n"
49" amount of wasted tile space.\n"
50" minWidth is the minimum width\n"
51" of these tiles and must be a\n"
52" power of two. A simple render\n"
53" is done with these tiles.\n");
54 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000055" simple, Render using the default rendering method.\n");
56 SkDebugf(
57" tile width[%] height[%], Do a simple render using tiles\n"
58" with the given dimensions.\n");
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000059 SkDebugf("\n");
60 SkDebugf(
61" --device bitmap"
62#if SK_SUPPORT_GPU
63" | gpu"
64#endif
65": Use the corresponding device. Default is bitmap.\n");
66 SkDebugf(
67" bitmap, Render to a bitmap.\n");
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000068#if SK_SUPPORT_GPU
keyar@chromium.orga40c20d2012-08-20 15:04:12 +000069 SkDebugf(
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000070" gpu, Render to the GPU.\n");
71#endif
junov@chromium.org777442d2012-06-12 14:56:36 +000072}
73
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +000074static void make_output_filepath(SkString* path, const SkString& dir,
junov@chromium.org777442d2012-06-12 14:56:36 +000075 const SkString& name) {
twiz@google.coma31b8bb2012-06-22 18:24:56 +000076 sk_tools::make_filepath(path, dir, name);
junov@chromium.org777442d2012-06-12 14:56:36 +000077 path->remove(path->size() - 3, 3);
78 path->append("png");
79}
80
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +000081static void write_output(const SkString& outputDir, const SkString& inputFilename,
keyar@chromium.org9299ede2012-08-21 19:05:08 +000082 const sk_tools::PictureRenderer& renderer) {
junov@chromium.org777442d2012-06-12 14:56:36 +000083 SkString outputPath;
84 make_output_filepath(&outputPath, outputDir, inputFilename);
keyar@chromium.org9299ede2012-08-21 19:05:08 +000085 bool isWritten = renderer.write(outputPath);
junov@chromium.org777442d2012-06-12 14:56:36 +000086 if (!isWritten) {
87 SkDebugf("Could not write to file %s\n", outputPath.c_str());
88 }
89}
90
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +000091static void render_picture(const SkString& inputPath, const SkString& outputDir,
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000092 sk_tools::PictureRenderer& renderer) {
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +000093 SkString inputFilename;
94 sk_tools::get_basename(&inputFilename, inputPath);
twiz@google.coma31b8bb2012-06-22 18:24:56 +000095
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +000096 SkFILEStream inputStream;
twiz@google.coma31b8bb2012-06-22 18:24:56 +000097 inputStream.setPath(inputPath.c_str());
98 if (!inputStream.isValid()) {
99 SkDebugf("Could not open file %s\n", inputPath.c_str());
100 return;
101 }
102
junov@chromium.org777442d2012-06-12 14:56:36 +0000103 SkPicture picture(&inputStream);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000104
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000105 renderer.init(&picture);
106
107 renderer.render();
108
keyar@chromium.org9299ede2012-08-21 19:05:08 +0000109 write_output(outputDir, inputFilename, renderer);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000110
111 renderer.end();
junov@chromium.org777442d2012-06-12 14:56:36 +0000112}
113
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000114static void process_input(const SkString& input, const SkString& outputDir,
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000115 sk_tools::PictureRenderer& renderer) {
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000116 SkOSFile::Iter iter(input.c_str(), "skp");
junov@chromium.org777442d2012-06-12 14:56:36 +0000117 SkString inputFilename;
118
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000119 if (iter.next(&inputFilename)) {
120 do {
121 SkString inputPath;
122 sk_tools::make_filepath(&inputPath, input, inputFilename);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000123 render_picture(inputPath, outputDir, renderer);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000124 } while(iter.next(&inputFilename));
125 } else {
126 SkString inputPath(input);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000127 render_picture(inputPath, outputDir, renderer);
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000128 }
129}
130
131static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs,
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000132 sk_tools::PictureRenderer*& renderer){
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000133 const char* argv0 = argv[0];
134 char* const* stop = argv + argc;
135
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000136 sk_tools::PictureRenderer::SkDeviceTypes deviceType =
137 sk_tools::PictureRenderer::kBitmap_DeviceType;
138
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000139 for (++argv; argv < stop; ++argv) {
keyar@chromium.org795cd472012-08-02 18:57:53 +0000140 if (0 == strcmp(*argv, "--mode")) {
141 SkDELETE(renderer);
142
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000143 ++argv;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000144 if (argv >= stop) {
145 SkDebugf("Missing mode for --mode\n");
146 usage(argv0);
147 exit(-1);
148 }
149
150 if (0 == strcmp(*argv, "pipe")) {
151 renderer = SkNEW(sk_tools::PipePictureRenderer);
152 } else if (0 == strcmp(*argv, "simple")) {
153 renderer = SkNEW(sk_tools::SimplePictureRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000154 } else if ((0 == strcmp(*argv, "tile")) || (0 == strcmp(*argv, "pow2tile"))) {
155 char* mode = *argv;
156 bool isPowerOf2Mode = false;
157
158 if (0 == strcmp(*argv, "pow2tile")) {
159 isPowerOf2Mode = true;
160 }
161
keyar@chromium.org795cd472012-08-02 18:57:53 +0000162 sk_tools::TiledPictureRenderer* tileRenderer =
163 SkNEW(sk_tools::TiledPictureRenderer);
164 ++argv;
165 if (argv >= stop) {
166 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000167 SkDebugf("Missing width for --mode %s\n", mode);
keyar@chromium.org795cd472012-08-02 18:57:53 +0000168 usage(argv0);
169 exit(-1);
170 }
171
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000172 if (isPowerOf2Mode) {
173 int minWidth = atoi(*argv);
174
175 if (!SkIsPow2(minWidth) || minWidth <= 0) {
176 SkDELETE(tileRenderer);
177 SkDebugf("--mode %s must be given a width"
178 " value that is a power of two\n", mode);
179 exit(-1);
180 }
181
182 tileRenderer->setTileMinPowerOf2Width(minWidth);
183 } else if (sk_tools::is_percentage(*argv)) {
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000184 tileRenderer->setTileWidthPercentage(atof(*argv));
185 if (!(tileRenderer->getTileWidthPercentage() > 0)) {
186 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000187 SkDebugf("--mode %s must be given a width percentage > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000188 exit(-1);
189 }
190 } else {
191 tileRenderer->setTileWidth(atoi(*argv));
192 if (!(tileRenderer->getTileWidth() > 0)) {
193 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000194 SkDebugf("--mode %s must be given a width > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000195 exit(-1);
196 }
197 }
keyar@chromium.org795cd472012-08-02 18:57:53 +0000198
199 ++argv;
200 if (argv >= stop) {
201 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000202 SkDebugf("Missing height for --mode %s\n", mode);
keyar@chromium.org795cd472012-08-02 18:57:53 +0000203 usage(argv0);
204 exit(-1);
205 }
206
keyar@chromium.org163b5672012-08-01 17:53:29 +0000207 if (sk_tools::is_percentage(*argv)) {
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000208 tileRenderer->setTileHeightPercentage(atof(*argv));
209 if (!(tileRenderer->getTileHeightPercentage() > 0)) {
210 SkDELETE(tileRenderer);
211 SkDebugf(
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000212 "--mode %s must be given a height percentage > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000213 exit(-1);
214 }
215 } else {
216 tileRenderer->setTileHeight(atoi(*argv));
217 if (!(tileRenderer->getTileHeight() > 0)) {
218 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000219 SkDebugf("--mode %s must be given a height > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000220 exit(-1);
221 }
222 }
keyar@chromium.org795cd472012-08-02 18:57:53 +0000223
224 renderer = tileRenderer;
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000225 } else {
keyar@chromium.org795cd472012-08-02 18:57:53 +0000226 SkDebugf("%s is not a valid mode for --mode\n", *argv);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000227 usage(argv0);
228 exit(-1);
229 }
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000230 } else if (0 == strcmp(*argv, "--device")) {
231 ++argv;
232 if (argv >= stop) {
233 SkDebugf("Missing mode for --deivce\n");
234 usage(argv0);
235 exit(-1);
236 }
237
238 if (0 == strcmp(*argv, "bitmap")) {
239 deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType;
240 }
241#if SK_SUPPORT_GPU
242 else if (0 == strcmp(*argv, "gpu")) {
243 deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
244 }
245#endif
246 else {
247 SkDebugf("%s is not a valid mode for --device\n", *argv);
248 usage(argv0);
249 exit(-1);
250 }
251
keyar@chromium.org472b3792012-07-20 22:34:27 +0000252 } else if ((0 == strcmp(*argv, "-h")) || (0 == strcmp(*argv, "--help"))) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000253 SkDELETE(renderer);
keyar@chromium.org472b3792012-07-20 22:34:27 +0000254 usage(argv0);
255 exit(-1);
keyar@chromium.orga2333d92012-07-16 17:29:16 +0000256 } else {
257 inputs->push_back(SkString(*argv));
258 }
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000259 }
keyar@chromium.org472b3792012-07-20 22:34:27 +0000260
261 if (inputs->count() < 2) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000262 SkDELETE(renderer);
keyar@chromium.org472b3792012-07-20 22:34:27 +0000263 usage(argv0);
264 exit(-1);
265 }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000266
267 if (NULL == renderer) {
268 renderer = SkNEW(sk_tools::SimplePictureRenderer);
269 }
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000270
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000271 renderer->setDeviceType(deviceType);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000272}
273
274int main(int argc, char* const argv[]) {
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000275 SkTArray<SkString> inputs;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000276 sk_tools::PictureRenderer* renderer = NULL;
keyar@chromium.org472b3792012-07-20 22:34:27 +0000277
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000278 parse_commandline(argc, argv, &inputs, renderer);
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000279 SkString outputDir = inputs[inputs.count() - 1];
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000280 SkASSERT(renderer);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000281
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000282 for (int i = 0; i < inputs.count() - 1; i ++) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000283 process_input(inputs[i], outputDir, *renderer);
junov@chromium.org777442d2012-06-12 14:56:36 +0000284 }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000285
286 SkDELETE(renderer);
junov@chromium.org777442d2012-06-12 14:56:36 +0000287}