54#ifndef SK_BUILD_FOR_WIN
58#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && defined(SK_HAS_HEIF_LIBRARY)
59 #include <binder/IPCThreadState.h>
62#if defined(SK_BUILD_FOR_MAC)
67#if defined(SK_ENABLE_SVG)
78 "Source types to test.");
80 "If true, write to FLAGS_writePath[0]/<hash>.png instead of "
81 "to FLAGS_writePath[0]/<config>/<sourceType>/<sourceOptions>/<name>.png");
82static DEFINE_bool2(pathOpsExtended,
x,
false,
"Run extended pathOps tests.");
84 "2x2 scale+skew matrix to apply or upright when using "
85 "'matrix' or 'upright' in config.");
88 "Space-separated config/src/srcOptions/name quadruples to skip. "
89 "'_' matches anything. '~' negates the match. E.g. \n"
90 "'--skip gpu skp _ _' will skip all SKPs drawn into the gpu config.\n"
91 "'--skip gpu skp _ _ 8888 gm _ aarects' will also skip the aarects GM on 8888.\n"
92 "'--skip ~8888 svg _ svgparse_' blocks non-8888 SVGs that contain \"svgparse_\" in "
96 "If set check for equality with golden results in this directory.");
101 "File containing a list of uninteresting hashes. If a result hashes to something in "
102 "this list, no image is written for that result.");
104static DEFINE_int(shards, 1,
"We're splitting source data into this many shards.");
107static DEFINE_string(mskps,
"",
"Directory to read mskps from, or a single mskp file.");
108static DEFINE_bool(forceRasterPipeline,
false,
"sets gSkForceRasterPipelineBlitter");
109static DEFINE_bool(forceRasterPipelineHP,
false,
"sets gSkForceRasterPipelineBlitter and gForceHighPrecisionRasterPipeline");
110static DEFINE_bool(createProtected,
false,
"attempts to create a protected backend context");
113 "Pair of: SKP file to bisect, followed by an l/r bisect trail string (e.g., 'lrll'). The "
114 "l/r trail specifies which half to keep at each step of a binary search through the SKP's "
115 "paths. An empty string performs no bisect. Only the SkPaths are bisected; all other draws "
116 "are thrown out. This is useful for finding a reduced repo case for path drawing bugs.");
118static DEFINE_bool(ignoreSigInt,
false,
"ignore SIGINT signals during test execution");
120static DEFINE_bool(checkF16,
false,
"Ensure that F16Norm pixels are clamped.");
123 "List of images and/or directories to decode with color correction. "
124 "A directory with no images is treated as a fatal error.");
126static DEFINE_bool2(veryVerbose,
V,
false,
"tell individual tests to be verbose.");
131static DEFINE_bool(neverYieldToWebGPU,
false,
"Run Graphite with never-yield context option.");
134 "just print the tests that would be run, without actually running them.");
137 "List of images and/or directories to decode. A directory with no images"
138 " is treated as a fatal error.");
141 "Runs of a subset of the codec tests, "
142 "with no scaling or subsetting, always using the canvas color type.");
145 "[~][^]substring[$] [...] of name to run.\n"
146 "Multiple matches may be separated by spaces.\n"
147 "~ causes a matching name to always be skipped\n"
148 "^ requires the start of the name to match\n"
149 "$ requires the end of the name to match\n"
150 "^ and $ requires an exact match\n"
151 "If a name does not match any list entry,\n"
152 "it is skipped unless some list entry starts with ~");
154static DEFINE_bool2(quiet, q,
false,
"if true, don't print status updates.");
158static DEFINE_string(lotties,
"lotties",
"Directory to read (Bodymovin) jsons from.");
159static DEFINE_string(svgs,
"",
"Directory to read SVGs from, or a single SVG file.");
162 "Run threadsafe tests on a threadpool with this many extra threads, "
163 "defaulting to one extra thread per core.");
166 "Space-separated key/value pairs to add to JSON identifying this builder.");
168 "Space-separated key/value pairs to add to JSON identifying this run.");
170static DEFINE_bool(rasterize_pdf,
false,
"Rasterize PDFs when possible.");
172#if defined(__MSVC_RUNTIME_CHECKS)
174int RuntimeCheckErrorFunc(
int errorType,
const char* filename,
int linenumber,
181 SkDebugf(
"Line #%d\nFile: %s\nModule: %s\n",
219 va_copy(vlogArgs,
args);
235 static SkSpinlock mutex;
246 info(
"\t%s\n",
id.c_str());
251 if (!FLAGS_writePath.isEmpty()) {
252 JsonWriter::DumpJson(FLAGS_writePath[0], FLAGS_key, FLAGS_properties);
263static void done(
const char* config,
const char*
src,
const char* srcOptions,
const char*
name) {
265 bool updateDueToProgress;
278 updateDueToProgress =
gPending % 500 == 0;
283 vlog(
"[%d/%d] %s done\n", totalCounts - pending, totalCounts,
id.c_str());
288 bool updateDueToTime = now - lastUpdate > 4e9;
289 if (updateDueToProgress || updateDueToTime) {
301 info(
"\n[%d/%d] %dMB RAM, %dMB peak, %d queued, %d threads:\n\t%s done\n",
312static void start(
const char* config,
const char*
src,
const char* srcOptions,
const char*
name) {
314 vlog(
"\tstart %s\n",
id.c_str());
323 if (task.thread == thisThread) {
324 info(
"Likely culprit:\n");
330#if defined(SK_BUILD_FOR_WIN)
332 static const struct {
337 _(EXCEPTION_ACCESS_VIOLATION),
338 _(EXCEPTION_BREAKPOINT),
339 _(EXCEPTION_INT_DIVIDE_BY_ZERO),
340 _(EXCEPTION_STACK_OVERFLOW),
347 const DWORD code =
e->ExceptionRecord->ExceptionCode;
348 info(
"\nCaught exception %lu",
code);
349 for (
const auto& exception : kExceptions) {
350 if (exception.code ==
code) {
351 info(
" %s", exception.name);
354 info(
", was running:\n");
362 return EXCEPTION_EXECUTE_HANDLER;
370 #if !defined(SK_BUILD_FOR_ANDROID)
371 #include <execinfo.h>
375 static constexpr int max_of() {
return 0; }
376 template <
typename... Rest>
377 static constexpr int max_of(
int x, Rest... rest) {
386 info(
"\nCaught signal %d [%s] (%dMB RAM, peak %dMB), was running:\n",
395 #if !defined(SK_BUILD_FOR_ANDROID)
399 info(
"\nStack trace:\n");
406 if (sig == SIGINT && FLAGS_ignoreSigInt) {
407 info(
"Ignoring signal %d because of --ignoreSigInt.\n"
408 "This is probably a sign the bot is overloaded with work.\n", sig);
416 const int kSignals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM };
417 for (
int sig : kSignals) {
450 if (!FLAGS_readPath.isEmpty()) {
461#if defined(SK_BUILD_FOR_WIN)
462 static constexpr char kNewline[] =
"\r\n";
470 if (!FLAGS_uninterestingHashesFile.isEmpty()) {
473 info(
"WARNING: unable to read uninteresting hashes from %s\n",
474 FLAGS_uninterestingHashesFile[0]);
486 info(
"FYI: loaded %d distinct uninteresting hashes from %d lines\n",
509 return N++ % FLAGS_shards == FLAGS_shard;
513 std::unique_ptr<Src>
src(inSrc);
514 if (
in_shard() && FLAGS_src.contains(tag) &&
517 s.reset(
src.release());
525 if (FLAGS_simpleCodec) {
526 const bool simple = CodecSrc::kCodec_Mode ==
mode || CodecSrc::kAnimated_Mode ==
mode;
527 if (!simple || dstColorType != CodecSrc::kGetFromCanvas_DstColorType ||
scale != 1.0f) {
534 case CodecSrc::kCodec_Mode:
537 case CodecSrc::kCodecZeroInit_Mode:
538 folder.append(
"codec_zero_init");
540 case CodecSrc::kScanline_Mode:
541 folder.append(
"scanline");
543 case CodecSrc::kStripe_Mode:
546 case CodecSrc::kCroppedScanline_Mode:
549 case CodecSrc::kSubset_Mode:
550 folder.append(
"codec_subset");
552 case CodecSrc::kAnimated_Mode:
553 folder.append(
"codec_animated");
557 switch (dstColorType) {
558 case CodecSrc::kGrayscale_Always_DstColorType:
561 case CodecSrc::kNonNative8888_Always_DstColorType:
562 folder.append(
"_kNonNative");
568 switch (dstAlphaType) {
573 folder.append(
"_unpremul");
590 folder.append(
"scaled_codec");
592 switch (dstColorType) {
593 case CodecSrc::kGrayscale_Always_DstColorType:
596 case CodecSrc::kNonNative8888_Always_DstColorType:
597 folder.append(
"_kNonNative");
603 switch (dstAlphaType) {
608 folder.append(
"_unpremul");
614 if (1 != sampleSize) {
615 folder.appendf(
"_%.3f", 1.0f / (
float) sampleSize);
626 case ImageGenSrc::kCodec_Mode:
627 folder.append(
"gen_codec");
629 case ImageGenSrc::kPlatform_Mode:
630 folder.append(
"gen_platform");
645 folder.append(
"_unpremul");
656#ifdef SK_ENABLE_ANDROID_UTILS
658 uint32_t sampleSize) {
661 case BRDSrc::kFullImage_Mode:
663 case BRDSrc::kDivisor_Mode:
664 folder.append(
"_divisor");
671 switch (dstColorType) {
672 case CodecSrc::kGetFromCanvas_DstColorType:
674 case CodecSrc::kGrayscale_Always_DstColorType:
682 if (1 != sampleSize) {
683 folder.appendf(
"_%.3f", 1.0f / (
float) sampleSize);
686 BRDSrc*
src =
new BRDSrc(
path,
mode, dstColorType, sampleSize);
690static void push_brd_srcs(
Path path,
bool gray) {
696 push_brd_src(
path, CodecSrc::kGrayscale_Always_DstColorType,
697 BRDSrc::kFullImage_Mode, 2);
705 const uint32_t sampleSizes[] = { 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 24, 32, 64 };
707 const BRDSrc::Mode modes[] = { BRDSrc::kFullImage_Mode, BRDSrc::kDivisor_Mode, };
709 for (uint32_t sampleSize : sampleSizes) {
711 push_brd_src(
path, CodecSrc::kGetFromCanvas_DstColorType,
mode, sampleSize);
724 if (
nullptr == codec) {
730 bool supportsNativeScaling =
false;
733 nativeModes.
push_back(CodecSrc::kCodec_Mode);
734 nativeModes.
push_back(CodecSrc::kCodecZeroInit_Mode);
735 switch (codec->getEncodedFormat()) {
737 nativeModes.
push_back(CodecSrc::kScanline_Mode);
738 nativeModes.
push_back(CodecSrc::kStripe_Mode);
739 nativeModes.
push_back(CodecSrc::kCroppedScanline_Mode);
740 supportsNativeScaling =
true;
743 nativeModes.
push_back(CodecSrc::kSubset_Mode);
744 supportsNativeScaling =
true;
749 nativeModes.
push_back(CodecSrc::kScanline_Mode);
754 colorTypes.
push_back(CodecSrc::kGetFromCanvas_DstColorType);
755 colorTypes.
push_back(CodecSrc::kNonNative8888_Always_DstColorType);
756 switch (codec->getInfo().colorType()) {
758 colorTypes.
push_back(CodecSrc::kGrayscale_Always_DstColorType);
775 if (CodecSrc::kCroppedScanline_Mode ==
mode &&
784 if (supportsNativeScaling &&
785 CodecSrc::kNonNative8888_Always_DstColorType ==
colorType) {
788 for (
auto scale : { 0.125f, 0.25f, 0.375f, 0.5f, 0.625f, 0.750f, 0.875f }) {
797 std::vector<SkCodec::FrameInfo> frameInfos = codec->getFrameInfo();
798 if (frameInfos.size() > 1) {
799 for (
auto dstCT : { CodecSrc::kNonNative8888_Always_DstColorType,
800 CodecSrc::kGetFromCanvas_DstColorType }) {
805 for (
float scale : { .5f, .33f }) {
813 if (FLAGS_simpleCodec) {
817 const int sampleSizes[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
819 for (
int sampleSize : sampleSizes) {
824 if (CodecSrc::kNonNative8888_Always_DstColorType ==
colorType && sampleSize > 3) {
837 static const char*
const rawExts[] = {
838 "arw",
"cr2",
"dng",
"nef",
"nrw",
"orf",
"raf",
"rw2",
"pef",
"srw",
839 "ARW",
"CR2",
"DNG",
"NEF",
"NRW",
"ORF",
"RAF",
"RW2",
"PEF",
"SRW",
841 for (
const char* rawExt : rawExts) {
842 if (0 == strcmp(rawExt,
ext)) {
848#ifdef SK_ENABLE_ANDROID_UTILS
849 static const char*
const brdExts[] = {
850 "jpg",
"jpeg",
"png",
"webp",
851 "JPG",
"JPEG",
"PNG",
"WEBP",
853 for (
const char* brdExt : brdExts) {
854 if (0 == strcmp(brdExt,
ext)) {
856 push_brd_srcs(
path, gray);
870#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
877#elif defined(SK_BUILD_FOR_WIN)
883#elif defined(SK_ENABLE_NDK_IMAGES)
892 const char* src_name =
nullptr) {
898 for (
int i = 0;
i <
flags.size();
i++) {
916 gather_file_srcs<SKPSrc>(FLAGS_skps,
"skp");
917 gather_file_srcs<MSKPSrc>(FLAGS_mskps,
"mskp");
918#if defined(SK_ENABLE_SKOTTIE)
919 gather_file_srcs<SkottieSrc>(FLAGS_lotties,
"json",
"lottie");
921#if defined(SK_ENABLE_SVG)
922 gather_file_srcs<SVGSrc>(FLAGS_svgs,
"svg");
924 if (!FLAGS_bisect.isEmpty()) {
927 new BisectSrc(FLAGS_bisect[0], FLAGS_bisect.size() > 1 ? FLAGS_bisect[1] :
""));
944 for (
const SkString& colorImage : colorImages) {
953 std::unique_ptr<Sink> sink(
s);
956 struct :
public Src {
962 Name name()
const override {
return "justOneRect"; }
975 ts.reset(sink.release());
983 if (!testFactory.
get(gpuConfig->getContextType(), gpuConfig->getContextOverrides())) {
984 info(
"WARNING: can not create GPU context for config '%s'. "
985 "GM tests will be skipped.\n", gpuConfig->getTag().c_str());
988 if (gpuConfig->getTestPersistentCache()) {
990 }
else if (gpuConfig->getTestPrecompile()) {
992 }
else if (gpuConfig->getUseDDLSink()) {
993 return new GPUDDLSink(gpuConfig, grCtxOptions);
994 }
else if (gpuConfig->getSlug()) {
996 }
else if (gpuConfig->getSerializedSlug()) {
998 }
else if (gpuConfig->getRemoteSlug()) {
1001 return new GPUSink(gpuConfig, grCtxOptions);
1005#if defined(SK_GRAPHITE)
1006 if (FLAGS_graphite) {
1007 if (
const SkCommandLineConfigGraphite *graphiteConfig = config->
asConfigGraphite()) {
1008#if defined(SK_ENABLE_PRECOMPILE)
1009 if (graphiteConfig->getTestPrecompile()) {
1010 return new GraphitePrecompileTestingSink(graphiteConfig);
1014 return new GraphiteSink(graphiteConfig);
1020 int pageIndex = svgConfig->getPageIndex();
1021 return new SVGSink(pageIndex);
1024#define SINK(t, sink, ...) if (config->getBackend().equals(t)) return new sink(__VA_ARGS__)
1057#define VIA(t, via, ...) if (tag.equals(t)) return new via(__VA_ARGS__)
1065 if (FLAGS_matrix.size() == 4) {
1068 m.setScaleX((
SkScalar)atof(FLAGS_matrix[0]));
1069 m.setSkewX ((
SkScalar)atof(FLAGS_matrix[1]));
1070 m.setSkewY ((
SkScalar)atof(FLAGS_matrix[2]));
1071 m.setScaleY((
SkScalar)atof(FLAGS_matrix[3]));
1082 if (FLAGS_src.size() == 1 && FLAGS_src.contains(
"tests")) {
1094 if (sink ==
nullptr) {
1095 info(
"Skipping config %s: Don't understand '%s'.\n", config.
getTag().
c_str(),
1104 for (
int j =
parts.size(); j-- > 0;) {
1107 if (
next ==
nullptr) {
1108 info(
"Skipping config %s: Don't understand '%s'.\n", config.
getTag().
c_str(),
1132static bool match(
const char* needle,
const char* haystack) {
1133 if (
'~' == needle[0]) {
1134 return !
match(needle + 1, haystack);
1136 if (0 == strcmp(
"_", needle)) {
1139 return nullptr != strstr(haystack, needle);
1143 const char* srcOptions,
const char*
name) {
1144 for (
int i = 0;
i < FLAGS_skip.size() - 3;
i += 4) {
1145 if (
match(FLAGS_skip[
i+0], sink) &&
1147 match(FLAGS_skip[
i+2], srcOptions) &&
1171 if (!FLAGS_dryRun) {
1177 if (!
log.isEmpty()) {
1201 std::unique_ptr<SkStreamAsset> ownedData(
data);
1203 std::unique_ptr<HashAndEncode> hashAndEncode;
1206 if (!FLAGS_writePath.isEmpty() || !FLAGS_readPath.isEmpty()) {
1208 if (
data->getLength()) {
1212 hashAndEncode = std::make_unique<HashAndEncode>(
bitmap);
1213 hashAndEncode->feedHash(&
hash);
1215 md5 =
hash.finish().toLowercaseHexString();
1218 if (!FLAGS_readPath.isEmpty() &&
1227 FLAGS_readPath[0]));
1231 const char*
ext = task.
sink->fileExtension();
1232 if (
ext && !FLAGS_writePath.isEmpty()) {
1233 #if defined(SK_BUILD_FOR_MAC)
1239 SkUniqueCFRef<CGDataProviderRef> provider{
1240 CGDataProviderCreateWithData(
nullptr,
1245 SkUniqueCFRef<CGPDFDocumentRef> pdf{
1246 CGPDFDocumentCreateWithProvider(provider.get())};
1248 CGPDFPageRef
page = CGPDFDocumentGetPage(pdf.get(), 1);
1250 CGRect
bounds = CGPDFPageGetBoxRect(
page, kCGPDFMediaBox);
1259 SkUniqueCFRef<CGColorSpaceRef> cs{CGColorSpaceCreateDeviceRGB()};
1260 CGBitmapInfo
info = kCGBitmapByteOrder32Big |
1261 (CGBitmapInfo)kCGImageAlphaPremultipliedLast;
1263 SkUniqueCFRef<CGContextRef> ctx{CGBitmapContextCreate(
1265 CGContextDrawPDFPage(ctx.get(),
page);
1268 hashAndEncode = std::make_unique<HashAndEncode>(rasterized);
1269 WriteToDisk(task,
md5,
"png",
nullptr,0, &rasterized, hashAndEncode.get());
1272 if (
data->getLength()) {
1275 }
else if (!
bitmap.drawsNothing()) {
1282 bitmap.peekPixels(&pm)) {
1283 bool unclamped =
false;
1284 for (
int y = 0;
y < pm.
height() && !unclamped; ++
y)
1285 for (
int x = 0;
x < pm.
width() && !unclamped; ++
x) {
1289 SkDebugf(
"[%s] F16Norm pixel [%d, %d] unclamped: (%g, %g, %g, %g)\n",
1308 for (
int i = 0;
i < 3;
i++)
1309 for (
int j = 0; j < 3; j++) {
1310 if (
x.vals[
i][j] !=
y.vals[
i][j]) {
return false; }
1345 if (tf.
a == 1 && tf.
b == 0 && tf.
c == 0 && tf.
d == 0 && tf.
e == 0 && tf.
f == 0) {
1351 tf.
g, tf.
a, tf.
b, tf.
c, tf.
d, tf.
e, tf.
f);
1356 tf.
a, tf.
b, tf.
c, tf.
d, tf.
e, tf.
f);
1361 tf.
a, tf.
b, tf.
c, tf.
d, tf.
e, tf.
f+1);
1377 bool isOldestSupportedSkp =
false;
1378 for (
int i = 1;
i < FLAGS_key.size();
i += 2) {
1379 if (0 == strcmp(FLAGS_key[
i-1],
"extra_config") &&
1380 0 == strcmp(FLAGS_key[
i],
"OldestSupportedSkpVersion")) {
1381 isOldestSupportedSkp =
true;
1393 if (isOldestSupportedSkp && 0 == strcmp(
result.sourceType.c_str(),
"skp")) {
1394 result.sourceType =
"old-skp";
1406 JsonWriter::AddBitmapResult(
result);
1414 const char*
dir = FLAGS_writePath[0];
1416 if (0 == strcmp(
dir,
"@")) {
1422 if (FLAGS_nameByHash) {
1444 if (!
file.isValid()) {
1453 FLAGS_properties)) {
1476 if (!FLAGS_src.contains(
"tests")) {
1486 if (
test.fTestType == TestType::kGanesh && FLAGS_gpu) {
1488 }
else if (
test.fTestType == TestType::kGraphite && FLAGS_graphite) {
1490 }
else if (
test.fTestType == TestType::kCPU && FLAGS_cpu) {
1492 }
else if (
test.fTestType == TestType::kCPUSerial && FLAGS_cpu) {
1503 return FLAGS_pathOpsExtended;
1505 bool verbose()
const override {
return FLAGS_veryVerbose; }
1515 done(
"unit",
"test",
"",
test.fName);
1529 done(
"unit",
"test",
"",
test.fName);
1536 test.modifyGraphiteContextOptions(&
options.fContextOptions);
1542 done(
"unit",
"test",
"",
test.fName);
1554#if defined(__MSVC_RUNTIME_CHECKS)
1555 _RTC_SetErrorFunc(RuntimeCheckErrorFunc);
1557#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && defined(SK_HAS_HEIF_LIBRARY)
1564#if !defined(SK_BUILD_FOR_GOOGLE3) && defined(SK_BUILD_FOR_IOS)
1567 setbuf(stdout,
nullptr);
1577 if (!FLAGS_writePath.isEmpty()) {
1581 if (FLAGS_verbose) {
1586 if (FLAGS_neverYieldToWebGPU) {
1596#if defined(SK_ENABLE_SVG)
1603 info(
"Some resources are missing. Do you need to set --resourcePath?\n");
1612 for (
int i = 0;
i < argc;
i++) {
1613 if (strcmp(
argv[
i],
"--config") == 0) {
1627 info(
"%d srcs * %d sinks + %d tests == %d tasks\n",
1640 if (
src->veto(sink->flags()) ||
1642 src.options.c_str(),
src->name().c_str())) {
1649 if (
src->serial() || sink->serial()) {
1677 info(
"Failures:\n");
1686 info(
"Finished!\n");
static SkMD5::Digest md5(const SkBitmap &bm)
static const char defaultConfigs[]
void ParseConfigs(const CommandLineFlags::StringArray &configs, SkCommandLineConfigArray *outResult)
static bool should_skip(const char *sink, const char *src, const char *srcOptions, const char *name)
static void push_codec_src(Path path, CodecSrc::Mode mode, CodecSrc::DstColorType dstColorType, SkAlphaType dstAlphaType, float scale)
static void gather_gold()
static TArray< TaggedSink, kMemcpyOK > * gSinks
static DEFINE_int(shards, 1, "We're splitting source data into this many shards.")
static void push_codec_srcs(Path path)
static void find_culprit()
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
static SkTDArray< skiatest::Test > * gGaneshTests
static void gather_uninteresting_hashes()
static double gLastUpdate
void gather_file_srcs(const CommandLineFlags::StringArray &flags, const char *ext, const char *src_name=nullptr)
static THashSet< Gold, Gold::Hash > * gGold
int main(int argc, char **argv)
static void add_gold(JsonWriter::BitmapResult r)
static DEFINE_bool(nameByHash, false, "If true, write to FLAGS_writePath[0]/<hash>.png instead of " "to FLAGS_writePath[0]/<config>/<sourceType>/<sourceOptions>/<name>.png")
static void push_src(const char *tag, ImplicitString options, Src *inSrc)
static bool gather_srcs()
static bool gather_sinks(const GrContextOptions &grCtxOptions, bool defaultConfigs)
static void run_ganesh_test(skiatest::Test test, const GrContextOptions &grCtxOptions)
static THashSet< SkString > * gUninterestingHashes
bool gCreateProtectedContext
static void start(const char *config, const char *src, const char *srcOptions, const char *name)
bool gForceHighPrecisionRasterPipeline
static Sink * create_via(const SkString &tag, Sink *wrapped)
static SkTDArray< skiatest::Test > * gCPUSerialTests
static constexpr char kNewline[]
static void push_android_codec_src(Path path, CodecSrc::DstColorType dstColorType, SkAlphaType dstAlphaType, int sampleSize)
static constexpr int max_of()
TestHarness CurrentTestHarness()
static void fail(const SkString &err)
static void run_graphite_test(skiatest::Test test, skiatest::graphite::TestOptions &options)
static DEFINE_int_2(threads, j, -1, "Run threadsafe tests on a threadpool with this many extra threads, " "defaulting to one extra thread per core.")
static constexpr bool kMemcpyOK
static DEFINE_bool2(pathOpsExtended, x, false, "Run extended pathOps tests.")
static void(* previous_handler[max_of(SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTERM)+1])(int)
static void crash_handler(int sig)
static SkNoDestructor< TArray< Running > > gRunning
static TArray< SkString > * gFailures
static bool match(const char *needle, const char *haystack)
static void push_image_gen_src(Path path, ImageGenSrc::Mode mode, SkAlphaType alphaType, bool isGpu)
static void gather_tests()
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static SkTaskGroup * gDefinitelyThreadSafeWork
static DEFINE_string2(readPath, r, "", "If set check for equality with golden results in this directory.")
bool gSkForceRasterPipelineBlitter
static void run_cpu_test(skiatest::Test test)
#define SINK(t, sink,...)
static void push_sink(const SkCommandLineConfig &config, Sink *s)
static Sink * create_sink(const GrContextOptions &grCtxOptions, const SkCommandLineConfig *config)
static TArray< TaggedSrc, kMemcpyOK > * gSrcs
static void vlog(const char *fmt,...) SK_PRINTF_LIKE(1
static SkTDArray< skiatest::Test > * gCPUTests
static SkTDArray< skiatest::Test > * gGraphiteTests
static void setup_crash_handler()
static DEFINE_string(src, "tests gm skp mskp lottie rive svg image colorImage", "Source types to test.")
void initializeEventTracingForTools(const char *traceFlag)
static bool eq(const SkM44 &a, const SkM44 &b, float tol)
static float next(float f)
static const size_t testCount
static const uint32_t rgba[kNumPixels]
sk_sp< SkData > GetResourceAsData(const char *resource)
SkString GetResourcePath(const char *resource)
@ kOpaque_SkAlphaType
pixel is opaque
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SK_PRINTF_LIKE(A, B)
static constexpr skcms_Matrix3x3 gNarrow_toXYZD50
@ kBGR_101010x_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
@ 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;
@ kRGB_101010x_SkColorType
pixel with 10 bits each for red, green, blue; in 32-bit word
@ kSRGBA_8888_SkColorType
@ 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
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
@ kBGRA_1010102_SkColorType
10 bits for blue, green, red; 2 bits for alpha; in 32-bit word
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
constexpr SkColor SK_ColorWHITE
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static constexpr SkScalar SK_ScalarDefaultRasterDPI
static bool skip(SkStream *stream, size_t amount)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
bool sk_mkdir(const char *path)
bool sk_exists(const char *path, SkFILE_Flags=(SkFILE_Flags) 0)
bool sk_isdir(const char *path)
static uint32_t hash(const SkShaderBase::GradientInfo &v)
bool equals(SkDrawable *a, SkDrawable *b)
void SkStrSplit(const char *str, const char *delimiters, SkStrSplitMode splitMode, TArray< SkString > *out)
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
SkThreadID SkGetThreadID()
static sk_sp< GrTextureProxy > wrapped(skiatest::Reporter *reporter, GrRecordingContext *rContext, GrProxyProvider *proxyProvider, SkBackingFit fit)
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
static bool ShouldSkip(const SkTDArray< const char * > &strings, const char *name)
static void Parse(int argc, const char *const *argv)
bool encodePNG(SkWStream *, const char *md5, CommandLineFlags::StringArray key, CommandLineFlags::StringArray properties) const
void allocPixels(const SkImageInfo &info, size_t rowBytes)
void eraseColor(SkColor4f) const
void drawRect(const SkRect &rect, const SkPaint &paint)
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
bool toXYZD50(skcms_Matrix3x3 *toXYZD50) const
void transferFn(float gabcdef[7]) const
sk_sp< SkColorSpace > refColorSpace() const
const SkString & getTag() const
virtual const SkCommandLineConfigSvg * asConfigSvg() const
const skia_private::TArray< SkString > & getViaParts() const
virtual const SkCommandLineConfigGpu * asConfigGpu() const
virtual const SkCommandLineConfigGraphite * asConfigGraphite() const
const void * data() const
static sk_sp< SkData > MakeFromStream(SkStream *, size_t size)
static sk_sp< SkData > MakeFromFileName(const char path[])
static void PurgeAllCaches()
static OpenTypeSVGDecoderFactory SetOpenTypeSVGDecoderFactory(OpenTypeSVGDecoderFactory)
SK_SPI bool next(SkString *name, bool getDir=false)
static SkString Join(const char *rootPath, const char *relativePath)
const uint64_t * addr64() const
static std::unique_ptr< SkOpenTypeSVGDecoder > Make(const uint8_t *svg, size_t svgLength)
void append(const char text[])
const char * c_str() const
void add(std::function< void(void)> fn)
GrDirectContext * get(ContextType type, ContextOverrides overrides=ContextOverrides::kNone)
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
T __attribute__((ext_vector_type(N))) V
std::array< MockImage, 3 > images
void RegisterAllAvailable()
bool CollectImages(const CommandLineFlags::StringArray &dir, skia_private::TArray< SkString > *output)
void SetCtxOptions(struct GrContextOptions *)
static constexpr skcms_Matrix3x3 kSRGB
static constexpr skcms_Matrix3x3 kAdobeRGB
static constexpr skcms_Matrix3x3 kXYZ
static constexpr skcms_Matrix3x3 kRec2020
static constexpr skcms_Matrix3x3 kDisplayP3
static constexpr skcms_TransferFunction kRec2020
static constexpr skcms_TransferFunction kSRGB
static constexpr skcms_TransferFunction kHLG
static constexpr skcms_TransferFunction kPQ
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
sk_sp< const SkImage > image
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
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 dir
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
std::function< std::unique_ptr< skiagm::GM >()> GMFactory
void SetFontTestDataDirectory()
SIN Vec< N, float > from_half(const Vec< N, uint16_t > &x)
SIT bool any(const Vec< 1, T > &x)
static SkString fmt(SkColor4f c)
skcms_TFType skcms_TransferFunction_getType(const skcms_TransferFunction *tf)
bool verbose() const override
bool allowExtendedTest() const override
void reportFailed(const skiatest::Failure &failure) override
virtual void setColorSpace(sk_sp< SkColorSpace >)
uint32_t operator()(const Gold &g) const
Gold(const SkString &sink, const SkString &src, const SkString &srcOptions, const SkString &name, const SkString &md5)
static constexpr SkISize Make(int32_t w, int32_t h)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static constexpr SkRect MakeWH(float w, float h)
static SkString identify_transfer_fn(SkColorSpace *cs)
static void WriteToDisk(const Task &task, SkString md5, const char *ext, SkStream *data, size_t len, const SkBitmap *bitmap, const HashAndEncode *hashAndEncode)
static SkString identify_gamut(SkColorSpace *cs)
static void Run(const Task &task)
Task(const TaggedSrc &src, const TaggedSink &sink)
SkString toString() const
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)
std::shared_ptr< const fml::Mapping > data