76#if defined(SK_BUILD_FOR_WIN)
82#include <XpsObjectModel.h>
85#if defined(SK_ENABLE_SKOTTIE)
90#if defined(SK_ENABLE_SVG)
97#if defined(SK_GRAPHITE)
109#if defined(SK_ENABLE_PRECOMPILE)
124#if defined(SK_ENABLE_ANDROID_UTILS)
134static DEFINE_bool(RAW_threading,
true,
"Allow RAW decodes to run on multiple threads?");
147 std::unique_ptr<skiagm::GM> gm(fFactory());
148 if (gm->isBazelOnly()) {
156 switch (gpuSetupResult) {
164 switch (drawResult) {
176 std::unique_ptr<skiagm::GM> gm(fFactory());
177 return gm->getISize();
181 std::unique_ptr<skiagm::GM> gm(fFactory());
182 return gm->getName();
186 std::unique_ptr<skiagm::GM> gm(fFactory());
187 gm->modifyGrContextOptions(
options);
190#if defined(SK_GRAPHITE)
192 std::unique_ptr<skiagm::GM> gm(fFactory());
193 gm->modifyGraphiteContextOptions(
options);
203#ifdef SK_ENABLE_ANDROID_UTILS
207 , fDstColorType(dstColorType)
208 , fSampleSize(sampleSize)
211bool BRDSrc::veto(SinkFlags
flags)
const {
214 ||
flags.approach != SinkFlags::kDirect;
217static std::unique_ptr<android::skia::BitmapRegionDecoder> create_brd(
Path path) {
235 CodecSrc::kGetFromCanvas_DstColorType != fDstColorType)
237 return Result::Skip(
"Testing non-565 to 565 is uninteresting.");
239 switch (fDstColorType) {
240 case CodecSrc::kGetFromCanvas_DstColorType:
242 case CodecSrc::kGrayscale_Always_DstColorType:
250 auto brd = create_brd(
fPath);
251 if (
nullptr == brd) {
252 return Result::Skip(
"Could not create brd for %s.",
fPath.c_str());
255 auto recommendedCT = brd->computeOutputColorType(
colorType);
257 return Result::Skip(
"Skip decoding non-opaque to 565.");
261 auto colorSpace = brd->computeOutputColorSpace(
colorType,
nullptr);
263 const uint32_t
width = brd->width();
264 const uint32_t
height = brd->height();
266 if ((
width / fSampleSize <= 10 ||
height / fSampleSize <= 10) && 1 != fSampleSize) {
267 return Result::Skip(
"Scaling very small images is uninteresting.");
270 case kFullImage_Mode: {
273 fSampleSize,
colorType,
false, colorSpace)) {
281 case kDivisor_Mode: {
282 const uint32_t divisor = 2;
284 return Result::Skip(
"Divisor is larger than image dimension.");
292 const uint32_t scaledBorder =
std::min(5u, maxBorder);
293 const uint32_t unscaledBorder = scaledBorder * fSampleSize;
308 for (uint32_t
x = 0;
x < divisor;
x++) {
309 for (uint32_t
y = 0;
y < divisor;
y++) {
311 uint32_t subsetWidth =
width / divisor;
312 uint32_t subsetHeight =
height / divisor;
313 const int left =
x * subsetWidth;
314 const int top =
y * subsetHeight;
318 subsetWidth += (
x + 1 == divisor) ? (
width % divisor) : 0;
319 subsetHeight += (
y + 1 == divisor) ? (
height % divisor) : 0;
322 const int decodeLeft =
left - unscaledBorder;
323 const int decodeTop = top - unscaledBorder;
324 const uint32_t decodeWidth = subsetWidth + unscaledBorder * 2;
325 const uint32_t decodeHeight = subsetHeight + unscaledBorder * 2;
328 decodeTop, decodeWidth, decodeHeight), fSampleSize,
colorType,
false,
336 (
SkScalar) (subsetWidth / fSampleSize),
337 (
SkScalar) (subsetHeight / fSampleSize)),
340 (
SkScalar) (subsetWidth / fSampleSize),
341 (
SkScalar) (subsetHeight / fSampleSize)),
355 auto brd = create_brd(
fPath);
357 return {
std::max(1, brd->width() / (
int)fSampleSize),
358 std::max(1, brd->height() / (
int)fSampleSize)};
366 if (1 == fSampleSize) {
377 if (!FLAGS_RAW_threading) {
378 static const char*
const exts[] = {
379 "arw",
"cr2",
"dng",
"nef",
"nrw",
"orf",
"raf",
"rw2",
"pef",
"srw",
380 "ARW",
"CR2",
"DNG",
"NEF",
"NRW",
"ORF",
"RAF",
"RW2",
"PEF",
"SRW",
382 const char* actualExt = strrchr(
path.c_str(),
'.');
385 for (
auto*
ext : exts) {
386 if (0 == strcmp(
ext, actualExt)) {
399 , fDstColorType(dstColorType)
400 , fDstAlphaType(dstAlphaType)
416 for (
int y = 0;
y <
bitmap.height();
y++) {
417 uint32_t* row = (uint32_t*)
bitmap.getAddr(0,
y);
424 switch (dstColorType) {
436#ifdef SK_PMCOLOR_IS_RGBA
481 if (
nullptr == codec) {
494 std::unique_ptr<SkAndroidCodec> androidCodec;
497 size = androidCodec->getSampledDimensions(1 / fScale);
501 return Result::Skip(
"Test without scaling is uninteresting.");
507 return Result::Skip(
"Scaling very small images is uninteresting.");
512 const size_t rowBytes =
size.
width() * bpp;
532 if (fScale != 1.0f) {
535 auto dims = androidCodec->getSampledDimensions(androidOptions.
fSampleSize);
539 std::vector<SkCodec::FrameInfo> frameInfos = androidCodec
540 ? androidCodec->codec()->getFrameInfo() : codec->getFrameInfo();
541 if (frameInfos.size() <= 1) {
548 const float root =
sqrt((
float) frameInfos.size());
554 for (
int i = 0;
static_cast<size_t>(
i) < frameInfos.size();
i++) {
557 const int reqFrame = frameInfos[
i].fRequiredFrame;
559 && priorFramePixels.
get()) {
561 memcpy(pixels.
get(), priorFramePixels.
get(), safeSize);
567 ? androidCodec->getAndroidPixels(decodeInfo, pixels.
get(), rowBytes,
569 : codec->getPixels(decodeInfo, pixels.
get(), rowBytes, &androidOptions);
585 if (
static_cast<size_t>(
i+1) < frameInfos.size()
586 && frameInfos[
i+1].fRequiredFrame ==
i) {
587 memcpy(priorFramePixels.
reset(safeSize), pixels.
get(), safeSize);
592 const int xTranslate = (
i % factor) * decodeInfo.
width();
593 const int yTranslate = (
i / factor) * decodeInfo.
height();
604 "Cannot decode frame %i to 565 (%s).",
i, fPath.
c_str());
609 "Couldn't getPixels for frame %i in %s.",
i, fPath.
c_str());
616 switch (codec->getPixels(decodeInfo, pixels.
get(), rowBytes, &
options)) {
634 const bool useIncremental = [
this]() {
635 auto exts = {
"png",
"PNG",
"gif",
"GIF" };
636 for (
auto ext : exts) {
645 const bool ico = fPath.
endsWith(
"ico");
646 bool useOldScanlineMethod = !useIncremental && !ico;
647 if (useIncremental || ico) {
651 auto result = codec->incrementalDecode(&rowsDecoded);
653 codec->fillIncompleteImage(decodeInfo,
dst, rowBytes,
658 if (useIncremental) {
664 useOldScanlineMethod =
true;
668 if (useOldScanlineMethod) {
675 codec->getScanlines(
dst,
height, rowBytes);
685 const int stripeHeight = 37;
686 const int numStripes = (
height + stripeHeight - 1) / stripeHeight;
700 for (
int i = 0;
i < numStripes;
i += 2) {
702 const int linesToSkip =
std::min(stripeHeight,
height -
i * stripeHeight);
703 codec->skipScanlines(linesToSkip);
706 const int startY = (
i + 1) * stripeHeight;
708 if (linesToRead > 0) {
709 codec->getScanlines(SkTAddOffset<void>(
dst, rowBytes * startY), linesToRead,
715 const SkCodec::Result startResult = codec->startScanlineDecode(decodeInfo);
717 return Result::Fatal(
"Failed to restart scanline decoder with same parameters.");
719 for (
int i = 0;
i < numStripes;
i += 2) {
721 const int startY =
i * stripeHeight;
723 codec->getScanlines(SkTAddOffset<void>(
dst, rowBytes * startY), linesToRead,
727 const int linesToSkip =
std::min(stripeHeight,
height - (
i + 1) * stripeHeight);
728 if (linesToSkip > 0) {
729 codec->skipScanlines(linesToSkip);
742 const int tileSize = 36;
744 for (
int x = 0;
x <
width;
x += tileSize) {
751 codec->getScanlines(SkTAddOffset<void>(pixels.
get(),
x * bpp),
height, rowBytes);
761 const int W = codec->getInfo().width();
762 const int H = codec->getInfo().height();
763 if (divisor >
W || divisor >
H) {
764 return Result::Skip(
"Cannot codec subset: divisor %d is too big "
765 "for %s with dimensions (%d x %d)", divisor,
781 for (
int x = 0;
x <
W;
x +=
w) {
783 for (
int y = 0;
y <
H;
y+=
h) {
787 subset.
setXYWH(
x,
y, preScaleW, preScaleH);
793 decodeInfo = decodeInfo.
makeWH(scaledW, scaledH);
795 size_t subsetRowBytes = subsetBitmapInfo.
minRowBytes();
804 return Result::Fatal(
"subset codec failed to decode (%d, %d, %d, %d) "
805 "from %s with dimensions (%d x %d)\t error %d",
813 top += decodeInfo.
height();
816 left += decodeInfo.
width();
830 if (
nullptr == codec) {
835 return codec->getScaledDimensions(fScale);
841 const size_t count = codec->getFrameInfo().size();
846 auto imageSize = androidCodec->getSampledDimensions(1 / fScale);
847 imageSize.fWidth = imageSize.fWidth * factor;
857 if (1.0f == fScale) {
868 , fDstColorType(dstColorType)
869 , fDstAlphaType(dstAlphaType)
870 , fSampleSize(sampleSize)
886 if (
nullptr == codec) {
897 SkISize size = codec->getSampledDimensions(fSampleSize);
902 return Result::Skip(
"Scaling very small images is uninteresting.");
920 options.fSampleSize = fSampleSize;
922 switch (codec->getAndroidPixels(decodeInfo, pixels.
get(), rowBytes, &
options)) {
937 if (
nullptr == codec) {
940 return codec->getSampledDimensions(fSampleSize);
946 if (1 == fSampleSize) {
957 , fDstAlphaType(alphaType)
974 return Result::Skip(
"Uninteresting to test image generator to 565.");
982#if defined(SK_BUILD_FOR_WIN)
984 SkAutoCoInitialize com;
985 if (!com.succeeded()) {
990 std::unique_ptr<SkImageGenerator>
gen(
nullptr);
995 return Result::Fatal(
"Could not create codec image generator.");
999#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
1000 gen = SkImageGeneratorCG::MakeFromEncodedCG(encoded);
1001#elif defined(SK_BUILD_FOR_WIN)
1002 gen = SkImageGeneratorWIC::MakeFromEncodedWIC(encoded);
1003#elif defined(SK_ENABLE_NDK_IMAGES)
1004 gen = SkImageGeneratorNDK::MakeFromEncodedNDK(encoded);
1007 return Result::Fatal(
"Could not create platform image generator.");
1020 return Result::Fatal(
"Could not create image from codec image generator.");
1027 SkImageInfo decodeInfo =
gen->getInfo().makeAlphaType(fDstAlphaType);
1030 size_t rowBytes = decodeInfo.
width() * bpp;
1032 if (!
gen->getPixels(decodeInfo, pixels.
get(), rowBytes)) {
1034#if defined(SK_BUILD_FOR_WIN)
1054 if (
nullptr == codec) {
1057 return codec->getInfo().dimensions();
1067 , fDecodeToDst(decode_to_dst) {}
1081 if (
nullptr == codec) {
1097 return Result::Skip(
"Skipping decoding without color transform.");
1111 return Result::Skip(
"SkCodec can't decode to this format.");
1120 if (
nullptr == codec) {
1123 return {codec->getInfo().width(), codec->getInfo().height()};
1133 "Width & height of the viewport used to crop skp rendering.");
1138 struct DeserializationContext {
1140#if defined(SK_GRAPHITE)
1145#if defined(SK_GRAPHITE)
1157 DeserializationContext* context =
reinterpret_cast<DeserializationContext*
>(ctx);
1159 if (context->fDirectContext) {
1199 return info.fCullRect;
1224 class PathFindingCanvas :
public SkCanvas {
1244 int start = 0,
end = pathFinder.foundPaths().size();
1245 for (
const char* ch = fTrail.
c_str(); *ch; ++ch) {
1249 }
else if (
'r' == *ch) {
1255 const FoundPath&
path = pathFinder.foundPaths()[
i];
1266#if defined(SK_ENABLE_SKOTTIE)
1268 "Prioritize embedded glyph paths over native fonts.");
1281 static constexpr char kInterceptPrefix[] =
"__";
1282 auto precomp_interceptor =
1283 sk_make_sp<skottie_utils::ExternalAnimationPrecompInterceptor>(resource_provider,
1286 if (FLAGS_useLottieGlyphPaths) {
1292 .setResourceProvider(std::move(resource_provider))
1293 .setPrecompInterceptor(std::move(precomp_interceptor))
1295 .makeFromFile(
fPath.c_str());
1302 const auto t_rate = 1.0f / (kTileCount * kTileCount - 1);
1307 static constexpr int frameOrder[] = { 4, 0, 3, 1, 2 };
1308 static_assert(
std::size(frameOrder) == kTileCount,
"");
1310 for (
int i = 0;
i < kTileCount; ++
i) {
1311 const SkScalar y = frameOrder[
i] * kTileSize;
1313 for (
int j = 0; j < kTileCount; ++j) {
1314 const SkScalar x = frameOrder[j] * kTileSize;
1317 const auto t = t_rate * (frameOrder[
i] * kTileCount + frameOrder[j]);
1324 animation->render(canvas);
1338bool SkottieSrc::veto(SinkFlags
flags)
const {
1349#if defined(SK_ENABLE_SVG)
1351static const SkSize kDefaultSVGSize = {1000, 1000};
1354static const SkSize kMinimumSVGSize = {128, 128};
1374 .setResourceProvider(std::move(rp))
1382 const SkSize& sz = fDom->containerSize();
1385 fDom->setContainerSize(kDefaultSVGSize);
1398 canvas->
scale(fScale, fScale);
1400 fDom->render(canvas);
1410 return SkSize{fDom->containerSize().
width() * fScale, fDom->containerSize().height() * fScale}
1416bool SVGSrc::veto(SinkFlags
flags)
const {
1442 return i >= 0 &&
i < fPages.
size() ? fPages[
i].fSize.toCeil() :
SkISize{0, 0};
1446 return this->
draw(FLAGS_mskpFrame, c, testContext);
1450 return Result::Fatal(
"Unable to parse MultiPictureDocument file: %s", fPath.
c_str());
1452 if (
i >= fPages.
size() ||
i < 0) {
1453 return Result::Fatal(
"MultiPictureDocument page number out of range: %d",
i);
1462 return Result::Fatal(
"SkMultiPictureDocument reader failed on page %d: %s",
i,
1465 page = fPages[
i].fPicture.get();
1490 SkString errString(
"Pixels don't match reference");
1492 errString.
append(
"\nExpected: ");
1493 errString.
append(encoded);
1495 errString.
append(
"\nExpected image failed to encode: ");
1496 errString.
append(encoded);
1499 errString.
append(
"\nActual: ");
1500 errString.
append(encoded);
1502 errString.
append(
"\nActual image failed to encode: ");
1503 errString.
append(encoded);
1512static DEFINE_bool(gpuStats,
false,
"Append GPU stats to the log for each GPU task?");
1514 "Test abandoning the GrContext before running the test.");
1516 "Test abandoning the GrContext after running each test.");
1518 "Test releasing all gpu resources and abandoning the GrContext "
1519 "after running each test");
1520static DEFINE_bool(drawOpClip,
false,
"Clip each GrDrawOp to its device bounds for testing.");
1521static DEFINE_bool(programBinaryCache,
true,
"Use in-memory program binary cache");
1525 : fContextType(config->getContextType())
1526 , fContextOverrides(config->getContextOverrides())
1527 , fSurfType(config->getSurfType())
1528 , fSampleCount(config->getSamples())
1529 , fSurfaceFlags(config->getSurfaceFlags())
1532 , fBaseContextOptions(grCtxOptions) {
1533 if (FLAGS_programBinaryCache) {
1539 return this->
onDraw(src,
dst, dstStream,
log, fBaseContextOptions);
1548 switch (fSurfType) {
1593 src.modifyGrContextOptions(&grOptions);
1600 initContext(direct);
1603 const int maxDimension = direct->priv().caps()->maxTextureSize();
1604 if (maxDimension <
std::max(
src.size().width(),
src.size().height())) {
1605 return Result::Skip(
"Src too large to create a texture.\n");
1612 if (FLAGS_preAbandonGpuContext) {
1616 auto canvas =
surface->getCanvas();
1617 if (wrapCanvas !=
nullptr) {
1618 canvas = wrapCanvas(canvas);
1626 if (FLAGS_gpuStats) {
1627 direct->priv().dumpCacheStats(
log);
1628 direct->priv().dumpGpuStats(
log);
1629 direct->priv().dumpContextStats(
log);
1634 if (FLAGS_abandonGpuContext) {
1636 }
else if (FLAGS_releaseAndAbandonGpuContext) {
1641 direct->storeVkPipelineCacheData();
1659 testCanvas.
init(canvas);
1660 return testCanvas.
get();
1679 testCanvas.
init(canvas);
1680 return testCanvas.
get();
1699 testCanvas.
init(canvas);
1700 return testCanvas.
get();
1708 , fCacheType(config->getTestPersistentCache()) {}
1717 if (fCacheType == 2) {
1730 Result refResult = this->
onDraw(src, &reference, &refStream, &refLog, contextOptions);
1731 if (!refResult.
isOk()) {
1781 Result refResult = this->
onDraw(src, &reference, &refStream, &refLog, replayOptions,
1783 if (!refResult.
isOk()) {
1794 , fRecordingExecutor(
SkExecutor::MakeLIFOThreadPool(1))
1826 sk_sp<SkPicture> newSKP = promiseImageHelper.recreateSKP(dContext, inputPicture.get());
1828 return Result::Fatal(
"GPUDDLSink: Couldn't recreate the SKP");
1839 promiseImageHelper.uploadAllToGPU(gpuTaskGroup, dContext);
1844 constexpr int kNumDivisions = 3;
1846 kNumDivisions, kNumDivisions,
1849 tiles.createBackendTextures(gpuTaskGroup, dContext);
1851 tiles.kickOffThreadedWork(recordingTaskGroup, gpuTaskGroup, dContext, newSKP.
get());
1856 recordingTaskGroup->
wait();
1860 if (FLAGS_preAbandonGpuContext) {
1868 gpuTaskGroup->
add([dstSurface, ddl =
tiles.composeDDL()]() {
1869 skgpu::ganesh::DrawDDL(dstSurface, ddl);
1873 gpuTaskGroup->
add([dContext]() {
1886 promiseImageHelper.deleteAllFromGPU(gpuTaskGroup, dContext);
1888 tiles.deleteBackendTextures(gpuTaskGroup, dContext);
1895 gpuTaskGroup->
wait();
1916 SkASSERT(mainCtx->priv().getGpu());
1929 SkASSERT(otherCtx->priv().getGpu());
1932 SkTaskGroup recordingTaskGroup(*fRecordingExecutor);
1944 mainTestCtx, mainCtx);
1952 if (FLAGS_gpuStats) {
1953 mainCtx->priv().dumpCacheStats(
log);
1954 mainCtx->priv().dumpGpuStats(
log);
1955 mainCtx->priv().dumpContextStats(
log);
1958 otherCtx->priv().dumpCacheStats(
log);
1959 otherCtx->priv().dumpGpuStats(
log);
1960 otherCtx->priv().dumpContextStats(
log);
1973 if (
src.size().isEmpty()) {
1977 int pageCount =
src.pageCount();
1978 for (
int i = 0;
i < pageCount; ++
i) {
1983 return Result::Fatal(
"SkDocument::beginPage(w,h) returned nullptr");
1999 metadata.
fSubject =
"rendering correctness test";
2004#if SK_PDF_TEST_EXECUTOR
2010 return Result::Fatal(
"SkPDF::MakeDocument() returned nullptr");
2019#if defined(SK_SUPPORT_XPS)
2020static SkTScopedComPtr<IXpsOMObjectFactory> make_xps_factory() {
2021 IXpsOMObjectFactory* factory;
2022 HRN(CoCreateInstance(CLSID_XpsOMObjectFactory,
2024 CLSCTX_INPROC_SERVER,
2025 IID_PPV_ARGS(&factory)));
2026 return SkTScopedComPtr<IXpsOMObjectFactory>(factory);
2030 SkAutoCoInitialize com;
2031 if (!com.succeeded()) {
2034 SkTScopedComPtr<IXpsOMObjectFactory> factory = make_xps_factory();
2040 return Result::Fatal(
"SkXPS::MakeDocument() returned nullptr");
2046 return Result::Fatal(
"XPS not supported on this platform.");
2087 debugCanvas.
toJSON(writer, dataManager, nullCanvas.get());
2098#if defined(SK_ENABLE_SVG)
2099 if (
src.pageCount() > 1) {
2100 int pageCount =
src.pageCount();
2101 if (fPageIndex > pageCount - 1) {
2102 return Result::Fatal(
"Page index %d too high for document with only %d pages.",
2103 fPageIndex, pageCount);
2106 return src.draw(fPageIndex,
2125 if (
size.isEmpty()) {
2135 return src.draw(
surface->getCanvas(),
nullptr);
2140#if defined(SK_GRAPHITE)
2142GraphiteSink::GraphiteSink(
const SkCommandLineConfigGraphite* config)
2143 : fOptions(config->getOptions())
2144 , fContextType(config->getContextType())
2145 , fSurfaceType(config->getSurfaceType())
2158 options.fContextOptions.fOptionsPriv = &optionsPriv;
2160 src.modifyGraphiteContextOptions(&
options.fContextOptions);
2169 std::unique_ptr<skgpu::graphite::Recorder> recorder =
2170 context->
makeRecorder(ToolUtils::CreateTestingRecorderOptions());
2187 if (!
dst->peekPixels(&pm) ||
2188 !
surface->readPixels(pm, 0, 0)) {
2193 std::unique_ptr<skgpu::graphite::Recording> recording = recorder->snap();
2199 info.fRecording = recording.get();
2212 switch (fSurfaceType) {
2216 case SurfaceType::kWrapTextureView:
2217 return sk_gpu_test::MakeBackendTextureViewSurface(recorder,
2228#if defined(SK_ENABLE_PRECOMPILE)
2230GraphitePrecompileTestingSink::GraphitePrecompileTestingSink(
2231 const SkCommandLineConfigGraphite* config) : GraphiteSink(config) {}
2233GraphitePrecompileTestingSink::~GraphitePrecompileTestingSink() {}
2235Result GraphitePrecompileTestingSink::drawSrc(
2240 fRecorder = context->
makeRecorder(ToolUtils::CreateTestingRecorderOptions());
2255 std::unique_ptr<skgpu::graphite::Recording> recording = fRecorder->snap();
2261 info.fRecording = recording.get();
2272Result GraphitePrecompileTestingSink::resetAndRecreatePipelines(
2280 std::vector<skgpu::UniqueKey> origKeys;
2287 context->
priv().globalCache()->resetGraphicsPipelines();
2289 SkASSERT(context->
priv().globalCache()->numGraphicsPipelines() == 0);
2301 Precompile(context, rteDict, pipelineDesc, renderPassDesc);
2306 SkASSERT(numBeforeReset == postRecreate);
2309 std::vector<skgpu::UniqueKey> recreatedKeys;
2314 if(
std::find(recreatedKeys.begin(), recreatedKeys.end(), origKey) ==
2315 recreatedKeys.end()) {
2328 &originalPipelineDesc,
2329 &originalRenderPassDesc);
2331 SkDebugf(
"------- Missing key from rebuilt keys:\n");
2332 origKey.dump(
"original key:");
2333 UniqueKeyUtils::DumpDescs(rendererProvider, dict,
2334 originalPipelineDesc,
2335 originalRenderPassDesc);
2338 SkDebugf(
"Have %d recreated keys -----------------\n", (
int) recreatedKeys.size());
2345 &recreatedPipelineDesc,
2346 &recreatedRenderPassDesc);
2349 recreatedKey.dump(
"recreated key:");
2350 UniqueKeyUtils::DumpDescs(rendererProvider, dict,
2351 recreatedPipelineDesc,
2352 recreatedRenderPassDesc);
2373 options.fContextOptions.fOptionsPriv = &optionsPriv;
2375 src.modifyGraphiteContextOptions(&
options.fContextOptions);
2396 result = this->resetAndRecreatePipelines(context);
2429 class ProxySrc :
public Src {
2433 return fDraw(canvas, testContext);
2435 Name name()
const override {
return "ProxySrc"; }
2446static DEFINE_bool(
check,
true,
"If true, have most Via- modes fail if they affect the output.");
2452 if (FLAGS_check &&
bitmap) {
2484 canvas->concat(matrix);
2485 return src.draw(canvas, testContext);
2544 canvas->drawPicture(deserialized);
2545 return Result::Ok();
2560 SkPictureRecorder recorder;
2561 sk_sp<SkPicture> pic;
2562 Result result = src.draw(recorder.beginRecording(SkIntToScalar(size.width()),
2563 SkIntToScalar(size.height())),
2565 if (!result.isOk()) {
2568 pic = recorder.finishRecordingAsPicture();
2591 if (std::optional<SkBlendMode>
mode =
paint.asBlendMode()) {
2603 RuntimeBlendFilterCanvas runtimeBlendCanvas{canvas};
2604 return src.draw(&runtimeBlendCanvas, testContext);
2614 [&](
SkCanvas* canvas, Src::GraphiteTestContext* testContext) -> Result {
2615 SkDynamicMemoryWStream wstream;
2616 SkXMLStreamWriter writer(&wstream);
2617 Result result = src.draw(SkSVGCanvas::Make(SkRect::Make(size), &writer).get(),
2619 if (!result.isOk()) {
2629 std::unique_ptr<SkStream> rstream(wstream.detachAsStream());
2636 dom->render(canvas);
2638 return Result::Ok();
static DEFINE_bool(RAW_threading, true, "Allow RAW decodes to run on multiple threads?")
static DEFINE_int(mskpFrame, 0, "Which MSKP frame to draw?")
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
for(const auto glyph :glyphs)
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
static GrDirectContext * GrAsDirectContext(GrContext_Base *base)
@ kBottomLeft_GrSurfaceOrigin
@ kTopLeft_GrSurfaceOrigin
#define check(reporter, ref, unref, make, kill)
sk_sp< SkBlender > GetRuntimeBlendForBlendMode(SkBlendMode mode)
static constexpr T SkAlign2(T x)
@ kOpaque_SkAlphaType
pixel is opaque
#define SK_ABORT(message,...)
#define SkASSERT_RELEASE(cond)
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
constexpr SkColor SK_ColorWHITE
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static bool SkEncodedOriginSwapsWidthHeight(SkEncodedOrigin origin)
#define sk_float_ceil2int(x)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static SkImage_Base * as_IB(SkImage *image)
SK_API std::unique_ptr< SkCanvas > SkMakeNullCanvas()
bool SkPicture_StreamIsSKP(SkStream *stream, SkPictInfo *pInfo)
static bool left(const SkPoint &p0, const SkPoint &p1)
#define INHERITED(method,...)
static SkScalar SkScalarSignAsScalar(SkScalar x)
#define SkScalarRoundToInt(x)
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
int find(T *array, int N, T item)
SkISize size() const override
AndroidCodecSrc(Path, CodecSrc::DstColorType, SkAlphaType, int sampleSize)
bool veto(SinkFlags) const override
Result draw(SkCanvas *, GraphiteTestContext *) const override
Name name() const override
Result draw(SkCanvas *, GraphiteTestContext *) const override
BisectSrc(Path path, const char *trail)
bool veto(SinkFlags) const override
SkISize size() const override
@ kGetFromCanvas_DstColorType
@ kGrayscale_Always_DstColorType
@ kNonNative8888_Always_DstColorType
Name name() const override
Result draw(SkCanvas *, GraphiteTestContext *) const override
Result draw(SkCanvas *, GraphiteTestContext *) const override
Name name() const override
bool veto(SinkFlags) const override
ColorCodecSrc(Path, bool decode_to_dst)
SkISize size() const override
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
Name name() const override
Result draw(SkCanvas *, GraphiteTestContext *) const override
void modifyGrContextOptions(GrContextOptions *options) const override
SkISize size() const override
GPUDDLSink(const SkCommandLineConfigGpu *, const GrContextOptions &)
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
GPUPersistentCacheTestingSink(const SkCommandLineConfigGpu *, const GrContextOptions &)
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
GPUPrecompileTestingSink(const SkCommandLineConfigGpu *, const GrContextOptions &)
GPURemoteSlugSink(const SkCommandLineConfigGpu *, const GrContextOptions &)
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
GPUSerializeSlugSink(const SkCommandLineConfigGpu *, const GrContextOptions &)
const sk_gpu_test::GrContextFactory::ContextOverrides & contextOverrides() const
GPUSink(const SkCommandLineConfigGpu *, const GrContextOptions &)
skgpu::ContextType contextType() const
Result onDraw(const Src &, SkBitmap *, SkWStream *, SkString *, const GrContextOptions &baseOptions, std::function< void(GrDirectContext *)> initContext=nullptr, std::function< SkCanvas *(SkCanvas *)> wrapCanvas=nullptr) const
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
const GrContextOptions & baseContextOptions() const
bool readBack(SkSurface *, SkBitmap *dst) const
SkColorInfo colorInfo() const override
sk_sp< SkSurface > createDstSurface(GrDirectContext *, SkISize size) const
GPUSlugSink(const SkCommandLineConfigGpu *, const GrContextOptions &)
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
bool veto(SinkFlags) const override
Name name() const override
ImageGenSrc(Path, Mode, SkAlphaType, bool)
SkISize size() const override
Result draw(SkCanvas *, GraphiteTestContext *) const override
SkISize size() const override
Result draw(SkCanvas *c, GraphiteTestContext *) const override
int pageCount() const override
Name name() const override
Result draw(const Src &src, SkBitmap *, SkWStream *, SkString *) const override
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
SkColorInfo colorInfo() const override
static Result Skip(const char *fmt,...) SK_PRINTF_LIKE(1
static Result Fatal(const char *fmt,...) SK_PRINTF_LIKE(1
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
Name name() const override
Result draw(SkCanvas *, GraphiteTestContext *) const override
SkISize size() const override
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
ViaMatrix(SkMatrix, Sink *)
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
ViaUpright(SkMatrix, Sink *)
std::unique_ptr< Sink > fSink
Result draw(const Src &, SkBitmap *, SkWStream *, SkString *) const override
void toJSON(SkJSONWriter &writer, UrlDataManager &urlDataManager, SkCanvas *)
bool submit(GrSyncCpu sync=GrSyncCpu::kNo)
GrSemaphoresSubmitted flush(const GrFlushInfo &info)
void abandonContext() override
static std::unique_ptr< SkAndroidCodec > MakeFromData(sk_sp< SkData >, SkPngChunkReader *=nullptr)
static std::unique_ptr< SkAndroidCodec > MakeFromCodec(std::unique_ptr< SkCodec >)
void * reset(size_t size=0, OnShrink shrink=kAlloc_OnShrink)
void allocPixels(const SkImageInfo &info, size_t rowBytes)
size_t computeByteSize() const
@ kZeroPixels_AllocFlag
zero pixel memory. No effect. This is the default.
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void translate(SkScalar dx, SkScalar dy)
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
virtual GrRecordingContext * recordingContext() const
virtual skgpu::graphite::Recorder * recorder() const
virtual SkISize getBaseLayerSize() const
@ kStrict_SrcRectConstraint
sample only inside bounds; slower
void clear(SkColor color)
void drawImageRect(const SkImage *, const SkRect &src, const SkRect &dst, const SkSamplingOptions &, const SkPaint *, SrcRectConstraint)
void drawPath(const SkPath &path, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
void concat(const SkMatrix &matrix)
void drawPicture(const SkPicture *picture)
SkImageInfo imageInfo() const
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY)
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
static std::unique_ptr< SkImageGenerator > MakeFromEncodedCodec(sk_sp< SkData >, std::optional< SkAlphaType >=std::nullopt)
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
@ kTopDown_SkScanlineOrder
static constexpr int kNoFrame
static sk_sp< SkColorSpace > MakeSRGB()
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
static sk_sp< SkData > MakeFromFileName(const char path[])
SkCanvas * beginPage(SkScalar width, SkScalar height, const SkRect *content=nullptr)
static std::unique_ptr< SkExecutor > MakeFIFOThreadPool(int threads=0, bool allowBorrowing=true)
sk_sp< SkImage > makeRasterImage(GrDirectContext *, CachingHint cachingHint=kDisallow_CachingHint) const
void beginObject(const char *name=nullptr, bool multiline=true)
static SkMatrix RectToRect(const SkRect &src, const SkRect &dst, ScaleToFit mode=kFill_ScaleToFit)
SkScalar getSkewY() const
SkMatrix & setSkewX(SkScalar v)
@ kCenter_ScaleToFit
scales and aligns to center
SkScalar getSkewX() const
bool invert(SkMatrix *inverse) const
bool rectStaysRect() const
SkScalar getScaleX() const
static const SkMatrix & I()
SkScalar getScaleY() const
SkMatrix & setScaleY(SkScalar v)
SkMatrix & setSkewY(SkScalar v)
SkMatrix & setScaleX(SkScalar v)
static SkString Basename(const char *fullPath)
static SkString Dirname(const char *fullPath)
SkPaintFilterCanvas(SkCanvas *canvas)
virtual bool onFilter(SkPaint &paint) const =0
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
sk_sp< SkData > serialize(const SkSerialProcs *procs=nullptr) const
static sk_sp< SkPicture > MakeFromData(const SkData *data, const SkDeserialProcs *procs=nullptr)
static sk_sp< SkPicture > MakeFromStream(SkStream *stream, const SkDeserialProcs *procs=nullptr)
static std::unique_ptr< SkCanvas > Make(const SkRect &bounds, SkWStream *, uint32_t flags=0)
Builder & setTextShapingFactory(sk_sp< SkShapers::Factory >)
sk_sp< SkSVGDOM > make(SkStream &) const
Builder & setFontManager(sk_sp< SkFontMgr >)
static std::unique_ptr< SkStreamAsset > MakeFromFile(const char path[])
void append(const char text[])
bool endsWith(const char suffixStr[]) const
const char * c_str() const
bool characterize(GrSurfaceCharacterization *characterization) const
T * init(Args &&... args)
void add(std::function< void(void)> fn)
static sk_sp< SkTypeface > MakeDeserialize(SkStream *, sk_sp< SkFontMgr > lastResortMgr)
static std::unique_ptr< BitmapRegionDecoder > Make(sk_sp< SkData > data)
GrDirectContext * directContext() const
TestContext * testContext() const
ContextInfo getContextInfo(ContextType type, ContextOverrides=ContextOverrides::kNone)
ContextInfo getSharedContextInfo(GrDirectContext *shareContext, uint32_t shareIndex=0)
void releaseResourcesAndAbandonContexts()
int numCacheMisses() const
int numCacheStores() const
void makeNotCurrent() const
const GlobalCache * globalCache() const
const RendererProvider * rendererProvider() const
const ShaderCodeDictionary * shaderCodeDictionary() const
std::unique_ptr< Recorder > makeRecorder(const RecorderOptions &={})
bool submit(SyncToCpu=SyncToCpu::kNo)
bool insertRecording(const InsertRecordingInfo &)
sk_sp< GraphicsPipeline > findGraphicsPipeline(const UniqueKey &) SK_EXCLUDES(fSpinLock)
void syncedSubmit(skgpu::graphite::Context *)
static sk_sp< DataURIResourceProviderProxy > Make(sk_sp< ResourceProvider > rp, ImageDecodeStrategy=ImageDecodeStrategy::kLazyDecode, sk_sp< const SkFontMgr > fontMgr=nullptr)
static sk_sp< FileResourceProvider > Make(SkString base_dir, ImageDecodeStrategy=ImageDecodeStrategy::kLazyDecode)
@ kRaster
Suitable for thread which raster data.
sk_sp< SkFontMgr > fontMgr
FlutterSemanticsFlag flags
FlPixelBufferTexturePrivate * priv
Dart_NativeFunction function
static float max(float r, float g, float b)
static float min(float r, float g, float b)
static Result compare_bitmaps(const SkBitmap &reference, const SkBitmap &bitmap)
static SkSerialProcs serial_procs_using_png()
static bool serial_from_path_name(const SkString &path)
static void draw_to_canvas(SkCanvas *canvas, const SkImageInfo &info, void *pixels, size_t rowBytes, CodecSrc::DstColorType dstColorType, SkScalar left=0, SkScalar top=0)
static Result draw_to_canvas(Sink *sink, SkBitmap *bitmap, SkWStream *stream, SkString *log, SkISize size, const DrawToCanvasFn &draw)
static SkISize auto_compute_translate(SkMatrix *matrix, int srcW, int srcH)
static SkRect get_cull_rect_for_skp(const char *path)
static void set_bitmap_color_space(SkImageInfo *info)
static DEFINE_int(skpViewportSize, 1000, "Width & height of the viewport used to crop skp rendering.")
static Result check_against_reference(const SkBitmap *bitmap, const Src &src, Sink *sink)
static SkString get_scaled_name(const Path &path, float scale)
static bool get_decode_info(SkImageInfo *decodeInfo, SkColorType canvasColorType, CodecSrc::DstColorType dstColorType, SkAlphaType dstAlphaType)
static DEFINE_bool(gpuStats, false, "Append GPU stats to the log for each GPU task?")
static Result draw_skdocument(const Src &src, SkDocument *doc, SkWStream *dst)
static void swap_rb_if_necessary(SkBitmap &bitmap, CodecSrc::DstColorType dstColorType)
std::function< DM::Result(SkCanvas *, Src::GraphiteTestContext *)> DrawToCanvasFn
SK_API sk_sp< SkImage > DeferredFromEncodedData(sk_sp< SkData > encoded, std::optional< SkAlphaType > alphaType=std::nullopt)
SK_API sk_sp< SkImage > DeferredFromGenerator(std::unique_ptr< SkImageGenerator > imageGenerator)
SK_API sk_sp< SkImage > TextureFromImage(GrDirectContext *, const SkImage *, skgpu::Mipmapped=skgpu::Mipmapped::kNo, skgpu::Budgeted=skgpu::Budgeted::kYes)
SK_API bool Read(SkStreamSeekable *src, SkDocumentPage *dstArray, int dstArrayCount, const SkDeserialProcs *=nullptr)
SK_API int ReadPageCount(SkStreamSeekable *src)
bool ReadPageSizes(SkStreamSeekable *stream, SkDocumentPage *dstArray, int dstArrayCount)
Swizzle_8888_u32 RGBA_to_BGRA
SK_API sk_sp< SkDocument > MakeDocument(SkWStream *stream, const Metadata &metadata)
SK_API SkImageInfo SwapWidthHeight(const SkImageInfo &info)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
sk_sp< const SkImage > image
sk_sp< Factory > BestAvailable()
SK_API sk_sp< SkSurface > WrapPixels(const SkImageInfo &imageInfo, void *pixels, size_t rowBytes, const SkSurfaceProps *surfaceProps=nullptr)
SK_API sk_sp< SkSurface > RenderTarget(GrRecordingContext *context, skgpu::Budgeted budgeted, const SkImageInfo &imageInfo, int sampleCount, GrSurfaceOrigin surfaceOrigin, const SkSurfaceProps *surfaceProps, bool shouldCreateWithMips=false, bool isProtected=false)
void FetchUniqueKeys(GlobalCache *globalCache, std::vector< UniqueKey > *keys)
bool ExtractKeyDescs(Context *context, const UniqueKey &origKey, GraphicsPipelineDesc *pipelineDesc, RenderPassDesc *renderPassDesc)
void Fatal(char const *file, int line, char const *error)
DlVertices::Builder Builder
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir Path to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace Enable an endless trace buffer The default is a ring buffer This is useful when very old events need to viewed For during application launch Memory usage will continue to grow indefinitely however Start app with an specific route defined on the framework flutter assets Path to the Flutter assets directory enable service port Allow the VM service to fallback to automatic port selection if binding to a specified port fails trace Trace early application lifecycle Automatically switches to an endless trace buffer trace skia Filters out all Skia trace event categories except those that are specified in this comma separated list dump skp on shader Automatically dump the skp that triggers new shader compilations This is useful for writing custom ShaderWarmUp to reduce jank By this is not enabled to reduce the overhead purge persistent cache
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library name
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive mode
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
const myers::Point & get(const myers::Segment &)
sk_sp< SkSurface > MakeBackendRenderTargetSurface(GrDirectContext *dContext, const SkImageInfo &ii, GrSurfaceOrigin origin, int sampleCnt, GrProtected isProtected, const SkSurfaceProps *props)
sk_sp< SkSurface > MakeBackendTextureSurface(GrDirectContext *dContext, const SkImageInfo &ii, GrSurfaceOrigin origin, int sampleCnt, skgpu::Mipmapped mipmapped, GrProtected isProtected, const SkSurfaceProps *props)
SkYUVAPixmapInfo::SupportedDataTypes SupportedTextureFormats(const GrImageContext &context)
void Precompile(Context *context, const PaintOptions &paintOptions, DrawTypeFlags drawTypes=kMostCommon)
std::function< std::unique_ptr< skiagm::GM >()> GMFactory
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
constexpr struct @263 tiles[]
void write(SkWStream *wStream, const T &text)
virtual Result draw(const Src &, SkBitmap *, SkWStream *, SkString *log) const =0
virtual void modifyGrContextOptions(GrContextOptions *) const
virtual void modifyGraphiteContextOptions(skgpu::graphite::ContextOptions *) const
PersistentCache * fPersistentCache
bool fSupportBilerpFromGlyphAtlas
int fRuntimeProgramCacheSize
ShaderCacheStrategy fShaderCacheStrategy
SkDeserialTypefaceProc fTypefaceProc
SkDeserialImageProc fImageProc
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
void setXYWH(int32_t x, int32_t y, int32_t width, int32_t height)
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
static constexpr SkISize Make(int32_t w, int32_t h)
constexpr int32_t width() const
constexpr int32_t height() const
SkImageInfo makeWH(int newWidth, int newHeight) const
SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const
size_t minRowBytes() const
size_t computeByteSize(size_t rowBytes) const
SkImageInfo makeDimensions(SkISize newSize) const
SkColorSpace * colorSpace() const
int bytesPerPixel() const
SkISize dimensions() const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkAlphaType alphaType() const
SkColorType colorType() const
SkImageInfo makeColorType(SkColorType newColorType) const
static constexpr SkRect MakeEmpty()
bool intersect(const SkRect &r)
static SkRect MakeIWH(int w, int h)
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
void roundOut(SkIRect *dst) const
static constexpr SkRect MakeSize(const SkSize &size)
static constexpr SkRect MakeWH(float w, float h)
SkSerialImageProc fImageProc
static constexpr SkSize Make(SkScalar w, SkScalar h)
GraphiteTestContext * fTestContext
skgpu::graphite::Context * fContext
std::shared_ptr< const fml::Mapping > data