60#if defined(SK_ENABLE_SVG)
66#ifdef SK_ENABLE_ANDROID_UTILS
71#if defined(SK_GRAPHITE)
90#ifndef SK_BUILD_FOR_WIN
113 help.printf(
"Number of times to run each bench. Set this to %d to auto-"
114 "tune for each bench. Timings are only reported when auto-tuning.",
127static DEFINE_int(samples, 10,
"Number of samples to measure for each bench.");
128static DEFINE_int(ms, 0,
"If >0, run each bench for this many ms instead of obeying --samples.");
129static DEFINE_int(overheadLoops, 100000,
"Loops to estimate timer overhead.");
131 "Loop until timer overhead is at most this fraction of our measurments.");
134 "If unknown, estimated maximum number of frames GPU allows to lag.");
136static DEFINE_string(outResultsFile,
"",
"If given, write results here as JSON.");
138 "Try up to this many times to guess loops for a bench, or skip the bench.");
139static DEFINE_int(maxLoops, 1000000,
"Never run a bench more times than this.");
143 "Comma-separated zoomMax,zoomPeriodMs factors for a periodic SKP zoom "
144 "function that ping-pongs between 1.0 and zoomMax.");
146static DEFINE_bool(loopSKP,
true,
"Loop SKPs like we do for micro benches?");
147static DEFINE_int(flushEvery, 10,
"Flush --outResultsFile every Nth run.");
148static DEFINE_bool(gpuStats,
false,
"Print GPU stats after each gpu benchmark?");
149static DEFINE_bool(gpuStatsDump,
false,
"Dump GPU stats after each benchmark to json");
150static DEFINE_bool(dmsaaStatsDump,
false,
"Dump DMSAA stats after each benchmark to json");
151static DEFINE_bool(keepAlive,
false,
"Print a message every so often so that we don't time out");
154 "Apply usual --match rules to source type: bench, gm, skp, image, etc.");
156 "Apply usual --match rules to bench type: micro, recording, "
157 "piping, playback, skcodec, etc.");
159static DEFINE_bool(forceRasterPipeline,
false,
"sets gSkForceRasterPipelineBlitter");
160static DEFINE_bool(forceRasterPipelineHP,
false,
"sets gSkForceRasterPipelineBlitter and gForceHighPrecisionRasterPipeline");
163 "Log before running each test. May be incomprehensible when threading");
168 "just print the tests that would be run, without actually running them.");
170 "List of images and/or directories to decode. A directory with no images"
171 " is treated as a fatal error.");
173 "Runs of a subset of the codec tests, always N32, Premul or Opaque");
176 "[~][^]substring[$] [...] of name to run.\n"
177 "Multiple matches may be separated by spaces.\n"
178 "~ causes a matching name to always be skipped\n"
179 "^ requires the start of the name to match\n"
180 "$ requires the end of the name to match\n"
181 "^ and $ requires an exact match\n"
182 "If a name does not match any list entry,\n"
183 "it is skipped unless some list entry starts with ~");
185static DEFINE_bool2(quiet, q,
false,
"if true, don't print status updates.");
191static DEFINE_string(svgs,
"",
"Directory to read SVGs from, or a single SVG file.");
192static DEFINE_string(texttraces,
"",
"Directory to read TextBlobTrace files from.");
195 "Run threadsafe tests on a threadpool with this many extra threads, "
196 "defaulting to one extra thread per core.");
201 "Space-separated key/value pairs to add to JSON identifying this builder.");
203 "Space-separated key/value pairs to add to JSON identifying this run.");
206 "Call SkGraphics::PurgeAllCaches() between each benchmark?");
209 "Create separate perfetto trace files for each benchmark?\n"
210 "Will only take effect if perfetto tracing is enabled. See --trace.");
212static DEFINE_bool(runtimeCPUDetection,
true,
"Skip runtime CPU detection and optimization");
217 if (FLAGS_verbose)
return SkStringPrintf(
"%" PRIu64, (uint64_t)(ms*1e6));
220#define HUMANIZE(ms) humanize(ms).c_str()
238 SkDebugf(
"Can't read canvas pixels.\n");
273 *maxFrameLag = FLAGS_gpuFrameLag;
280 this->factory = std::make_unique<GrContextFactory>(
options);
283 this->factory->get(this->config.ctxType, this->config.ctxOverrides),
286 this->config.samples,
289 this->factory->getContextInfo(this->
config.ctxType, this->config.ctxOverrides);
294 SkDebugf(
"WARNING: GL context for config \"%s\" does not support fence sync. "
295 "Timings might not be accurate.\n", this->
config.name.c_str());
303 context->
priv().printCacheStats();
304 context->priv().printGpuStats();
305 context->priv().printContextStats();
309#if defined(SK_GRAPHITE)
310struct GraphiteTarget :
public Target {
311 explicit GraphiteTarget(
const Config& c) :
Target(c) {}
315 std::unique_ptr<ContextFactory> factory;
319 std::unique_ptr<skgpu::graphite::Recorder> recorder;
321 ~GraphiteTarget()
override {
329 if (context && recorder) {
330 std::unique_ptr<skgpu::graphite::Recording> recording = this->recorder->snap();
332 this->testContext->submitRecordingAndWaitOnSync(this->context, recording.get());
337 if (context && recorder) {
341 std::unique_ptr<skgpu::graphite::Recording> recording = this->recorder->snap();
344 info.fRecording = recording.get();
360 this->factory = std::make_unique<ContextFactory>();
363 this->factory->getContextInfo(this->config.ctxType);
370 this->recorder = this->context->
makeRecorder(ToolUtils::CreateTestingRecorderOptions());
371 if (!this->recorder) {
381 if (!this->contextInfo.testContext()->fenceSyncSupport()) {
382 SkDebugf(
"WARNING: GL context for config \"%s\" does not support fence sync. "
383 "Timings might not be accurate.\n", this->config.name.c_str());
399 bench->preDraw(canvas);
401 canvas =
target->beginTiming(canvas);
403 bench->draw(loops, canvas);
407 bench->postDraw(canvas);
413 for (
int i = 0;
i < FLAGS_overheadLoops;
i++) {
417 return overhead / FLAGS_overheadLoops;
430 SkDebugf(
"ERROR: clamping loops from %d to 1. "
431 "There's probably something wrong with the bench.\n", loops);
434 if (loops > FLAGS_maxLoops) {
435 SkDebugf(
"WARNING: clamping loops from %d to FLAGS_maxLoops, %d.\n", loops, FLAGS_maxLoops);
436 return FLAGS_maxLoops;
446 if (
target->getCanvas() &&
453 if (!
target->capturePixels(&bmp)) {
477 double bench_plus_overhead = 0.0;
479 int loops =
bench->shouldLoop() ? FLAGS_loops : 1;
481 while (bench_plus_overhead < overhead) {
482 if (
round++ == FLAGS_maxCalibrationAttempts) {
483 SkDebugf(
"WARNING: Can't estimate loops for %s (%s vs. %s); skipping.\n",
508 const double numer = overhead / FLAGS_overheadGoal - overhead;
509 const double denom = bench_plus_overhead - overhead;
510 loops = (
int)
ceil(numer / denom);
521 int loops =
bench->shouldLoop() ? FLAGS_loops : 1;
526 if (1<<30 == loops) {
534 for (
int i = 0;
i < maxGpuFrameLag;
i++) {
537 }
while (elapsed < FLAGS_gpuMs);
540 loops = (
int)
ceil(loops * FLAGS_gpuMs / elapsed);
544 target->submitWorkAndSyncCPU();
550 for (
int i = 0;
i < maxGpuFrameLag;
i++) {
557#define kBogusContextType skgpu::ContextType::kGL
558#define kBogusContextOverrides GrContextFactory::ContextOverrides::kNone
561 if (
const auto* gpuConfig = config->
asConfigGpu()) {
567 const auto ctxType = gpuConfig->getContextType();
568 const auto ctxOverrides = gpuConfig->getContextOverrides();
569 const auto sampleCount = gpuConfig->getSamples();
570 const auto colorType = gpuConfig->getColorType();
572 SkDebugf(
"This tool only supports the default surface type.");
577 if (
const auto ctx = factory.
get(ctxType, ctxOverrides)) {
579 int supportedSampleCount =
580 ctx->priv().caps()->getRenderTargetSampleCount(sampleCount,
format);
581 if (sampleCount != supportedSampleCount) {
582 SkDebugf(
"Configuration '%s' sample count %d is not a supported sample count.\n",
592 return Config{gpuConfig->getTag(),
600 gpuConfig->getSurfaceFlags()};
602#if defined(SK_GRAPHITE)
609 const auto graphiteCtxType = gpuConfig->getContextType();
610 const auto sampleCount = 1;
611 const auto colorType = gpuConfig->getColorType();
615 ContextFactory factory(gpuConfig->asConfigGraphite()->getOptions());
622 int supportedSampleCount =
623 ctx->
priv().
caps()->getRenderTargetSampleCount(sampleCount,
format);
624 if (sampleCount != supportedSampleCount) {
625 SkDebugf(
"Configuration '%s' sample count %d is not a supported sample count.\n",
631 if (sampleCount > 1) {
632 SkDebugf(
"Configuration '%s' sample count %d is not a supported sample count.\n",
643 return Config{gpuConfig->getTag(),
655#define CPU_CONFIG(name, backend, color, alpha) \
656 if (config->getBackend().equals(name)) { \
658 SkDebugf("Skipping config '%s' as requested.\n", config->getTag().c_str()); \
659 return std::nullopt; \
661 return Config{SkString(name), \
662 Benchmark::backend, \
665 config->refColorSpace(), \
668 kBogusContextOverrides, \
692 for (
int i = 0;
i < array.
size(); ++
i) {
699 if (array.
size() == 0 || FLAGS_config.size() == 0 ||
709#pragma warning ( push )
710#pragma warning ( disable : 4065 )
715 if (!
bench->isSuitableFor(config.backend)) {
724 switch (config.backend) {
728#if defined(SK_GRAPHITE)
730 target =
new GraphiteTarget(config);
746#pragma warning ( pop )
749#ifdef SK_ENABLE_ANDROID_UTILS
753 if (
nullptr == brd) {
758 if (sampleSize * minOutputSize > (uint32_t) brd->width() || sampleSize * minOutputSize >
759 (uint32_t) brd->height()) {
766 *
width = brd->width();
779 for (
int i = 0;
i < paths.
size(); ++
i) {
801 if (4 != sscanf(FLAGS_clip[0],
"%d,%d,%d,%d",
803 SkDebugf(
"Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0]);
807 for (
int i = 0;
i < FLAGS_scales.size();
i++) {
808 if (1 != sscanf(FLAGS_scales[
i],
"%f", &fScales.
push_back())) {
809 SkDebugf(
"Can't parse %s from --scales as an SkScalar.\n", FLAGS_scales[
i]);
814 if (2 != sscanf(FLAGS_zoom[0],
"%f,%lf", &fZoomMax, &fZoomPeriodMs)) {
815 SkDebugf(
"Can't parse %s from --zoom as a zoomMax,zoomPeriodMs.\n", FLAGS_zoom[0]);
826 if (!FLAGS_simpleCodec) {
875#if defined(SK_ENABLE_SVG)
902 std::unique_ptr<Benchmark>
bench;
910 return bench.release();
916 fBenches = fBenches->
next();
917 fSourceType =
"bench";
918 fBenchType =
"micro";
923 std::unique_ptr<skiagm::GM> gm = fGMs->
get()();
924 if (gm->isBazelOnly()) {
932 if (gm->runAsBench()) {
934 fBenchType =
"micro";
935 return new GMBench(std::move(gm));
939 while (fCurrentTextBlobTrace < fTextBlobTraces.
size()) {
940 SkString path = fTextBlobTraces[fCurrentTextBlobTrace++];
942 static constexpr char kEnding[] =
".trace";
946 fSourceType =
"texttrace";
947 fBenchType =
"micro";
950 [
path](){ return SkStream::MakeFromFile(path.c_str()); });
954 while (fCurrentRecording < fSKPs.
size()) {
962 fBenchType =
"recording";
969 while (fCurrentDeserialPicture < fSKPs.
size()) {
970 const SkString&
path = fSKPs[fCurrentDeserialPicture++];
977 fBenchType =
"deserial";
978 fSKPBytes =
static_cast<double>(
data->size());
984 while (fCurrentScale < fScales.
size()) {
985 while (fCurrentSKP < fSKPs.
size()) {
1002 fSourceType =
"skp";
1003 fBenchType =
"playback";
1004 return new SKPBench(
name.c_str(), pic.
get(), fClip, fScales[fCurrentScale],
1008 while (fCurrentSVG < fSVGs.
size()) {
1009 const char*
path = fSVGs[fCurrentSVG++].c_str();
1011 fSourceType =
"svg";
1012 fBenchType =
"playback";
1014 fScales[fCurrentScale], FLAGS_loopSKP);
1024 if (fZoomMax != 1.0f && fZoomPeriodMs > 0) {
1025 while (fCurrentAnimSKP < fSKPs.
size()) {
1043 while (fCurrentMSKP < fMSKPs.
size()) {
1045 std::unique_ptr<MSKPPlayer> player =
ReadMSKP(
path.c_str());
1050 fSourceType =
"mskp";
1051 fBenchType =
"mskp";
1055 for (; fCurrentCodec < fImages.
size(); fCurrentCodec++) {
1056 fSourceType =
"image";
1057 fBenchType =
"skcodec";
1070 while (fCurrentColorType < fColorTypes.
size()) {
1073 SkAlphaType alphaType = codec->getInfo().alphaType();
1074 if (FLAGS_simpleCodec) {
1079 fCurrentColorType++;
1081 switch (alphaType) {
1084 fCurrentColorType++;
1088 if (0 == fCurrentAlphaType) {
1091 fCurrentAlphaType++;
1095 fCurrentAlphaType = 0;
1096 fCurrentColorType++;
1101 fCurrentColorType++;
1108 codec->getInfo().makeColorType(
colorType).makeAlphaType(alphaType);
1109 const size_t rowBytes =
info.minRowBytes();
1113 info, storage.
get(), rowBytes);
1128 fCurrentColorType = 0;
1132 const int sampleSizes[] = { 2, 4, 8 };
1133 for (; fCurrentAndroidCodec < fImages.
size(); fCurrentAndroidCodec++) {
1134 fSourceType =
"image";
1135 fBenchType =
"skandroidcodec";
1149 while (fCurrentSampleSize < (
int)
std::size(sampleSizes)) {
1150 int sampleSize = sampleSizes[fCurrentSampleSize];
1151 fCurrentSampleSize++;
1152 if (10 * sampleSize >
std::min(codec->getInfo().width(), codec->getInfo().height())) {
1158 encoded.
get(), sampleSize);
1160 fCurrentSampleSize = 0;
1163#ifdef SK_ENABLE_ANDROID_UTILS
1177 const uint32_t brdSampleSizes[] = { 1, 2, 4, 8, 16 };
1178 const uint32_t minOutputSize = 512;
1179 for (; fCurrentBRDImage < fImages.
size(); fCurrentBRDImage++) {
1180 fSourceType =
"image";
1188 while (fCurrentColorType < fColorTypes.
size()) {
1189 while (fCurrentSampleSize < (
int)
std::size(brdSampleSizes)) {
1190 while (fCurrentSubsetType <= kLastSingle_SubsetType) {
1194 uint32_t sampleSize = brdSampleSizes[fCurrentSampleSize];
1195 int currentSubsetType = fCurrentSubsetType++;
1199 if (!valid_brd_bench(encoded,
colorType, sampleSize, minOutputSize,
1206 const uint32_t subsetSize = sampleSize * minOutputSize;
1207 switch (currentSubsetType) {
1208 case kTopLeft_SubsetType:
1212 case kTopRight_SubsetType:
1217 case kMiddle_SubsetType:
1220 (
height - subsetSize) / 2, subsetSize, subsetSize);
1222 case kBottomLeft_SubsetType:
1227 case kBottomRight_SubsetType:
1230 height - subsetSize, subsetSize, subsetSize);
1236 return new BitmapRegionDecoderBench(
basename.c_str(), encoded.
get(),
1239 fCurrentSubsetType = 0;
1240 fCurrentSampleSize++;
1242 fCurrentSampleSize = 0;
1243 fCurrentColorType++;
1245 fCurrentColorType = 0;
1253 log.appendCString(
"source_type", fSourceType);
1254 log.appendCString(
"bench_type", fBenchType);
1255 if (0 == strcmp(fSourceType,
"skp")) {
1256 log.appendString(
"clip",
1265 if (0 == strcmp(fBenchType,
"recording")) {
1266 log.appendMetric(
"bytes", fSKPBytes);
1267 log.appendMetric(
"ops", fSKPOps);
1272#ifdef SK_ENABLE_ANDROID_UTILS
1274 kTopLeft_SubsetType = 0,
1275 kTopRight_SubsetType = 1,
1276 kMiddle_SubsetType = 2,
1277 kBottomLeft_SubsetType = 3,
1278 kBottomRight_SubsetType = 4,
1279 kTranslate_SubsetType = 5,
1280 kZoom_SubsetType = 6,
1281 kLast_SubsetType = kZoom_SubsetType,
1282 kLastSingle_SubsetType = kBottomRight_SubsetType,
1297 double fZoomPeriodMs;
1299 double fSKPBytes, fSKPOps;
1301 const char* fSourceType;
1302 const char* fBenchType;
1303 int fCurrentRecording = 0;
1304 int fCurrentDeserialPicture = 0;
1305 int fCurrentMSKP = 0;
1306 int fCurrentScale = 0;
1307 int fCurrentSKP = 0;
1308 int fCurrentSVG = 0;
1309 int fCurrentTextBlobTrace = 0;
1310 int fCurrentCodec = 0;
1311 int fCurrentAndroidCodec = 0;
1312#ifdef SK_ENABLE_ANDROID_UTILS
1313 int fCurrentBRDImage = 0;
1314 int fCurrentSubsetType = 0;
1316 int fCurrentColorType = 0;
1317 int fCurrentAlphaType = 0;
1318 int fCurrentSampleSize = 0;
1319 int fCurrentAnimSKP = 0;
1325 static std::thread* intentionallyLeaked =
new std::thread([]{
1327 static const int kSec = 1200;
1328 #if defined(SK_BUILD_FOR_WIN)
1333 SkDebugf(
"\nBenchmarks still running...\n");
1336 (void)intentionallyLeaked;
1341 void compileError(
const char* shader,
const char*
errors)
override {
1354#if defined(SK_BUILD_FOR_IOS)
1358 if (FLAGS_runtimeCPUDetection) {
1375 FLAGS_gpuFrameLag = 0;
1378 if (!FLAGS_writePath.isEmpty()) {
1379 SkDebugf(
"Writing files to %s.\n", FLAGS_writePath[0]);
1380 if (!
sk_mkdir(FLAGS_writePath[0])) {
1381 SkDebugf(
"Could not create %s. Files won't be written.\n", FLAGS_writePath[0]);
1382 FLAGS_writePath.set(0,
nullptr);
1387 if (!FLAGS_outResultsFile.isEmpty()) {
1388#if defined(SK_RELEASE)
1389 logStream.reset(
new SkFILEWStream(FLAGS_outResultsFile[0]));
1391 SkDebugf(
"I'm ignoring --outResultsFile because this is a Debug build.");
1398 if (1 == FLAGS_properties.size() % 2) {
1399 SkDebugf(
"ERROR: --properties must be passed with an even number of arguments.\n");
1402 for (
int i = 1;
i < FLAGS_properties.size();
i += 2) {
1403 log.appendCString(FLAGS_properties[
i-1], FLAGS_properties[
i]);
1406 if (1 == FLAGS_key.size() % 2) {
1407 SkDebugf(
"ERROR: --key must be passed with an even number of arguments.\n");
1410 if (FLAGS_key.size()) {
1411 log.beginObject(
"key");
1412 for (
int i = 1;
i < FLAGS_key.size();
i += 2) {
1413 log.appendCString(FLAGS_key[
i - 1], FLAGS_key[
i]);
1419 if (!FLAGS_quiet && !FLAGS_csv) {
1426 SkDebugf(
"Fixed number of loops; times would only be misleading so we won't print them.\n");
1427 }
else if (FLAGS_quiet) {
1428 SkDebugf(
"! -> high variance, ? -> moderate variance\n");
1430 }
else if (FLAGS_csv) {
1431 SkDebugf(
"min,median,mean,max,stddev,config,bench\n");
1432 }
else if (FLAGS_ms) {
1433 SkDebugf(
"curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\n");
1435 SkDebugf(
"curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconfig\tbench\n",
1436 FLAGS_samples,
"samples");
1444 if (FLAGS_keepAlive) {
1455 log.beginObject(
"results");
1462 std::unique_ptr<Benchmark>
bench(
b);
1469 bench->getUniqueName(),
bench->getSize().width(),
bench->getSize().height());
1470 bench->delayedSetup();
1480 const char* config =
target->config.name.c_str();
1482 if (FLAGS_pre_log || FLAGS_dryRun) {
1484 ,
bench->getUniqueName()
1491 if (FLAGS_purgeBetweenBenches) {
1495 if (FLAGS_splitPerfettoTracesByBenchmark) {
1502 bench->perCanvasPreDraw(canvas);
1505 int loops =
target->needsFrameTiming(&maxFrameLag)
1515 if (runs == 0 && FLAGS_ms < 1000) {
1518 auto stop =
now_ms() + 1000;
1522 }
while (
now_ms() < stop);
1527 auto stop =
now_ms() + FLAGS_ms;
1531 }
while (
now_ms() < stop);
1533 samples.
reset(FLAGS_samples);
1534 for (
int s = 0;
s < FLAGS_samples;
s++) {
1541 for (
double& sample : samples) {
1542 sample *= (1.0 /
bench->getUnits());
1548 if (FLAGS_gpuStatsDump) {
1554 dmsaaStats.dumpKeyValuePairs(&keys, &
values);
1560 bench->perCanvasPostDraw(canvas);
1563 !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) {
1566 pngFilename.
append(
".png");
1572 const bool want_plot = !FLAGS_quiet && !FLAGS_ms;
1575 log.beginObject(config);
1577 log.beginObject(
"options");
1578 log.appendCString(
"name",
bench->getName());
1583 log.appendMetric(
"min_ms",
stats.min);
1585 log.beginArray(
"samples");
1586 for (
double sample : samples) {
1587 log.appendDoubleDigits(sample, 16);
1591 if (!keys.
empty()) {
1594 for (
int j = 0; j < keys.
size(); j++) {
1595 log.appendMetric(keys[j].c_str(),
values[j]);
1601 if (runs++ % FLAGS_flushEvery == 0) {
1612 ,
bench->getUniqueName()
1615 }
else if (FLAGS_quiet) {
1616 const char*
mark =
" ";
1617 const double stddev_percent =
1619 if (stddev_percent > 5)
mark =
"?";
1620 if (stddev_percent > 10)
mark =
"!";
1624 }
else if (FLAGS_csv) {
1625 const double stddev_percent =
1634 ,
bench->getUniqueName()
1637 const double stddev_percent =
1639 SkDebugf(
"%4d/%-4dMB\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n"
1650 ,
bench->getUniqueName()
1658 if (FLAGS_verbose) {
1660 for (
int j = 0; j < samples.size(); j++) {
1673 if (FLAGS_dmsaaStatsDump) {
1674 SkDebugf(
"<<Total Combined DMSAA Stats>>\n");
1680 log.beginBench(
"memory_usage", 0, 0);
1681 log.beginObject(
"meta");
void ParseConfigs(const CommandLineFlags::StringArray &configs, SkCommandLineConfigArray *outResult)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
void initializeEventTracingForTools(const char *traceFlag)
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
GrRecordingContextPriv::DMSAAStats combinedDMSAAStats
static void round(SkPoint *p)
@ kOpaque_SkAlphaType
pixel is opaque
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#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
@ 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
@ kUnknown_SkColorType
uninitialized
constexpr SkColor SK_ColorWHITE
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
static constexpr double sk_ieee_double_divide(double numer, double denom)
Benchmark * CreateDiffCanvasBench(SkString name, std::function< std::unique_ptr< SkStreamAsset >()> dataSrc)
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
#define SK_INTENTIONALLY_LEAKED(X)
static constexpr int32_t SK_MaxS32
bool sk_mkdir(const char *path)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
void RunSkSLModuleBenchmarks(NanoJSONResultsWriter *log)
static void bench(NanoJSONResultsWriter *log, const char *name, int bytes)
bool SkStrEndsWith(const char string[], const char suffixStr[])
SK_API SkString SkStringPrintf(const char *format,...) SK_PRINTF_LIKE(1
Creates a new string and writes into it using a printf()-style format.
#define TRACE_EVENT_API_NEW_TRACE_SECTION
#define TRACE_STR_COPY(str)
SkString HumanizeMs(double ms)
static std::unique_ptr< MSKPPlayer > ReadMSKP(const char *path)
static sk_sp< SkPicture > ReadSVGPicture(const char *path)
void fillCurrentOptions(NanoJSONResultsWriter &log) const
static sk_sp< SkPicture > ReadPicture(const char *path)
void fillCurrentMetrics(NanoJSONResultsWriter &log) const
static bool ShouldSkip(const SkTDArray< const char * > &strings, const char *name)
static void Parse(int argc, const char *const *argv)
GrDirectContextPriv priv()
GrRecordingContextPriv priv()
static std::unique_ptr< MSKPPlayer > Make(SkStreamSeekable *stream)
static sk_sp< Animation > MakeZoomAnimation(SkScalar zoomMax, double zoomPeriodMs)
static std::unique_ptr< SkAndroidCodec > MakeFromData(sk_sp< SkData >, SkPngChunkReader *=nullptr)
void allocPixels(const SkImageInfo &info, size_t rowBytes)
const SkPixmap & pixmap() const
virtual GrRecordingContext * recordingContext() const
void clear(SkColor color)
SkImageInfo imageInfo() const
bool readPixels(const SkImageInfo &dstInfo, void *dstPixels, size_t dstRowBytes, int srcX, int srcY)
static std::unique_ptr< SkCodec > MakeFromData(sk_sp< SkData >, SkSpan< const SkCodecs::Decoder > decoders, SkPngChunkReader *=nullptr)
sk_sp< SkColorSpace > refColorSpace() const
const SkString & getTag() const
virtual const SkCommandLineConfigGpu * asConfigGpu() const
virtual const SkCommandLineConfigGraphite * asConfigGraphite() const
static sk_sp< SkData > MakeFromFileName(const char path[])
static void PurgeAllCaches()
SK_SPI bool next(SkString *name, bool getDir=false)
static SkString Join(const char *rootPath, const char *relativePath)
static SkString Basename(const char *fullPath)
static SkString Dirname(const char *fullPath)
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
virtual SkRect cullRect() const =0
virtual void playback(SkCanvas *canvas, AbortCallback *callback=nullptr) const =0
virtual size_t approximateBytesUsed() const =0
static sk_sp< SkPicture > MakeFromStream(SkStream *stream, const SkDeserialProcs *procs=nullptr)
virtual int approximateOpCount(bool nested=false) const =0
void render(SkCanvas *) const
void setContainerSize(const SkSize &)
const SkSize & containerSize() const
static std::unique_ptr< SkStreamAsset > MakeFromFile(const char path[])
void append(const char text[])
void appendS32(int32_t value)
const char * c_str() const
static std::unique_ptr< BitmapRegionDecoder > Make(sk_sp< SkData > data)
GrDirectContext * directContext() const
TestContext * testContext() const
GrDirectContext * get(ContextType type, ContextOverrides overrides=ContextOverrides::kNone)
bool getMaxGpuFrameLag(int *maxFrameLag) const
void flushAndWaitOnSync(GrDirectContext *context)
void flushAndSyncCpu(GrDirectContext *)
bool fenceSyncSupport() const
void reset(T *ptr=nullptr)
const Caps * caps() const
std::unique_ptr< Recorder > makeRecorder(const RecorderOptions &={})
bool submit(SyncToCpu=SyncToCpu::kNo)
bool insertRecording(const InsertRecordingInfo &)
@ kRaster
Suitable for thread which raster data.
uint32_t uint32_t * format
static void mark(SkCanvas *canvas, SkScalar x, SkScalar y, Fn &&fn)
static float min(float r, float g, float b)
std::array< MockImage, 3 > images
bool CollectImages(const CommandLineFlags::StringArray &dir, skia_private::TArray< SkString > *output)
void SetCtxOptions(struct GrContextOptions *)
void SK_API Register(Decoder d)
constexpr SkCodecs::Decoder Decoder()
constexpr SkCodecs::Decoder Decoder()
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
std::string BuildShaderErrorMessage(const char *shader, const char *errors)
sk_sp< Factory > BestAvailable()
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
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)
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
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 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_tools::Registry< GMFactory > GMRegistry
SIN Vec< N, float > sqrt(const Vec< N, float > &x)
SIN Vec< N, float > ceil(const Vec< N, float > &x)
static Target * is_enabled(Benchmark *bench, const Config &config)
void create_configs(TArray< Config > *configs)
#define kBogusContextOverrides
static std::optional< Config > create_config(const SkCommandLineConfig *config)
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 void cleanup_run(Target *target)
static int setup_gpu_bench(Target *target, Benchmark *bench, int maxGpuFrameLag)
int main(int argc, char **argv)
static bool write_canvas_png(Target *target, const SkString &filename)
static SkString to_string(int n)
static DEFINE_bool2(pre_log, p, false, "Log before running each test. May be incomprehensible when threading")
static void start_keepalive()
static void collect_files(const CommandLineFlags::StringArray &paths, const char *ext, TArray< SkString > *list)
static double time(int loops, Benchmark *bench, Target *target)
bool gForceHighPrecisionRasterPipeline
static int detect_forever_loops(int loops)
static double estimate_timer_overhead()
static DEFINE_bool(bbh, true, "Build a BBH for SKPs?")
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 SkString humanize(double ms)
static SkString loops_help_txt()
static int setup_cpu_bench(const double overhead, Target *target, Benchmark *bench)
static DEFINE_string(outResultsFile, "", "If given, write results here as JSON.")
static const int kAutoTuneLoops
bool gSkForceRasterPipelineBlitter
static DEFINE_double(overheadGoal, 0.0001, "Loop until timer overhead is at most this fraction of our measurments.")
static int clamp_loops(int loops)
#define CPU_CONFIG(name, backend, color, alpha)
static DEFINE_int(loops, kAutoTuneLoops, loops_help_txt().c_str())
GrContextOptions grContextOpts
void submitWorkAndSyncCPU() override
bool init(SkImageInfo info, Benchmark *bench) override
GPUTarget(const Config &c)
bool needsFrameTiming(int *maxFrameLag) const override
std::unique_ptr< GrContextFactory > factory
void dumpStats() override
void endTiming() override
ShaderErrorHandler * fShaderErrorHandler
int32_t fBottom
larger y-axis bounds
int32_t fTop
smaller y-axis bounds
static constexpr SkIRect MakeXYWH(int32_t x, int32_t y, int32_t w, int32_t h)
int32_t fLeft
smaller x-axis bounds
int32_t fRight
larger x-axis bounds
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
constexpr float height() const
constexpr float width() const
static constexpr SkSize Make(SkScalar w, SkScalar h)
virtual void submitWorkAndSyncCPU()
sk_sp< SkSurface > surface
virtual bool capturePixels(SkBitmap *bmp)
virtual bool needsFrameTiming(int *frameLag) const
virtual bool init(SkImageInfo info, Benchmark *bench)
SkCanvas * getCanvas() const
GraphiteTestContext * fTestContext
skgpu::graphite::Context * fContext
std::shared_ptr< const fml::Mapping > data
#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)