blob: 5ec2ede3e7d507a65c9388a6d8a93e00fd6a9c73 [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"
borenet@google.com10ef79e2012-09-10 17:19:06 +000011#include "SkGraphics.h"
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000012#include "SkMath.h"
junov@chromium.org777442d2012-06-12 14:56:36 +000013#include "SkOSFile.h"
14#include "SkPicture.h"
15#include "SkStream.h"
16#include "SkString.h"
senorblanco@chromium.org3cbbb542012-07-13 18:55:53 +000017#include "SkTArray.h"
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000018#include "PictureRenderer.h"
twiz@google.coma31b8bb2012-06-22 18:24:56 +000019#include "picture_utils.h"
junov@chromium.org777442d2012-06-12 14:56:36 +000020
junov@chromium.org777442d2012-06-12 14:56:36 +000021static void usage(const char* argv0) {
22 SkDebugf("SkPicture rendering tool\n");
23 SkDebugf("\n"
24"Usage: \n"
keyar@chromium.org472b3792012-07-20 22:34:27 +000025" %s <input>... <outputDir> \n"
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000026" [--mode pipe | pow2tile minWidth height[%] | simple\n"
27" | tile width[%] height[%]]\n"
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000028" [--device bitmap"
29#if SK_SUPPORT_GPU
30" | gpu"
31#endif
32"]"
junov@chromium.org777442d2012-06-12 14:56:36 +000033, argv0);
keyar@chromium.org472b3792012-07-20 22:34:27 +000034 SkDebugf("\n\n");
junov@chromium.org777442d2012-06-12 14:56:36 +000035 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000036" input: A list of directories and files to use as input. Files are\n"
37" expected to have the .skp extension.\n\n");
junov@chromium.org777442d2012-06-12 14:56:36 +000038 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000039" outputDir: directory to write the rendered images.\n\n");
keyar@chromium.org472b3792012-07-20 22:34:27 +000040 SkDebugf(
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000041" --mode pipe | pow2tile minWidth height[%] | simple\n"
42" | tile width[%] height[%]: Run in the corresponding mode.\n"
43" Default is simple.\n");
keyar@chromium.org472b3792012-07-20 22:34:27 +000044 SkDebugf(
keyar@chromium.org795cd472012-08-02 18:57:53 +000045" pipe, Render using a SkGPipe.\n");
46 SkDebugf(
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +000047" 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(
keyar@chromium.org795cd472012-08-02 18:57:53 +000056" 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");
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000060 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");
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000069#if SK_SUPPORT_GPU
keyar@chromium.orga40c20d2012-08-20 15:04:12 +000070 SkDebugf(
keyar@chromium.orgc81686c2012-08-20 15:04:04 +000071" gpu, Render to the GPU.\n");
72#endif
junov@chromium.org777442d2012-06-12 14:56:36 +000073}
74
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +000075static void make_output_filepath(SkString* path, const SkString& dir,
junov@chromium.org777442d2012-06-12 14:56:36 +000076 const SkString& name) {
twiz@google.coma31b8bb2012-06-22 18:24:56 +000077 sk_tools::make_filepath(path, dir, name);
junov@chromium.org777442d2012-06-12 14:56:36 +000078 path->remove(path->size() - 3, 3);
79 path->append("png");
80}
81
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +000082static void write_output(const SkString& outputDir, const SkString& inputFilename,
keyar@chromium.org9299ede2012-08-21 19:05:08 +000083 const sk_tools::PictureRenderer& renderer) {
junov@chromium.org777442d2012-06-12 14:56:36 +000084 SkString outputPath;
85 make_output_filepath(&outputPath, outputDir, inputFilename);
keyar@chromium.org9299ede2012-08-21 19:05:08 +000086 bool isWritten = renderer.write(outputPath);
junov@chromium.org777442d2012-06-12 14:56:36 +000087 if (!isWritten) {
88 SkDebugf("Could not write to file %s\n", outputPath.c_str());
89 }
90}
91
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +000092static void render_picture(const SkString& inputPath, const SkString& outputDir,
keyar@chromium.org451bb9f2012-07-26 17:27:57 +000093 sk_tools::PictureRenderer& renderer) {
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +000094 SkString inputFilename;
95 sk_tools::get_basename(&inputFilename, inputPath);
twiz@google.coma31b8bb2012-06-22 18:24:56 +000096
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +000097 SkFILEStream inputStream;
twiz@google.coma31b8bb2012-06-22 18:24:56 +000098 inputStream.setPath(inputPath.c_str());
99 if (!inputStream.isValid()) {
100 SkDebugf("Could not open file %s\n", inputPath.c_str());
101 return;
102 }
103
junov@chromium.org777442d2012-06-12 14:56:36 +0000104 SkPicture picture(&inputStream);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000105
borenet@google.com03fcee82012-09-10 18:18:38 +0000106 SkDebugf("drawing... [%i %i] %s\n", picture.width(), picture.height(),
107 inputPath.c_str());
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000108 renderer.init(&picture);
109
scroggo@google.com9a412522012-09-07 15:21:18 +0000110 renderer.render(true);
111
112 renderer.resetState();
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000113
keyar@chromium.org9299ede2012-08-21 19:05:08 +0000114 write_output(outputDir, inputFilename, renderer);
keyar@chromium.org9d696c02012-08-07 17:11:33 +0000115
116 renderer.end();
junov@chromium.org777442d2012-06-12 14:56:36 +0000117}
118
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000119static void process_input(const SkString& input, const SkString& outputDir,
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000120 sk_tools::PictureRenderer& renderer) {
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000121 SkOSFile::Iter iter(input.c_str(), "skp");
junov@chromium.org777442d2012-06-12 14:56:36 +0000122 SkString inputFilename;
123
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000124 if (iter.next(&inputFilename)) {
125 do {
126 SkString inputPath;
127 sk_tools::make_filepath(&inputPath, input, inputFilename);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000128 render_picture(inputPath, outputDir, renderer);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000129 } while(iter.next(&inputFilename));
130 } else {
131 SkString inputPath(input);
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000132 render_picture(inputPath, outputDir, renderer);
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000133 }
134}
135
136static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* inputs,
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000137 sk_tools::PictureRenderer*& renderer){
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000138 const char* argv0 = argv[0];
139 char* const* stop = argv + argc;
140
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000141 sk_tools::PictureRenderer::SkDeviceTypes deviceType =
142 sk_tools::PictureRenderer::kBitmap_DeviceType;
143
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000144 for (++argv; argv < stop; ++argv) {
keyar@chromium.org795cd472012-08-02 18:57:53 +0000145 if (0 == strcmp(*argv, "--mode")) {
146 SkDELETE(renderer);
147
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000148 ++argv;
keyar@chromium.org795cd472012-08-02 18:57:53 +0000149 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);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000159 } 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
keyar@chromium.org795cd472012-08-02 18:57:53 +0000167 sk_tools::TiledPictureRenderer* tileRenderer =
168 SkNEW(sk_tools::TiledPictureRenderer);
169 ++argv;
170 if (argv >= stop) {
171 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000172 SkDebugf("Missing width for --mode %s\n", mode);
keyar@chromium.org795cd472012-08-02 18:57:53 +0000173 usage(argv0);
174 exit(-1);
175 }
176
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000177 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)) {
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000189 tileRenderer->setTileWidthPercentage(atof(*argv));
190 if (!(tileRenderer->getTileWidthPercentage() > 0)) {
191 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000192 SkDebugf("--mode %s must be given a width percentage > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000193 exit(-1);
194 }
195 } else {
196 tileRenderer->setTileWidth(atoi(*argv));
197 if (!(tileRenderer->getTileWidth() > 0)) {
198 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000199 SkDebugf("--mode %s must be given a width > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000200 exit(-1);
201 }
202 }
keyar@chromium.org795cd472012-08-02 18:57:53 +0000203
204 ++argv;
205 if (argv >= stop) {
206 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000207 SkDebugf("Missing height for --mode %s\n", mode);
keyar@chromium.org795cd472012-08-02 18:57:53 +0000208 usage(argv0);
209 exit(-1);
210 }
211
keyar@chromium.org163b5672012-08-01 17:53:29 +0000212 if (sk_tools::is_percentage(*argv)) {
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000213 tileRenderer->setTileHeightPercentage(atof(*argv));
214 if (!(tileRenderer->getTileHeightPercentage() > 0)) {
215 SkDELETE(tileRenderer);
216 SkDebugf(
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000217 "--mode %s must be given a height percentage > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000218 exit(-1);
219 }
220 } else {
221 tileRenderer->setTileHeight(atoi(*argv));
222 if (!(tileRenderer->getTileHeight() > 0)) {
223 SkDELETE(tileRenderer);
keyar@chromium.orgf4959ab2012-08-23 20:53:25 +0000224 SkDebugf("--mode %s must be given a height > 0\n", mode);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000225 exit(-1);
226 }
227 }
keyar@chromium.org795cd472012-08-02 18:57:53 +0000228
229 renderer = tileRenderer;
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000230 } else {
keyar@chromium.org795cd472012-08-02 18:57:53 +0000231 SkDebugf("%s is not a valid mode for --mode\n", *argv);
keyar@chromium.orgcc6e5ef2012-07-27 20:09:26 +0000232 usage(argv0);
233 exit(-1);
234 }
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000235 } 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
keyar@chromium.org472b3792012-07-20 22:34:27 +0000257 } else if ((0 == strcmp(*argv, "-h")) || (0 == strcmp(*argv, "--help"))) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000258 SkDELETE(renderer);
keyar@chromium.org472b3792012-07-20 22:34:27 +0000259 usage(argv0);
260 exit(-1);
keyar@chromium.orga2333d92012-07-16 17:29:16 +0000261 } else {
262 inputs->push_back(SkString(*argv));
263 }
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000264 }
keyar@chromium.org472b3792012-07-20 22:34:27 +0000265
266 if (inputs->count() < 2) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000267 SkDELETE(renderer);
keyar@chromium.org472b3792012-07-20 22:34:27 +0000268 usage(argv0);
269 exit(-1);
270 }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000271
272 if (NULL == renderer) {
273 renderer = SkNEW(sk_tools::SimplePictureRenderer);
274 }
keyar@chromium.org4ea96c52012-08-20 15:03:29 +0000275
keyar@chromium.orgc81686c2012-08-20 15:04:04 +0000276 renderer->setDeviceType(deviceType);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000277}
278
279int main(int argc, char* const argv[]) {
borenet@google.com10ef79e2012-09-10 17:19:06 +0000280 SkGraphics::Init();
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000281 SkTArray<SkString> inputs;
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000282 sk_tools::PictureRenderer* renderer = NULL;
keyar@chromium.org472b3792012-07-20 22:34:27 +0000283
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000284 parse_commandline(argc, argv, &inputs, renderer);
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000285 SkString outputDir = inputs[inputs.count() - 1];
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000286 SkASSERT(renderer);
keyar@chromium.orgd1dc9202012-07-09 18:32:08 +0000287
keyar@chromium.org1cbd47c2012-07-13 18:22:59 +0000288 for (int i = 0; i < inputs.count() - 1; i ++) {
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000289 process_input(inputs[i], outputDir, *renderer);
junov@chromium.org777442d2012-06-12 14:56:36 +0000290 }
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000291
robertphillips@google.com163c84b2012-09-13 15:40:37 +0000292#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
keyar@chromium.org451bb9f2012-07-26 17:27:57 +0000302 SkDELETE(renderer);
borenet@google.com10ef79e2012-09-10 17:19:06 +0000303 SkGraphics::Term();
junov@chromium.org777442d2012-06-12 14:56:36 +0000304}