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.");
186static DEFINE_bool2(verbose, v,
false,
"enable verbose output from the test driver.");
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 {
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();
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)) {
459 SkDebugf(
"Can't make dir %s.\n", dir.c_str());
463 if (!stream.isValid()) {
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) {
693 if (std::optional<Config> config =
create_config(array[i].get())) {
694 configs->push_back(*config);
699 if (array.
size() == 0 || FLAGS_config.size() == 0 ||
701 array.
size() == configs->size()) {
709#pragma warning ( push )
710#pragma warning ( disable : 4065 )
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) {
785 while (it.
next(&path)) {
795 , fGMs(
skiagm::GMRegistry::Head()) {
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) {
842 SkDebugf(
"Could not read %s.\n", path);
849 static std::unique_ptr<MSKPPlayer>
ReadMSKP(
const char* path) {
858 SkDebugf(
"Could not read %s.\n", path);
871 SkDebugf(
"Could not read %s.\n", path);
875#if defined(SK_ENABLE_SVG)
882 SkDebugf(
"Could not parse %s.\n", path);
888 if (svgDom->containerSize().isEmpty()) {
889 svgDom->setContainerSize(kDefaultContainerSize);
893 svgDom->render(recorder.
beginRecording(svgDom->containerSize().width(),
894 svgDom->containerSize().height()));
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";
943 if (basename.endsWith(kEnding)) {
944 basename.remove(basename.size() - strlen(kEnding), strlen(kEnding));
946 fSourceType =
"texttrace";
947 fBenchType =
"micro";
950 [path](){ return SkStream::MakeFromFile(path.c_str()); });
954 while (fCurrentRecording < fSKPs.
size()) {
955 const SkString& path = fSKPs[fCurrentRecording++];
962 fBenchType =
"recording";
963 fSKPBytes =
static_cast<double>(pic->approximateBytesUsed());
964 fSKPOps = pic->approximateOpCount();
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()) {
986 const SkString& path = fSKPs[fCurrentSKP++];
997 pic->cullRect().height(),
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()) {
1026 const SkString& path = fSKPs[fCurrentAnimSKP];
1043 while (fCurrentMSKP < fMSKPs.
size()) {
1044 const SkString& path = fMSKPs[fCurrentMSKP++];
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";
1058 const SkString& path = fImages[fCurrentCodec];
1066 SkDebugf(
"Cannot find codec for %s\n", path.c_str());
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++;
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";
1137 const SkString& path = fImages[fCurrentAndroidCodec];
1145 SkDebugf(
"Cannot find codec for %s\n", path.c_str());
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";
1183 const SkString& path = fImages[fCurrentBRDImage];
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:
1209 basename.append(
"_TopLeft");
1212 case kTopRight_SubsetType:
1213 basename.append(
"_TopRight");
1217 case kMiddle_SubsetType:
1218 basename.append(
"_Middle");
1220 (
height - subsetSize) / 2, subsetSize, subsetSize);
1222 case kBottomLeft_SubsetType:
1223 basename.append(
"_BottomLeft");
1227 case kBottomRight_SubsetType:
1228 basename.append(
"_BottomRight");
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",
1260 log.appendString(
"scale",
SkStringPrintf(
"%.2g", fScales[fCurrentScale]));
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;
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);
1467 if (!configs.empty()) {
1469 bench->getUniqueName(),
bench->getSize().width(),
bench->getSize().height());
1470 bench->delayedSetup();
1472 for (
int i = 0; i < configs.size(); ++i) {
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) {
1550 bench->getGpuStats(canvas, &keys, &values);
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;
1574 Stats stats(samples, want_plot);
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) {
1606 if (configs.size() == 1) {
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 =
"!";
1623 stats.median*1e3,
mark,
bench->getUniqueName(), config);
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++) {
1668 if (!configs.empty()) {
1673 if (FLAGS_dmsaaStatsDump) {
1674 SkDebugf(
"<<Total Combined DMSAA Stats>>\n");
1680 log.beginBench(
"memory_usage", 0, 0);
1681 log.beginObject(
"meta");
#define DEFINE_bool(name, defaultValue, helpString)
#define DEFINE_int(name, defaultValue, helpString)
#define DEFINE_bool2(name, shortName, defaultValue, helpString)
#define DEFINE_string2(name, shortName, defaultValue, helpString)
#define DEFINE_double(name, defaultValue, helpString)
#define DEFINE_int_2(name, shortName, defaultValue, helpString)
#define DEFINE_string(name, defaultValue, helpString)
void ParseConfigs(const CommandLineFlags::StringArray &configs, SkCommandLineConfigArray *outResult)
static bool match(const char *needle, const char *haystack)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
void initializeEventTracingForTools(const char *traceFlag)
GrRecordingContextPriv::DMSAAStats combinedDMSAAStats
static void round(SkPoint *p)
@ kOpaque_SkAlphaType
pixel is opaque
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SkAssertResult(cond)
#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)
SK_API SkString static SkString SkStringPrintf()
bool SkStrEndsWith(const char string[], const char suffixStr[])
#define TRACE_EVENT_API_NEW_TRACE_SECTION
#define TRACE_STR_COPY(str)
SkString HumanizeMs(double ms)
Type::kYUV Type::kRGBA() int(0.7 *637)
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)
void compileError(const char *shader, const char *errors) override
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()
static sk_sp< SkPicture > MakeFromStream(SkStream *stream, const SkDeserialProcs *procs=nullptr)
Builder & setTextShapingFactory(sk_sp< SkShapers::Factory >)
sk_sp< SkSVGDOM > make(SkStream &) const
Builder & setFontManager(sk_sp< SkFontMgr >)
static std::unique_ptr< SkStreamAsset > MakeFromFile(const char path[])
void append(const char text[])
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 &)
uint32_t uint32_t * format
static void mark(SkCanvas *canvas, SkScalar x, SkScalar y, Fn &&fn)
bool CollectImages(const CommandLineFlags::StringArray &dir, skia_private::TArray< SkString > *output)
void SetCtxOptions(struct GrContextOptions *)
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)
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 void cleanup_run(Target *target)
static int setup_gpu_bench(Target *target, Benchmark *bench, int maxGpuFrameLag)
static bool write_canvas_png(Target *target, const SkString &filename)
static SkString to_string(int n)
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 SkString humanize(double ms)
static SkString loops_help_txt()
static int setup_cpu_bench(const double overhead, Target *target, Benchmark *bench)
static const int kAutoTuneLoops
bool gSkForceRasterPipelineBlitter
static int clamp_loops(int loops)
#define CPU_CONFIG(name, backend, color, alpha)
GrContextOptions grContextOpts
Benchmark::Backend backend
sk_sp< SkColorSpace > colorSpace
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
SkImageInfo makeAlphaType(SkAlphaType newAlphaType) const
size_t minRowBytes() const
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
SkImageInfo makeColorType(SkColorType newColorType) 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
#define TRACE_EVENT2(category_group, name, arg1_name, arg1_val, arg2_name, arg2_val)