Flutter Engine
The Flutter Engine
Classes | Macros | Functions | Variables
DM.cpp File Reference
#include "dm/DMJsonWriter.h"
#include "dm/DMSrcSink.h"
#include "include/codec/SkCodec.h"
#include "include/codec/SkEncodedImageFormat.h"
#include "include/core/SkBBHFactory.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkData.h"
#include "include/core/SkDocument.h"
#include "include/core/SkGraphics.h"
#include "src/base/SkHalf.h"
#include "src/base/SkLeanWindows.h"
#include "src/base/SkNoDestructor.h"
#include "src/base/SkSpinlock.h"
#include "src/base/SkTime.h"
#include "src/base/SkVx.h"
#include "src/core/SkChecksum.h"
#include "src/core/SkColorSpacePriv.h"
#include "src/core/SkMD5.h"
#include "src/core/SkOSFile.h"
#include "src/core/SkStringUtils.h"
#include "src/core/SkTHash.h"
#include "src/core/SkTaskGroup.h"
#include "src/utils/SkOSPath.h"
#include "tests/Test.h"
#include "tests/TestHarness.h"
#include "tools/AutoreleasePool.h"
#include "tools/CodecUtils.h"
#include "tools/HashAndEncode.h"
#include "tools/ProcStats.h"
#include "tools/Resources.h"
#include "tools/TestFontDataProvider.h"
#include "tools/ToolUtils.h"
#include "tools/flags/CommonFlags.h"
#include "tools/flags/CommonFlagsConfig.h"
#include "tools/fonts/FontToolUtils.h"
#include "tools/ios_utils.h"
#include "tools/trace/ChromeTracingTracer.h"
#include "tools/trace/EventTracingPriv.h"
#include "tools/trace/SkDebugfTracer.h"
#include <memory>
#include <vector>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <execinfo.h>

Go to the source code of this file.

Classes

struct  Running
 
struct  Gold
 
struct  Gold::Hash
 
struct  TaggedSrc
 
struct  TaggedSink
 
struct  Task
 
struct  DMReporter
 

Macros

#define SINK(t, sink, ...)   if (config->getBackend().equals(t)) return new sink(__VA_ARGS__)
 
#define VIA(t, via, ...)   if (tag.equals(t)) return new via(__VA_ARGS__)
 

Functions

static DEFINE_string (src, "tests gm skp mskp lottie rive svg image colorImage", "Source types to test.")
 
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 DEFINE_bool2 (pathOpsExtended, x, false, "Run extended pathOps tests.")
 
static DEFINE_string (matrix, "1 0 0 1", "2x2 scale+skew matrix to apply or upright when using " "'matrix' or 'upright' in config.")
 
static DEFINE_string (skip, "", "Space-separated config/src/srcOptions/name quadruples to skip. " "'_' matches anything. '~' negates the match. E.g. \n" "'--skip gpu skp _ _' will skip all SKPs drawn into the gpu config.\n" "'--skip gpu skp _ _ 8888 gm _ aarects' will also skip the aarects GM on 8888.\n" "'--skip ~8888 svg _ svgparse_' blocks non-8888 SVGs that contain \"svgparse_\" in " "the name.")
 
static DEFINE_string2 (readPath, r, "", "If set check for equality with golden results in this directory.")
 
 DEFINE_string2 (writePath, w, "", "If set, write bitmaps here as .pngs.")
 
static DEFINE_string (uninterestingHashesFile, "", "File containing a list of uninteresting hashes. If a result hashes to something in " "this list, no image is written for that result.")
 
static DEFINE_int (shards, 1, "We're splitting source data into this many shards.")
 
static DEFINE_int (shard, 0, "Which shard do I run?")
 
static DEFINE_string (mskps, "", "Directory to read mskps from, or a single mskp file.")
 
static DEFINE_bool (forceRasterPipeline, false, "sets gSkForceRasterPipelineBlitter")
 
static DEFINE_bool (forceRasterPipelineHP, false, "sets gSkForceRasterPipelineBlitter and gForceHighPrecisionRasterPipeline")
 
static DEFINE_bool (createProtected, false, "attempts to create a protected backend context")
 
static DEFINE_string (bisect, "", "Pair of: SKP file to bisect, followed by an l/r bisect trail string (e.g., 'lrll'). The " "l/r trail specifies which half to keep at each step of a binary search through the SKP's " "paths. An empty string performs no bisect. Only the SkPaths are bisected; all other draws " "are thrown out. This is useful for finding a reduced repo case for path drawing bugs.")
 
static DEFINE_bool (ignoreSigInt, false, "ignore SIGINT signals during test execution")
 
static DEFINE_bool (checkF16, false, "Ensure that F16Norm pixels are clamped.")
 
static DEFINE_string (colorImages, "", "List of images and/or directories to decode with color correction. " "A directory with no images is treated as a fatal error.")
 
static DEFINE_bool2 (veryVerbose, V, false, "tell individual tests to be verbose.")
 
static DEFINE_bool (cpu, true, "Run CPU-bound work?")
 
static DEFINE_bool (gpu, true, "Run GPU-bound work?")
 
static DEFINE_bool (graphite, true, "Run Graphite work?")
 
static DEFINE_bool (neverYieldToWebGPU, false, "Run Graphite with never-yield context option.")
 
static DEFINE_bool (dryRun, false, "just print the tests that would be run, without actually running them.")
 
static DEFINE_string (images, "", "List of images and/or directories to decode. A directory with no images" " is treated as a fatal error.")
 
static DEFINE_bool (simpleCodec, false, "Runs of a subset of the codec tests, " "with no scaling or subsetting, always using the canvas color type.")
 
static DEFINE_string2 (match, m, nullptr, "[~][^]substring[$] [...] of name to run.\n" "Multiple matches may be separated by spaces.\n" "~ causes a matching name to always be skipped\n" "^ requires the start of the name to match\n" "$ requires the end of the name to match\n" "^ and $ requires an exact match\n" "If a name does not match any list entry,\n" "it is skipped unless some list entry starts with ~")
 
static DEFINE_bool2 (quiet, q, false, "if true, don't print status updates.")
 
static DEFINE_bool2 (verbose, v, false, "enable verbose output from the test driver.")
 
static DEFINE_string (skps, "skps", "Directory to read skps from.")
 
static DEFINE_string (lotties, "lotties", "Directory to read (Bodymovin) jsons from.")
 
static DEFINE_string (svgs, "", "Directory to read SVGs from, or a single SVG file.")
 
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 DEFINE_string (key, "", "Space-separated key/value pairs to add to JSON identifying this builder.")
 
static DEFINE_string (properties, "", "Space-separated key/value pairs to add to JSON identifying this run.")
 
static DEFINE_bool (rasterize_pdf, false, "Rasterize PDFs when possible.")
 
static void vlog (const char *fmt,...) SK_PRINTF_LIKE(1
 
static void info (const char *fmt,...) SK_PRINTF_LIKE(1
 
static void fail (const SkString &err)
 
static void dump_json ()
 
static void done (const char *config, const char *src, const char *srcOptions, const char *name)
 
static void start (const char *config, const char *src, const char *srcOptions, const char *name)
 
static void find_culprit ()
 
static constexpr int max_of ()
 
template<typename... Rest>
static constexpr int max_of (int x, Rest... rest)
 
static void crash_handler (int sig)
 
static void setup_crash_handler ()
 
static void add_gold (JsonWriter::BitmapResult r)
 
static void gather_gold ()
 
static void gather_uninteresting_hashes ()
 
static bool in_shard ()
 
static void push_src (const char *tag, ImplicitString options, Src *inSrc)
 
static void push_codec_src (Path path, CodecSrc::Mode mode, CodecSrc::DstColorType dstColorType, SkAlphaType dstAlphaType, float scale)
 
static void push_android_codec_src (Path path, CodecSrc::DstColorType dstColorType, SkAlphaType dstAlphaType, int sampleSize)
 
static void push_image_gen_src (Path path, ImageGenSrc::Mode mode, SkAlphaType alphaType, bool isGpu)
 
static void push_codec_srcs (Path path)
 
template<typename T >
void gather_file_srcs (const CommandLineFlags::StringArray &flags, const char *ext, const char *src_name=nullptr)
 
static bool gather_srcs ()
 
static void push_sink (const SkCommandLineConfig &config, Sink *s)
 
static Sinkcreate_sink (const GrContextOptions &grCtxOptions, const SkCommandLineConfig *config)
 
static Sinkcreate_via (const SkString &tag, Sink *wrapped)
 
static bool gather_sinks (const GrContextOptions &grCtxOptions, bool defaultConfigs)
 
static bool match (const char *needle, const char *haystack)
 
static bool should_skip (const char *sink, const char *src, const char *srcOptions, const char *name)
 
static void gather_tests ()
 
static void run_cpu_test (skiatest::Test test)
 
static void run_ganesh_test (skiatest::Test test, const GrContextOptions &grCtxOptions)
 
static void run_graphite_test (skiatest::Test test, skiatest::graphite::TestOptions &options)
 
TestHarness CurrentTestHarness ()
 
int main (int argc, char **argv)
 

Variables

bool gSkForceRasterPipelineBlitter
 
bool gForceHighPrecisionRasterPipeline
 
bool gCreateProtectedContext
 
static FILE * gVLog
 
static TArray< SkString > * gFailures = new TArray<SkString>
 
static SkSpinlock gMutex
 
static int gPending
 
static int gTotalCounts
 
static double gLastUpdate
 
static SkNoDestructor< TArray< Running > > gRunning
 
static void(* previous_handler [max_of(SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTERM)+1])(int)
 
static THashSet< Gold, Gold::Hash > * gGold = new THashSet<Gold, Gold::Hash>
 
static constexpr char kNewline [] = "\n"
 
static THashSet< SkString > * gUninterestingHashes = new THashSet<SkString>
 
static constexpr bool kMemcpyOK = true
 
static TArray< TaggedSrc, kMemcpyOK > * gSrcs = new TArray<TaggedSrc, kMemcpyOK>
 
static TArray< TaggedSink, kMemcpyOK > * gSinks = new TArray<TaggedSink, kMemcpyOK>
 
static SkTaskGroupgDefinitelyThreadSafeWork = new SkTaskGroup
 
static SkTDArray< skiatest::Test > * gCPUTests = new SkTDArray<skiatest::Test>
 
static SkTDArray< skiatest::Test > * gCPUSerialTests = new SkTDArray<skiatest::Test>
 
static SkTDArray< skiatest::Test > * gGaneshTests = new SkTDArray<skiatest::Test>
 
static SkTDArray< skiatest::Test > * gGraphiteTests = new SkTDArray<skiatest::Test>
 

Macro Definition Documentation

◆ SINK

#define SINK (   t,
  sink,
  ... 
)    if (config->getBackend().equals(t)) return new sink(__VA_ARGS__)

◆ VIA

#define VIA (   t,
  via,
  ... 
)    if (tag.equals(t)) return new via(__VA_ARGS__)

Function Documentation

◆ add_gold()

static void add_gold ( JsonWriter::BitmapResult  r)
static

Definition at line 445 of file DM.cpp.

445 {
446 gGold->add(Gold(r.config, r.sourceType, r.sourceOptions, r.name, r.md5));
447}
static THashSet< Gold, Gold::Hash > * gGold
Definition: DM.cpp:443
Definition: DM.cpp:425

◆ crash_handler()

static void crash_handler ( int  sig)
static

Definition at line 383 of file DM.cpp.

383 {
385
386 info("\nCaught signal %d [%s] (%dMB RAM, peak %dMB), was running:\n",
387 sig, strsignal(sig),
389
390 for (auto& task : *gRunning) {
391 task.dump();
392 }
393 find_culprit();
394
395 #if !defined(SK_BUILD_FOR_ANDROID)
396 void* stack[128];
397 int count = backtrace(stack, std::size(stack));
398 char** symbols = backtrace_symbols(stack, count);
399 info("\nStack trace:\n");
400 for (int i = 0; i < count; i++) {
401 info(" %s\n", symbols[i]);
402 }
403 #endif
404 fflush(stdout);
405
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);
409 } else {
410 signal(sig, previous_handler[sig]);
411 raise(sig);
412 }
413 }
static void find_culprit()
Definition: DM.cpp:319
static SkSpinlock gMutex
Definition: DM.cpp:257
static void(* previous_handler[max_of(SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTERM)+1])(int)
Definition: DM.cpp:381
static SkNoDestructor< TArray< Running > > gRunning
Definition: DM.cpp:261
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
int count
Definition: FontMgrTest.cpp:50
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
Definition: switches.h:259
int getCurrResidentSetSizeMB()
Definition: ProcStats.cpp:92
int getMaxResidentSetSizeMB()
Definition: ProcStats.cpp:87

◆ create_sink()

static Sink * create_sink ( const GrContextOptions grCtxOptions,
const SkCommandLineConfig config 
)
static

Definition at line 979 of file DM.cpp.

979 {
980 if (FLAGS_gpu) {
981 if (const SkCommandLineConfigGpu* gpuConfig = config->asConfigGpu()) {
982 GrContextFactory testFactory(grCtxOptions);
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());
986 return nullptr;
987 }
988 if (gpuConfig->getTestPersistentCache()) {
989 return new GPUPersistentCacheTestingSink(gpuConfig, grCtxOptions);
990 } else if (gpuConfig->getTestPrecompile()) {
991 return new GPUPrecompileTestingSink(gpuConfig, grCtxOptions);
992 } else if (gpuConfig->getUseDDLSink()) {
993 return new GPUDDLSink(gpuConfig, grCtxOptions);
994 } else if (gpuConfig->getSlug()) {
995 return new GPUSlugSink(gpuConfig, grCtxOptions);
996 } else if (gpuConfig->getSerializedSlug()) {
997 return new GPUSerializeSlugSink(gpuConfig, grCtxOptions);
998 } else if (gpuConfig->getRemoteSlug()) {
999 return new GPURemoteSlugSink(gpuConfig, grCtxOptions);
1000 } else {
1001 return new GPUSink(gpuConfig, grCtxOptions);
1002 }
1003 }
1004 }
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);
1011 } else
1012#endif // SK_ENABLE_PRECOMPILE
1013 {
1014 return new GraphiteSink(graphiteConfig);
1015 }
1016 }
1017 }
1018#endif // SK_GRAPHITE
1019 if (const SkCommandLineConfigSvg* svgConfig = config->asConfigSvg()) {
1020 int pageIndex = svgConfig->getPageIndex();
1021 return new SVGSink(pageIndex);
1022 }
1023
1024#define SINK(t, sink, ...) if (config->getBackend().equals(t)) return new sink(__VA_ARGS__)
1025
1026 if (FLAGS_cpu) {
1030 SINK("8888", RasterSink, kN32_SkColorType);
1036 SINK("bgra1010102", RasterSink, kBGRA_1010102_SkColorType);
1042
1043 SINK("pdf", PDFSink, false, SK_ScalarDefaultRasterDPI);
1044 SINK("skp", SKPSink);
1045 SINK("svg", SVGSink);
1046 SINK("null", NullSink);
1047 SINK("xps", XPSSink);
1048 SINK("pdfa", PDFSink, true, SK_ScalarDefaultRasterDPI);
1049 SINK("pdf300", PDFSink, false, 300);
1050 SINK("jsdebug", DebugSink);
1051 }
1052#undef SINK
1053 return nullptr;
1054}
#define SINK(t, sink,...)
@ kR8_unorm_SkColorType
Definition: SkColorType.h:54
@ kBGR_101010x_SkColorType
pixel with 10 bits each for blue, green, red; in 32-bit word
Definition: SkColorType.h:30
@ kARGB_4444_SkColorType
pixel with 4 bits for alpha, red, green, blue; in 16-bit word
Definition: SkColorType.h:23
@ kBGRA_8888_SkColorType
pixel with 8 bits for blue, green, red, alpha; in 32-bit word
Definition: SkColorType.h:26
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:38
@ kRGB_101010x_SkColorType
pixel with 10 bits each for red, green, blue; in 32-bit word
Definition: SkColorType.h:29
@ kSRGBA_8888_SkColorType
Definition: SkColorType.h:53
@ kRGB_565_SkColorType
pixel with 5 bits red, 6 bits green, 5 bits blue, in 16-bit word
Definition: SkColorType.h:22
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition: SkColorType.h:24
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
Definition: SkColorType.h:25
@ kBGRA_1010102_SkColorType
10 bits for blue, green, red; 2 bits for alpha; in 32-bit word
Definition: SkColorType.h:28
@ kRGBA_F32_SkColorType
pixel using C float for red, green, blue, alpha; in 128-bit word
Definition: SkColorType.h:40
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
Definition: SkColorType.h:27
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
Definition: SkColorType.h:36
static constexpr SkScalar SK_ScalarDefaultRasterDPI
Definition: SkDocument.h:20
virtual const SkCommandLineConfigSvg * asConfigSvg() const
virtual const SkCommandLineConfigGpu * asConfigGpu() const
virtual const SkCommandLineConfigGraphite * asConfigGraphite() const

◆ create_via()

static Sink * create_via ( const SkString tag,
Sink wrapped 
)
static

Definition at line 1056 of file DM.cpp.

1056 {
1057#define VIA(t, via, ...) if (tag.equals(t)) return new via(__VA_ARGS__)
1058#ifdef TEST_VIA_SVG
1059 VIA("svg", ViaSVG, wrapped);
1060#endif
1061 VIA("serialize", ViaSerialization, wrapped);
1062 VIA("pic", ViaPicture, wrapped);
1063 VIA("rtblend", ViaRuntimeBlend, wrapped);
1064
1065 if (FLAGS_matrix.size() == 4) {
1066 SkMatrix m;
1067 m.reset();
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]));
1072 VIA("matrix", ViaMatrix, m, wrapped);
1073 VIA("upright", ViaUpright, m, wrapped);
1074 }
1075
1076#undef VIA
1077
1078 return nullptr;
1079}
#define VIA(t, via,...)
static sk_sp< GrTextureProxy > wrapped(skiatest::Reporter *reporter, GrRecordingContext *rContext, GrProxyProvider *proxyProvider, SkBackingFit fit)
float SkScalar
Definition: extension.cpp:12

◆ CurrentTestHarness()

TestHarness CurrentTestHarness ( )

Definition at line 1547 of file DM.cpp.

1547 {
1548 return TestHarness::kDM;
1549}

◆ DEFINE_bool() [1/13]

static DEFINE_bool ( checkF16  ,
false  ,
"Ensure that F16Norm pixels are clamped."   
)
static

◆ DEFINE_bool() [2/13]

static DEFINE_bool ( cpu  ,
true  ,
"Run CPU-bound work?"   
)
static

◆ DEFINE_bool() [3/13]

static DEFINE_bool ( createProtected  ,
false  ,
"attempts to create a protected backend context"   
)
static

◆ DEFINE_bool() [4/13]

static DEFINE_bool ( dryRun  ,
false  ,
"just print the tests that would be  run,
without actually running them."   
)
static

◆ DEFINE_bool() [5/13]

static DEFINE_bool ( forceRasterPipeline  ,
false  ,
"sets gSkForceRasterPipelineBlitter  
)
static

◆ DEFINE_bool() [6/13]

static DEFINE_bool ( forceRasterPipelineHP  ,
false  ,
"sets gSkForceRasterPipelineBlitter and gForceHighPrecisionRasterPipeline  
)
static

◆ DEFINE_bool() [7/13]

static DEFINE_bool ( gpu  ,
true  ,
"Run GPU-bound work?"   
)
static

◆ DEFINE_bool() [8/13]

static DEFINE_bool ( graphite  ,
true  ,
"Run Graphite work?"   
)
static

◆ DEFINE_bool() [9/13]

static DEFINE_bool ( ignoreSigInt  ,
false  ,
"ignore SIGINT signals during test execution"   
)
static

◆ DEFINE_bool() [10/13]

static DEFINE_bool ( nameByHash  ,
false  ,
"If  true,
write to FLAGS_writePath/< hash >.png instead of " "to FLAGS_writePath/< config >/< sourceType >/< sourceOptions >/< name >.png"  [0][0] 
)
static

◆ DEFINE_bool() [11/13]

static DEFINE_bool ( neverYieldToWebGPU  ,
false  ,
"Run Graphite with never-yield context option."   
)
static

◆ DEFINE_bool() [12/13]

static DEFINE_bool ( rasterize_pdf  ,
false  ,
"Rasterize PDFs when possible."   
)
static

◆ DEFINE_bool() [13/13]

static DEFINE_bool ( simpleCodec  ,
false  ,
"Runs of a subset of the codec  tests,
" "with no scaling or  subsetting,
always using the canvas color type."   
)
static

◆ DEFINE_bool2() [1/4]

static DEFINE_bool2 ( pathOpsExtended  ,
x  ,
false  ,
"Run extended pathOps tests."   
)
static

◆ DEFINE_bool2() [2/4]

static DEFINE_bool2 ( quiet  ,
,
false  ,
"if  true,
don 't print status updates."   
)
static

◆ DEFINE_bool2() [3/4]

static DEFINE_bool2 ( verbose  ,
,
false  ,
"enable verbose output from the test driver."   
)
static

◆ DEFINE_bool2() [4/4]

static DEFINE_bool2 ( veryVerbose  ,
V  ,
false  ,
"tell individual tests to be verbose."   
)
static

◆ DEFINE_int() [1/2]

static DEFINE_int ( shard  ,
,
"Which shard do I run?"   
)
static

◆ DEFINE_int() [2/2]

static DEFINE_int ( shards  ,
,
"We're splitting source data into this many shards."   
)
static

◆ DEFINE_int_2()

static DEFINE_int_2 ( threads  ,
,
1,
"Run threadsafe tests on a threadpool with this many extra  threads,
" "defaulting to one extra thread per core."   
)
static

◆ DEFINE_string() [1/13]

static DEFINE_string ( bisect  ,
""  ,
"Pair of: SKP file to  bisect,
followed by an l/r bisect trail string(e.g., 'lrll'). The " "l/r trail specifies which half to keep at each step of a binary search through the SKP 's " "paths. An empty string performs no bisect. Only the SkPaths are bisected;all other draws " "are thrown out. This is useful for finding a reduced repo case for path drawing bugs."   
)
static

◆ DEFINE_string() [2/13]

static DEFINE_string ( colorImages  ,
""  ,
"List of images and/or directories to decode with color correction. " "A directory with no images is treated as a fatal error."   
)
static

◆ DEFINE_string() [3/13]

static DEFINE_string ( images  ,
""  ,
"List of images and/or directories to decode. A directory with no images" " is treated as a fatal error."   
)
static

◆ DEFINE_string() [4/13]

static DEFINE_string ( key  ,
""  ,
"Space-separated key/value pairs to add to JSON identifying this builder."   
)
static

◆ DEFINE_string() [5/13]

static DEFINE_string ( lotties  ,
"lotties"  ,
"Directory to read (Bodymovin) jsons from."   
)
static

◆ DEFINE_string() [6/13]

static DEFINE_string ( matrix  ,
"1 0 0 1"  ,
"2x2 scale+skew matrix to apply or upright when using " "'matrix' or 'upright' in config."   
)
static

◆ DEFINE_string() [7/13]

static DEFINE_string ( mskps  ,
""  ,
"Directory to read mskps  from,
or a single mskp file."   
)
static

◆ DEFINE_string() [8/13]

static DEFINE_string ( properties  ,
""  ,
"Space-separated key/value pairs to add to JSON identifying this run."   
)
static

◆ DEFINE_string() [9/13]

static DEFINE_string ( skip  ,
""  ,
"Space-separated config/src/srcOptions/name quadruples to skip. " "'_' matches anything. '~' negates the match. E.g. \n" "'--skip gpu skp _ _' will skip all SKPs drawn into the gpu config.\n" "'--skip gpu skp _ _ 8888 gm _ aarects' will also skip the aarects GM on 8888.\n" "'--skip ~8888 svg _ svgparse_' blocks non-8888 SVGs that contain \"svgparse_\" in " "the name."   
)
static

◆ DEFINE_string() [10/13]

static DEFINE_string ( skps  ,
"skps"  ,
"Directory to read skps from."   
)
static

◆ DEFINE_string() [11/13]

static DEFINE_string ( src  ,
"tests gm skp mskp lottie rive svg image colorImage"  ,
"Source types to test."   
)
static

◆ DEFINE_string() [12/13]

static DEFINE_string ( svgs  ,
""  ,
"Directory to read SVGs  from,
or a single SVG file."   
)
static

◆ DEFINE_string() [13/13]

static DEFINE_string ( uninterestingHashesFile  ,
""  ,
"File containing a list of uninteresting hashes. If a result hashes to something in " "this  list,
no image is written for that result."   
)
static

◆ DEFINE_string2() [1/3]

static DEFINE_string2 ( match  ,
,
nullptr  ,
"substring of name to run.\n" "Multiple matches may be separated by spaces.\n" "~ causes a matching name to always be skipped\n" "^ requires the start of the name to match\n" "$ requires the end of the name to match\n" "^ and $ requires an exact match\n" "If a name does not match any list  entry[~][^][$][...],
\n" "it is skipped unless some list entry starts with ~"   
)
static

◆ DEFINE_string2() [2/3]

static DEFINE_string2 ( readPath  ,
,
""  ,
"If set check for equality with golden results in this directory."   
)
static

◆ DEFINE_string2() [3/3]

DEFINE_string2 ( writePath  ,
w  ,
""  ,
"If  set,
write bitmaps here as .pngs."   
)

◆ done()

static void done ( const char *  config,
const char *  src,
const char *  srcOptions,
const char *  name 
)
static

Definition at line 263 of file DM.cpp.

263 {
264 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name);
265 bool updateDueToProgress;
266 double lastUpdate;
267 int totalCounts;
268 int pending;
269 {
271 for (int i = 0; i < gRunning->size(); i++) {
272 if (gRunning->at(i).id == id) {
273 gRunning->removeShuffle(i);
274 break;
275 }
276 }
277 --gPending;
278 updateDueToProgress = gPending % 500 == 0;
279 lastUpdate = gLastUpdate;
280 totalCounts = gTotalCounts;
281 pending = gPending;
282 }
283 vlog("[%d/%d] %s done\n", totalCounts - pending, totalCounts, id.c_str());
284
285 // We write out dm.json file and print out a progress update every once in a while.
286 // Notice this also handles the final dm.json and progress update when pending == 0.
287 double now = SkTime::GetNSecs();
288 bool updateDueToTime = now - lastUpdate > 4e9;
289 if (updateDueToProgress || updateDueToTime) {
290 dump_json();
291
294
296
297 // Since multiple threads can call `done`, it's possible that another thread has raced with
298 // this one and printed an update since we did our progress check above. We detect this case
299 // by checking to see if `gLastUpdate` has changed; if so, we don't need to print anything.
300 if (lastUpdate == gLastUpdate) {
301 info("\n[%d/%d] %dMB RAM, %dMB peak, %d queued, %d threads:\n\t%s done\n",
303 curr, peak, gPending - gRunning->size(), gRunning->size() + 1, id.c_str());
304 for (auto& task : *gRunning) {
305 task.dump();
306 }
307 gLastUpdate = now;
308 }
309 }
310}
static double gLastUpdate
Definition: DM.cpp:260
static int gTotalCounts
Definition: DM.cpp:259
static void dump_json()
Definition: DM.cpp:250
static void vlog(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:201
static int gPending
Definition: DM.cpp:258
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
double GetNSecs()
Definition: SkTime.cpp:17
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32

◆ dump_json()

static void dump_json ( )
static

Definition at line 250 of file DM.cpp.

250 {
251 if (!FLAGS_writePath.isEmpty()) {
252 JsonWriter::DumpJson(FLAGS_writePath[0], FLAGS_key, FLAGS_properties);
253 }
254}

◆ fail()

static void fail ( const SkString err)
static

Definition at line 234 of file DM.cpp.

234 {
235 static SkSpinlock mutex;
236 SkAutoSpinlock lock(mutex);
237 SkDebugf("\n\nFAILURE: %s\n\n", err.c_str());
238 gFailures->push_back(err);
239}
static TArray< SkString > * gFailures
Definition: DM.cpp:232
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
const char * c_str() const
Definition: SkString.h:133

◆ find_culprit()

static void find_culprit ( )
static

Definition at line 319 of file DM.cpp.

319 {
320 // Assumes gMutex is locked.
321 SkThreadID thisThread = SkGetThreadID();
322 for (auto& task : *gRunning) {
323 if (task.thread == thisThread) {
324 info("Likely culprit:\n");
325 task.dump();
326 }
327 }
328}
SkThreadID SkGetThreadID()
Definition: SkThreadID.cpp:15
int64_t SkThreadID
Definition: SkThreadID.h:16

◆ gather_file_srcs()

template<typename T >
void gather_file_srcs ( const CommandLineFlags::StringArray flags,
const char *  ext,
const char *  src_name = nullptr 
)

Definition at line 890 of file DM.cpp.

892 {
893 if (!src_name) {
894 // With the exception of Lottie files, the source name is the extension.
895 src_name = ext;
896 }
897
898 for (int i = 0; i < flags.size(); i++) {
899 const char* path = flags[i];
900 if (sk_isdir(path)) {
902 for (SkString file; it.next(&file); ) {
903 push_src(src_name, "", new T(SkOSPath::Join(path, file.c_str())));
904 }
905 } else {
906 push_src(src_name, "", new T(path));
907 }
908 }
909}
static void push_src(const char *tag, ImplicitString options, Src *inSrc)
Definition: DM.cpp:512
bool sk_isdir(const char *path)
static SkString Join(const char *rootPath, const char *relativePath)
Definition: SkOSPath.cpp:14
FlutterSemanticsFlag flags
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
Definition: switches.h:57
#define T
Definition: precompiler.cc:65

◆ gather_gold()

static void gather_gold ( )
static

Definition at line 449 of file DM.cpp.

449 {
450 if (!FLAGS_readPath.isEmpty()) {
451 SkString path(FLAGS_readPath[0]);
452 path.append("/dm.json");
453 if (!JsonWriter::ReadJson(path.c_str(), add_gold)) {
454 fail(SkStringPrintf("Couldn't read %s for golden results.", path.c_str()));
455 }
456 }
457}
static void add_gold(JsonWriter::BitmapResult r)
Definition: DM.cpp:445
static void fail(const SkString &err)
Definition: DM.cpp:234
void append(const char text[])
Definition: SkString.h:203

◆ gather_sinks()

static bool gather_sinks ( const GrContextOptions grCtxOptions,
bool  defaultConfigs 
)
static

Definition at line 1081 of file DM.cpp.

1081 {
1082 if (FLAGS_src.size() == 1 && FLAGS_src.contains("tests")) {
1083 // If we're just running tests skip trying to accumulate sinks. The 'justOneRect' test
1084 // can fail for protected contexts.
1085 return true;
1086 }
1087
1089 ParseConfigs(FLAGS_config, &configs);
1091 for (int i = 0; i < configs.size(); i++) {
1092 const SkCommandLineConfig& config = *configs[i];
1093 Sink* sink = create_sink(grCtxOptions, &config);
1094 if (sink == nullptr) {
1095 info("Skipping config %s: Don't understand '%s'.\n", config.getTag().c_str(),
1096 config.getTag().c_str());
1097 continue;
1098 }
1099
1100 // The command line config already parsed out the via-style color space. Apply it here.
1101 sink->setColorSpace(config.refColorSpace());
1102
1103 const TArray<SkString>& parts = config.getViaParts();
1104 for (int j = parts.size(); j-- > 0;) {
1105 const SkString& part = parts[j];
1106 Sink* next = create_via(part, sink);
1107 if (next == nullptr) {
1108 info("Skipping config %s: Don't understand '%s'.\n", config.getTag().c_str(),
1109 part.c_str());
1110 delete sink;
1111 sink = nullptr;
1112 break;
1113 }
1114 sink = next;
1115 }
1116 if (sink) {
1117 push_sink(config, sink);
1118 }
1119 }
1120
1121 // If no configs were requested (just running tests, perhaps?), then we're okay.
1122 if (configs.size() == 0 ||
1123 // If we're using the default configs, we're okay.
1125 // Otherwise, make sure that all specified configs have become sinks.
1126 configs.size() == gSinks->size()) {
1127 return true;
1128 }
1129 return false;
1130}
AutoreleasePool pool
static const char defaultConfigs[]
void ParseConfigs(const CommandLineFlags::StringArray &configs, SkCommandLineConfigArray *outResult)
static TArray< TaggedSink, kMemcpyOK > * gSinks
Definition: DM.cpp:505
static Sink * create_via(const SkString &tag, Sink *wrapped)
Definition: DM.cpp:1056
static void push_sink(const SkCommandLineConfig &config, Sink *s)
Definition: DM.cpp:952
static Sink * create_sink(const GrContextOptions &grCtxOptions, const SkCommandLineConfig *config)
Definition: DM.cpp:979
static float next(float f)
sk_sp< SkColorSpace > refColorSpace() const
const SkString & getTag() const
const skia_private::TArray< SkString > & getViaParts() const
virtual void setColorSpace(sk_sp< SkColorSpace >)
Definition: DMSrcSink.h:120

◆ gather_srcs()

static bool gather_srcs ( )
static

Definition at line 911 of file DM.cpp.

911 {
913 push_src("gm", "", new GMSrc(f));
914 }
915
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");
920#endif
921#if defined(SK_ENABLE_SVG)
922 gather_file_srcs<SVGSrc>(FLAGS_svgs, "svg");
923#endif
924 if (!FLAGS_bisect.isEmpty()) {
925 // An empty l/r trail string will draw all the paths.
926 push_src("bisect", "",
927 new BisectSrc(FLAGS_bisect[0], FLAGS_bisect.size() > 1 ? FLAGS_bisect[1] : ""));
928 }
929
931 if (!CommonFlags::CollectImages(FLAGS_images, &images)) {
932 return false;
933 }
934
935 for (const SkString& image : images) {
937 }
938
939 TArray<SkString> colorImages;
940 if (!CommonFlags::CollectImages(FLAGS_colorImages, &colorImages)) {
941 return false;
942 }
943
944 for (const SkString& colorImage : colorImages) {
945 push_src("colorImage", "decode_native", new ColorCodecSrc(colorImage, false));
946 push_src("colorImage", "decode_to_dst", new ColorCodecSrc(colorImage, true));
947 }
948
949 return true;
950}
static void push_codec_srcs(Path path)
Definition: DM.cpp:717
std::array< MockImage, 3 > images
Definition: mock_vulkan.cc:41
bool CollectImages(const CommandLineFlags::StringArray &dir, skia_private::TArray< SkString > *output)
sk_sp< const SkImage > image
Definition: SkRecords.h:269
std::function< std::unique_ptr< skiagm::GM >()> GMFactory
Definition: gm.h:239

◆ gather_tests()

static void gather_tests ( )
static

Definition at line 1475 of file DM.cpp.

1475 {
1476 if (!FLAGS_src.contains("tests")) {
1477 return;
1478 }
1480 if (!in_shard()) {
1481 continue;
1482 }
1483 if (CommandLineFlags::ShouldSkip(FLAGS_match, test.fName)) {
1484 continue;
1485 }
1486 if (test.fTestType == TestType::kGanesh && FLAGS_gpu) {
1487 gGaneshTests->push_back(test);
1488 } else if (test.fTestType == TestType::kGraphite && FLAGS_graphite) {
1489 gGraphiteTests->push_back(test);
1490 } else if (test.fTestType == TestType::kCPU && FLAGS_cpu) {
1491 gCPUTests->push_back(test);
1492 } else if (test.fTestType == TestType::kCPUSerial && FLAGS_cpu) {
1493 gCPUSerialTests->push_back(test);
1494 }
1495 }
1496}
static SkTDArray< skiatest::Test > * gGaneshTests
Definition: DM.cpp:1472
static SkTDArray< skiatest::Test > * gCPUSerialTests
Definition: DM.cpp:1471
static bool in_shard()
Definition: DM.cpp:507
static SkTDArray< skiatest::Test > * gCPUTests
Definition: DM.cpp:1470
static SkTDArray< skiatest::Test > * gGraphiteTests
Definition: DM.cpp:1473
static bool ShouldSkip(const SkTDArray< const char * > &strings, const char *name)

◆ gather_uninteresting_hashes()

static void gather_uninteresting_hashes ( )
static

Definition at line 469 of file DM.cpp.

469 {
470 if (!FLAGS_uninterestingHashesFile.isEmpty()) {
471 sk_sp<SkData> data(SkData::MakeFromFileName(FLAGS_uninterestingHashesFile[0]));
472 if (!data) {
473 info("WARNING: unable to read uninteresting hashes from %s\n",
474 FLAGS_uninterestingHashesFile[0]);
475 return;
476 }
477
478 // Copy to a string to make sure SkStrSplit has a terminating \0 to find.
479 SkString contents((const char*)data->data(), data->size());
480
482 SkStrSplit(contents.c_str(), kNewline, &hashes);
483 for (const SkString& hash : hashes) {
485 }
486 info("FYI: loaded %d distinct uninteresting hashes from %d lines\n",
487 gUninterestingHashes->count(), hashes.size());
488 }
489}
static THashSet< SkString > * gUninterestingHashes
Definition: DM.cpp:467
static constexpr char kNewline[]
Definition: DM.cpp:464
static uint32_t hash(const SkShaderBase::GradientInfo &v)
void SkStrSplit(const char *str, const char *delimiters, SkStrSplitMode splitMode, TArray< SkString > *out)
static sk_sp< SkData > MakeFromFileName(const char path[])
Definition: SkData.cpp:148
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ in_shard()

static bool in_shard ( )
static

Definition at line 507 of file DM.cpp.

507 {
508 static int N = 0;
509 return N++ % FLAGS_shards == FLAGS_shard;
510}
#define N
Definition: beziers.cpp:19

◆ info()

static void static void info ( const char *  fmt,
  ... 
)
static

Definition at line 213 of file DM.cpp.

213 {
214 va_list args;
215 va_start(args, fmt);
216
217 if (gVLog) {
218 va_list vlogArgs;
219 va_copy(vlogArgs, args);
220 vfprintf(gVLog, fmt, vlogArgs);
221 fflush(gVLog);
222 va_end(vlogArgs);
223 }
224
225 if (!FLAGS_quiet) {
226 vprintf(fmt, args);
227 }
228
229 va_end(args);
230}
static FILE * gVLog
Definition: DM.cpp:197
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
va_start(args, format)
va_end(args)
static SkString fmt(SkColor4f c)
Definition: p3.cpp:43

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 1553 of file DM.cpp.

1553 {
1554#if defined(__MSVC_RUNTIME_CHECKS)
1555 _RTC_SetErrorFunc(RuntimeCheckErrorFunc);
1556#endif
1557#if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && defined(SK_HAS_HEIF_LIBRARY)
1558 android::ProcessState::self()->startThreadPool();
1559#endif
1561
1563
1564#if !defined(SK_BUILD_FOR_GOOGLE3) && defined(SK_BUILD_FOR_IOS)
1565 cd_Documents();
1566#endif
1567 setbuf(stdout, nullptr);
1569
1571
1572 gSkForceRasterPipelineBlitter = FLAGS_forceRasterPipelineHP || FLAGS_forceRasterPipeline;
1573 gForceHighPrecisionRasterPipeline = FLAGS_forceRasterPipelineHP;
1574 gCreateProtectedContext = FLAGS_createProtected;
1575
1576 // The bots like having a verbose.log to upload, so always touch the file even if --verbose.
1577 if (!FLAGS_writePath.isEmpty()) {
1578 sk_mkdir(FLAGS_writePath[0]);
1579 gVLog = fopen(SkOSPath::Join(FLAGS_writePath[0], "verbose.log").c_str(), "w");
1580 }
1581 if (FLAGS_verbose) {
1582 gVLog = stderr;
1583 }
1584
1585 skiatest::graphite::TestOptions graphiteOptions;
1586 if (FLAGS_neverYieldToWebGPU) {
1587 graphiteOptions.fNeverYieldToWebGPU = true;
1588 }
1589
1590 GrContextOptions grCtxOptions;
1591 CommonFlags::SetCtxOptions(&grCtxOptions);
1592
1593 dump_json(); // It's handy for the bots to assume this is ~never missing.
1594
1596#if defined(SK_ENABLE_SVG)
1598#endif
1599 SkTaskGroup::Enabler enabled(FLAGS_threads);
1601
1602 if (nullptr == GetResourceAsData("images/color_wheel.png")) {
1603 info("Some resources are missing. Do you need to set --resourcePath?\n");
1604 }
1605 gather_gold();
1607
1608 if (!gather_srcs()) {
1609 return 1;
1610 }
1611 bool defaultConfigs = true;
1612 for (int i = 0; i < argc; i++) {
1613 if (strcmp(argv[i], "--config") == 0) {
1614 defaultConfigs = false;
1615 break;
1616 }
1617 }
1618 if (!gather_sinks(grCtxOptions, defaultConfigs)) {
1619 return 1;
1620 }
1621 gather_tests();
1622 int testCount = gCPUTests->size() + gCPUSerialTests->size() +
1623 gGaneshTests->size() + gGraphiteTests->size();
1624 gPending = gSrcs->size() * gSinks->size() + testCount;
1627 info("%d srcs * %d sinks + %d tests == %d tasks\n",
1628 gSrcs->size(), gSinks->size(), testCount,
1629 gPending);
1630
1631 // Kick off as much parallel work as we can, making note of any serial work we'll need to do.
1632 // However, execute all CPU-serial tests first so that they don't have races with parallel tests
1634
1635 SkTaskGroup parallel;
1637
1638 for (TaggedSink& sink : *gSinks) {
1639 for (TaggedSrc& src : *gSrcs) {
1640 if (src->veto(sink->flags()) ||
1641 should_skip(sink.tag.c_str(), src.tag.c_str(),
1642 src.options.c_str(), src->name().c_str())) {
1643 SkAutoSpinlock lock(gMutex);
1644 gPending--;
1645 continue;
1646 }
1647
1648 Task task(src, sink);
1649 if (src->serial() || sink->serial()) {
1650 serial.push_back(task);
1651 } else {
1652 parallel.add([task] { Task::Run(task); });
1653 }
1654 }
1655 }
1656 for (skiatest::Test& test : *gCPUTests) {
1657 parallel.add([test] { run_cpu_test(test); });
1658 }
1659
1660 // With the parallel work running, run serial tasks and tests here on main thread.
1661 for (Task& task : serial) { Task::Run(task); }
1662 for (skiatest::Test& test : *gGaneshTests) { run_ganesh_test(test, grCtxOptions); }
1663 for (skiatest::Test& test : *gGraphiteTests) { run_graphite_test(test, graphiteOptions); }
1664
1665 // Wait for any remaining parallel work to complete (including any spun off of serial tasks).
1666 parallel.wait();
1668
1669 // At this point we're back in single-threaded land.
1670
1671 // We'd better have run everything.
1672 SkASSERT(gPending == 0);
1673 // Make sure we've flushed all our results to disk.
1674 dump_json();
1675
1676 if (!gFailures->empty()) {
1677 info("Failures:\n");
1678 for (const SkString& fail : *gFailures) {
1679 info("\t%s\n", fail.c_str());
1680 }
1681 info("%d failures\n", gFailures->size());
1682 return 1;
1683 }
1684
1686 info("Finished!\n");
1687
1688 return 0;
1689}
static bool should_skip(const char *sink, const char *src, const char *srcOptions, const char *name)
Definition: DM.cpp:1142
static void gather_gold()
Definition: DM.cpp:449
static void gather_uninteresting_hashes()
Definition: DM.cpp:469
static bool gather_srcs()
Definition: DM.cpp:911
static bool gather_sinks(const GrContextOptions &grCtxOptions, bool defaultConfigs)
Definition: DM.cpp:1081
static void run_ganesh_test(skiatest::Test test, const GrContextOptions &grCtxOptions)
Definition: DM.cpp:1518
bool gCreateProtectedContext
bool gForceHighPrecisionRasterPipeline
static void run_graphite_test(skiatest::Test test, skiatest::graphite::TestOptions &options)
Definition: DM.cpp:1532
static void gather_tests()
Definition: DM.cpp:1475
static SkTaskGroup * gDefinitelyThreadSafeWork
Definition: DM.cpp:1157
bool gSkForceRasterPipelineBlitter
Definition: SkBlitter.cpp:44
static void run_cpu_test(skiatest::Test test)
Definition: DM.cpp:1508
static TArray< TaggedSrc, kMemcpyOK > * gSrcs
Definition: DM.cpp:504
static void setup_crash_handler()
Definition: DM.cpp:415
void initializeEventTracingForTools(const char *traceFlag)
static const size_t testCount
sk_sp< SkData > GetResourceAsData(const char *resource)
Definition: Resources.cpp:42
#define SkASSERT(cond)
Definition: SkAssert.h:116
bool sk_mkdir(const char *path)
static void Parse(int argc, const char *const *argv)
static void PurgeAllCaches()
Definition: SkGraphics.cpp:40
static OpenTypeSVGDecoderFactory SetOpenTypeSVGDecoderFactory(OpenTypeSVGDecoderFactory)
Definition: SkGraphics.cpp:96
static void Init()
Definition: SkGraphics.cpp:22
static std::unique_ptr< SkOpenTypeSVGDecoder > Make(const uint8_t *svg, size_t svgLength)
void add(std::function< void(void)> fn)
Definition: SkTaskGroup.cpp:16
bool empty() const
Definition: SkTArray.h:199
int size() const
Definition: SkTArray.h:421
void cd_Documents(void)
Definition: ios_utils.m:12
char ** argv
Definition: library.h:9
void RegisterAllAvailable()
Definition: CodecUtils.h:60
void SetCtxOptions(struct GrContextOptions *)
void SetFontTestDataDirectory()
Definition: DM.cpp:1161
static void Run(const Task &task)
Definition: DM.cpp:1166

◆ match()

static bool match ( const char *  needle,
const char *  haystack 
)
static

Definition at line 1132 of file DM.cpp.

1132 {
1133 if ('~' == needle[0]) {
1134 return !match(needle + 1, haystack);
1135 }
1136 if (0 == strcmp("_", needle)) {
1137 return true;
1138 }
1139 return nullptr != strstr(haystack, needle);
1140}
static bool match(const char *needle, const char *haystack)
Definition: DM.cpp:1132

◆ max_of() [1/2]

static constexpr int max_of ( )
staticconstexpr

Definition at line 375 of file DM.cpp.

375{ return 0; }

◆ max_of() [2/2]

template<typename... Rest>
static constexpr int max_of ( int  x,
Rest...  rest 
)
staticconstexpr

Definition at line 377 of file DM.cpp.

377 {
378 return x > max_of(rest...) ? x : max_of(rest...);
379 }
static constexpr int max_of()
Definition: DM.cpp:375
double x

◆ push_android_codec_src()

static void push_android_codec_src ( Path  path,
CodecSrc::DstColorType  dstColorType,
SkAlphaType  dstAlphaType,
int  sampleSize 
)
static

Definition at line 587 of file DM.cpp.

588 {
590 folder.append("scaled_codec");
591
592 switch (dstColorType) {
593 case CodecSrc::kGrayscale_Always_DstColorType:
594 folder.append("_kGray8");
595 break;
596 case CodecSrc::kNonNative8888_Always_DstColorType:
597 folder.append("_kNonNative");
598 break;
599 default:
600 break;
601 }
602
603 switch (dstAlphaType) {
605 folder.append("_premul");
606 break;
608 folder.append("_unpremul");
609 break;
610 default:
611 break;
612 }
613
614 if (1 != sampleSize) {
615 folder.appendf("_%.3f", 1.0f / (float) sampleSize);
616 }
617
618 AndroidCodecSrc* src = new AndroidCodecSrc(path, dstColorType, dstAlphaType, sampleSize);
619 push_src("image", folder, src);
620}
kUnpremul_SkAlphaType
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
folder
Definition: malisc.py:18

◆ push_codec_src()

static void push_codec_src ( Path  path,
CodecSrc::Mode  mode,
CodecSrc::DstColorType  dstColorType,
SkAlphaType  dstAlphaType,
float  scale 
)
static

Definition at line 523 of file DM.cpp.

524 {
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) {
528 // Only decode in the simple case.
529 return;
530 }
531 }
533 switch (mode) {
534 case CodecSrc::kCodec_Mode:
535 folder.append("codec");
536 break;
537 case CodecSrc::kCodecZeroInit_Mode:
538 folder.append("codec_zero_init");
539 break;
540 case CodecSrc::kScanline_Mode:
541 folder.append("scanline");
542 break;
543 case CodecSrc::kStripe_Mode:
544 folder.append("stripe");
545 break;
546 case CodecSrc::kCroppedScanline_Mode:
547 folder.append("crop");
548 break;
549 case CodecSrc::kSubset_Mode:
550 folder.append("codec_subset");
551 break;
552 case CodecSrc::kAnimated_Mode:
553 folder.append("codec_animated");
554 break;
555 }
556
557 switch (dstColorType) {
558 case CodecSrc::kGrayscale_Always_DstColorType:
559 folder.append("_kGray8");
560 break;
561 case CodecSrc::kNonNative8888_Always_DstColorType:
562 folder.append("_kNonNative");
563 break;
564 default:
565 break;
566 }
567
568 switch (dstAlphaType) {
570 folder.append("_premul");
571 break;
573 folder.append("_unpremul");
574 break;
575 default:
576 break;
577 }
578
579 if (1.0f != scale) {
580 folder.appendf("_%.3f", scale);
581 }
582
583 CodecSrc* src = new CodecSrc(path, mode, dstColorType, dstAlphaType, scale);
584 push_src("image", folder, src);
585}
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
Definition: switches.h:228
const Scalar scale

◆ push_codec_srcs()

static void push_codec_srcs ( Path  path)
static

Definition at line 717 of file DM.cpp.

717 {
719 if (!encoded) {
720 info("Couldn't read %s.", path.c_str());
721 return;
722 }
723 std::unique_ptr<SkCodec> codec = SkCodec::MakeFromData(encoded);
724 if (nullptr == codec) {
725 info("Couldn't create codec for %s.", path.c_str());
726 return;
727 }
728
729 // native scaling is only supported by WEBP and JPEG
730 bool supportsNativeScaling = false;
731
732 TArray<CodecSrc::Mode> nativeModes;
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;
741 break;
743 nativeModes.push_back(CodecSrc::kSubset_Mode);
744 supportsNativeScaling = true;
745 break;
747 break;
748 default:
749 nativeModes.push_back(CodecSrc::kScanline_Mode);
750 break;
751 }
752
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);
759 break;
760 default:
761 break;
762 }
763
764 TArray<SkAlphaType> alphaModes;
765 alphaModes.push_back(kPremul_SkAlphaType);
766 if (codec->getInfo().alphaType() != kOpaque_SkAlphaType) {
768 }
769
770 for (CodecSrc::Mode mode : nativeModes) {
771 for (CodecSrc::DstColorType colorType : colorTypes) {
772 for (SkAlphaType alphaType : alphaModes) {
773 // Only test kCroppedScanline_Mode when the alpha type is premul. The test is
774 // slow and won't be interestingly different with different alpha types.
775 if (CodecSrc::kCroppedScanline_Mode == mode &&
776 kPremul_SkAlphaType != alphaType) {
777 continue;
778 }
779
780 push_codec_src(path, mode, colorType, alphaType, 1.0f);
781
782 // Skip kNonNative on different native scales. It won't be interestingly
783 // different.
784 if (supportsNativeScaling &&
785 CodecSrc::kNonNative8888_Always_DstColorType == colorType) {
786 // Native Scales
787 // SkJpegCodec natively supports scaling to the following:
788 for (auto scale : { 0.125f, 0.25f, 0.375f, 0.5f, 0.625f, 0.750f, 0.875f }) {
789 push_codec_src(path, mode, colorType, alphaType, scale);
790 }
791 }
792 }
793 }
794 }
795
796 {
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 }) {
801 for (auto at : { kUnpremul_SkAlphaType, kPremul_SkAlphaType }) {
802 push_codec_src(path, CodecSrc::kAnimated_Mode, dstCT, at, 1.0f);
803 }
804 }
805 for (float scale : { .5f, .33f }) {
806 push_codec_src(path, CodecSrc::kAnimated_Mode, CodecSrc::kGetFromCanvas_DstColorType,
808 }
809 }
810
811 }
812
813 if (FLAGS_simpleCodec) {
814 return;
815 }
816
817 const int sampleSizes[] = { 1, 2, 3, 4, 5, 6, 7, 8 };
818
819 for (int sampleSize : sampleSizes) {
820 for (CodecSrc::DstColorType colorType : colorTypes) {
821 for (SkAlphaType alphaType : alphaModes) {
822 // We can exercise all of the kNonNative support code in the swizzler with just a
823 // few sample sizes. Skip the rest.
824 if (CodecSrc::kNonNative8888_Always_DstColorType == colorType && sampleSize > 3) {
825 continue;
826 }
827
828 push_android_codec_src(path, colorType, alphaType, sampleSize);
829 }
830 }
831 }
832
833 const char* ext = strrchr(path.c_str(), '.');
834 if (ext) {
835 ext++;
836
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",
840 };
841 for (const char* rawExt : rawExts) {
842 if (0 == strcmp(rawExt, ext)) {
843 // RAW is not supported by image generator (skbug.com/5079) or BRD.
844 return;
845 }
846 }
847
848#ifdef SK_ENABLE_ANDROID_UTILS
849 static const char* const brdExts[] = {
850 "jpg", "jpeg", "png", "webp",
851 "JPG", "JPEG", "PNG", "WEBP",
852 };
853 for (const char* brdExt : brdExts) {
854 if (0 == strcmp(brdExt, ext)) {
855 bool gray = codec->getInfo().colorType() == kGray_8_SkColorType;
856 push_brd_srcs(path, gray);
857 break;
858 }
859 }
860#endif
861 }
862
863 // Push image generator GPU test.
864 push_image_gen_src(path, ImageGenSrc::kCodec_Mode, codec->getInfo().alphaType(), true);
865
866 // Push image generator CPU tests.
867 for (SkAlphaType alphaType : alphaModes) {
868 push_image_gen_src(path, ImageGenSrc::kCodec_Mode, alphaType, false);
869
870#if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS)
871 if (SkEncodedImageFormat::kWEBP != codec->getEncodedFormat() &&
872 SkEncodedImageFormat::kWBMP != codec->getEncodedFormat() &&
873 kUnpremul_SkAlphaType != alphaType)
874 {
875 push_image_gen_src(path, ImageGenSrc::kPlatform_Mode, alphaType, false);
876 }
877#elif defined(SK_BUILD_FOR_WIN)
878 if (SkEncodedImageFormat::kWEBP != codec->getEncodedFormat() &&
879 SkEncodedImageFormat::kWBMP != codec->getEncodedFormat())
880 {
881 push_image_gen_src(path, ImageGenSrc::kPlatform_Mode, alphaType, false);
882 }
883#elif defined(SK_ENABLE_NDK_IMAGES)
884 push_image_gen_src(path, ImageGenSrc::kPlatform_Mode, alphaType, false);
885#endif
886 }
887}
static void push_codec_src(Path path, CodecSrc::Mode mode, CodecSrc::DstColorType dstColorType, SkAlphaType dstAlphaType, float scale)
Definition: DM.cpp:523
static void push_android_codec_src(Path path, CodecSrc::DstColorType dstColorType, SkAlphaType dstAlphaType, int sampleSize)
Definition: DM.cpp:587
static void push_image_gen_src(Path path, ImageGenSrc::Mode mode, SkAlphaType alphaType, bool isGpu)
Definition: DM.cpp:622
SkAlphaType
Definition: SkAlphaType.h:26
@ kOpaque_SkAlphaType
pixel is opaque
Definition: SkAlphaType.h:28
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition: SkColorType.h:35
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
Definition: SkCodec.cpp:241

◆ push_image_gen_src()

static void push_image_gen_src ( Path  path,
ImageGenSrc::Mode  mode,
SkAlphaType  alphaType,
bool  isGpu 
)
static

Definition at line 622 of file DM.cpp.

623{
625 switch (mode) {
626 case ImageGenSrc::kCodec_Mode:
627 folder.append("gen_codec");
628 break;
629 case ImageGenSrc::kPlatform_Mode:
630 folder.append("gen_platform");
631 break;
632 }
633
634 if (isGpu) {
635 folder.append("_gpu");
636 } else {
637 switch (alphaType) {
639 folder.append("_opaque");
640 break;
642 folder.append("_premul");
643 break;
645 folder.append("_unpremul");
646 break;
647 default:
648 break;
649 }
650 }
651
652 ImageGenSrc* src = new ImageGenSrc(path, mode, alphaType, isGpu);
653 push_src("image", folder, src);
654}

◆ push_sink()

static void push_sink ( const SkCommandLineConfig config,
Sink s 
)
static

Definition at line 952 of file DM.cpp.

952 {
953 std::unique_ptr<Sink> sink(s);
954
955 // Try a simple Src as a canary. If it fails, skip this sink.
956 struct : public Src {
958 c->drawRect(SkRect::MakeWH(1,1), SkPaint());
959 return Result::Ok();
960 }
961 SkISize size() const override { return SkISize::Make(16, 16); }
962 Name name() const override { return "justOneRect"; }
963 } justOneRect;
964
968 Result result = sink->draw(justOneRect, &bitmap, &stream, &log);
969 if (result.isFatal()) {
970 info("Could not run %s: %s\n", config.getTag().c_str(), result.c_str());
971 exit(1);
972 }
973
974 TaggedSink& ts = gSinks->push_back();
975 ts.reset(sink.release()); // NOLINT(misc-uniqueptr-reset-release)
976 ts.tag = config.getTag();
977}
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition: aaclip.cpp:27
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
struct MyStruct s
GAsyncResult * result
Definition: bitmap.py:1
exit(kErrorExitCode)
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static constexpr SkRect MakeWH(float w, float h)
Definition: SkRect.h:609
SkString tag
Definition: DM.cpp:499

◆ push_src()

static void push_src ( const char *  tag,
ImplicitString  options,
Src inSrc 
)
static

Definition at line 512 of file DM.cpp.

512 {
513 std::unique_ptr<Src> src(inSrc);
514 if (in_shard() && FLAGS_src.contains(tag) &&
515 !CommandLineFlags::ShouldSkip(FLAGS_match, src->name().c_str())) {
516 TaggedSrc& s = gSrcs->push_back();
517 s.reset(src.release()); // NOLINT(misc-uniqueptr-reset-release)
518 s.tag = tag;
519 s.options = options;
520 }
521}
const char * options

◆ run_cpu_test()

static void run_cpu_test ( skiatest::Test  test)
static

Definition at line 1508 of file DM.cpp.

1508 {
1510 if (!FLAGS_dryRun && !should_skip("_", "tests", "_", test.fName)) {
1512 start("unit", "test", "", test.fName);
1513 test.cpu(&reporter);
1514 }
1515 done("unit", "test", "", test.fName);
1516}
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
Definition: DM.cpp:263
static void start(const char *config, const char *src, const char *srcOptions, const char *name)
Definition: DM.cpp:312
reporter
Definition: FontMgrTest.cpp:39

◆ run_ganesh_test()

static void run_ganesh_test ( skiatest::Test  test,
const GrContextOptions grCtxOptions 
)
static

Definition at line 1518 of file DM.cpp.

1518 {
1520 if (!FLAGS_dryRun && !should_skip("_", "tests", "_", test.fName)) {
1522 GrContextOptions options = grCtxOptions;
1523 test.modifyGrContextOptions(&options);
1524
1526 start("unit", "test", "", test.fName);
1527 test.ganesh(&reporter, options);
1528 }
1529 done("unit", "test", "", test.fName);
1530}

◆ run_graphite_test()

static void run_graphite_test ( skiatest::Test  test,
skiatest::graphite::TestOptions options 
)
static

Definition at line 1532 of file DM.cpp.

1532 {
1534 if (!FLAGS_dryRun && !should_skip("_", "tests", "_", test.fName)) {
1536 test.modifyGraphiteContextOptions(&options.fContextOptions);
1537
1539 start("unit", "test", "", test.fName);
1540 test.graphite(&reporter, options);
1541 }
1542 done("unit", "test", "", test.fName);
1543}

◆ setup_crash_handler()

static void setup_crash_handler ( )
static

Definition at line 415 of file DM.cpp.

415 {
416 const int kSignals[] = { SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGINT, SIGSEGV, SIGTERM };
417 for (int sig : kSignals) {
418 previous_handler[sig] = signal(sig, crash_handler);
419 }
420 }
static void crash_handler(int sig)
Definition: DM.cpp:383

◆ should_skip()

static bool should_skip ( const char *  sink,
const char *  src,
const char *  srcOptions,
const char *  name 
)
static

Definition at line 1142 of file DM.cpp.

1143 {
1144 for (int i = 0; i < FLAGS_skip.size() - 3; i += 4) {
1145 if (match(FLAGS_skip[i+0], sink) &&
1146 match(FLAGS_skip[i+1], src) &&
1147 match(FLAGS_skip[i+2], srcOptions) &&
1148 match(FLAGS_skip[i+3], name)) {
1149 return true;
1150 }
1151 }
1152 return false;
1153}

◆ start()

static void start ( const char *  config,
const char *  src,
const char *  srcOptions,
const char *  name 
)
static

Definition at line 312 of file DM.cpp.

312 {
313 SkString id = SkStringPrintf("%s %s %s %s", config, src, srcOptions, name);
314 vlog("\tstart %s\n", id.c_str());
316 gRunning->push_back({id,SkGetThreadID()});
317}
const uintptr_t id

◆ vlog()

static void static void vlog ( const char *  fmt,
  ... 
)
static

Definition at line 201 of file DM.cpp.

201 {
202 if (gVLog) {
203 va_list args;
204 va_start(args, fmt);
205 vfprintf(gVLog, fmt, args);
206 fflush(gVLog);
207 va_end(args);
208 }
209}

Variable Documentation

◆ gCPUSerialTests

SkTDArray<skiatest::Test>* gCPUSerialTests = new SkTDArray<skiatest::Test>
static

Definition at line 1471 of file DM.cpp.

◆ gCPUTests

SkTDArray<skiatest::Test>* gCPUTests = new SkTDArray<skiatest::Test>
static

Definition at line 1470 of file DM.cpp.

◆ gCreateProtectedContext

bool gCreateProtectedContext
extern

Definition at line 45 of file GrContextFactory.cpp.

◆ gDefinitelyThreadSafeWork

SkTaskGroup* gDefinitelyThreadSafeWork = new SkTaskGroup
static

Definition at line 1157 of file DM.cpp.

◆ gFailures

TArray<SkString>* gFailures = new TArray<SkString>
static

Definition at line 232 of file DM.cpp.

◆ gForceHighPrecisionRasterPipeline

bool gForceHighPrecisionRasterPipeline
extern

Definition at line 29 of file SkRasterPipeline.cpp.

◆ gGaneshTests

SkTDArray<skiatest::Test>* gGaneshTests = new SkTDArray<skiatest::Test>
static

Definition at line 1472 of file DM.cpp.

◆ gGold

THashSet<Gold, Gold::Hash>* gGold = new THashSet<Gold, Gold::Hash>
static

Definition at line 443 of file DM.cpp.

◆ gGraphiteTests

SkTDArray<skiatest::Test>* gGraphiteTests = new SkTDArray<skiatest::Test>
static

Definition at line 1473 of file DM.cpp.

◆ gLastUpdate

double gLastUpdate
static

Definition at line 260 of file DM.cpp.

◆ gMutex

SkSpinlock gMutex
static

Definition at line 257 of file DM.cpp.

◆ gPending

int gPending
static

Definition at line 258 of file DM.cpp.

◆ gRunning

SkNoDestructor<TArray<Running> > gRunning
static

Definition at line 261 of file DM.cpp.

◆ gSinks

Definition at line 505 of file DM.cpp.

◆ gSkForceRasterPipelineBlitter

bool gSkForceRasterPipelineBlitter
extern

Definition at line 44 of file SkBlitter.cpp.

◆ gSrcs

Definition at line 504 of file DM.cpp.

◆ gTotalCounts

int gTotalCounts
static

Definition at line 259 of file DM.cpp.

◆ gUninterestingHashes

THashSet<SkString>* gUninterestingHashes = new THashSet<SkString>
static

Definition at line 467 of file DM.cpp.

◆ gVLog

FILE* gVLog
static

Definition at line 197 of file DM.cpp.

◆ kMemcpyOK

constexpr bool kMemcpyOK = true
staticconstexpr

Definition at line 502 of file DM.cpp.

◆ kNewline

constexpr char kNewline[] = "\n"
staticconstexpr

Definition at line 464 of file DM.cpp.

◆ previous_handler

void(* previous_handler[max_of(SIGABRT, SIGBUS, SIGFPE, SIGILL, SIGSEGV, SIGTERM)+1])(int) ( int  )
static

Definition at line 381 of file DM.cpp.