SkPicture* onNewPictureSnapshot() override { SkBigPicture::SnapshotArray* pictList = NULL; if (fDrawableList) { // TODO: should we plumb-down the BBHFactory and recordFlags from our host // PictureRecorder? pictList = fDrawableList->newDrawableSnapshot(); } SkAutoTUnref<SkLayerInfo> saveLayerData; if (fBBH && fDoSaveLayerInfo) { saveLayerData.reset(SkNEW(SkLayerInfo)); SkBBoxHierarchy* bbh = NULL; // we've already computed fBBH (received in constructor) // TODO: update saveLayer info computation to reuse the already computed // bounds in 'fBBH' SkRecordComputeLayers(fBounds, *fRecord, pictList, bbh, saveLayerData); } size_t subPictureBytes = 0; for (int i = 0; pictList && i < pictList->count(); i++) { subPictureBytes += SkPictureUtils::ApproximateBytesUsed(pictList->begin()[i]); } // SkBigPicture will take ownership of a ref on both fRecord and fBBH. // We're not willing to give up our ownership, so we must ref them for SkPicture. return SkNEW_ARGS(SkBigPicture, (fBounds, SkRef(fRecord.get()), pictList, SkSafeRef(fBBH.get()), saveLayerData.detach(), subPictureBytes)); }
SkPicture* SkPictureRecorder::endRecordingAsPicture() { fActivelyRecording = false; fRecorder->restoreToCount(1); // If we were missing any restores, add them now. if (fRecord->count() == 0) { return fMiniRecorder.detachAsPicture(fCullRect); } // TODO: delay as much of this work until just before first playback? SkRecordOptimize(fRecord); SkAutoTUnref<SkLayerInfo> saveLayerData; if (fBBH && (fFlags & kComputeSaveLayerInfo_RecordFlag)) { saveLayerData.reset(SkNEW(SkLayerInfo)); } SkDrawableList* drawableList = fRecorder->getDrawableList(); SkBigPicture::SnapshotArray* pictList = drawableList ? drawableList->newDrawableSnapshot() : NULL; if (fBBH.get()) { if (saveLayerData) { SkRecordComputeLayers(fCullRect, *fRecord, pictList, fBBH.get(), saveLayerData); } else { SkRecordFillBounds(fCullRect, *fRecord, fBBH.get()); } SkRect bbhBound = fBBH->getRootBound(); SkASSERT((bbhBound.isEmpty() || fCullRect.contains(bbhBound)) || (bbhBound.isEmpty() && fCullRect.isEmpty())); fCullRect = bbhBound; } size_t subPictureBytes = fRecorder->approxBytesUsedBySubPictures(); for (int i = 0; pictList && i < pictList->count(); i++) { subPictureBytes += SkPictureUtils::ApproximateBytesUsed(pictList->begin()[i]); } return SkNEW_ARGS(SkBigPicture, (fCullRect, fRecord.detach(), pictList, fBBH.detach(), saveLayerData.detach(), subPictureBytes)); }
SkCanvas* PictureRenderer::setupCanvas(int width, int height) { SkAutoTUnref<SkCanvas> canvas; switch(fDeviceType) { case kBitmap_DeviceType: { SkBitmap bitmap; sk_tools::setup_bitmap(&bitmap, width, height); canvas.reset(SkNEW_ARGS(SkCanvas, (bitmap))); } break; #if SK_SUPPORT_GPU #if SK_ANGLE case kAngle_DeviceType: // fall through #endif #if SK_MESA case kMesa_DeviceType: // fall through #endif case kGPU_DeviceType: case kNVPR_DeviceType: { SkAutoTUnref<GrSurface> target; if (fGrContext) { // create a render target to back the device GrSurfaceDesc desc; desc.fConfig = kSkia8888_GrPixelConfig; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fWidth = width; desc.fHeight = height; desc.fSampleCnt = fSampleCount; target.reset(fGrContext->textureProvider()->createTexture(desc, false, NULL, 0)); } uint32_t flags = fUseDFText ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0; SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); SkAutoTUnref<SkGpuDevice> device( SkGpuDevice::Create(target->asRenderTarget(), &props, SkGpuDevice::kUninit_InitContents)); if (!device) { return NULL; } canvas.reset(SkNEW_ARGS(SkCanvas, (device))); break; } #endif default: SkASSERT(0); return NULL; } if (fHasDrawFilters) { if (fDrawFilters[0] & PictureRenderer::kAAClip_DrawFilterFlag) { canvas->setAllowSoftClip(false); } canvas.reset(SkNEW_ARGS(FlagsFilterCanvas, (canvas.get(), fDrawFilters))); } this->scaleToScaleFactor(canvas); // Pictures often lie about their extent (i.e., claim to be 100x100 but // only ever draw to 90x100). Clear here so the undrawn portion will have // a consistent color canvas->clear(SK_ColorTRANSPARENT); return canvas.detach(); }
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(); }
SkImageFilter* SkiaImageFilterBuilder::build(const FilterOperations& operations) { SkAutoTUnref<SkImageFilter> filter; SkScalar matrix[20]; for (size_t i = 0; i < operations.size(); ++i) { const FilterOperation& op = *operations.at(i); switch (op.getOperationType()) { case FilterOperation::REFERENCE: { FilterEffect* filterEffect = static_cast<const ReferenceFilterOperation*>(&op)->filterEffect(); // FIXME: hook up parent filter to image source filter.reset(SkiaImageFilterBuilder::build(filterEffect)); break; } case FilterOperation::GRAYSCALE: { float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount(); getGrayscaleMatrix(1 - amount, matrix); filter.reset(createMatrixImageFilter(matrix, filter)); break; } case FilterOperation::SEPIA: { float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount(); getSepiaMatrix(1 - amount, matrix); filter.reset(createMatrixImageFilter(matrix, filter)); break; } case FilterOperation::SATURATE: { float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount(); getSaturateMatrix(amount, matrix); filter.reset(createMatrixImageFilter(matrix, filter)); break; } case FilterOperation::HUE_ROTATE: { float amount = static_cast<const BasicColorMatrixFilterOperation*>(&op)->amount(); getHueRotateMatrix(amount, matrix); filter.reset(createMatrixImageFilter(matrix, filter)); break; } case FilterOperation::INVERT: { float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount(); getInvertMatrix(amount, matrix); filter.reset(createMatrixImageFilter(matrix, filter)); break; } case FilterOperation::OPACITY: { float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount(); getOpacityMatrix(amount, matrix); filter.reset(createMatrixImageFilter(matrix, filter)); break; } case FilterOperation::BRIGHTNESS: { float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount(); getBrightnessMatrix(amount, matrix); filter.reset(createMatrixImageFilter(matrix, filter)); break; } case FilterOperation::CONTRAST: { float amount = static_cast<const BasicComponentTransferFilterOperation*>(&op)->amount(); getContrastMatrix(amount, matrix); filter.reset(createMatrixImageFilter(matrix, filter)); break; } case FilterOperation::BLUR: { float pixelRadius = static_cast<const BlurFilterOperation*>(&op)->stdDeviation().getFloatValue(); filter.reset(new SkBlurImageFilter(pixelRadius, pixelRadius, filter)); break; } case FilterOperation::DROP_SHADOW: { const DropShadowFilterOperation* drop = static_cast<const DropShadowFilterOperation*>(&op); filter.reset(new DropShadowImageFilter(SkIntToScalar(drop->x()), SkIntToScalar(drop->y()), SkIntToScalar(drop->stdDeviation()), drop->color().rgb(), filter)); break; } case FilterOperation::VALIDATED_CUSTOM: case FilterOperation::CUSTOM: // Not supported. case FilterOperation::PASSTHROUGH: case FilterOperation::NONE: break; } } return filter.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(); }