Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / skia / tools / PictureRenderingFlags.cpp
1 /*
2  * Copyright 2013 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 "PictureRenderingFlags.h"
9
10 #include "CopyTilesRenderer.h"
11 #include "PictureRenderer.h"
12 #include "picture_utils.h"
13 #include "SkCommandLineFlags.h"
14 #include "SkData.h"
15 #include "SkImage.h"
16 #include "SkImageDecoder.h"
17 #include "SkString.h"
18
19 // Alphabetized list of flags used by this file or bench_ and render_pictures.
20 DEFINE_string(bbh, "none", "bbhType [width height]: Set the bounding box hierarchy type to "
21               "be used. Accepted values are: none, rtree, quadtree, grid. "
22               "Not compatible with --pipe. With value "
23               "'grid', width and height must be specified. 'grid' can "
24               "only be used with modes tile, record, and "
25               "playbackCreation.");
26
27
28 #if SK_SUPPORT_GPU
29 static const char kGpuAPINameGL[] = "gl";
30 static const char kGpuAPINameGLES[] = "gles";
31 #define GPU_CONFIG_STRING "|gpu|msaa4|msaa16|nvprmsaa4|nvprmsaa16"
32 #else
33 #define GPU_CONFIG_STRING ""
34 #endif
35 #if SK_ANGLE
36 #define ANGLE_CONFIG_STRING "|angle"
37 #else
38 #define ANGLE_CONFIG_STRING ""
39 #endif
40 #if SK_MESA
41 #define MESA_CONFIG_STRING "|mesa"
42 #else
43 #define MESA_CONFIG_STRING ""
44 #endif
45
46 // Although this config does not support all the same options as gm, the names should be kept
47 // consistent.
48 DEFINE_string(config, "8888", "["
49               "8888" GPU_CONFIG_STRING ANGLE_CONFIG_STRING MESA_CONFIG_STRING
50               "]: Use the corresponding config.");
51
52 DEFINE_bool(deferImageDecoding, false, "Defer decoding until drawing images. "
53             "Has no effect if the provided skp does not have its images encoded.");
54 DEFINE_string(mode, "simple", "Run in the corresponding mode:\n"
55               "simple: Simple rendering.\n"
56               "tile width height: Use tiles with the given dimensions or percentages.\n"
57               "pow2tile minWidth height: Use tiles with widths that are all a power\n"
58               "\tof two such that they minimize the amount of wasted tile space.\n"
59               "\tminWidth must be a power of two.\n"
60               "copyTile width height: Draw the picture, then copy into tiles. If the\n"
61               "\tpicture is large enough, it is broken into larger tiles to avoid\n"
62               "\tcreating a large canvas.\n"
63 // TODO: If bench_pictures and render_pictures were two separate targets, we could use build flags
64 // to determine which modes to display.
65               "record: (Only in bench_pictures) Time recording from a picture to a new\n"
66               "\tpicture.\n"
67               "playbackCreation: (Only in bench_pictures) Time creation of the \n"
68               "\tSkPicturePlayback.\n"
69               "rerecord: (Only in render_pictures) Record the picture as a new skp,\n"
70               "\twith the bitmaps PNG encoded.\n");
71 DEFINE_bool(pipe, false, "Use SkGPipe rendering. Currently incompatible with \"mode\".");
72 DEFINE_string2(readPath, r, "", "skp files or directories of skp files to process.");
73 DEFINE_double(scale, 1, "Set the scale factor.");
74 DEFINE_string(tiles, "", "Used with --mode copyTile to specify number of tiles per larger tile "
75               "in the x and y directions.");
76 DEFINE_string(viewport, "", "width height: Set the viewport.");
77 #if SK_SUPPORT_GPU
78 DEFINE_string(gpuAPI, "", "Force use of specific gpu API.  Using \"gl\" "
79               "forces OpenGL API. Using \"gles\" forces OpenGL ES API. "
80               "Defaults to empty string, which selects the API native to the "
81               "system.");
82 #endif
83
84 sk_tools::PictureRenderer* parseRenderer(SkString& error, PictureTool tool) {
85     error.reset();
86
87     bool useTiles = false;
88     const char* widthString = NULL;
89     const char* heightString = NULL;
90     bool isPowerOf2Mode = false;
91     bool isCopyMode = false;
92     const char* mode = NULL;
93     bool gridSupported = false;
94
95     SkAutoTUnref<sk_tools::PictureRenderer> renderer;
96     if (FLAGS_mode.count() >= 1) {
97         mode = FLAGS_mode[0];
98         if (0 == strcmp(mode, "record")) {
99             renderer.reset(SkNEW(sk_tools::RecordPictureRenderer));
100             gridSupported = true;
101         } else if (0 == strcmp(mode, "tile") || 0 == strcmp(mode, "pow2tile")
102                    || 0 == strcmp(mode, "copyTile")) {
103             useTiles = true;
104
105             if (0 == strcmp(mode, "pow2tile")) {
106                 isPowerOf2Mode = true;
107             } else if (0 == strcmp(mode, "copyTile")) {
108                 isCopyMode = true;
109             } else {
110                 gridSupported = true;
111             }
112
113             if (FLAGS_mode.count() < 2) {
114                 error.printf("Missing width for --mode %s\n", mode);
115                 return NULL;
116             }
117
118             widthString = FLAGS_mode[1];
119             if (FLAGS_mode.count() < 3) {
120                 error.printf("Missing height for --mode %s\n", mode);
121                 return NULL;
122             }
123
124             heightString = FLAGS_mode[2];
125         } else if (0 == strcmp(mode, "playbackCreation") && kBench_PictureTool == tool) {
126             renderer.reset(SkNEW(sk_tools::PlaybackCreationRenderer));
127             gridSupported = true;
128         // undocumented
129         } else if (0 == strcmp(mode, "gatherPixelRefs") && kBench_PictureTool == tool) {
130             renderer.reset(sk_tools::CreateGatherPixelRefsRenderer());
131         } else if (0 == strcmp(mode, "rerecord") && kRender_PictureTool == tool) {
132             renderer.reset(SkNEW(sk_tools::RecordPictureRenderer));
133         // Allow 'mode' to be set to 'simple', but do not create a renderer, so we can
134         // ensure that pipe does not override a mode besides simple. The renderer will
135         // be created below.
136         } else if (0 == strcmp(mode, "simple")) {
137             gridSupported = true;
138         } else {
139             error.printf("%s is not a valid mode for --mode\n", mode);
140             return NULL;
141         }
142     }
143
144     if (useTiles) {
145         SkASSERT(NULL == renderer);
146         SkAutoTUnref<sk_tools::TiledPictureRenderer> tiledRenderer;
147         if (isCopyMode) {
148             int xTiles = -1;
149             int yTiles = -1;
150             if (FLAGS_tiles.count() > 0) {
151                 if (FLAGS_tiles.count() != 2) {
152                     error.printf("--tiles requires an x value and a y value.\n");
153                     return NULL;
154                 }
155                 xTiles = atoi(FLAGS_tiles[0]);
156                 yTiles = atoi(FLAGS_tiles[1]);
157             }
158
159             int x, y;
160             if (xTiles != -1 && yTiles != -1) {
161                 x = xTiles;
162                 y = yTiles;
163                 if (x <= 0 || y <= 0) {
164                     error.printf("--tiles must be given values > 0\n");
165                     return NULL;
166                 }
167             } else {
168                 x = y = 4;
169             }
170             tiledRenderer.reset(SkNEW_ARGS(sk_tools::CopyTilesRenderer, (x, y)));
171         } else {
172             tiledRenderer.reset(SkNEW(sk_tools::TiledPictureRenderer));
173         }
174
175         if (isPowerOf2Mode) {
176             int minWidth = atoi(widthString);
177             if (!SkIsPow2(minWidth) || minWidth < 0) {
178                 SkString err;
179                 error.printf("-mode %s must be given a width"
180                              " value that is a power of two\n", mode);
181                 return NULL;
182             }
183             tiledRenderer->setTileMinPowerOf2Width(minWidth);
184         } else if (sk_tools::is_percentage(widthString)) {
185             if (isCopyMode) {
186                 error.printf("--mode %s does not support percentages.\n", mode);
187                 return NULL;
188             }
189             tiledRenderer->setTileWidthPercentage(atof(widthString));
190             if (!(tiledRenderer->getTileWidthPercentage() > 0)) {
191                 error.printf("--mode %s must be given a width percentage > 0\n", mode);
192                 return NULL;
193             }
194         } else {
195             tiledRenderer->setTileWidth(atoi(widthString));
196             if (!(tiledRenderer->getTileWidth() > 0)) {
197                 error.printf("--mode %s must be given a width > 0\n", mode);
198                 return NULL;
199             }
200         }
201
202         if (sk_tools::is_percentage(heightString)) {
203             if (isCopyMode) {
204                 error.printf("--mode %s does not support percentages.\n", mode);
205                 return NULL;
206             }
207             tiledRenderer->setTileHeightPercentage(atof(heightString));
208             if (!(tiledRenderer->getTileHeightPercentage() > 0)) {
209                 error.printf("--mode %s must be given a height percentage > 0\n", mode);
210                 return NULL;
211             }
212         } else {
213             tiledRenderer->setTileHeight(atoi(heightString));
214             if (!(tiledRenderer->getTileHeight() > 0)) {
215                 SkString err;
216                 error.printf("--mode %s must be given a height > 0\n", mode);
217                 return NULL;
218             }
219         }
220
221         renderer.reset(tiledRenderer.detach());
222         if (FLAGS_pipe) {
223             error.printf("Pipe rendering is currently not compatible with tiling.\n"
224                          "Turning off pipe.\n");
225         }
226
227     } else { // useTiles
228         if (FLAGS_pipe) {
229             if (renderer != NULL) {
230                 error.printf("Pipe is incompatible with other modes.\n");
231                 return NULL;
232             }
233             renderer.reset(SkNEW(sk_tools::PipePictureRenderer));
234         }
235     }
236
237     if (NULL == renderer) {
238         renderer.reset(SkNEW(sk_tools::SimplePictureRenderer));
239     }
240
241     if (FLAGS_viewport.count() > 0) {
242         if (FLAGS_viewport.count() != 2) {
243             error.printf("--viewport requires a width and a height.\n");
244             return NULL;
245         }
246         SkISize viewport;
247         viewport.fWidth = atoi(FLAGS_viewport[0]);
248         viewport.fHeight = atoi(FLAGS_viewport[1]);
249         renderer->setViewport(viewport);
250     }
251
252     sk_tools::PictureRenderer::SkDeviceTypes deviceType =
253         sk_tools::PictureRenderer::kBitmap_DeviceType;
254 #if SK_SUPPORT_GPU
255     GrGLStandard gpuAPI = kNone_GrGLStandard;
256     if (1 == FLAGS_gpuAPI.count()) {
257         if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) {
258             gpuAPI = kGL_GrGLStandard;
259         } else if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) {
260             gpuAPI = kGLES_GrGLStandard;
261         } else {
262             error.printf("--gpuAPI invalid api value.\n");
263             return NULL;
264         }
265     } else if (FLAGS_gpuAPI.count() > 1) {
266         error.printf("--gpuAPI invalid api value.\n");
267         return NULL;
268     }
269
270     int sampleCount = 0;
271 #endif
272     if (FLAGS_config.count() > 0) {
273         if (0 == strcmp(FLAGS_config[0], "8888")) {
274             deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType;
275         }
276 #if SK_SUPPORT_GPU
277         else if (0 == strcmp(FLAGS_config[0], "gpu")) {
278             deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
279         }
280         else if (0 == strcmp(FLAGS_config[0], "msaa4")) {
281             deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
282             sampleCount = 4;
283         }
284         else if (0 == strcmp(FLAGS_config[0], "msaa16")) {
285             deviceType = sk_tools::PictureRenderer::kGPU_DeviceType;
286             sampleCount = 16;
287         }
288         else if (0 == strcmp(FLAGS_config[0], "nvprmsaa4")) {
289             deviceType = sk_tools::PictureRenderer::kNVPR_DeviceType;
290             sampleCount = 4;
291         }
292         else if (0 == strcmp(FLAGS_config[0], "nvprmsaa16")) {
293             deviceType = sk_tools::PictureRenderer::kNVPR_DeviceType;
294             sampleCount = 16;
295         }
296 #if SK_ANGLE
297         else if (0 == strcmp(FLAGS_config[0], "angle")) {
298             deviceType = sk_tools::PictureRenderer::kAngle_DeviceType;
299         }
300 #endif
301 #if SK_MESA
302         else if (0 == strcmp(FLAGS_config[0], "mesa")) {
303             deviceType = sk_tools::PictureRenderer::kMesa_DeviceType;
304         }
305 #endif
306 #endif
307         else {
308             error.printf("%s is not a valid mode for --config\n", FLAGS_config[0]);
309             return NULL;
310         }
311 #if SK_SUPPORT_GPU
312         if (!renderer->setDeviceType(deviceType, gpuAPI)) {
313 #else
314         if (!renderer->setDeviceType(deviceType)) {
315 #endif
316             error.printf("Could not create backend for --config %s\n", FLAGS_config[0]);
317             return NULL;
318         }
319 #if SK_SUPPORT_GPU
320         renderer->setSampleCount(sampleCount);
321 #endif
322     }
323
324
325     sk_tools::PictureRenderer::BBoxHierarchyType bbhType
326             = sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
327     if (FLAGS_bbh.count() > 0) {
328         const char* type = FLAGS_bbh[0];
329         if (0 == strcmp(type, "none")) {
330             bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType;
331         } else if (0 == strcmp(type, "quadtree")) {
332             bbhType = sk_tools::PictureRenderer::kQuadTree_BBoxHierarchyType;
333         } else if (0 == strcmp(type, "rtree")) {
334             bbhType = sk_tools::PictureRenderer::kRTree_BBoxHierarchyType;
335         } else if (0 == strcmp(type, "grid")) {
336             if (!gridSupported) {
337                 error.printf("'--bbh grid' is not compatible with --mode=%s.\n", mode);
338                 return NULL;
339             }
340             bbhType = sk_tools::PictureRenderer::kTileGrid_BBoxHierarchyType;
341             if (FLAGS_bbh.count() != 3) {
342                 error.printf("--bbh grid requires a width and a height.\n");
343                 return NULL;
344             }
345             int gridWidth = atoi(FLAGS_bbh[1]);
346             int gridHeight = atoi(FLAGS_bbh[2]);
347             renderer->setGridSize(gridWidth, gridHeight);
348
349         } else {
350             error.printf("%s is not a valid value for --bbhType\n", type);
351             return NULL;
352         }
353         if (FLAGS_pipe && sk_tools::PictureRenderer::kNone_BBoxHierarchyType != bbhType) {
354             error.printf("--pipe and --bbh cannot be used together\n");
355             return NULL;
356         }
357     }
358     renderer->setBBoxHierarchyType(bbhType);
359     renderer->setScaleFactor(SkDoubleToScalar(FLAGS_scale));
360
361     return renderer.detach();
362 }