blob: 186a214512e0edff63644b70a3b936e7cd13a547 [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
scroggo@google.com9a412522012-09-07 15:21:18 +0000107 renderer.render(true);
108
109 renderer.resetState();
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000110
keyar@chromium.org9299ede2012-08-21 19:05:08 +0000111 write_output(outputDir, inputFilename, renderer);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000112
113 renderer.end();
junov@chromium.org777442d2012-06-12 14:56:36 +0000114}
115
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000116static void process_input(const SkString& input, const SkString& outputDir,
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000117 sk_tools::PictureRenderer& renderer) {
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000118 SkOSFile::Iter iter(input.c_str(), "skp");
junov@chromium.org777442d2012-06-12 14:56:36 +0000119 SkString inputFilename;
120
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000121 if (iter.next(&inputFilename)) {
122 do {
123 SkString inputPath;
124 sk_tools::make_filepath(&inputPath, input, inputFilename);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000125 render_picture(inputPath, outputDir, renderer);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000126 } while(iter.next(&inputFilename));
127 } else {
128 SkString inputPath(input);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000129 render_picture(inputPath, outputDir, renderer);
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000130 }
131}
132
133static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs,
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000134 sk_tools::PictureRenderer*& renderer){
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000135 const char* argv0 = argv[0];
136 char* const* stop = argv + argc;
137
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000138 sk_tools::PictureRenderer::SkDeviceTypes deviceType =
139 sk_tools::PictureRenderer::kBitmap_DeviceType;
140
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000141 for (++argv; argv < stop; ++argv) {
keyar@chromium.org795cd472012-08-02 18:57:53 +0000142 if (0 == strcmp(*argv, "--mode")) {
143 SkDELETE(renderer);
144
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000145 ++argv;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000146 if (argv >= stop) {
147 SkDebugf("Missing mode for --mode\n");
148 usage(argv0);
149 exit(-1);
150 }
151
152 if (0 == strcmp(*argv, "pipe")) {
153 renderer = SkNEW(sk_tools::PipePictureRenderer);
154 } else if (0 == strcmp(*argv, "simple")) {
155 renderer = SkNEW(sk_tools::SimplePictureRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000156 } else if ((0 == strcmp(*argv, "tile")) || (0 == strcmp(*argv, "pow2tile"))) {
157 char* mode = *argv;
158 bool isPowerOf2Mode = false;
159
160 if (0 == strcmp(*argv, "pow2tile")) {
161 isPowerOf2Mode = true;
162 }
163
keyar@chromium.org795cd472012-08-02 18:57:53 +0000164 sk_tools::TiledPictureRenderer* tileRenderer =
165 SkNEW(sk_tools::TiledPictureRenderer);
166 ++argv;
167 if (argv >= stop) {
168 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000169 SkDebugf("Missing width for --mode %s\n", mode);
keyar@chromium.org795cd472012-08-02 18:57:53 +0000170 usage(argv0);
171 exit(-1);
172 }
173
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000174 if (isPowerOf2Mode) {
175 int minWidth = atoi(*argv);
176
177 if (!SkIsPow2(minWidth) || minWidth <= 0) {
178 SkDELETE(tileRenderer);
179 SkDebugf("--mode %s must be given a width"
180 " value that is a power of two\n", mode);
181 exit(-1);
182 }
183
184 tileRenderer->setTileMinPowerOf2Width(minWidth);
185 } else if (sk_tools::is_percentage(*argv)) {
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000186 tileRenderer->setTileWidthPercentage(atof(*argv));
187 if (!(tileRenderer->getTileWidthPercentage() > 0)) {
188 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000189 SkDebugf("--mode %s must be given a width percentage > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000190 exit(-1);
191 }
192 } else {
193 tileRenderer->setTileWidth(atoi(*argv));
194 if (!(tileRenderer->getTileWidth() > 0)) {
195 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000196 SkDebugf("--mode %s must be given a width > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000197 exit(-1);
198 }
199 }
keyar@chromium.org795cd472012-08-02 18:57:53 +0000200
201 ++argv;
202 if (argv >= stop) {
203 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000204 SkDebugf("Missing height for --mode %s\n", mode);
keyar@chromium.org795cd472012-08-02 18:57:53 +0000205 usage(argv0);
206 exit(-1);
207 }
208
keyar@chromium.org163b5672012-08-01 17:53:29 +0000209 if (sk_tools::is_percentage(*argv)) {
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000210 tileRenderer->setTileHeightPercentage(atof(*argv));
211 if (!(tileRenderer->getTileHeightPercentage() > 0)) {
212 SkDELETE(tileRenderer);
213 SkDebugf(
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000214 "--mode %s must be given a height percentage > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000215 exit(-1);
216 }
217 } else {
218 tileRenderer->setTileHeight(atoi(*argv));
219 if (!(tileRenderer->getTileHeight() > 0)) {
220 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000221 SkDebugf("--mode %s must be given a height > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000222 exit(-1);
223 }
224 }
keyar@chromium.org795cd472012-08-02 18:57:53 +0000225
226 renderer = tileRenderer;
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000227 } else {
keyar@chromium.org795cd472012-08-02 18:57:53 +0000228 SkDebugf("%s is not a valid mode for --mode\n", *argv);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000229 usage(argv0);
230 exit(-1);
231 }
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000232 } else if (0 == strcmp(*argv, "--device")) {
233 ++argv;
234 if (argv >= stop) {
235 SkDebugf("Missing mode for --deivce\n");
236 usage(argv0);
237 exit(-1);
238 }
239
240 if (0 == strcmp(*argv, "bitmap")) {
241 deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType;
242 }
243#if SK_SUPPORT_GPU
244 else if (0 == strcmp(*argv, "gpu")) {
245 deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
246 }
247#endif
248 else {
249 SkDebugf("%s is not a valid mode for --device\n", *argv);
250 usage(argv0);
251 exit(-1);
252 }
253
keyar@chromium.org472b3792012-07-20 22:34:27 +0000254 } else if ((0 == strcmp(*argv, "-h")) || (0 == strcmp(*argv, "--help"))) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000255 SkDELETE(renderer);
keyar@chromium.org472b3792012-07-20 22:34:27 +0000256 usage(argv0);
257 exit(-1);
keyar@chromium.orga2333d92012-07-16 17:29:16 +0000258 } else {
259 inputs->push_back(SkString(*argv));
260 }
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000261 }
keyar@chromium.org472b3792012-07-20 22:34:27 +0000262
263 if (inputs->count() < 2) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000264 SkDELETE(renderer);
keyar@chromium.org472b3792012-07-20 22:34:27 +0000265 usage(argv0);
266 exit(-1);
267 }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000268
269 if (NULL == renderer) {
270 renderer = SkNEW(sk_tools::SimplePictureRenderer);
271 }
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000272
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000273 renderer->setDeviceType(deviceType);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000274}
275
276int main(int argc, char* const argv[]) {
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000277 SkTArray<SkString> inputs;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000278 sk_tools::PictureRenderer* renderer = NULL;
keyar@chromium.org472b3792012-07-20 22:34:27 +0000279
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000280 parse_commandline(argc, argv, &inputs, renderer);
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000281 SkString outputDir = inputs[inputs.count() - 1];
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000282 SkASSERT(renderer);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000283
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000284 for (int i = 0; i < inputs.count() - 1; i ++) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000285 process_input(inputs[i], outputDir, *renderer);
junov@chromium.org777442d2012-06-12 14:56:36 +0000286 }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000287
288 SkDELETE(renderer);
junov@chromium.org777442d2012-06-12 14:56:36 +0000289}