sk_tools::PictureRenderer* parseRenderer(SkString& error, PictureTool tool) { error.reset(); if (FLAGS_multi <= 0) { error.printf("--multi must be > 0, was %i", FLAGS_multi); return NULL; } bool useTiles = false; const char* widthString = NULL; const char* heightString = NULL; bool isPowerOf2Mode = false; bool isCopyMode = false; const char* mode = NULL; bool gridSupported = false; SkAutoTUnref<sk_tools::PictureRenderer> renderer; if (FLAGS_mode.count() >= 1) { mode = FLAGS_mode[0]; if (0 == strcmp(mode, "record")) { renderer.reset(SkNEW(sk_tools::RecordPictureRenderer)); gridSupported = true; // undocumented } else if (0 == strcmp(mode, "clone")) { renderer.reset(sk_tools::CreatePictureCloneRenderer()); } else if (0 == strcmp(mode, "tile") || 0 == strcmp(mode, "pow2tile") || 0 == strcmp(mode, "copyTile")) { useTiles = true; if (0 == strcmp(mode, "pow2tile")) { isPowerOf2Mode = true; } else if (0 == strcmp(mode, "copyTile")) { isCopyMode = true; } else { gridSupported = true; } if (FLAGS_mode.count() < 2) { error.printf("Missing width for --mode %s\n", mode); return NULL; } widthString = FLAGS_mode[1]; if (FLAGS_mode.count() < 3) { error.printf("Missing height for --mode %s\n", mode); return NULL; } heightString = FLAGS_mode[2]; } else if (0 == strcmp(mode, "playbackCreation") && kBench_PictureTool == tool) { renderer.reset(SkNEW(sk_tools::PlaybackCreationRenderer)); gridSupported = true; // undocumented } else if (0 == strcmp(mode, "gatherPixelRefs") && kBench_PictureTool == tool) { renderer.reset(sk_tools::CreateGatherPixelRefsRenderer()); } else if (0 == strcmp(mode, "rerecord") && kRender_PictureTool == tool) { renderer.reset(SkNEW(sk_tools::RecordPictureRenderer)); // Allow 'mode' to be set to 'simple', but do not create a renderer, so we can // ensure that pipe does not override a mode besides simple. The renderer will // be created below. } else if (0 != strcmp(mode, "simple")) { error.printf("%s is not a valid mode for --mode\n", mode); return NULL; } } if (useTiles) { SkASSERT(NULL == renderer); SkAutoTUnref<sk_tools::TiledPictureRenderer> tiledRenderer; if (isCopyMode) { int xTiles = -1; int yTiles = -1; if (FLAGS_tiles.count() > 0) { if (FLAGS_tiles.count() != 2) { error.printf("--tiles requires an x value and a y value.\n"); return NULL; } xTiles = atoi(FLAGS_tiles[0]); yTiles = atoi(FLAGS_tiles[1]); } int x, y; if (xTiles != -1 && yTiles != -1) { x = xTiles; y = yTiles; if (x <= 0 || y <= 0) { error.printf("--tiles must be given values > 0\n"); return NULL; } } else { x = y = 4; } tiledRenderer.reset(SkNEW_ARGS(sk_tools::CopyTilesRenderer, (x, y))); } else if (FLAGS_multi > 1) { tiledRenderer.reset(SkNEW_ARGS(sk_tools::MultiCorePictureRenderer, (FLAGS_multi))); } else { tiledRenderer.reset(SkNEW(sk_tools::TiledPictureRenderer)); } if (isPowerOf2Mode) { int minWidth = atoi(widthString); if (!SkIsPow2(minWidth) || minWidth < 0) { SkString err; error.printf("-mode %s must be given a width" " value that is a power of two\n", mode); return NULL; } tiledRenderer->setTileMinPowerOf2Width(minWidth); } else if (sk_tools::is_percentage(widthString)) { if (isCopyMode) { error.printf("--mode %s does not support percentages.\n", mode); return NULL; } tiledRenderer->setTileWidthPercentage(atof(widthString)); if (!(tiledRenderer->getTileWidthPercentage() > 0)) { error.printf("--mode %s must be given a width percentage > 0\n", mode); return NULL; } } else { tiledRenderer->setTileWidth(atoi(widthString)); if (!(tiledRenderer->getTileWidth() > 0)) { error.printf("--mode %s must be given a width > 0\n", mode); return NULL; } } if (sk_tools::is_percentage(heightString)) { if (isCopyMode) { error.printf("--mode %s does not support percentages.\n", mode); return NULL; } tiledRenderer->setTileHeightPercentage(atof(heightString)); if (!(tiledRenderer->getTileHeightPercentage() > 0)) { error.printf("--mode %s must be given a height percentage > 0\n", mode); return NULL; } } else { tiledRenderer->setTileHeight(atoi(heightString)); if (!(tiledRenderer->getTileHeight() > 0)) { SkString err; error.printf("--mode %s must be given a height > 0\n", mode); return NULL; } } renderer.reset(tiledRenderer.detach()); if (FLAGS_pipe) { error.printf("Pipe rendering is currently not compatible with tiling.\n" "Turning off pipe.\n"); } } else { // useTiles if (FLAGS_multi > 1) { error.printf("Multithreaded drawing requires tiled rendering.\n"); return NULL; } if (FLAGS_pipe) { if (renderer != NULL) { error.printf("Pipe is incompatible with other modes.\n"); return NULL; } renderer.reset(SkNEW(sk_tools::PipePictureRenderer)); } } if (NULL == renderer) { renderer.reset(SkNEW(sk_tools::SimplePictureRenderer)); } if (FLAGS_viewport.count() > 0) { if (FLAGS_viewport.count() != 2) { error.printf("--viewport requires a width and a height.\n"); return NULL; } SkISize viewport; viewport.fWidth = atoi(FLAGS_viewport[0]); viewport.fHeight = atoi(FLAGS_viewport[1]); renderer->setViewport(viewport); } sk_tools::PictureRenderer::SkDeviceTypes deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType; #if SK_SUPPORT_GPU int sampleCount = 0; #endif if (FLAGS_config.count() > 0) { if (0 == strcmp(FLAGS_config[0], "8888")) { deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType; } #if SK_SUPPORT_GPU else if (0 == strcmp(FLAGS_config[0], "gpu")) { deviceType = sk_tools::PictureRenderer::kGPU_DeviceType; if (FLAGS_multi > 1) { error.printf("GPU not compatible with multithreaded tiling.\n"); return NULL; } } else if (0 == strcmp(FLAGS_config[0], "msaa4")) { deviceType = sk_tools::PictureRenderer::kGPU_DeviceType; if (FLAGS_multi > 1) { error.printf("GPU not compatible with multithreaded tiling.\n"); return NULL; } sampleCount = 4; } else if (0 == strcmp(FLAGS_config[0], "msaa16")) { deviceType = sk_tools::PictureRenderer::kGPU_DeviceType; if (FLAGS_multi > 1) { error.printf("GPU not compatible with multithreaded tiling.\n"); return NULL; } sampleCount = 16; } else if (0 == strcmp(FLAGS_config[0], "nvprmsaa4")) { deviceType = sk_tools::PictureRenderer::kNVPR_DeviceType; if (FLAGS_multi > 1) { error.printf("GPU not compatible with multithreaded tiling.\n"); return NULL; } sampleCount = 4; } else if (0 == strcmp(FLAGS_config[0], "nvprmsaa16")) { deviceType = sk_tools::PictureRenderer::kNVPR_DeviceType; if (FLAGS_multi > 1) { error.printf("GPU not compatible with multithreaded tiling.\n"); return NULL; } sampleCount = 16; } #if SK_ANGLE else if (0 == strcmp(FLAGS_config[0], "angle")) { deviceType = sk_tools::PictureRenderer::kAngle_DeviceType; if (FLAGS_multi > 1) { error.printf("Angle not compatible with multithreaded tiling.\n"); return NULL; } } #endif #if SK_MESA else if (0 == strcmp(FLAGS_config[0], "mesa")) { deviceType = sk_tools::PictureRenderer::kMesa_DeviceType; if (FLAGS_multi > 1) { error.printf("Mesa not compatible with multithreaded tiling.\n"); return NULL; } } #endif #endif else { error.printf("%s is not a valid mode for --config\n", FLAGS_config[0]); return NULL; } renderer->setDeviceType(deviceType); #if SK_SUPPORT_GPU renderer->setSampleCount(sampleCount); #endif } sk_tools::PictureRenderer::BBoxHierarchyType bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType; if (FLAGS_bbh.count() > 0) { const char* type = FLAGS_bbh[0]; if (0 == strcmp(type, "none")) { bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType; } else if (0 == strcmp(type, "quadtree")) { bbhType = sk_tools::PictureRenderer::kQuadTree_BBoxHierarchyType; } else if (0 == strcmp(type, "rtree")) { bbhType = sk_tools::PictureRenderer::kRTree_BBoxHierarchyType; } else if (0 == strcmp(type, "grid")) { if (!gridSupported) { error.printf("'--bbh grid' is not compatible with --mode=%s.\n", mode); return NULL; } bbhType = sk_tools::PictureRenderer::kTileGrid_BBoxHierarchyType; if (FLAGS_bbh.count() != 3) { error.printf("--bbh grid requires a width and a height.\n"); return NULL; } int gridWidth = atoi(FLAGS_bbh[1]); int gridHeight = atoi(FLAGS_bbh[2]); renderer->setGridSize(gridWidth, gridHeight); } else { error.printf("%s is not a valid value for --bbhType\n", type); return NULL; } if (FLAGS_pipe && sk_tools::PictureRenderer::kNone_BBoxHierarchyType != bbhType) { error.printf("--pipe and --bbh cannot be used together\n"); return NULL; } } renderer->setBBoxHierarchyType(bbhType); renderer->setScaleFactor(SkDoubleToScalar(FLAGS_scale)); return renderer.detach(); }
sk_tools::PictureRenderer* parseRenderer(SkString& error, PictureTool tool) { error.reset(); bool useTiles = false; const char* widthString = NULL; const char* heightString = NULL; bool isPowerOf2Mode = false; bool isCopyMode = false; const char* mode = NULL; #if SK_SUPPORT_GPU GrContextOptions grContextOpts; grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks; #define RENDERER_ARGS (grContextOpts) #else #define RENDERER_ARGS () #endif SkAutoTUnref<sk_tools::PictureRenderer> renderer; if (FLAGS_mode.count() >= 1) { mode = FLAGS_mode[0]; if (0 == strcmp(mode, "record")) { renderer.reset(SkNEW_ARGS(sk_tools::RecordPictureRenderer, RENDERER_ARGS)); } else if (0 == strcmp(mode, "tile") || 0 == strcmp(mode, "pow2tile") || 0 == strcmp(mode, "copyTile")) { useTiles = true; if (0 == strcmp(mode, "pow2tile")) { isPowerOf2Mode = true; } else if (0 == strcmp(mode, "copyTile")) { isCopyMode = true; } if (FLAGS_mode.count() < 2) { error.printf("Missing width for --mode %s\n", mode); return NULL; } widthString = FLAGS_mode[1]; if (FLAGS_mode.count() < 3) { error.printf("Missing height for --mode %s\n", mode); return NULL; } heightString = FLAGS_mode[2]; } else if (0 == strcmp(mode, "playbackCreation") && kBench_PictureTool == tool) { renderer.reset(SkNEW_ARGS(sk_tools::PlaybackCreationRenderer, RENDERER_ARGS)); // undocumented } else if (0 == strcmp(mode, "rerecord") && kRender_PictureTool == tool) { renderer.reset(SkNEW_ARGS(sk_tools::RecordPictureRenderer, RENDERER_ARGS)); } else if (0 == strcmp(mode, "simple")) { // Allow 'mode' to be set to 'simple', but do not create a renderer, so we can // ensure that pipe does not override a mode besides simple. The renderer will // be created below. } else { error.printf("%s is not a valid mode for --mode\n", mode); return NULL; } } if (useTiles) { SkASSERT(NULL == renderer); SkAutoTUnref<sk_tools::TiledPictureRenderer> tiledRenderer; if (isCopyMode) { int xTiles = -1; int yTiles = -1; if (FLAGS_tiles.count() > 0) { if (FLAGS_tiles.count() != 2) { error.printf("--tiles requires an x value and a y value.\n"); return NULL; } xTiles = atoi(FLAGS_tiles[0]); yTiles = atoi(FLAGS_tiles[1]); } int x, y; if (xTiles != -1 && yTiles != -1) { x = xTiles; y = yTiles; if (x <= 0 || y <= 0) { error.printf("--tiles must be given values > 0\n"); return NULL; } } else { x = y = 4; } #if SK_SUPPORT_GPU tiledRenderer.reset(SkNEW_ARGS(sk_tools::CopyTilesRenderer, (grContextOpts, x, y))); #else tiledRenderer.reset(SkNEW_ARGS(sk_tools::CopyTilesRenderer, (x, y))); #endif } else { tiledRenderer.reset(SkNEW_ARGS(sk_tools::TiledPictureRenderer, RENDERER_ARGS)); } if (isPowerOf2Mode) { int minWidth = atoi(widthString); if (!SkIsPow2(minWidth) || minWidth < 0) { SkString err; error.printf("-mode %s must be given a width" " value that is a power of two\n", mode); return NULL; } tiledRenderer->setTileMinPowerOf2Width(minWidth); } else if (sk_tools::is_percentage(widthString)) { if (isCopyMode) { error.printf("--mode %s does not support percentages.\n", mode); return NULL; } tiledRenderer->setTileWidthPercentage(atof(widthString)); if (!(tiledRenderer->getTileWidthPercentage() > 0)) { error.printf("--mode %s must be given a width percentage > 0\n", mode); return NULL; } } else { tiledRenderer->setTileWidth(atoi(widthString)); if (!(tiledRenderer->getTileWidth() > 0)) { error.printf("--mode %s must be given a width > 0\n", mode); return NULL; } } if (sk_tools::is_percentage(heightString)) { if (isCopyMode) { error.printf("--mode %s does not support percentages.\n", mode); return NULL; } tiledRenderer->setTileHeightPercentage(atof(heightString)); if (!(tiledRenderer->getTileHeightPercentage() > 0)) { error.printf("--mode %s must be given a height percentage > 0\n", mode); return NULL; } } else { tiledRenderer->setTileHeight(atoi(heightString)); if (!(tiledRenderer->getTileHeight() > 0)) { SkString err; error.printf("--mode %s must be given a height > 0\n", mode); return NULL; } } renderer.reset(tiledRenderer.detach()); if (FLAGS_pipe) { error.printf("Pipe rendering is currently not compatible with tiling.\n" "Turning off pipe.\n"); } } else { // useTiles if (FLAGS_pipe) { if (renderer != NULL) { error.printf("Pipe is incompatible with other modes.\n"); return NULL; } renderer.reset(SkNEW_ARGS(sk_tools::PipePictureRenderer, RENDERER_ARGS)); } } if (NULL == renderer) { renderer.reset(SkNEW_ARGS(sk_tools::SimplePictureRenderer, RENDERER_ARGS)); } if (FLAGS_viewport.count() > 0) { if (FLAGS_viewport.count() != 2) { error.printf("--viewport requires a width and a height.\n"); return NULL; } SkISize viewport; viewport.fWidth = atoi(FLAGS_viewport[0]); viewport.fHeight = atoi(FLAGS_viewport[1]); renderer->setViewport(viewport); } sk_tools::PictureRenderer::SkDeviceTypes deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType; #if SK_SUPPORT_GPU GrGLStandard gpuAPI = kNone_GrGLStandard; if (1 == FLAGS_gpuAPI.count()) { if (FLAGS_gpuAPI.contains(kGpuAPINameGL)) { gpuAPI = kGL_GrGLStandard; } else if (FLAGS_gpuAPI.contains(kGpuAPINameGLES)) { gpuAPI = kGLES_GrGLStandard; } else { error.printf("--gpuAPI invalid api value.\n"); return NULL; } } else if (FLAGS_gpuAPI.count() > 1) { error.printf("--gpuAPI invalid api value.\n"); return NULL; } int sampleCount = 0; bool useDFText = false; #endif if (FLAGS_config.count() > 0) { if (0 == strcmp(FLAGS_config[0], "8888")) { deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType; } #if SK_SUPPORT_GPU else if (0 == strcmp(FLAGS_config[0], "gpu")) { deviceType = sk_tools::PictureRenderer::kGPU_DeviceType; } else if (0 == strcmp(FLAGS_config[0], "msaa4")) { deviceType = sk_tools::PictureRenderer::kGPU_DeviceType; sampleCount = 4; } else if (0 == strcmp(FLAGS_config[0], "msaa16")) { deviceType = sk_tools::PictureRenderer::kGPU_DeviceType; sampleCount = 16; } else if (0 == strcmp(FLAGS_config[0], "nvprmsaa4")) { deviceType = sk_tools::PictureRenderer::kNVPR_DeviceType; sampleCount = 4; } else if (0 == strcmp(FLAGS_config[0], "nvprmsaa16")) { deviceType = sk_tools::PictureRenderer::kNVPR_DeviceType; sampleCount = 16; } else if (0 == strcmp(FLAGS_config[0], "gpudft")) { deviceType = sk_tools::PictureRenderer::kGPU_DeviceType; useDFText = true; } #if SK_ANGLE else if (0 == strcmp(FLAGS_config[0], "angle")) { deviceType = sk_tools::PictureRenderer::kAngle_DeviceType; } #endif #if SK_MESA else if (0 == strcmp(FLAGS_config[0], "mesa")) { deviceType = sk_tools::PictureRenderer::kMesa_DeviceType; } #endif #endif else { error.printf("%s is not a valid mode for --config\n", FLAGS_config[0]); return NULL; } #if SK_SUPPORT_GPU if (!renderer->setDeviceType(deviceType, gpuAPI)) { #else if (!renderer->setDeviceType(deviceType)) { #endif error.printf("Could not create backend for --config %s\n", FLAGS_config[0]); return NULL; } #if SK_SUPPORT_GPU renderer->setSampleCount(sampleCount); renderer->setUseDFText(useDFText); #endif } sk_tools::PictureRenderer::BBoxHierarchyType bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType; if (FLAGS_bbh.count() > 0) { const char* type = FLAGS_bbh[0]; if (0 == strcmp(type, "none")) { bbhType = sk_tools::PictureRenderer::kNone_BBoxHierarchyType; } else if (0 == strcmp(type, "rtree")) { bbhType = sk_tools::PictureRenderer::kRTree_BBoxHierarchyType; } else { error.printf("%s is not a valid value for --bbhType\n", type); return NULL; } if (FLAGS_pipe && sk_tools::PictureRenderer::kNone_BBoxHierarchyType != bbhType) { error.printf("--pipe and --bbh cannot be used together\n"); return NULL; } } renderer->setBBoxHierarchyType(bbhType); renderer->setScaleFactor(SkDoubleToScalar(FLAGS_scale)); return renderer.detach(); }