1f372321de3d4183de5b9ca436e677e471e358f31mtklein/* 2f372321de3d4183de5b9ca436e677e471e358f31mtklein * Copyright 2014 Google Inc. 3f372321de3d4183de5b9ca436e677e471e358f31mtklein * 4f372321de3d4183de5b9ca436e677e471e358f31mtklein * Use of this source code is governed by a BSD-style license that can be 5f372321de3d4183de5b9ca436e677e471e358f31mtklein * found in the LICENSE file. 6f372321de3d4183de5b9ca436e677e471e358f31mtklein */ 7f372321de3d4183de5b9ca436e677e471e358f31mtklein 8bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#include <ctype.h> 9bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 10d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#include "nanobench.h" 11d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 1284451024bfe06d138629dd7c27cf2ec0f9774dbemsarett#include "AndroidCodecBench.h" 13f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Benchmark.h" 147f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett#include "BitmapRegionDecoderBench.h" 1560869a42a133942f852dd0f1696444c2a5c9ad83scroggo#include "CodecBench.h" 167f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett#include "CodecBenchPriv.h" 17f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "CrashHandler.h" 18e714e75c725c987fe682a1f5473224fe3e80380dmtklein#include "GMBench.h" 19afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein#include "ProcStats.h" 2060317d0ffb5053df7b08a627d6decd11b684e80dmtklein#include "ResultsWriter.h" 21fd731ce804cd3223318f3feee2c98404890b65f2mtklein#include "RecordingBench.h" 22261c3ad7fde95748da92550735decc949dc73bf2joshualitt#include "SKPAnimationBench.h" 2392007583e43115998412ac8b0a06cc2780eb025cmtklein#include "SKPBench.h" 24f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Stats.h" 25f372321de3d4183de5b9ca436e677e471e358f31mtklein 2684451024bfe06d138629dd7c27cf2ec0f9774dbemsarett#include "SkAndroidCodec.h" 275cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett#include "SkBitmapRegionDecoder.h" 286838d854a87e79f1fbb7b89b9f395155ad44dc0amtklein#include "SkBBoxHierarchy.h" 29f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkCanvas.h" 3060869a42a133942f852dd0f1696444c2a5c9ad83scroggo#include "SkCodec.h" 3117f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclark#include "SkCommonFlags.h" 323e980c3d88fbc509b79e7ccef16ca38f5bbfb180kkinnunen#include "SkCommonFlagsConfig.h" 3395f192d19938b98a45dd1fa4112d965f60d10516msarett#include "SkData.h" 34f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkForceLinking.h" 35f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkGraphics.h" 362084050a33ae139d0fe9bb680f7905f91139a39fmtklein#include "SkOSFile.h" 372084050a33ae139d0fe9bb680f7905f91139a39fmtklein#include "SkPictureRecorder.h" 38051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein#include "SkPictureUtils.h" 39f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkString.h" 40f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkSurface.h" 415b69377507478623dcf5b11f3ecb010f87c4794frobertphillips#include "SkTaskGroup.h" 42c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett#include "SkThreadUtils.h" 433ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt#include "ThermalManager.h" 44f372321de3d4183de5b9ca436e677e471e358f31mtklein 4560e0fee6d4acff638ccc9670c4055aced529a7a0bungeman#include <stdlib.h> 4660e0fee6d4acff638ccc9670c4055aced529a7a0bungeman 4738ce0a7fe93444aa9184f1492656ceefdd75e74bscroggo#ifndef SK_BUILD_FOR_WIN32 4838ce0a7fe93444aa9184f1492656ceefdd75e74bscroggo #include <unistd.h> 4938ce0a7fe93444aa9184f1492656ceefdd75e74bscroggo#endif 5038ce0a7fe93444aa9184f1492656ceefdd75e74bscroggo 51d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 52d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson #include "nanobenchAndroid.h" 53d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 54d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 55bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 56bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio #include "gl/GrGLDefines.h" 57762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon #include "GrCaps.h" 58bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein #include "GrContextFactory.h" 5969a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski SkAutoTDelete<GrContextFactory> gGrFactory; 60bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 61bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 62682c269a1511200322916af83053e26004c0ec40bsalomon struct GrContextOptions; 63682c269a1511200322916af83053e26004c0ec40bsalomon 64f372321de3d4183de5b9ca436e677e471e358f31mtklein__SK_FORCE_IMAGE_DECODER_LINKING; 65f372321de3d4183de5b9ca436e677e471e358f31mtklein 665324978a88677ac6b758324321816427814e7793reedstatic const int kAutoTuneLoops = 0; 676eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 68b511042bb07a6a289b0d1146cb57f6e8b80580d6mtkleinstatic const int kDefaultLoops = 696eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon#ifdef SK_DEBUG 706eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 1; 71a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein#else 726eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon kAutoTuneLoops; 73a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein#endif 74a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 756eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic SkString loops_help_txt() { 766eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString help; 776eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon help.printf("Number of times to run each bench. Set this to %d to auto-" 786eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon "tune for each bench. Timings are only reported when auto-tuning.", 796eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon kAutoTuneLoops); 806eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return help; 816eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 826eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 83e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdaltonstatic SkString to_string(int n) { 84e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton SkString str; 85e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton str.appendS32(n); 86e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton return str; 87e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton} 88e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton 896eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonDEFINE_int32(loops, kDefaultLoops, loops_help_txt().c_str()); 906eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 91f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_int32(samples, 10, "Number of samples to measure for each bench."); 92bbba16878f343b232d844281fbdf056c00e20fb6mtkleinDEFINE_int32(ms, 0, "If >0, run each bench for this many ms instead of obeying --samples."); 93f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_int32(overheadLoops, 100000, "Loops to estimate timer overhead."); 94f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_double(overheadGoal, 0.0001, 95f372321de3d4183de5b9ca436e677e471e358f31mtklein "Loop until timer overhead is at most this fraction of our measurments."); 96bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinDEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); 97d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdaltonDEFINE_int32(gpuFrameLag, 5, "If unknown, estimated maximum number of frames GPU allows to lag."); 9812b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevskiDEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling back to " 9912b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski "software path rendering."); 100f372321de3d4183de5b9ca436e677e471e358f31mtklein 10160317d0ffb5053df7b08a627d6decd11b684e80dmtkleinDEFINE_string(outResultsFile, "", "If given, write results here as JSON."); 10255b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinDEFINE_int32(maxCalibrationAttempts, 3, 10355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein "Try up to this many times to guess loops for a bench, or skip the bench."); 10455b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinDEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this."); 10592007583e43115998412ac8b0a06cc2780eb025cmtkleinDEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs."); 10692007583e43115998412ac8b0a06cc2780eb025cmtkleinDEFINE_string(scales, "1.0", "Space-separated scales for SKPs."); 10763a82855b1f0b83952b65fca330954c50ebe7a4bcdaltonDEFINE_string(zoom, "1.0,0", "Comma-separated zoomMax,zoomPeriodMs factors for a periodic SKP zoom " 10863a82855b1f0b83952b65fca330954c50ebe7a4bcdalton "function that ping-pongs between 1.0 and zoomMax."); 1092084050a33ae139d0fe9bb680f7905f91139a39fmtkleinDEFINE_bool(bbh, true, "Build a BBH for SKPs?"); 1105b69377507478623dcf5b11f3ecb010f87c4794frobertphillipsDEFINE_bool(mpd, true, "Use MultiPictureDraw for the SKPs?"); 111b4022965a280dd1ed64d6103dd29e2189abe6e00cdaltonDEFINE_bool(loopSKP, true, "Loop SKPs like we do for micro benches?"); 112e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtkleinDEFINE_int32(flushEvery, 10, "Flush --outResultsFile every Nth run."); 11355e88b226ccb85d2c712a9e3e9e1f5bdcaac05acmtkleinDEFINE_bool(resetGpuContext, true, "Reset the GrContext before running each test."); 114b12ea41286ce36e085c5a14711da0cf9f240fdf1bsalomonDEFINE_bool(gpuStats, false, "Print GPU stats after each gpu benchmark?"); 115e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualittDEFINE_bool(gpuStatsDump, false, "Dump GPU states after each benchmark to json"); 116c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarettDEFINE_bool(keepAlive, false, "Print a message every so often so that we don't time out"); 1173ebd050be551e9d1364dbd115708e8f86397cd6fjoshualittDEFINE_string(useThermalManager, "0,1,10,1000", "enabled,threshold,sleepTimeMs,TimeoutMs for " 1183ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt "thermalManager\n"); 11992007583e43115998412ac8b0a06cc2780eb025cmtklein 12065dfd2fe5d93d63b655663707c7233917e293accmtkleinDEFINE_string(sourceType, "", 12165dfd2fe5d93d63b655663707c7233917e293accmtklein "Apply usual --match rules to source type: bench, gm, skp, image, etc."); 12265dfd2fe5d93d63b655663707c7233917e293accmtkleinDEFINE_string(benchType, "", 12365dfd2fe5d93d63b655663707c7233917e293accmtklein "Apply usual --match rules to bench type: micro, recording, playback, skcodec, etc."); 12465dfd2fe5d93d63b655663707c7233917e293accmtklein 125bbba16878f343b232d844281fbdf056c00e20fb6mtkleinstatic double now_ms() { return SkTime::GetNSecs() * 1e-6; } 126bbba16878f343b232d844281fbdf056c00e20fb6mtklein 127f372321de3d4183de5b9ca436e677e471e358f31mtkleinstatic SkString humanize(double ms) { 128dc5bbab138bfffc85d6ba525d990aad09c322ff6mtklein if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); 129748ca3bf2d170708f263693e8579e6722389d0efmtklein return HumanizeMs(ms); 130f372321de3d4183de5b9ca436e677e471e358f31mtklein} 13155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein#define HUMANIZE(ms) humanize(ms).c_str() 132f372321de3d4183de5b9ca436e677e471e358f31mtklein 133d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonbool Target::init(SkImageInfo info, Benchmark* bench) { 134d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (Benchmark::kRaster_Backend == config.backend) { 135d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->surface.reset(SkSurface::NewRaster(info)); 136d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!this->surface.get()) { 137d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 138d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 139d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 140d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 141d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson} 142d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonbool Target::capturePixels(SkBitmap* bmp) { 14375a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson SkCanvas* canvas = this->getCanvas(); 144d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!canvas) { 145d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 146d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 147d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson bmp->setInfo(canvas->imageInfo()); 148d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!canvas->readPixels(bmp, 0, 0)) { 149d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkDebugf("Can't read canvas pixels.\n"); 150d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 151d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 152d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 153d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson} 154d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 155d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#if SK_SUPPORT_GPU 156d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonstruct GPUTarget : public Target { 15796fcdcc219d2a0d3579719b84b28bede76efba64halcanary explicit GPUTarget(const Config& c) : Target(c), gl(nullptr) { } 158d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkGLContext* gl; 159d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 160d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void setup() override { 161d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->gl->makeCurrent(); 162d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson // Make sure we're done with whatever came before. 163d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Finish()); 164d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 165d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void endTiming() override { 166d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (this->gl) { 167d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Flush()); 16801836add2ab778ed085735fa8a206b54d5fc4f23joshualitt this->gl->waitOnSyncOrSwap(); 169d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 170d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 171d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void fence() override { 172d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Finish()); 173d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 174d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein 175d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton bool needsFrameTiming(int* maxFrameLag) const override { 176d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton if (!this->gl->getMaxGpuFrameLag(maxFrameLag)) { 177d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton // Frame lag is unknown. 178d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton *maxFrameLag = FLAGS_gpuFrameLag; 179d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton } 180d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton return true; 181d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton } 182d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson bool init(SkImageInfo info, Benchmark* bench) override { 183afcd7cd32497cc79035e61fd64b0baa03ed04bccbsalomon uint32_t flags = this->config.useDFText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 184afcd7cd32497cc79035e61fd64b0baa03ed04bccbsalomon 0; 185d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); 1865219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen this->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(this->config.ctxType, 1875219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen this->config.ctxOptions), 1885ec26ae9bfca635ccc98283aad5deda11519d826bsalomon SkBudgeted::kNo, info, 189d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->config.samples, &props)); 1903e980c3d88fbc509b79e7ccef16ca38f5bbfb180kkinnunen this->gl = gGrFactory->getContextInfo(this->config.ctxType, 1913405800d7a5407365143eed93e300fd5896caceekkinnunen this->config.ctxOptions).fGLContext; 192d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!this->surface.get()) { 193d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 194d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 195d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton if (!this->gl->fenceSyncSupport()) { 196d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton SkDebugf("WARNING: GL context for config \"%s\" does not support fence sync. " 197c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen "Timings might not be accurate.\n", this->config.name.c_str()); 198d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton } 199d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 200d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 201d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void fillOptions(ResultsWriter* log) override { 202d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson const GrGLubyte* version; 203d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_VERSION)); 204d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_VERSION", (const char*)(version)); 205d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 206d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_RENDERER)); 207d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_RENDERER", (const char*) version); 208d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 209d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_VENDOR)); 210d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_VENDOR", (const char*) version); 211d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 212d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); 213d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version); 214d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 215d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson}; 216d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein 217d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 218d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 21975a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudsonstatic double time(int loops, Benchmark* bench, Target* target) { 22075a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson SkCanvas* canvas = target->getCanvas(); 2216eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (canvas) { 2226eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon canvas->clear(SK_ColorWHITE); 2236eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2248a6697af95b340aad6dee7e6228048fa305c1e59joshualitt bench->preDraw(canvas); 225bbba16878f343b232d844281fbdf056c00e20fb6mtklein double start = now_ms(); 22675a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson canvas = target->beginTiming(canvas); 22775a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson bench->draw(loops, canvas); 228f372321de3d4183de5b9ca436e677e471e358f31mtklein if (canvas) { 229f372321de3d4183de5b9ca436e677e471e358f31mtklein canvas->flush(); 230f372321de3d4183de5b9ca436e677e471e358f31mtklein } 23175a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson target->endTiming(); 232bbba16878f343b232d844281fbdf056c00e20fb6mtklein double elapsed = now_ms() - start; 2338a6697af95b340aad6dee7e6228048fa305c1e59joshualitt bench->postDraw(canvas); 234bbba16878f343b232d844281fbdf056c00e20fb6mtklein return elapsed; 235f372321de3d4183de5b9ca436e677e471e358f31mtklein} 236f372321de3d4183de5b9ca436e677e471e358f31mtklein 237bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic double estimate_timer_overhead() { 238bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein double overhead = 0; 239bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_overheadLoops; i++) { 240bbba16878f343b232d844281fbdf056c00e20fb6mtklein double start = now_ms(); 241bbba16878f343b232d844281fbdf056c00e20fb6mtklein overhead += now_ms() - start; 242bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 243bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return overhead / FLAGS_overheadLoops; 244bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 245f372321de3d4183de5b9ca436e677e471e358f31mtklein 2465324978a88677ac6b758324321816427814e7793reedstatic int detect_forever_loops(int loops) { 2475324978a88677ac6b758324321816427814e7793reed // look for a magic run-forever value 2485324978a88677ac6b758324321816427814e7793reed if (loops < 0) { 2495324978a88677ac6b758324321816427814e7793reed loops = SK_MaxS32; 2505324978a88677ac6b758324321816427814e7793reed } 2515324978a88677ac6b758324321816427814e7793reed return loops; 2525324978a88677ac6b758324321816427814e7793reed} 2535324978a88677ac6b758324321816427814e7793reed 25455b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinstatic int clamp_loops(int loops) { 25555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops < 1) { 256527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein SkDebugf("ERROR: clamping loops from %d to 1. " 257527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein "There's probably something wrong with the bench.\n", loops); 25855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return 1; 25955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 26055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops > FLAGS_maxLoops) { 26155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("WARNING: clamping loops from %d to FLAGS_maxLoops, %d.\n", loops, FLAGS_maxLoops); 26255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return FLAGS_maxLoops; 26355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 26455b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return loops; 26555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein} 26655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein 267d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonstatic bool write_canvas_png(Target* target, const SkString& filename) { 268d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2696eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (filename.isEmpty()) { 2706eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2716eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 27275a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson if (target->getCanvas() && 27375a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson kUnknown_SkColorType == target->getCanvas()->imageInfo().colorType()) { 2746eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2756eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 276d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2776eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkBitmap bmp; 278d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 279d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!target->capturePixels(&bmp)) { 2806eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2816eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 282d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2836eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString dir = SkOSPath::Dirname(filename.c_str()); 2846eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(dir.c_str())) { 2856eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't make dir %s.\n", dir.c_str()); 2866eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2876eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2886eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkFILEWStream stream(filename.c_str()); 2896eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!stream.isValid()) { 2906eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't write %s.\n", filename.c_str()); 2916eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2926eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2936eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!SkImageEncoder::EncodeStream(&stream, bmp, SkImageEncoder::kPNG_Type, 100)) { 2946eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't encode a PNG.\n"); 2956eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2966eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2976eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return true; 2986eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 2996eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 3006eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic int kFailedLoops = -2; 301e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdaltonstatic int setup_cpu_bench(const double overhead, Target* target, Benchmark* bench) { 302bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First figure out approximately how many loops of bench it takes to make overhead negligible. 3032069e220034f09aad2f68b262f395e7c25b3d178mtklein double bench_plus_overhead = 0.0; 30455b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein int round = 0; 305b4022965a280dd1ed64d6103dd29e2189abe6e00cdalton int loops = bench->calculateLoops(FLAGS_loops); 306b4022965a280dd1ed64d6103dd29e2189abe6e00cdalton if (kAutoTuneLoops == loops) { 3076eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon while (bench_plus_overhead < overhead) { 3086eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (round++ == FLAGS_maxCalibrationAttempts) { 3096eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skipping.\n", 310962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein bench->getUniqueName(), HUMANIZE(bench_plus_overhead), HUMANIZE(overhead)); 3116eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return kFailedLoops; 3126eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 31375a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson bench_plus_overhead = time(1, bench, target); 31455b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 3152069e220034f09aad2f68b262f395e7c25b3d178mtklein } 316f372321de3d4183de5b9ca436e677e471e358f31mtklein 317bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Later we'll just start and stop the timer once but loop N times. 318f372321de3d4183de5b9ca436e677e471e358f31mtklein // We'll pick N to make timer overhead negligible: 319f372321de3d4183de5b9ca436e677e471e358f31mtklein // 320bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead 321bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------- < FLAGS_overheadGoal 322bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead + N * Bench Time 323f372321de3d4183de5b9ca436e677e471e358f31mtklein // 324bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // where bench_plus_overhead ≈ overhead + Bench Time. 325f372321de3d4183de5b9ca436e677e471e358f31mtklein // 326f372321de3d4183de5b9ca436e677e471e358f31mtklein // Doing some math, we get: 327f372321de3d4183de5b9ca436e677e471e358f31mtklein // 328bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // (overhead / FLAGS_overheadGoal) - overhead 329bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------------------------ < N 330bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // bench_plus_overhead - overhead) 331f372321de3d4183de5b9ca436e677e471e358f31mtklein // 332f372321de3d4183de5b9ca436e677e471e358f31mtklein // Luckily, this also works well in practice. :) 3336eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 3346eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double numer = overhead / FLAGS_overheadGoal - overhead; 3356eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double denom = bench_plus_overhead - overhead; 3366eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = (int)ceil(numer / denom); 3375324978a88677ac6b758324321816427814e7793reed loops = clamp_loops(loops); 3385324978a88677ac6b758324321816427814e7793reed } else { 3395324978a88677ac6b758324321816427814e7793reed loops = detect_forever_loops(loops); 3406eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 341bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 342bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 343f372321de3d4183de5b9ca436e677e471e358f31mtklein} 344f372321de3d4183de5b9ca436e677e471e358f31mtklein 345e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdaltonstatic int setup_gpu_bench(Target* target, Benchmark* bench, int maxGpuFrameLag) { 346bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First, figure out how many loops it'll take to get a frame up to FLAGS_gpuMs. 347b4022965a280dd1ed64d6103dd29e2189abe6e00cdalton int loops = bench->calculateLoops(FLAGS_loops); 3486eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 3496eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = 1; 350a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein double elapsed = 0; 351a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein do { 352527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein if (1<<30 == loops) { 353527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein // We're about to wrap. Something's wrong with the bench. 354527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein loops = 0; 355527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein break; 356527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein } 357a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops *= 2; 358a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // If the GPU lets frames lag at all, we need to make sure we're timing 359d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton // _this_ round, not still timing last round. 360d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton for (int i = 0; i < maxGpuFrameLag; i++) { 36175a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson elapsed = time(loops, bench, target); 362a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 363a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } while (elapsed < FLAGS_gpuMs); 364a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 365a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // We've overshot at least a little. Scale back linearly. 366a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); 3675324978a88677ac6b758324321816427814e7793reed loops = clamp_loops(loops); 368a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 369d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson // Make sure we're not still timing our calibration. 370d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target->fence(); 3715324978a88677ac6b758324321816427814e7793reed } else { 3725324978a88677ac6b758324321816427814e7793reed loops = detect_forever_loops(loops); 373a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 374bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 375bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Pretty much the same deal as the calibration: do some warmup to make 376bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // sure we're timing steady-state pipelined frames. 377d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton for (int i = 0; i < maxGpuFrameLag - 1; i++) { 37875a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson time(loops, bench, target); 379f372321de3d4183de5b9ca436e677e471e358f31mtklein } 380bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 381bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 382f372321de3d4183de5b9ca436e677e471e358f31mtklein} 383bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 384c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 385c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType GrContextFactory::kNative_GLContextType 3865219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen#define kBogusGLContextOptions GrContextFactory::kNone_GLContextOptions 387c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#else 388c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType 0 3895219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen#define kBogusGLContextOptions 0 390e714e75c725c987fe682a1f5473224fe3e80380dmtklein#endif 391c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 392c47635e0ed52970fa40a16ffb280071e6b838a52svaisanenstatic void create_config(const SkCommandLineConfig* config, SkTArray<Config>* configs) { 393c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen 394c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen#if SK_SUPPORT_GPU 395c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen if (const auto* gpuConfig = config->asConfigGpu()) { 396c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen if (!FLAGS_gpu) 397c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen return; 398c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen 399c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen const auto ctxOptions = gpuConfig->getUseNVPR() ? GrContextFactory::kEnableNVPR_GLContextOptions 400c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen : GrContextFactory::kNone_GLContextOptions; 401c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen const auto ctxType = gpuConfig->getContextType(); 402c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen const auto sampleCount = gpuConfig->getSamples(); 403c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen 404c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen if (const GrContext* ctx = gGrFactory->get(ctxType, ctxOptions)) { 405c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen const auto maxSampleCount = ctx->caps()->maxSampleCount(); 406c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen if (sampleCount > ctx->caps()->maxSampleCount()) { 407c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen SkDebugf("Configuration sample count %d exceeds maximum %d.\n", 408c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen sampleCount, maxSampleCount); 409c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen return; 410c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen } 411c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen } else { 412c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen SkDebugf("No context was available matching config type and options.\n"); 413c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen return; 414c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen } 415c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen 416c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen Config target = { 417c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen config->getTag(), 418c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen Benchmark::kGPU_Backend, 419c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen kN32_SkColorType, 420c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen kPremul_SkAlphaType, 421c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen sampleCount, 422c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen ctxType, 423c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen ctxOptions, 424c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen false }; 425c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen 426c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen configs->push_back(target); 427c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen return; 428c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen } 429c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen#endif 430c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen 431c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen #define CPU_CONFIG(name, backend, color, alpha) \ 432c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen if (config->getTag().equals(#name)) { \ 433c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen Config config = { SkString(#name), Benchmark::backend, color, alpha, 0, \ 434c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen kBogusGLContextType, kBogusGLContextOptions, \ 435c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen false }; \ 436c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen configs->push_back(config); \ 437c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen return; \ 438f372321de3d4183de5b9ca436e677e471e358f31mtklein } 439e714e75c725c987fe682a1f5473224fe3e80380dmtklein 44040b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_cpu) { 441c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(nonrendering, kNonRendering_Backend, kUnknown_SkColorType, kUnpremul_SkAlphaType) 442c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(8888, kRaster_Backend, kN32_SkColorType, kPremul_SkAlphaType) 443c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(565, kRaster_Backend, kRGB_565_SkColorType, kOpaque_SkAlphaType) 44440b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 445f372321de3d4183de5b9ca436e677e471e358f31mtklein 446c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen #undef CPU_CONFIG 447d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 448d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 449817c72ad40bfbb42824010837c0bcc572a9eb9bcdjsollen if (config->getTag().equals("hwui")) { 450817c72ad40bfbb42824010837c0bcc572a9eb9bcdjsollen Config config = { SkString("hwui"), Benchmark::kHWUI_Backend, kRGBA_8888_SkColorType, 4515219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen kPremul_SkAlphaType, 0, kBogusGLContextType, kBogusGLContextOptions, 4525219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen false }; 453c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen configs->push_back(config); 454d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 455d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 456f372321de3d4183de5b9ca436e677e471e358f31mtklein} 457f372321de3d4183de5b9ca436e677e471e358f31mtklein 458c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen// Append all configs that are enabled and supported. 459c47635e0ed52970fa40a16ffb280071e6b838a52svaisanenvoid create_configs(SkTArray<Config>* configs) { 460c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen SkCommandLineConfigArray array; 461c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen ParseConfigs(FLAGS_config, &array); 462c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen for (int i = 0; i < array.count(); ++i) { 463c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen create_config(array[i], configs); 464c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen } 465c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen} 466c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen 46796fcdcc219d2a0d3579719b84b28bede76efba64halcanary// If bench is enabled for config, returns a Target* for it, otherwise nullptr. 468c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic Target* is_enabled(Benchmark* bench, const Config& config) { 469c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!bench->isSuitableFor(config.backend)) { 47096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 471c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 472c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 473e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkImageInfo info = SkImageInfo::Make(bench->getSize().fX, bench->getSize().fY, 474e5ea500d4714a7d84de2bf913e81be3b65d2de68reed config.color, config.alpha); 475c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 47696fcdcc219d2a0d3579719b84b28bede76efba64halcanary Target* target = nullptr; 477c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 478d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson switch (config.backend) { 479c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 480d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson case Benchmark::kGPU_Backend: 481d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new GPUTarget(config); 482d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 483d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 484d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 485d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson case Benchmark::kHWUI_Backend: 486d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new HWUITarget(config, bench); 487d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 488c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 489d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson default: 490d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new Target(config); 491d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 492d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 493c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 494d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!target->init(info, bench)) { 495c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon delete target; 49696fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 497c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 498c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return target; 499c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 500c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 5015cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarettstatic bool valid_brd_bench(SkData* encoded, SkBitmapRegionDecoder::Strategy strategy, 5027f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkColorType colorType, uint32_t sampleSize, uint32_t minOutputSize, int* width, 5037f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int* height) { 5045cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett SkAutoTDelete<SkBitmapRegionDecoder> brd( 5055cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett SkBitmapRegionDecoder::Create(encoded, strategy)); 5067f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett if (nullptr == brd.get()) { 5077f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // This is indicates that subset decoding is not supported for a particular image format. 5087f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return false; 5097f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 5107f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 51135e5d1b4495478ca3bede66914ae07f50a447c4dmsarett SkBitmap bitmap; 51235e5d1b4495478ca3bede66914ae07f50a447c4dmsarett if (!brd->decodeRegion(&bitmap, nullptr, SkIRect::MakeXYWH(0, 0, brd->width(), brd->height()), 51335e5d1b4495478ca3bede66914ae07f50a447c4dmsarett 1, colorType, false)) { 51435e5d1b4495478ca3bede66914ae07f50a447c4dmsarett return false; 51535e5d1b4495478ca3bede66914ae07f50a447c4dmsarett } 5167f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 5177f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett if (sampleSize * minOutputSize > (uint32_t) brd->width() || sampleSize * minOutputSize > 5187f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett (uint32_t) brd->height()) { 5197f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // This indicates that the image is not large enough to decode a 5207f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // minOutputSize x minOutputSize subset at the given sampleSize. 5217f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return false; 5227f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 5237f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 5247f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // Set the image width and height. The calling code will use this to choose subsets to decode. 5257f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett *width = brd->width(); 5267f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett *height = brd->height(); 5277f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return true; 5287f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett} 5297f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 5303bf9206ada256277a39988c263f0379d544fc27begdanielstatic void cleanup_run(Target* target) { 531385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete target; 5323bf9206ada256277a39988c263f0379d544fc27begdaniel#if SK_SUPPORT_GPU 5333bf9206ada256277a39988c263f0379d544fc27begdaniel if (FLAGS_abandonGpuContext) { 5343bf9206ada256277a39988c263f0379d544fc27begdaniel gGrFactory->abandonContexts(); 5353bf9206ada256277a39988c263f0379d544fc27begdaniel } 5363bf9206ada256277a39988c263f0379d544fc27begdaniel if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { 5373bf9206ada256277a39988c263f0379d544fc27begdaniel gGrFactory->destroyContexts(); 5383bf9206ada256277a39988c263f0379d544fc27begdaniel } 5393bf9206ada256277a39988c263f0379d544fc27begdaniel#endif 5403bf9206ada256277a39988c263f0379d544fc27begdaniel} 5413bf9206ada256277a39988c263f0379d544fc27begdaniel 542e714e75c725c987fe682a1f5473224fe3e80380dmtkleinclass BenchmarkStream { 543e714e75c725c987fe682a1f5473224fe3e80380dmtkleinpublic: 54492007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream() : fBenches(BenchRegistry::Head()) 54592007583e43115998412ac8b0a06cc2780eb025cmtklein , fGMs(skiagm::GMRegistry::Head()) 546fd731ce804cd3223318f3feee2c98404890b65f2mtklein , fCurrentRecording(0) 54792007583e43115998412ac8b0a06cc2780eb025cmtklein , fCurrentScale(0) 5485b69377507478623dcf5b11f3ecb010f87c4794frobertphillips , fCurrentSKP(0) 54995f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentUseMPD(0) 55060869a42a133942f852dd0f1696444c2a5c9ad83scroggo , fCurrentCodec(0) 55184451024bfe06d138629dd7c27cf2ec0f9774dbemsarett , fCurrentAndroidCodec(0) 5527f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett , fCurrentBRDImage(0) 55395f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentColorType(0) 554c7796b93f02e736df967301d3c46cec46dd02d5cmsarett , fCurrentAlphaType(0) 555b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett , fCurrentSubsetType(0) 5567f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett , fCurrentBRDStrategy(0) 55784451024bfe06d138629dd7c27cf2ec0f9774dbemsarett , fCurrentSampleSize(0) 558b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett , fCurrentAnimSKP(0) { 55992007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_skps.count(); i++) { 56092007583e43115998412ac8b0a06cc2780eb025cmtklein if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { 56192007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = FLAGS_skps[i]; 56292007583e43115998412ac8b0a06cc2780eb025cmtklein } else { 56392007583e43115998412ac8b0a06cc2780eb025cmtklein SkOSFile::Iter it(FLAGS_skps[i], ".skp"); 56492007583e43115998412ac8b0a06cc2780eb025cmtklein SkString path; 56592007583e43115998412ac8b0a06cc2780eb025cmtklein while (it.next(&path)) { 56692007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str()); 56792007583e43115998412ac8b0a06cc2780eb025cmtklein } 56892007583e43115998412ac8b0a06cc2780eb025cmtklein } 56992007583e43115998412ac8b0a06cc2780eb025cmtklein } 57092007583e43115998412ac8b0a06cc2780eb025cmtklein 57192007583e43115998412ac8b0a06cc2780eb025cmtklein if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d", 57292007583e43115998412ac8b0a06cc2780eb025cmtklein &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom)) { 57392007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0]); 57492007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 57592007583e43115998412ac8b0a06cc2780eb025cmtklein } 57692007583e43115998412ac8b0a06cc2780eb025cmtklein 57792007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_scales.count(); i++) { 57892007583e43115998412ac8b0a06cc2780eb025cmtklein if (1 != sscanf(FLAGS_scales[i], "%f", &fScales.push_back())) { 57992007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --scales as an SkScalar.\n", FLAGS_scales[i]); 58092007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 58192007583e43115998412ac8b0a06cc2780eb025cmtklein } 58292007583e43115998412ac8b0a06cc2780eb025cmtklein } 5835b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 58463a82855b1f0b83952b65fca330954c50ebe7a4bcdalton if (2 != sscanf(FLAGS_zoom[0], "%f,%lf", &fZoomMax, &fZoomPeriodMs)) { 58563a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SkDebugf("Can't parse %s from --zoom as a zoomMax,zoomPeriodMs.\n", FLAGS_zoom[0]); 586261c3ad7fde95748da92550735decc949dc73bf2joshualitt exit(1); 587261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 588261c3ad7fde95748da92550735decc949dc73bf2joshualitt 5895b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (FLAGS_mpd) { 5905b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fUseMPDs.push_back() = true; 5915b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 592c751ecb3681072fda53dd3cebeb2eb41fc73b314mtklein fUseMPDs.push_back() = false; 59395553d917c73ef333ede967521560957a5b6a0admtklein 59495f192d19938b98a45dd1fa4112d965f60d10516msarett // Prepare the images for decoding 5958673714d75ff1020f78217ff8839f1e18c3591e4scroggo if (!CollectImages(&fImages)) { 5968673714d75ff1020f78217ff8839f1e18c3591e4scroggo exit(1); 59795f192d19938b98a45dd1fa4112d965f60d10516msarett } 59895553d917c73ef333ede967521560957a5b6a0admtklein 59995f192d19938b98a45dd1fa4112d965f60d10516msarett // Choose the candidate color types for image decoding 60095f192d19938b98a45dd1fa4112d965f60d10516msarett const SkColorType colorTypes[] = 601b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett { kN32_SkColorType, 602b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kRGB_565_SkColorType, 603b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kAlpha_8_SkColorType, 604b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kIndex_8_SkColorType, 605b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kGray_8_SkColorType }; 60674deb981d5e9c11c88fe431e78166d6cf8dacc1amsarett fColorTypes.reset(colorTypes, SK_ARRAY_COUNT(colorTypes)); 60792007583e43115998412ac8b0a06cc2780eb025cmtklein } 608e714e75c725c987fe682a1f5473224fe3e80380dmtklein 609fd731ce804cd3223318f3feee2c98404890b65f2mtklein static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) { 610fd731ce804cd3223318f3feee2c98404890b65f2mtklein // Not strictly necessary, as it will be checked again later, 611fd731ce804cd3223318f3feee2c98404890b65f2mtklein // but helps to avoid a lot of pointless work if we're going to skip it. 61291e457d17f8c6c06de33eb2bb430a90ba472eda5cdalton if (SkCommandLineFlags::ShouldSkip(FLAGS_match, SkOSPath::Basename(path).c_str())) { 613fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 614fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 615fd731ce804cd3223318f3feee2c98404890b65f2mtklein 616a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path)); 61796fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (stream.get() == nullptr) { 618fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkDebugf("Could not read %s.\n", path); 619fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 620fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 621fd731ce804cd3223318f3feee2c98404890b65f2mtklein 62257f27bdcbd328491a121918b4ab9301fbcdec642mtklein pic->reset(SkPicture::CreateFromStream(stream.get())); 62396fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (pic->get() == nullptr) { 624fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkDebugf("Could not read %s as an SkPicture.\n", path); 625fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 626fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 627fd731ce804cd3223318f3feee2c98404890b65f2mtklein return true; 628fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 629fd731ce804cd3223318f3feee2c98404890b65f2mtklein 63092007583e43115998412ac8b0a06cc2780eb025cmtklein Benchmark* next() { 63165dfd2fe5d93d63b655663707c7233917e293accmtklein SkAutoTDelete<Benchmark> bench; 63265dfd2fe5d93d63b655663707c7233917e293accmtklein do { 63365dfd2fe5d93d63b655663707c7233917e293accmtklein bench.reset(this->rawNext()); 63465dfd2fe5d93d63b655663707c7233917e293accmtklein if (!bench) { 63565dfd2fe5d93d63b655663707c7233917e293accmtklein return nullptr; 63665dfd2fe5d93d63b655663707c7233917e293accmtklein } 63765dfd2fe5d93d63b655663707c7233917e293accmtklein } while(SkCommandLineFlags::ShouldSkip(FLAGS_sourceType, fSourceType) || 63865dfd2fe5d93d63b655663707c7233917e293accmtklein SkCommandLineFlags::ShouldSkip(FLAGS_benchType, fBenchType)); 63965dfd2fe5d93d63b655663707c7233917e293accmtklein return bench.detach(); 64065dfd2fe5d93d63b655663707c7233917e293accmtklein } 64165dfd2fe5d93d63b655663707c7233917e293accmtklein 64265dfd2fe5d93d63b655663707c7233917e293accmtklein Benchmark* rawNext() { 643e714e75c725c987fe682a1f5473224fe3e80380dmtklein if (fBenches) { 64496fcdcc219d2a0d3579719b84b28bede76efba64halcanary Benchmark* bench = fBenches->factory()(nullptr); 645e714e75c725c987fe682a1f5473224fe3e80380dmtklein fBenches = fBenches->next(); 64692007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "bench"; 647fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "micro"; 648e714e75c725c987fe682a1f5473224fe3e80380dmtklein return bench; 649e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 65092007583e43115998412ac8b0a06cc2780eb025cmtklein 651e714e75c725c987fe682a1f5473224fe3e80380dmtklein while (fGMs) { 65296fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr)); 653e714e75c725c987fe682a1f5473224fe3e80380dmtklein fGMs = fGMs->next(); 654cf5d9c993dcbd75d4cefe2d1de25c2b9645f6957mtklein if (gm->runAsBench()) { 65592007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "gm"; 656fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "micro"; 657385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new GMBench(gm.detach()); 658e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 659e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 66092007583e43115998412ac8b0a06cc2780eb025cmtklein 661fd731ce804cd3223318f3feee2c98404890b65f2mtklein // First add all .skps as RecordingBenches. 662fd731ce804cd3223318f3feee2c98404890b65f2mtklein while (fCurrentRecording < fSKPs.count()) { 663fd731ce804cd3223318f3feee2c98404890b65f2mtklein const SkString& path = fSKPs[fCurrentRecording++]; 664fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkPicture> pic; 665fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (!ReadPicture(path.c_str(), &pic)) { 666fd731ce804cd3223318f3feee2c98404890b65f2mtklein continue; 667fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 668fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkString name = SkOSPath::Basename(path.c_str()); 669fd731ce804cd3223318f3feee2c98404890b65f2mtklein fSourceType = "skp"; 670fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "recording"; 6710aa5cea8694d3686b6742a36eab81ab9001de954bsalomon fSKPBytes = static_cast<double>(SkPictureUtils::ApproximateBytesUsed(pic)); 672051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein fSKPOps = pic->approximateOpCount(); 673385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new RecordingBench(name.c_str(), pic.get(), FLAGS_bbh); 674fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 675fd731ce804cd3223318f3feee2c98404890b65f2mtklein 676fd731ce804cd3223318f3feee2c98404890b65f2mtklein // Then once each for each scale as SKPBenches (playback). 67792007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentScale < fScales.count()) { 67892007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentSKP < fSKPs.count()) { 6795b69377507478623dcf5b11f3ecb010f87c4794frobertphillips const SkString& path = fSKPs[fCurrentSKP]; 680fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkPicture> pic; 681fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (!ReadPicture(path.c_str(), &pic)) { 6825b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentSKP++; 68392007583e43115998412ac8b0a06cc2780eb025cmtklein continue; 68492007583e43115998412ac8b0a06cc2780eb025cmtklein } 6855b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 6865b69377507478623dcf5b11f3ecb010f87c4794frobertphillips while (fCurrentUseMPD < fUseMPDs.count()) { 6875b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (FLAGS_bbh) { 6885b69377507478623dcf5b11f3ecb010f87c4794frobertphillips // The SKP we read off disk doesn't have a BBH. Re-record so it grows one. 6895b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkRTreeFactory factory; 6905b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkPictureRecorder recorder; 6915b69377507478623dcf5b11f3ecb010f87c4794frobertphillips static const int kFlags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag; 6925b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic->playback(recorder.beginRecording(pic->cullRect().width(), 6935b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic->cullRect().height(), 694748ca3bf2d170708f263693e8579e6722389d0efmtklein &factory, 695e451c4df7369c5e253ef9c9e0a8713beda25f34brobertphillips fUseMPDs[fCurrentUseMPD] ? kFlags : 0)); 6965b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic.reset(recorder.endRecording()); 6975b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 6985b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkString name = SkOSPath::Basename(path.c_str()); 6995b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fSourceType = "skp"; 7005b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fBenchType = "playback"; 701385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SKPBench(name.c_str(), pic.get(), fClip, fScales[fCurrentScale], 702385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fUseMPDs[fCurrentUseMPD++], FLAGS_loopSKP); 7032084050a33ae139d0fe9bb680f7905f91139a39fmtklein } 7045b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentUseMPD = 0; 7055b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentSKP++; 70692007583e43115998412ac8b0a06cc2780eb025cmtklein } 70792007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentSKP = 0; 70892007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentScale++; 70992007583e43115998412ac8b0a06cc2780eb025cmtklein } 71092007583e43115998412ac8b0a06cc2780eb025cmtklein 711261c3ad7fde95748da92550735decc949dc73bf2joshualitt // Now loop over each skp again if we have an animation 71263a82855b1f0b83952b65fca330954c50ebe7a4bcdalton if (fZoomMax != 1.0f && fZoomPeriodMs > 0) { 713261c3ad7fde95748da92550735decc949dc73bf2joshualitt while (fCurrentAnimSKP < fSKPs.count()) { 714261c3ad7fde95748da92550735decc949dc73bf2joshualitt const SkString& path = fSKPs[fCurrentAnimSKP]; 715261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkAutoTUnref<SkPicture> pic; 716261c3ad7fde95748da92550735decc949dc73bf2joshualitt if (!ReadPicture(path.c_str(), &pic)) { 717261c3ad7fde95748da92550735decc949dc73bf2joshualitt fCurrentAnimSKP++; 718261c3ad7fde95748da92550735decc949dc73bf2joshualitt continue; 719261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 720261c3ad7fde95748da92550735decc949dc73bf2joshualitt 721261c3ad7fde95748da92550735decc949dc73bf2joshualitt fCurrentAnimSKP++; 722261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkString name = SkOSPath::Basename(path.c_str()); 72363a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SkAutoTUnref<SKPAnimationBench::Animation> animation( 72463a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SKPAnimationBench::CreateZoomAnimation(fZoomMax, fZoomPeriodMs)); 725385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SKPAnimationBench(name.c_str(), pic.get(), fClip, animation, 726385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary FLAGS_loopSKP); 727261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 728261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 729261c3ad7fde95748da92550735decc949dc73bf2joshualitt 73060869a42a133942f852dd0f1696444c2a5c9ad83scroggo for (; fCurrentCodec < fImages.count(); fCurrentCodec++) { 731303fa350125f372bbfc29bec1235885493dab9b4scroggo fSourceType = "image"; 732303fa350125f372bbfc29bec1235885493dab9b4scroggo fBenchType = "skcodec"; 73360869a42a133942f852dd0f1696444c2a5c9ad83scroggo const SkString& path = fImages[fCurrentCodec]; 7346f0ff91c6561549a1ea8de3e8896b80a584c45b9mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path.c_str())) { 7356f0ff91c6561549a1ea8de3e8896b80a584c45b9mtklein continue; 7366f0ff91c6561549a1ea8de3e8896b80a584c45b9mtklein } 73760869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 73860869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); 73960869a42a133942f852dd0f1696444c2a5c9ad83scroggo if (!codec) { 74060869a42a133942f852dd0f1696444c2a5c9ad83scroggo // Nothing to time. 7419d9725c892743cf8fc66ea6cdd5ce21fe2df6d14msarett SkDebugf("Cannot find codec for %s\n", path.c_str()); 74260869a42a133942f852dd0f1696444c2a5c9ad83scroggo continue; 74360869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 74421027994192f395bbd1507558b84f59b3c7cf0dascroggo 74560869a42a133942f852dd0f1696444c2a5c9ad83scroggo while (fCurrentColorType < fColorTypes.count()) { 74621027994192f395bbd1507558b84f59b3c7cf0dascroggo const SkColorType colorType = fColorTypes[fCurrentColorType]; 74721027994192f395bbd1507558b84f59b3c7cf0dascroggo 748c7796b93f02e736df967301d3c46cec46dd02d5cmsarett SkAlphaType alphaType = codec->getInfo().alphaType(); 749c7796b93f02e736df967301d3c46cec46dd02d5cmsarett switch (alphaType) { 750c7796b93f02e736df967301d3c46cec46dd02d5cmsarett case kOpaque_SkAlphaType: 751c7796b93f02e736df967301d3c46cec46dd02d5cmsarett // We only need to test one alpha type (opaque). 752c7796b93f02e736df967301d3c46cec46dd02d5cmsarett fCurrentColorType++; 753c7796b93f02e736df967301d3c46cec46dd02d5cmsarett break; 754c7796b93f02e736df967301d3c46cec46dd02d5cmsarett case kUnpremul_SkAlphaType: 755c7796b93f02e736df967301d3c46cec46dd02d5cmsarett case kPremul_SkAlphaType: 756c7796b93f02e736df967301d3c46cec46dd02d5cmsarett if (0 == fCurrentAlphaType) { 757c7796b93f02e736df967301d3c46cec46dd02d5cmsarett // Test unpremul first. 758c7796b93f02e736df967301d3c46cec46dd02d5cmsarett alphaType = kUnpremul_SkAlphaType; 759c7796b93f02e736df967301d3c46cec46dd02d5cmsarett fCurrentAlphaType++; 760c7796b93f02e736df967301d3c46cec46dd02d5cmsarett } else { 761c7796b93f02e736df967301d3c46cec46dd02d5cmsarett // Test premul. 762c7796b93f02e736df967301d3c46cec46dd02d5cmsarett alphaType = kPremul_SkAlphaType; 763c7796b93f02e736df967301d3c46cec46dd02d5cmsarett fCurrentAlphaType = 0; 764c7796b93f02e736df967301d3c46cec46dd02d5cmsarett fCurrentColorType++; 765c7796b93f02e736df967301d3c46cec46dd02d5cmsarett } 766c7796b93f02e736df967301d3c46cec46dd02d5cmsarett break; 767c7796b93f02e736df967301d3c46cec46dd02d5cmsarett default: 768c7796b93f02e736df967301d3c46cec46dd02d5cmsarett SkASSERT(false); 769c7796b93f02e736df967301d3c46cec46dd02d5cmsarett fCurrentColorType++; 770c7796b93f02e736df967301d3c46cec46dd02d5cmsarett break; 77121027994192f395bbd1507558b84f59b3c7cf0dascroggo } 77221027994192f395bbd1507558b84f59b3c7cf0dascroggo 773c7796b93f02e736df967301d3c46cec46dd02d5cmsarett // Make sure we can decode to this color type and alpha type. 774c7796b93f02e736df967301d3c46cec46dd02d5cmsarett SkImageInfo info = 775c7796b93f02e736df967301d3c46cec46dd02d5cmsarett codec->getInfo().makeColorType(colorType).makeAlphaType(alphaType); 77621027994192f395bbd1507558b84f59b3c7cf0dascroggo const size_t rowBytes = info.minRowBytes(); 77721027994192f395bbd1507558b84f59b3c7cf0dascroggo SkAutoMalloc storage(info.getSafeSize(rowBytes)); 77821027994192f395bbd1507558b84f59b3c7cf0dascroggo 77921027994192f395bbd1507558b84f59b3c7cf0dascroggo // Used if fCurrentColorType is kIndex_8_SkColorType 78021027994192f395bbd1507558b84f59b3c7cf0dascroggo int colorCount = 256; 78121027994192f395bbd1507558b84f59b3c7cf0dascroggo SkPMColor colors[256]; 78221027994192f395bbd1507558b84f59b3c7cf0dascroggo 783eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo const SkCodec::Result result = codec->getPixels( 78496fcdcc219d2a0d3579719b84b28bede76efba64halcanary info, storage.get(), rowBytes, nullptr, colors, 78521027994192f395bbd1507558b84f59b3c7cf0dascroggo &colorCount); 78660869a42a133942f852dd0f1696444c2a5c9ad83scroggo switch (result) { 787eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo case SkCodec::kSuccess: 788eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo case SkCodec::kIncompleteInput: 78960869a42a133942f852dd0f1696444c2a5c9ad83scroggo return new CodecBench(SkOSPath::Basename(path.c_str()), 790c7796b93f02e736df967301d3c46cec46dd02d5cmsarett encoded, colorType, alphaType); 791eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo case SkCodec::kInvalidConversion: 79260869a42a133942f852dd0f1696444c2a5c9ad83scroggo // This is okay. Not all conversions are valid. 79360869a42a133942f852dd0f1696444c2a5c9ad83scroggo break; 79460869a42a133942f852dd0f1696444c2a5c9ad83scroggo default: 79560869a42a133942f852dd0f1696444c2a5c9ad83scroggo // This represents some sort of failure. 79660869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkASSERT(false); 79760869a42a133942f852dd0f1696444c2a5c9ad83scroggo break; 79860869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 79960869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 80060869a42a133942f852dd0f1696444c2a5c9ad83scroggo fCurrentColorType = 0; 80160869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 80260869a42a133942f852dd0f1696444c2a5c9ad83scroggo 80384451024bfe06d138629dd7c27cf2ec0f9774dbemsarett // Run AndroidCodecBenches 80484451024bfe06d138629dd7c27cf2ec0f9774dbemsarett const int sampleSizes[] = { 2, 4, 8 }; 80584451024bfe06d138629dd7c27cf2ec0f9774dbemsarett for (; fCurrentAndroidCodec < fImages.count(); fCurrentAndroidCodec++) { 80684451024bfe06d138629dd7c27cf2ec0f9774dbemsarett fSourceType = "image"; 80784451024bfe06d138629dd7c27cf2ec0f9774dbemsarett fBenchType = "skandroidcodec"; 80884451024bfe06d138629dd7c27cf2ec0f9774dbemsarett 80984451024bfe06d138629dd7c27cf2ec0f9774dbemsarett const SkString& path = fImages[fCurrentAndroidCodec]; 81084451024bfe06d138629dd7c27cf2ec0f9774dbemsarett if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path.c_str())) { 81184451024bfe06d138629dd7c27cf2ec0f9774dbemsarett continue; 81284451024bfe06d138629dd7c27cf2ec0f9774dbemsarett } 81384451024bfe06d138629dd7c27cf2ec0f9774dbemsarett SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 81484451024bfe06d138629dd7c27cf2ec0f9774dbemsarett SkAutoTDelete<SkAndroidCodec> codec(SkAndroidCodec::NewFromData(encoded)); 81584451024bfe06d138629dd7c27cf2ec0f9774dbemsarett if (!codec) { 81684451024bfe06d138629dd7c27cf2ec0f9774dbemsarett // Nothing to time. 81784451024bfe06d138629dd7c27cf2ec0f9774dbemsarett SkDebugf("Cannot find codec for %s\n", path.c_str()); 81884451024bfe06d138629dd7c27cf2ec0f9774dbemsarett continue; 81984451024bfe06d138629dd7c27cf2ec0f9774dbemsarett } 82084451024bfe06d138629dd7c27cf2ec0f9774dbemsarett 82184451024bfe06d138629dd7c27cf2ec0f9774dbemsarett while (fCurrentSampleSize < (int) SK_ARRAY_COUNT(sampleSizes)) { 82284451024bfe06d138629dd7c27cf2ec0f9774dbemsarett int sampleSize = sampleSizes[fCurrentSampleSize]; 82384451024bfe06d138629dd7c27cf2ec0f9774dbemsarett fCurrentSampleSize++; 82484451024bfe06d138629dd7c27cf2ec0f9774dbemsarett if (10 * sampleSize > SkTMin(codec->getInfo().width(), codec->getInfo().height())) { 82584451024bfe06d138629dd7c27cf2ec0f9774dbemsarett // Avoid benchmarking scaled decodes of already small images. 82684451024bfe06d138629dd7c27cf2ec0f9774dbemsarett break; 82784451024bfe06d138629dd7c27cf2ec0f9774dbemsarett } 82884451024bfe06d138629dd7c27cf2ec0f9774dbemsarett 82984451024bfe06d138629dd7c27cf2ec0f9774dbemsarett return new AndroidCodecBench(SkOSPath::Basename(path.c_str()), encoded, sampleSize); 83084451024bfe06d138629dd7c27cf2ec0f9774dbemsarett } 83184451024bfe06d138629dd7c27cf2ec0f9774dbemsarett fCurrentSampleSize = 0; 83284451024bfe06d138629dd7c27cf2ec0f9774dbemsarett } 83384451024bfe06d138629dd7c27cf2ec0f9774dbemsarett 8347f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // Run the BRDBenches 8357f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // We will benchmark multiple BRD strategies. 836303fa350125f372bbfc29bec1235885493dab9b4scroggo static const struct { 8375cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett SkBitmapRegionDecoder::Strategy fStrategy; 8380459c9425f567b6d11ca534fb13a05de9f37b7eemsarett const char* fName; 839303fa350125f372bbfc29bec1235885493dab9b4scroggo } strategies[] = { 8400459c9425f567b6d11ca534fb13a05de9f37b7eemsarett { SkBitmapRegionDecoder::kCanvas_Strategy, "BRD_canvas" }, 8415cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett { SkBitmapRegionDecoder::kAndroidCodec_Strategy, "BRD_android_codec" }, 8427f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett }; 8437f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 8447f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // We intend to create benchmarks that model the use cases in 8457f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // android/libraries/social/tiledimage. In this library, an image is decoded in 512x512 8467f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // tiles. The image can be translated freely, so the location of a tile may be anywhere in 8477f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // the image. For that reason, we will benchmark decodes in five representative locations 8487f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // in the image. Additionally, this use case utilizes power of two scaling, so we will 8497f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // test on power of two sample sizes. The output tile is always 512x512, so, when a 8507f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // sampleSize is used, the size of the subset that is decoded is always 8517f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // (sampleSize*512)x(sampleSize*512). 8527f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // There are a few good reasons to only test on power of two sample sizes at this time: 8537f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // All use cases we are aware of only scale by powers of two. 8547f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // PNG decodes use the indicated sampling strategy regardless of the sample size, so 8557f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // these tests are sufficient to provide good coverage of our scaling options. 85684451024bfe06d138629dd7c27cf2ec0f9774dbemsarett const uint32_t brdSampleSizes[] = { 1, 2, 4, 8, 16 }; 8577f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett const uint32_t minOutputSize = 512; 8586f0ff91c6561549a1ea8de3e8896b80a584c45b9mtklein for (; fCurrentBRDImage < fImages.count(); fCurrentBRDImage++) { 8596f0ff91c6561549a1ea8de3e8896b80a584c45b9mtklein const SkString& path = fImages[fCurrentBRDImage]; 8606f0ff91c6561549a1ea8de3e8896b80a584c45b9mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path.c_str())) { 8616f0ff91c6561549a1ea8de3e8896b80a584c45b9mtklein continue; 8626f0ff91c6561549a1ea8de3e8896b80a584c45b9mtklein } 8637f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentBRDStrategy < (int) SK_ARRAY_COUNT(strategies)) { 864303fa350125f372bbfc29bec1235885493dab9b4scroggo fSourceType = "image"; 865303fa350125f372bbfc29bec1235885493dab9b4scroggo fBenchType = strategies[fCurrentBRDStrategy].fName; 866860e8a67190e024b7375e52e270e6bd0a17af86escroggo 8675cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett const SkBitmapRegionDecoder::Strategy strategy = 868860e8a67190e024b7375e52e270e6bd0a17af86escroggo strategies[fCurrentBRDStrategy].fStrategy; 869860e8a67190e024b7375e52e270e6bd0a17af86escroggo 8707f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentColorType < fColorTypes.count()) { 87184451024bfe06d138629dd7c27cf2ec0f9774dbemsarett while (fCurrentSampleSize < (int) SK_ARRAY_COUNT(brdSampleSizes)) { 8727f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentSubsetType <= kLastSingle_SubsetType) { 873860e8a67190e024b7375e52e270e6bd0a17af86escroggo 8747f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 8757f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett const SkColorType colorType = fColorTypes[fCurrentColorType]; 87684451024bfe06d138629dd7c27cf2ec0f9774dbemsarett uint32_t sampleSize = brdSampleSizes[fCurrentSampleSize]; 8777f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int currentSubsetType = fCurrentSubsetType++; 8787f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 8797f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int width = 0; 8807f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int height = 0; 8817f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett if (!valid_brd_bench(encoded.get(), strategy, colorType, sampleSize, 8827f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett minOutputSize, &width, &height)) { 8837f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 8847f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 8857f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 8867f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkString basename = SkOSPath::Basename(path.c_str()); 8877f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkIRect subset; 8887f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett const uint32_t subsetSize = sampleSize * minOutputSize; 8897f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett switch (currentSubsetType) { 8907f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kTopLeft_SubsetType: 8917f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_TopLeft"); 8927f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(0, 0, subsetSize, subsetSize); 8937f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 8947f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kTopRight_SubsetType: 8957f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_TopRight"); 8967f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(width - subsetSize, 0, subsetSize, 8977f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subsetSize); 8987f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 8997f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kMiddle_SubsetType: 9007f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_Middle"); 9017f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH((width - subsetSize) / 2, 9027f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett (height - subsetSize) / 2, subsetSize, subsetSize); 9037f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 9047f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kBottomLeft_SubsetType: 9057f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_BottomLeft"); 9067f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(0, height - subsetSize, subsetSize, 9077f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subsetSize); 9087f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 9097f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kBottomRight_SubsetType: 9107f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_BottomRight"); 9117f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(width - subsetSize, 9127f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett height - subsetSize, subsetSize, subsetSize); 9137f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 9147f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett default: 9157f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkASSERT(false); 9167f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 9177f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 9187f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return new BitmapRegionDecoderBench(basename.c_str(), encoded.get(), 9197f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett strategy, colorType, sampleSize, subset); 9207f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 9217f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentSubsetType = 0; 92284451024bfe06d138629dd7c27cf2ec0f9774dbemsarett fCurrentSampleSize++; 9237f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 92484451024bfe06d138629dd7c27cf2ec0f9774dbemsarett fCurrentSampleSize = 0; 9257f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentColorType++; 9267f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 9277f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentColorType = 0; 9287f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDStrategy++; 9297f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 9307f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDStrategy = 0; 9317f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 9327f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 93396fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 934e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 93592007583e43115998412ac8b0a06cc2780eb025cmtklein 93692007583e43115998412ac8b0a06cc2780eb025cmtklein void fillCurrentOptions(ResultsWriter* log) const { 93792007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("source_type", fSourceType); 938fd731ce804cd3223318f3feee2c98404890b65f2mtklein log->configOption("bench_type", fBenchType); 93992007583e43115998412ac8b0a06cc2780eb025cmtklein if (0 == strcmp(fSourceType, "skp")) { 94092007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("clip", 94192007583e43115998412ac8b0a06cc2780eb025cmtklein SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, 94292007583e43115998412ac8b0a06cc2780eb025cmtklein fClip.fRight, fClip.fBottom).c_str()); 943f2b340fc885ad2a12d2d73974eff9c8f4c94192cdjsollen SkASSERT_RELEASE(fCurrentScale < fScales.count()); // debugging paranoia 94492007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentScale]).c_str()); 9455b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (fCurrentUseMPD > 0) { 9465b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkASSERT(1 == fCurrentUseMPD || 2 == fCurrentUseMPD); 9475b69377507478623dcf5b11f3ecb010f87c4794frobertphillips log->configOption("multi_picture_draw", fUseMPDs[fCurrentUseMPD-1] ? "true" : "false"); 9485b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 94992007583e43115998412ac8b0a06cc2780eb025cmtklein } 950051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein if (0 == strcmp(fBenchType, "recording")) { 951051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("bytes", fSKPBytes); 952051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("ops", fSKPOps); 953051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein } 95492007583e43115998412ac8b0a06cc2780eb025cmtklein } 95592007583e43115998412ac8b0a06cc2780eb025cmtklein 956e714e75c725c987fe682a1f5473224fe3e80380dmtkleinprivate: 957b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett enum SubsetType { 958b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kTopLeft_SubsetType = 0, 959b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kTopRight_SubsetType = 1, 960ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kMiddle_SubsetType = 2, 961ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kBottomLeft_SubsetType = 3, 962ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kBottomRight_SubsetType = 4, 963ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kTranslate_SubsetType = 5, 964ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kZoom_SubsetType = 6, 9657f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett kLast_SubsetType = kZoom_SubsetType, 9667f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett kLastSingle_SubsetType = kBottomRight_SubsetType, 967b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett }; 968b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett 969e714e75c725c987fe682a1f5473224fe3e80380dmtklein const BenchRegistry* fBenches; 970e714e75c725c987fe682a1f5473224fe3e80380dmtklein const skiagm::GMRegistry* fGMs; 97192007583e43115998412ac8b0a06cc2780eb025cmtklein SkIRect fClip; 97292007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkScalar> fScales; 97392007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkString> fSKPs; 9745b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkTArray<bool> fUseMPDs; 97595f192d19938b98a45dd1fa4112d965f60d10516msarett SkTArray<SkString> fImages; 97674deb981d5e9c11c88fe431e78166d6cf8dacc1amsarett SkTArray<SkColorType, true> fColorTypes; 97763a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SkScalar fZoomMax; 97863a82855b1f0b83952b65fca330954c50ebe7a4bcdalton double fZoomPeriodMs; 97992007583e43115998412ac8b0a06cc2780eb025cmtklein 980051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein double fSKPBytes, fSKPOps; 981051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein 982fd731ce804cd3223318f3feee2c98404890b65f2mtklein const char* fSourceType; // What we're benching: bench, GM, SKP, ... 983fd731ce804cd3223318f3feee2c98404890b65f2mtklein const char* fBenchType; // How we bench it: micro, recording, playback, ... 984fd731ce804cd3223318f3feee2c98404890b65f2mtklein int fCurrentRecording; 98592007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentScale; 98692007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentSKP; 9875b69377507478623dcf5b11f3ecb010f87c4794frobertphillips int fCurrentUseMPD; 98860869a42a133942f852dd0f1696444c2a5c9ad83scroggo int fCurrentCodec; 98984451024bfe06d138629dd7c27cf2ec0f9774dbemsarett int fCurrentAndroidCodec; 9907f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int fCurrentBRDImage; 99195f192d19938b98a45dd1fa4112d965f60d10516msarett int fCurrentColorType; 992c7796b93f02e736df967301d3c46cec46dd02d5cmsarett int fCurrentAlphaType; 993b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett int fCurrentSubsetType; 9947f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int fCurrentBRDStrategy; 99584451024bfe06d138629dd7c27cf2ec0f9774dbemsarett int fCurrentSampleSize; 996261c3ad7fde95748da92550735decc949dc73bf2joshualitt int fCurrentAnimSKP; 997e714e75c725c987fe682a1f5473224fe3e80380dmtklein}; 998e714e75c725c987fe682a1f5473224fe3e80380dmtklein 999c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett// Some runs (mostly, Valgrind) are so slow that the bot framework thinks we've hung. 1000c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett// This prints something every once in a while so that it knows we're still working. 1001c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarettstatic void start_keepalive() { 1002c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett struct Loop { 1003c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett static void forever(void*) { 1004c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett for (;;) { 1005c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett static const int kSec = 1200; 1006c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett #if defined(SK_BUILD_FOR_WIN) 1007c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett Sleep(kSec * 1000); 1008c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett #else 1009c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett sleep(kSec); 1010c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett #endif 1011c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett SkDebugf("\nBenchmarks still running...\n"); 1012c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett } 1013c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett } 1014c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett }; 1015c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett static SkThread* intentionallyLeaked = new SkThread(Loop::forever); 1016c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett intentionallyLeaked->start(); 1017c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett} 1018c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett 10193b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorioint nanobench_main(); 102017f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclarkint nanobench_main() { 10213b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio SetupCrashHandler(); 1022f372321de3d4183de5b9ca436e677e471e358f31mtklein SkAutoGraphics ag; 1023cc29d26f5742449eb2a2bafa7bbb6ec5ee701aefmtklein SkTaskGroup::Enabler enabled(FLAGS_threads); 1024f372321de3d4183de5b9ca436e677e471e358f31mtklein 102569a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#if SK_SUPPORT_GPU 1026682c269a1511200322916af83053e26004c0ec40bsalomon GrContextOptions grContextOpts; 102712b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks; 1028385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary gGrFactory.reset(new GrContextFactory(grContextOpts)); 102969a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#endif 103069a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski 103106cddec8570cbf29f89e89736afb0487b5b95abdbsalomon if (FLAGS_veryVerbose) { 103206cddec8570cbf29f89e89736afb0487b5b95abdbsalomon FLAGS_verbose = true; 103306cddec8570cbf29f89e89736afb0487b5b95abdbsalomon } 103406cddec8570cbf29f89e89736afb0487b5b95abdbsalomon 10356eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 1036a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_samples = 1; 1037a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_gpuFrameLag = 0; 1038a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 1039a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 10406eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!FLAGS_writePath.isEmpty()) { 10416eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); 10426eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(FLAGS_writePath[0])) { 10436eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_writePath[0]); 104496fcdcc219d2a0d3579719b84b28bede76efba64halcanary FLAGS_writePath.set(0, nullptr); 10456eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 10466eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 10476eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 1048385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTDelete<ResultsWriter> log(new ResultsWriter); 104960317d0ffb5053df7b08a627d6decd11b684e80dmtklein if (!FLAGS_outResultsFile.isEmpty()) { 10505352015fa318fc6c25b789cb0a81d2d586d6121fmtklein#if defined(SK_RELEASE) 1051385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary log.reset(new NanoJSONResultsWriter(FLAGS_outResultsFile[0])); 10525352015fa318fc6c25b789cb0a81d2d586d6121fmtklein#else 10535352015fa318fc6c25b789cb0a81d2d586d6121fmtklein SkDebugf("I'm ignoring --outResultsFile because this is a Debug build."); 10545352015fa318fc6c25b789cb0a81d2d586d6121fmtklein return 1; 10555352015fa318fc6c25b789cb0a81d2d586d6121fmtklein#endif 105660317d0ffb5053df7b08a627d6decd11b684e80dmtklein } 1057bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 10581915b62637bea20e1471a8a358b22e9e47a4a385mtklein if (1 == FLAGS_properties.count() % 2) { 10591915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkDebugf("ERROR: --properties must be passed with an even number of arguments.\n"); 1060bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio return 1; 1061bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 10621915b62637bea20e1471a8a358b22e9e47a4a385mtklein for (int i = 1; i < FLAGS_properties.count(); i += 2) { 10631915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->property(FLAGS_properties[i-1], FLAGS_properties[i]); 1064bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 106594e51567dd691c3e1e8dfa6005a301d72cecf48emtklein 10661915b62637bea20e1471a8a358b22e9e47a4a385mtklein if (1 == FLAGS_key.count() % 2) { 10671915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkDebugf("ERROR: --key must be passed with an even number of arguments.\n"); 106894e51567dd691c3e1e8dfa6005a301d72cecf48emtklein return 1; 106994e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 10701915b62637bea20e1471a8a358b22e9e47a4a385mtklein for (int i = 1; i < FLAGS_key.count(); i += 2) { 10711915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->key(FLAGS_key[i-1], FLAGS_key[i]); 107294e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 107360317d0ffb5053df7b08a627d6decd11b684e80dmtklein 1074f372321de3d4183de5b9ca436e677e471e358f31mtklein const double overhead = estimate_timer_overhead(); 107555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead)); 1076912947737a973421f4c58682b6171cb5ee00ad3aMike Klein 1077e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton SkTArray<double> samples; 1078bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 10796eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 10806eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Fixed number of loops; times would only be misleading so we won't print them.\n"); 1081f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 108266cfcffd5d0a430f00bf0e36bedb088a25957183mtklein SkDebugf("! -> high variance, ? -> moderate variance\n"); 108366cfcffd5d0a430f00bf0e36bedb088a25957183mtklein SkDebugf(" micros \tbench\n"); 1084bbba16878f343b232d844281fbdf056c00e20fb6mtklein } else if (FLAGS_ms) { 1085e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\n"); 1086f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 1087d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconfig\tbench\n", 10888247ec313d87afcdd4da59b1f2f0d24e0983e359qiankun.miao FLAGS_samples, "samples"); 1089f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1090f372321de3d4183de5b9ca436e677e471e358f31mtklein 1091c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen SkTArray<Config> configs; 1092c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon create_configs(&configs); 1093c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 10943ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt#ifdef THERMAL_MANAGER_SUPPORTED 10953ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt int tmEnabled, tmThreshold, tmSleepTimeMs, tmTimeoutMs; 10963ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt if (4 != sscanf(FLAGS_useThermalManager[0], "%d,%d,%d,%d", 10973ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt &tmEnabled, &tmThreshold, &tmSleepTimeMs, &tmTimeoutMs)) { 10983ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt SkDebugf("Can't parse %s from --useThermalManager.\n", FLAGS_useThermalManager[0]); 10993ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt exit(1); 11003ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt } 11013ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt ThermalManager tm(tmThreshold, tmSleepTimeMs, tmTimeoutMs); 11023ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt#endif 11033ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt 1104c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett if (FLAGS_keepAlive) { 1105c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett start_keepalive(); 1106c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett } 1107c149f0e36e0ca0ff35ec6e2f79419b58d529db40msarett 1108e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein int runs = 0; 110992007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream benchStream; 111092007583e43115998412ac8b0a06cc2780eb025cmtklein while (Benchmark* b = benchStream.next()) { 1111e714e75c725c987fe682a1f5473224fe3e80380dmtklein SkAutoTDelete<Benchmark> bench(b); 1112962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName())) { 1113f372321de3d4183de5b9ca436e677e471e358f31mtklein continue; 1114f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1115f372321de3d4183de5b9ca436e677e471e358f31mtklein 1116c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen if (!configs.empty()) { 1117962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSize().fY); 11188a6697af95b340aad6dee7e6228048fa305c1e59joshualitt bench->delayedSetup(); 1119bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 11203bf9206ada256277a39988c263f0379d544fc27begdaniel for (int i = 0; i < configs.count(); ++i) { 11213ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt#ifdef THERMAL_MANAGER_SUPPORTED 11223ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt if (tmEnabled && !tm.coolOffIfNecessary()) { 11233ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt SkDebugf("Could not cool off, timings will be throttled\n"); 11243ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt } 11253ebd050be551e9d1364dbd115708e8f86397cd6fjoshualitt#endif 11263bf9206ada256277a39988c263f0379d544fc27begdaniel Target* target = is_enabled(b, configs[i]); 11273bf9206ada256277a39988c263f0379d544fc27begdaniel if (!target) { 11283bf9206ada256277a39988c263f0379d544fc27begdaniel continue; 11293bf9206ada256277a39988c263f0379d544fc27begdaniel } 11303bf9206ada256277a39988c263f0379d544fc27begdaniel 113196fcdcc219d2a0d3579719b84b28bede76efba64halcanary // During HWUI output this canvas may be nullptr. 11323bf9206ada256277a39988c263f0379d544fc27begdaniel SkCanvas* canvas = target->getCanvas(); 1133c47635e0ed52970fa40a16ffb280071e6b838a52svaisanen const char* config = target->config.name.c_str(); 1134bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 11357a5ada8c429b99b6ea061d7ea710d3c8349502acbrianosman if (FLAGS_pre_log || FLAGS_dryRun) { 11368d61f0dd1b6fde5202a14dfafcc1bceccf0d74adbenjaminwagner SkDebugf("Running %s\t%s\n" 11378d61f0dd1b6fde5202a14dfafcc1bceccf0d74adbenjaminwagner , bench->getUniqueName() 11388d61f0dd1b6fde5202a14dfafcc1bceccf0d74adbenjaminwagner , config); 11397a5ada8c429b99b6ea061d7ea710d3c8349502acbrianosman if (FLAGS_dryRun) { 11407a5ada8c429b99b6ea061d7ea710d3c8349502acbrianosman continue; 11417a5ada8c429b99b6ea061d7ea710d3c8349502acbrianosman } 11428d61f0dd1b6fde5202a14dfafcc1bceccf0d74adbenjaminwagner } 11438d61f0dd1b6fde5202a14dfafcc1bceccf0d74adbenjaminwagner 11443bf9206ada256277a39988c263f0379d544fc27begdaniel target->setup(); 11455b69377507478623dcf5b11f3ecb010f87c4794frobertphillips bench->perCanvasPreDraw(canvas); 11465b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 1147e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton int maxFrameLag; 1148a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein int loops = target->needsFrameTiming(&maxFrameLag) 11493bf9206ada256277a39988c263f0379d544fc27begdaniel ? setup_gpu_bench(target, bench.get(), maxFrameLag) 11503bf9206ada256277a39988c263f0379d544fc27begdaniel : setup_cpu_bench(overhead, target, bench.get()); 1151e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton 1152bbba16878f343b232d844281fbdf056c00e20fb6mtklein if (FLAGS_ms) { 1153bbba16878f343b232d844281fbdf056c00e20fb6mtklein samples.reset(); 1154bbba16878f343b232d844281fbdf056c00e20fb6mtklein auto stop = now_ms() + FLAGS_ms; 1155bbba16878f343b232d844281fbdf056c00e20fb6mtklein do { 1156bbba16878f343b232d844281fbdf056c00e20fb6mtklein samples.push_back(time(loops, bench, target) / loops); 1157bbba16878f343b232d844281fbdf056c00e20fb6mtklein } while (now_ms() < stop); 1158bbba16878f343b232d844281fbdf056c00e20fb6mtklein } else { 1159e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton samples.reset(FLAGS_samples); 1160e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton for (int s = 0; s < FLAGS_samples; s++) { 11613bf9206ada256277a39988c263f0379d544fc27begdaniel samples[s] = time(loops, bench, target) / loops; 1162e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton } 1163e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton } 1164f372321de3d4183de5b9ca436e677e471e358f31mtklein 1165e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt#if SK_SUPPORT_GPU 1166e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt SkTArray<SkString> keys; 1167e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt SkTArray<double> values; 1168e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt bool gpuStatsDump = FLAGS_gpuStatsDump && Benchmark::kGPU_Backend == configs[i].backend; 1169e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt if (gpuStatsDump) { 1170e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt // TODO cache stats 1171e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt bench->getGpuStats(canvas, &keys, &values); 1172e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt } 1173e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt#endif 1174e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt 11755b69377507478623dcf5b11f3ecb010f87c4794frobertphillips bench->perCanvasPostDraw(canvas); 11765b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 11773bf9206ada256277a39988c263f0379d544fc27begdaniel if (Benchmark::kNonRendering_Backend != target->config.backend && 1178d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { 11796eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config); 1180962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniqueName()); 11816eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon pngFilename.append(".png"); 11823bf9206ada256277a39988c263f0379d544fc27begdaniel write_canvas_png(target, pngFilename); 11836eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 11846eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 11856eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kFailedLoops == loops) { 11862069e220034f09aad2f68b262f395e7c25b3d178mtklein // Can't be timed. A warning note has already been printed. 11873bf9206ada256277a39988c263f0379d544fc27begdaniel cleanup_run(target); 1188e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein continue; 1189e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein } 119060317d0ffb5053df7b08a627d6decd11b684e80dmtklein 1191e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton Stats stats(samples); 11921915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->config(config); 1193962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein log->configOption("name", bench->getName()); 11941915b62637bea20e1471a8a358b22e9e47a4a385mtklein benchStream.fillCurrentOptions(log.get()); 11953bf9206ada256277a39988c263f0379d544fc27begdaniel target->fillOptions(log.get()); 1196051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("min_ms", stats.min); 1197e5cf2c6d940fa6a1d7c3016f631c734d3d29dec2mtklein log->metric("median_ms", stats.median); 1198e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt#if SK_SUPPORT_GPU 1199e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt if (gpuStatsDump) { 1200e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt // dump to json, only SKPBench currently returns valid keys / values 1201e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt SkASSERT(keys.count() == values.count()); 1202e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt for (int i = 0; i < keys.count(); i++) { 1203e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt log->metric(keys[i].c_str(), values[i]); 1204e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt } 1205e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt } 1206e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt#endif 1207e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt 1208e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein if (runs++ % FLAGS_flushEvery == 0) { 1209e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein log->flush(); 1210e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein } 121160317d0ffb5053df7b08a627d6decd11b684e80dmtklein 12126eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 12133bf9206ada256277a39988c263f0379d544fc27begdaniel if (configs.count() == 1) { 1214a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein config = ""; // Only print the config if we run the same bench on more than one. 1215a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 1216d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("%4d/%-4dMB\t%s\t%s\n" 1217d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getCurrResidentSetSizeMB() 1218d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getMaxResidentSetSizeMB() 121953d2562006ee371222963750009a706cfd1a94f7mtklein , bench->getUniqueName() 122053d2562006ee371222963750009a706cfd1a94f7mtklein , config); 1221f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 122266cfcffd5d0a430f00bf0e36bedb088a25957183mtklein const char* mark = " "; 122366cfcffd5d0a430f00bf0e36bedb088a25957183mtklein const double stddev_percent = 100 * sqrt(stats.var) / stats.mean; 122466cfcffd5d0a430f00bf0e36bedb088a25957183mtklein if (stddev_percent > 5) mark = "?"; 122566cfcffd5d0a430f00bf0e36bedb088a25957183mtklein if (stddev_percent > 10) mark = "!"; 122666cfcffd5d0a430f00bf0e36bedb088a25957183mtklein 122766cfcffd5d0a430f00bf0e36bedb088a25957183mtklein SkDebugf("%10.2f %s\t%s\t%s\n", 122866cfcffd5d0a430f00bf0e36bedb088a25957183mtklein stats.median*1e3, mark, bench->getUniqueName(), config); 1229f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 1230f372321de3d4183de5b9ca436e677e471e358f31mtklein const double stddev_percent = 100 * sqrt(stats.var) / stats.mean; 1231d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("%4d/%-4dMB\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" 1232d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getCurrResidentSetSizeMB() 1233d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getMaxResidentSetSizeMB() 1234f372321de3d4183de5b9ca436e677e471e358f31mtklein , loops 123555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.min) 123655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.median) 123755b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.mean) 123855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.max) 1239f372321de3d4183de5b9ca436e677e471e358f31mtklein , stddev_percent 1240bbba16878f343b232d844281fbdf056c00e20fb6mtklein , FLAGS_ms ? to_string(samples.count()).c_str() : stats.plot.c_str() 1241f372321de3d4183de5b9ca436e677e471e358f31mtklein , config 1242962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein , bench->getUniqueName() 1243f372321de3d4183de5b9ca436e677e471e358f31mtklein ); 1244f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1245e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt 1246b12ea41286ce36e085c5a14711da0cf9f240fdf1bsalomon#if SK_SUPPORT_GPU 1247e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt if (FLAGS_gpuStats && Benchmark::kGPU_Backend == configs[i].backend) { 12485219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen GrContext* context = gGrFactory->get(configs[i].ctxType, 12493e980c3d88fbc509b79e7ccef16ca38f5bbfb180kkinnunen configs[i].ctxOptions); 12505219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen context->printCacheStats(); 12515219fd9ff7aa6ebf64c905ad40f5e0027a39962bkkinnunen context->printGpuStats(); 125206cddec8570cbf29f89e89736afb0487b5b95abdbsalomon } 125306cddec8570cbf29f89e89736afb0487b5b95abdbsalomon#endif 1254e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt 12552c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton if (FLAGS_verbose) { 12562c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton SkDebugf("Samples: "); 12572c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton for (int i = 0; i < samples.count(); i++) { 12582c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton SkDebugf("%s ", HUMANIZE(samples[i])); 12592c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton } 12602c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton SkDebugf("%s\n", bench->getUniqueName()); 12612c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton } 12623bf9206ada256277a39988c263f0379d544fc27begdaniel cleanup_run(target); 1263f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1264f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1265f372321de3d4183de5b9ca436e677e471e358f31mtklein 1266e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->bench("memory_usage", 0,0); 1267e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->config("meta"); 1268e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->metric("max_rss_mb", sk_tools::getMaxResidentSetSizeMB()); 1269e109145bf31d63963b3f78c6af6e404d5464a55bmtklein 1270e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt#if SK_SUPPORT_GPU 1271e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt // Make sure we clean up the global GrContextFactory here, otherwise we might race with the 1272e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt // SkEventTracer destructor 127396fcdcc219d2a0d3579719b84b28bede76efba64halcanary gGrFactory.reset(nullptr); 1274e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt#endif 1275e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt 1276f372321de3d4183de5b9ca436e677e471e358f31mtklein return 0; 1277f372321de3d4183de5b9ca436e677e471e358f31mtklein} 1278f372321de3d4183de5b9ca436e677e471e358f31mtklein 12793b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio#if !defined SK_BUILD_FOR_IOS 12803b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorioint main(int argc, char** argv) { 12813b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio SkCommandLineFlags::Parse(argc, argv); 12823b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio return nanobench_main(); 12833b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio} 12843b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio#endif 1285