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