nanobench.cpp revision 66cfcffd5d0a430f00bf0e36bedb088a25957183
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 12f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Benchmark.h" 137f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett#include "BitmapRegionDecoderBench.h" 1460869a42a133942f852dd0f1696444c2a5c9ad83scroggo#include "CodecBench.h" 157f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett#include "CodecBenchPriv.h" 16f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "CrashHandler.h" 1795f192d19938b98a45dd1fa4112d965f60d10516msarett#include "DecodingBench.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" 24b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett#include "SubsetSingleBench.h" 25b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett#include "SubsetTranslateBench.h" 26b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett#include "SubsetZoomBench.h" 27f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Stats.h" 28f372321de3d4183de5b9ca436e677e471e358f31mtklein 295cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett#include "SkBitmapRegionDecoder.h" 306838d854a87e79f1fbb7b89b9f395155ad44dc0amtklein#include "SkBBoxHierarchy.h" 31f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkCanvas.h" 3260869a42a133942f852dd0f1696444c2a5c9ad83scroggo#include "SkCodec.h" 3317f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclark#include "SkCommonFlags.h" 3495f192d19938b98a45dd1fa4112d965f60d10516msarett#include "SkData.h" 35f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkForceLinking.h" 36f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkGraphics.h" 372084050a33ae139d0fe9bb680f7905f91139a39fmtklein#include "SkOSFile.h" 382084050a33ae139d0fe9bb680f7905f91139a39fmtklein#include "SkPictureRecorder.h" 39051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein#include "SkPictureUtils.h" 40f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkString.h" 41f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkSurface.h" 425b69377507478623dcf5b11f3ecb010f87c4794frobertphillips#include "SkTaskGroup.h" 43f372321de3d4183de5b9ca436e677e471e358f31mtklein 4460e0fee6d4acff638ccc9670c4055aced529a7a0bungeman#include <stdlib.h> 4560e0fee6d4acff638ccc9670c4055aced529a7a0bungeman 46d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 47d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson #include "nanobenchAndroid.h" 48d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 49d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 50bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 51bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio #include "gl/GrGLDefines.h" 52762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon #include "GrCaps.h" 53bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein #include "GrContextFactory.h" 5469a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski SkAutoTDelete<GrContextFactory> gGrFactory; 55bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 56bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 57682c269a1511200322916af83053e26004c0ec40bsalomon struct GrContextOptions; 58682c269a1511200322916af83053e26004c0ec40bsalomon 59f372321de3d4183de5b9ca436e677e471e358f31mtklein__SK_FORCE_IMAGE_DECODER_LINKING; 60f372321de3d4183de5b9ca436e677e471e358f31mtklein 615324978a88677ac6b758324321816427814e7793reedstatic const int kAutoTuneLoops = 0; 626eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 63b511042bb07a6a289b0d1146cb57f6e8b80580d6mtkleinstatic const int kDefaultLoops = 646eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon#ifdef SK_DEBUG 656eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 1; 66a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein#else 676eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon kAutoTuneLoops; 68a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein#endif 69a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 706eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic SkString loops_help_txt() { 716eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString help; 726eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon help.printf("Number of times to run each bench. Set this to %d to auto-" 736eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon "tune for each bench. Timings are only reported when auto-tuning.", 746eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon kAutoTuneLoops); 756eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return help; 766eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 776eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 78e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdaltonstatic SkString to_string(int n) { 79e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton SkString str; 80e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton str.appendS32(n); 81e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton return str; 82e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton} 83e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton 846eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonDEFINE_int32(loops, kDefaultLoops, loops_help_txt().c_str()); 856eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 86f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_int32(samples, 10, "Number of samples to measure for each bench."); 87bbba16878f343b232d844281fbdf056c00e20fb6mtkleinDEFINE_int32(ms, 0, "If >0, run each bench for this many ms instead of obeying --samples."); 88f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_int32(overheadLoops, 100000, "Loops to estimate timer overhead."); 89f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_double(overheadGoal, 0.0001, 90f372321de3d4183de5b9ca436e677e471e358f31mtklein "Loop until timer overhead is at most this fraction of our measurments."); 91bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinDEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); 92d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdaltonDEFINE_int32(gpuFrameLag, 5, "If unknown, estimated maximum number of frames GPU allows to lag."); 9312b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevskiDEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling back to " 9412b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski "software path rendering."); 95f372321de3d4183de5b9ca436e677e471e358f31mtklein 9660317d0ffb5053df7b08a627d6decd11b684e80dmtkleinDEFINE_string(outResultsFile, "", "If given, write results here as JSON."); 9755b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinDEFINE_int32(maxCalibrationAttempts, 3, 9855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein "Try up to this many times to guess loops for a bench, or skip the bench."); 9955b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinDEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this."); 10092007583e43115998412ac8b0a06cc2780eb025cmtkleinDEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs."); 10192007583e43115998412ac8b0a06cc2780eb025cmtkleinDEFINE_string(scales, "1.0", "Space-separated scales for SKPs."); 10263a82855b1f0b83952b65fca330954c50ebe7a4bcdaltonDEFINE_string(zoom, "1.0,0", "Comma-separated zoomMax,zoomPeriodMs factors for a periodic SKP zoom " 10363a82855b1f0b83952b65fca330954c50ebe7a4bcdalton "function that ping-pongs between 1.0 and zoomMax."); 1042084050a33ae139d0fe9bb680f7905f91139a39fmtkleinDEFINE_bool(bbh, true, "Build a BBH for SKPs?"); 1055b69377507478623dcf5b11f3ecb010f87c4794frobertphillipsDEFINE_bool(mpd, true, "Use MultiPictureDraw for the SKPs?"); 106b4022965a280dd1ed64d6103dd29e2189abe6e00cdaltonDEFINE_bool(loopSKP, true, "Loop SKPs like we do for micro benches?"); 107e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtkleinDEFINE_int32(flushEvery, 10, "Flush --outResultsFile every Nth run."); 10855e88b226ccb85d2c712a9e3e9e1f5bdcaac05acmtkleinDEFINE_bool(resetGpuContext, true, "Reset the GrContext before running each test."); 109b12ea41286ce36e085c5a14711da0cf9f240fdf1bsalomonDEFINE_bool(gpuStats, false, "Print GPU stats after each gpu benchmark?"); 110e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualittDEFINE_bool(gpuStatsDump, false, "Dump GPU states after each benchmark to json"); 11192007583e43115998412ac8b0a06cc2780eb025cmtklein 112bbba16878f343b232d844281fbdf056c00e20fb6mtkleinstatic double now_ms() { return SkTime::GetNSecs() * 1e-6; } 113bbba16878f343b232d844281fbdf056c00e20fb6mtklein 114f372321de3d4183de5b9ca436e677e471e358f31mtkleinstatic SkString humanize(double ms) { 115dc5bbab138bfffc85d6ba525d990aad09c322ff6mtklein if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); 116748ca3bf2d170708f263693e8579e6722389d0efmtklein return HumanizeMs(ms); 117f372321de3d4183de5b9ca436e677e471e358f31mtklein} 11855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein#define HUMANIZE(ms) humanize(ms).c_str() 119f372321de3d4183de5b9ca436e677e471e358f31mtklein 120d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonbool Target::init(SkImageInfo info, Benchmark* bench) { 121d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (Benchmark::kRaster_Backend == config.backend) { 122d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->surface.reset(SkSurface::NewRaster(info)); 123d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!this->surface.get()) { 124d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 125d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 126d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 127d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 128d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson} 129d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonbool Target::capturePixels(SkBitmap* bmp) { 13075a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson SkCanvas* canvas = this->getCanvas(); 131d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!canvas) { 132d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 133d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 134d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson bmp->setInfo(canvas->imageInfo()); 135d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!canvas->readPixels(bmp, 0, 0)) { 136d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkDebugf("Can't read canvas pixels.\n"); 137d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 138d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 139d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 140d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson} 141d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 142d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#if SK_SUPPORT_GPU 143d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonstruct GPUTarget : public Target { 14496fcdcc219d2a0d3579719b84b28bede76efba64halcanary explicit GPUTarget(const Config& c) : Target(c), gl(nullptr) { } 145d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkGLContext* gl; 146d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 147d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void setup() override { 148d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->gl->makeCurrent(); 149d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson // Make sure we're done with whatever came before. 150d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Finish()); 151d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 152d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void endTiming() override { 153d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (this->gl) { 154d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Flush()); 155d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->gl->swapBuffers(); 156d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 157d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 158d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void fence() override { 159d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Finish()); 160d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 161d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein 162d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton bool needsFrameTiming(int* maxFrameLag) const override { 163d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton if (!this->gl->getMaxGpuFrameLag(maxFrameLag)) { 164d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton // Frame lag is unknown. 165d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton *maxFrameLag = FLAGS_gpuFrameLag; 166d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton } 167d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton return true; 168d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton } 169d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson bool init(SkImageInfo info, Benchmark* bench) override { 170afcd7cd32497cc79035e61fd64b0baa03ed04bccbsalomon uint32_t flags = this->config.useDFText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 171afcd7cd32497cc79035e61fd64b0baa03ed04bccbsalomon 0; 172d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); 173a0a024e323ebf73ea4559d4b29f937902703828bbsalomon this->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(this->config.ctxType), 174d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkSurface::kNo_Budgeted, info, 175d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->config.samples, &props)); 176a0a024e323ebf73ea4559d4b29f937902703828bbsalomon this->gl = gGrFactory->getContextInfo(this->config.ctxType)->fGLContext; 177d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!this->surface.get()) { 178d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 179d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 180d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton if (!this->gl->fenceSyncSupport()) { 181d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton SkDebugf("WARNING: GL context for config \"%s\" does not support fence sync. " 182d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton "Timings might not be accurate.\n", this->config.name); 183d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton } 184d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 185d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 186d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void fillOptions(ResultsWriter* log) override { 187d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson const GrGLubyte* version; 188d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_VERSION)); 189d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_VERSION", (const char*)(version)); 190d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 191d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_RENDERER)); 192d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_RENDERER", (const char*) version); 193d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 194d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_VENDOR)); 195d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_VENDOR", (const char*) version); 196d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 197d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); 198d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version); 199d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 200d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson}; 201d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein 202d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 203d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 20475a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudsonstatic double time(int loops, Benchmark* bench, Target* target) { 20575a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson SkCanvas* canvas = target->getCanvas(); 2066eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (canvas) { 2076eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon canvas->clear(SK_ColorWHITE); 2086eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2098a6697af95b340aad6dee7e6228048fa305c1e59joshualitt bench->preDraw(canvas); 210bbba16878f343b232d844281fbdf056c00e20fb6mtklein double start = now_ms(); 21175a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson canvas = target->beginTiming(canvas); 21275a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson bench->draw(loops, canvas); 213f372321de3d4183de5b9ca436e677e471e358f31mtklein if (canvas) { 214f372321de3d4183de5b9ca436e677e471e358f31mtklein canvas->flush(); 215f372321de3d4183de5b9ca436e677e471e358f31mtklein } 21675a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson target->endTiming(); 217bbba16878f343b232d844281fbdf056c00e20fb6mtklein double elapsed = now_ms() - start; 2188a6697af95b340aad6dee7e6228048fa305c1e59joshualitt bench->postDraw(canvas); 219bbba16878f343b232d844281fbdf056c00e20fb6mtklein return elapsed; 220f372321de3d4183de5b9ca436e677e471e358f31mtklein} 221f372321de3d4183de5b9ca436e677e471e358f31mtklein 222bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic double estimate_timer_overhead() { 223bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein double overhead = 0; 224bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_overheadLoops; i++) { 225bbba16878f343b232d844281fbdf056c00e20fb6mtklein double start = now_ms(); 226bbba16878f343b232d844281fbdf056c00e20fb6mtklein overhead += now_ms() - start; 227bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 228bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return overhead / FLAGS_overheadLoops; 229bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 230f372321de3d4183de5b9ca436e677e471e358f31mtklein 2315324978a88677ac6b758324321816427814e7793reedstatic int detect_forever_loops(int loops) { 2325324978a88677ac6b758324321816427814e7793reed // look for a magic run-forever value 2335324978a88677ac6b758324321816427814e7793reed if (loops < 0) { 2345324978a88677ac6b758324321816427814e7793reed loops = SK_MaxS32; 2355324978a88677ac6b758324321816427814e7793reed } 2365324978a88677ac6b758324321816427814e7793reed return loops; 2375324978a88677ac6b758324321816427814e7793reed} 2385324978a88677ac6b758324321816427814e7793reed 23955b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinstatic int clamp_loops(int loops) { 24055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops < 1) { 241527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein SkDebugf("ERROR: clamping loops from %d to 1. " 242527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein "There's probably something wrong with the bench.\n", loops); 24355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return 1; 24455b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 24555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops > FLAGS_maxLoops) { 24655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("WARNING: clamping loops from %d to FLAGS_maxLoops, %d.\n", loops, FLAGS_maxLoops); 24755b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return FLAGS_maxLoops; 24855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 24955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return loops; 25055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein} 25155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein 252d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonstatic bool write_canvas_png(Target* target, const SkString& filename) { 253d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2546eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (filename.isEmpty()) { 2556eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2566eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 25775a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson if (target->getCanvas() && 25875a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson kUnknown_SkColorType == target->getCanvas()->imageInfo().colorType()) { 2596eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2606eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 261d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2626eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkBitmap bmp; 263d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 264d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!target->capturePixels(&bmp)) { 2656eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2666eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 267d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2686eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString dir = SkOSPath::Dirname(filename.c_str()); 2696eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(dir.c_str())) { 2706eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't make dir %s.\n", dir.c_str()); 2716eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2726eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2736eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkFILEWStream stream(filename.c_str()); 2746eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!stream.isValid()) { 2756eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't write %s.\n", filename.c_str()); 2766eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2776eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2786eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!SkImageEncoder::EncodeStream(&stream, bmp, SkImageEncoder::kPNG_Type, 100)) { 2796eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't encode a PNG.\n"); 2806eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2816eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2826eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return true; 2836eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 2846eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 2856eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic int kFailedLoops = -2; 286e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdaltonstatic int setup_cpu_bench(const double overhead, Target* target, Benchmark* bench) { 287bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First figure out approximately how many loops of bench it takes to make overhead negligible. 2882069e220034f09aad2f68b262f395e7c25b3d178mtklein double bench_plus_overhead = 0.0; 28955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein int round = 0; 290b4022965a280dd1ed64d6103dd29e2189abe6e00cdalton int loops = bench->calculateLoops(FLAGS_loops); 291b4022965a280dd1ed64d6103dd29e2189abe6e00cdalton if (kAutoTuneLoops == loops) { 2926eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon while (bench_plus_overhead < overhead) { 2936eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (round++ == FLAGS_maxCalibrationAttempts) { 2946eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skipping.\n", 295962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein bench->getUniqueName(), HUMANIZE(bench_plus_overhead), HUMANIZE(overhead)); 2966eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return kFailedLoops; 2976eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 29875a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson bench_plus_overhead = time(1, bench, target); 29955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 3002069e220034f09aad2f68b262f395e7c25b3d178mtklein } 301f372321de3d4183de5b9ca436e677e471e358f31mtklein 302bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Later we'll just start and stop the timer once but loop N times. 303f372321de3d4183de5b9ca436e677e471e358f31mtklein // We'll pick N to make timer overhead negligible: 304f372321de3d4183de5b9ca436e677e471e358f31mtklein // 305bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead 306bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------- < FLAGS_overheadGoal 307bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead + N * Bench Time 308f372321de3d4183de5b9ca436e677e471e358f31mtklein // 309bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // where bench_plus_overhead ≈ overhead + Bench Time. 310f372321de3d4183de5b9ca436e677e471e358f31mtklein // 311f372321de3d4183de5b9ca436e677e471e358f31mtklein // Doing some math, we get: 312f372321de3d4183de5b9ca436e677e471e358f31mtklein // 313bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // (overhead / FLAGS_overheadGoal) - overhead 314bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------------------------ < N 315bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // bench_plus_overhead - overhead) 316f372321de3d4183de5b9ca436e677e471e358f31mtklein // 317f372321de3d4183de5b9ca436e677e471e358f31mtklein // Luckily, this also works well in practice. :) 3186eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 3196eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double numer = overhead / FLAGS_overheadGoal - overhead; 3206eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double denom = bench_plus_overhead - overhead; 3216eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = (int)ceil(numer / denom); 3225324978a88677ac6b758324321816427814e7793reed loops = clamp_loops(loops); 3235324978a88677ac6b758324321816427814e7793reed } else { 3245324978a88677ac6b758324321816427814e7793reed loops = detect_forever_loops(loops); 3256eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 326bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 327bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 328f372321de3d4183de5b9ca436e677e471e358f31mtklein} 329f372321de3d4183de5b9ca436e677e471e358f31mtklein 330e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdaltonstatic int setup_gpu_bench(Target* target, Benchmark* bench, int maxGpuFrameLag) { 331bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First, figure out how many loops it'll take to get a frame up to FLAGS_gpuMs. 332b4022965a280dd1ed64d6103dd29e2189abe6e00cdalton int loops = bench->calculateLoops(FLAGS_loops); 3336eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 3346eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = 1; 335a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein double elapsed = 0; 336a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein do { 337527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein if (1<<30 == loops) { 338527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein // We're about to wrap. Something's wrong with the bench. 339527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein loops = 0; 340527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein break; 341527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein } 342a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops *= 2; 343a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // If the GPU lets frames lag at all, we need to make sure we're timing 344d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton // _this_ round, not still timing last round. 345d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton for (int i = 0; i < maxGpuFrameLag; i++) { 34675a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson elapsed = time(loops, bench, target); 347a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 348a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } while (elapsed < FLAGS_gpuMs); 349a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 350a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // We've overshot at least a little. Scale back linearly. 351a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); 3525324978a88677ac6b758324321816427814e7793reed loops = clamp_loops(loops); 353a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 354d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson // Make sure we're not still timing our calibration. 355d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target->fence(); 3565324978a88677ac6b758324321816427814e7793reed } else { 3575324978a88677ac6b758324321816427814e7793reed loops = detect_forever_loops(loops); 358a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 359bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 360bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Pretty much the same deal as the calibration: do some warmup to make 361bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // sure we're timing steady-state pipelined frames. 362d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton for (int i = 0; i < maxGpuFrameLag - 1; i++) { 36375a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson time(loops, bench, target); 364f372321de3d4183de5b9ca436e677e471e358f31mtklein } 365bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 366bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 367f372321de3d4183de5b9ca436e677e471e358f31mtklein} 368bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 369bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic SkString to_lower(const char* str) { 370bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkString lower(str); 371bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (size_t i = 0; i < lower.size(); i++) { 372bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein lower[i] = tolower(lower[i]); 373bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 374bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return lower; 375bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 376bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 377c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic bool is_cpu_config_allowed(const char* name) { 378bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_config.count(); i++) { 379c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (to_lower(FLAGS_config[i]).equals(name)) { 380c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return true; 381bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 382f372321de3d4183de5b9ca436e677e471e358f31mtklein } 383c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 384bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 385f372321de3d4183de5b9ca436e677e471e358f31mtklein 386c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 387c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextType ctxType, 388c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon int sampleCnt) { 389c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!is_cpu_config_allowed(name)) { 390c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 391c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 392a0a024e323ebf73ea4559d4b29f937902703828bbsalomon if (const GrContext* ctx = gGrFactory->get(ctxType)) { 393762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon return sampleCnt <= ctx->caps()->maxSampleCount(); 394c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 395c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 396c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 397c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 398c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 399c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 400c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType GrContextFactory::kNative_GLContextType 401c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#else 402c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType 0 403e714e75c725c987fe682a1f5473224fe3e80380dmtklein#endif 404c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 405c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// Append all configs that are enabled and supported. 406c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic void create_configs(SkTDArray<Config>* configs) { 407a0a024e323ebf73ea4559d4b29f937902703828bbsalomon #define CPU_CONFIG(name, backend, color, alpha) \ 408a0a024e323ebf73ea4559d4b29f937902703828bbsalomon if (is_cpu_config_allowed(#name)) { \ 409a0a024e323ebf73ea4559d4b29f937902703828bbsalomon Config config = { #name, Benchmark::backend, color, alpha, 0, \ 410a0a024e323ebf73ea4559d4b29f937902703828bbsalomon kBogusGLContextType, false }; \ 411a0a024e323ebf73ea4559d4b29f937902703828bbsalomon configs->push(config); \ 412f372321de3d4183de5b9ca436e677e471e358f31mtklein } 413e714e75c725c987fe682a1f5473224fe3e80380dmtklein 41440b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_cpu) { 415c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(nonrendering, kNonRendering_Backend, kUnknown_SkColorType, kUnpremul_SkAlphaType) 416c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(8888, kRaster_Backend, kN32_SkColorType, kPremul_SkAlphaType) 417c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(565, kRaster_Backend, kRGB_565_SkColorType, kOpaque_SkAlphaType) 41840b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 419f372321de3d4183de5b9ca436e677e471e358f31mtklein 420bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 421a0a024e323ebf73ea4559d4b29f937902703828bbsalomon #define GPU_CONFIG(name, ctxType, samples, useDFText) \ 422a0a024e323ebf73ea4559d4b29f937902703828bbsalomon if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, samples)) { \ 423c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Config config = { \ 424c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon #name, \ 425c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Benchmark::kGPU_Backend, \ 426c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon kN32_SkColorType, \ 427c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon kPremul_SkAlphaType, \ 428c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon samples, \ 4294736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GrContextFactory::ctxType, \ 4304736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth useDFText }; \ 431c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon configs->push(config); \ 432f372321de3d4183de5b9ca436e677e471e358f31mtklein } 433e714e75c725c987fe682a1f5473224fe3e80380dmtklein 43440b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_gpu) { 435a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(gpu, kNative_GLContextType, 0, false) 436a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(msaa4, kNative_GLContextType, 4, false) 437a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(msaa16, kNative_GLContextType, 16, false) 438a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4, false) 439a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16, false) 440a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(gpudft, kNative_GLContextType, 0, true) 441a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(debug, kDebug_GLContextType, 0, false) 442a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(nullgpu, kNull_GLContextType, 0, false) 4433b4d077fba1ad037536db198608a940c47d91888bsalomon#ifdef SK_ANGLE 444a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(angle, kANGLE_GLContextType, 0, false) 445a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(angle-gl, kANGLE_GL_GLContextType, 0, false) 4463b4d077fba1ad037536db198608a940c47d91888bsalomon#endif 447885bf0925514b9dfe3365bab227d36897d866b5dhendrikw#ifdef SK_COMMAND_BUFFER 448a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(commandbuffer, kCommandBuffer_GLContextType, 0, false) 449885bf0925514b9dfe3365bab227d36897d866b5dhendrikw#endif 450d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton#if SK_MESA 451a0a024e323ebf73ea4559d4b29f937902703828bbsalomon GPU_CONFIG(mesa, kMESA_GLContextType, 0, false) 452d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton#endif 45340b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 454bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 455d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 456d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 457d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (is_cpu_config_allowed("hwui")) { 458d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson Config config = { "hwui", Benchmark::kHWUI_Backend, kRGBA_8888_SkColorType, 4599323dc6a72de301f23e1187adc2365395b4b23d8scroggo kPremul_SkAlphaType, 0, kBogusGLContextType, false }; 460d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson configs->push(config); 461d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 462d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 463f372321de3d4183de5b9ca436e677e471e358f31mtklein} 464f372321de3d4183de5b9ca436e677e471e358f31mtklein 46596fcdcc219d2a0d3579719b84b28bede76efba64halcanary// If bench is enabled for config, returns a Target* for it, otherwise nullptr. 466c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic Target* is_enabled(Benchmark* bench, const Config& config) { 467c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!bench->isSuitableFor(config.backend)) { 46896fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 469c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 470c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 471e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkImageInfo info = SkImageInfo::Make(bench->getSize().fX, bench->getSize().fY, 472e5ea500d4714a7d84de2bf913e81be3b65d2de68reed config.color, config.alpha); 473c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 47496fcdcc219d2a0d3579719b84b28bede76efba64halcanary Target* target = nullptr; 475c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 476d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson switch (config.backend) { 477c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 478d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson case Benchmark::kGPU_Backend: 479d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new GPUTarget(config); 480d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 481d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 482d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 483d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson case Benchmark::kHWUI_Backend: 484d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new HWUITarget(config, bench); 485d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 486c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 487d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson default: 488d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new Target(config); 489d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 490d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 491c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 492d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!target->init(info, bench)) { 493c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon delete target; 49496fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 495c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 496c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return target; 497c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 498c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 499b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett/* 500ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo * We only run our subset benches on files that are supported by BitmapRegionDecoder: 5010459c9425f567b6d11ca534fb13a05de9f37b7eemsarett * i.e. PNG, JPEG, and WEBP. We do *not* test WEBP, since we do not have a scanline 5020459c9425f567b6d11ca534fb13a05de9f37b7eemsarett * decoder for WEBP, which is necessary for running the subset bench. (Another bench 5030459c9425f567b6d11ca534fb13a05de9f37b7eemsarett * must be used to test WEBP, which decodes subsets natively.) 504ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo */ 5050459c9425f567b6d11ca534fb13a05de9f37b7eemsarettstatic bool run_subset_bench(const SkString& path) { 506ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo static const char* const exts[] = { 5070459c9425f567b6d11ca534fb13a05de9f37b7eemsarett "jpg", "jpeg", "png", 5080459c9425f567b6d11ca534fb13a05de9f37b7eemsarett "JPG", "JPEG", "PNG", 509ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo }; 510ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo 5110459c9425f567b6d11ca534fb13a05de9f37b7eemsarett for (uint32_t i = 0; i < SK_ARRAY_COUNT(exts); i++) { 5120459c9425f567b6d11ca534fb13a05de9f37b7eemsarett if (path.endsWith(exts[i])) { 5130459c9425f567b6d11ca534fb13a05de9f37b7eemsarett return true; 514ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo } 515ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo } 516ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo 5172da1a854b0836001533aa29ade89d87f420cbbc3scroggo return false; 518ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo} 519ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo 520ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo/* 521b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett * Returns true if set up for a subset decode succeeds, false otherwise 522b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett * If the set-up succeeds, the width and height parameters will be set 523b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett */ 5240459c9425f567b6d11ca534fb13a05de9f37b7eemsarettstatic bool valid_subset_bench(const SkString& path, SkColorType colorType, 525b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett int* width, int* height) { 526b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 527b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkAutoTDelete<SkMemoryStream> stream(new SkMemoryStream(encoded)); 528b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett 5290459c9425f567b6d11ca534fb13a05de9f37b7eemsarett // Check that we can create a codec. 5300459c9425f567b6d11ca534fb13a05de9f37b7eemsarett SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); 5310459c9425f567b6d11ca534fb13a05de9f37b7eemsarett if (nullptr == codec) { 5320459c9425f567b6d11ca534fb13a05de9f37b7eemsarett SkDebugf("Could not create codec for %s. Skipping bench.\n", path.c_str()); 5330459c9425f567b6d11ca534fb13a05de9f37b7eemsarett return false; 5340459c9425f567b6d11ca534fb13a05de9f37b7eemsarett } 535b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett 5360459c9425f567b6d11ca534fb13a05de9f37b7eemsarett // These will be initialized by SkCodec if the color type is kIndex8 and 5370459c9425f567b6d11ca534fb13a05de9f37b7eemsarett // unused otherwise. 5380459c9425f567b6d11ca534fb13a05de9f37b7eemsarett SkPMColor colors[256]; 5390459c9425f567b6d11ca534fb13a05de9f37b7eemsarett int colorCount; 5400459c9425f567b6d11ca534fb13a05de9f37b7eemsarett const SkImageInfo info = codec->getInfo().makeColorType(colorType); 5410459c9425f567b6d11ca534fb13a05de9f37b7eemsarett if (codec->startScanlineDecode(info, nullptr, colors, &colorCount) != SkCodec::kSuccess) 5420459c9425f567b6d11ca534fb13a05de9f37b7eemsarett { 5430459c9425f567b6d11ca534fb13a05de9f37b7eemsarett SkDebugf("Could not create scanline decoder for %s with color type %s. " 5440459c9425f567b6d11ca534fb13a05de9f37b7eemsarett "Skipping bench.\n", path.c_str(), color_type_to_str(colorType)); 5450459c9425f567b6d11ca534fb13a05de9f37b7eemsarett return false; 546b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett } 5470459c9425f567b6d11ca534fb13a05de9f37b7eemsarett *width = info.width(); 5480459c9425f567b6d11ca534fb13a05de9f37b7eemsarett *height = info.height(); 549ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett 550ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett // Check if the image is large enough for a meaningful subset benchmark. 551ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett if (*width <= 512 && *height <= 512) { 552ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett // This should not print a message since it is not an error. 553ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett return false; 554ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett } 555ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett 556b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett return true; 557b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett} 558bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 5595cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarettstatic bool valid_brd_bench(SkData* encoded, SkBitmapRegionDecoder::Strategy strategy, 5607f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkColorType colorType, uint32_t sampleSize, uint32_t minOutputSize, int* width, 5617f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int* height) { 5625cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett SkAutoTDelete<SkBitmapRegionDecoder> brd( 5635cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett SkBitmapRegionDecoder::Create(encoded, strategy)); 5647f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett if (nullptr == brd.get()) { 5657f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // This is indicates that subset decoding is not supported for a particular image format. 5667f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return false; 5677f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 5687f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 56935e5d1b4495478ca3bede66914ae07f50a447c4dmsarett SkBitmap bitmap; 57035e5d1b4495478ca3bede66914ae07f50a447c4dmsarett if (!brd->decodeRegion(&bitmap, nullptr, SkIRect::MakeXYWH(0, 0, brd->width(), brd->height()), 57135e5d1b4495478ca3bede66914ae07f50a447c4dmsarett 1, colorType, false)) { 57235e5d1b4495478ca3bede66914ae07f50a447c4dmsarett return false; 57335e5d1b4495478ca3bede66914ae07f50a447c4dmsarett } 5747f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 5757f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett if (sampleSize * minOutputSize > (uint32_t) brd->width() || sampleSize * minOutputSize > 5767f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett (uint32_t) brd->height()) { 5777f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // This indicates that the image is not large enough to decode a 5787f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // minOutputSize x minOutputSize subset at the given sampleSize. 5797f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return false; 5807f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 5817f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 5827f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // Set the image width and height. The calling code will use this to choose subsets to decode. 5837f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett *width = brd->width(); 5847f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett *height = brd->height(); 5857f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return true; 5867f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett} 5877f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 5883bf9206ada256277a39988c263f0379d544fc27begdanielstatic void cleanup_run(Target* target) { 589385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete target; 5903bf9206ada256277a39988c263f0379d544fc27begdaniel#if SK_SUPPORT_GPU 5913bf9206ada256277a39988c263f0379d544fc27begdaniel if (FLAGS_abandonGpuContext) { 5923bf9206ada256277a39988c263f0379d544fc27begdaniel gGrFactory->abandonContexts(); 5933bf9206ada256277a39988c263f0379d544fc27begdaniel } 5943bf9206ada256277a39988c263f0379d544fc27begdaniel if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { 5953bf9206ada256277a39988c263f0379d544fc27begdaniel gGrFactory->destroyContexts(); 5963bf9206ada256277a39988c263f0379d544fc27begdaniel } 5973bf9206ada256277a39988c263f0379d544fc27begdaniel#endif 5983bf9206ada256277a39988c263f0379d544fc27begdaniel} 5993bf9206ada256277a39988c263f0379d544fc27begdaniel 600e714e75c725c987fe682a1f5473224fe3e80380dmtkleinclass BenchmarkStream { 601e714e75c725c987fe682a1f5473224fe3e80380dmtkleinpublic: 60292007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream() : fBenches(BenchRegistry::Head()) 60392007583e43115998412ac8b0a06cc2780eb025cmtklein , fGMs(skiagm::GMRegistry::Head()) 604fd731ce804cd3223318f3feee2c98404890b65f2mtklein , fCurrentRecording(0) 60592007583e43115998412ac8b0a06cc2780eb025cmtklein , fCurrentScale(0) 6065b69377507478623dcf5b11f3ecb010f87c4794frobertphillips , fCurrentSKP(0) 60795f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentUseMPD(0) 60860869a42a133942f852dd0f1696444c2a5c9ad83scroggo , fCurrentCodec(0) 60995f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentImage(0) 61095f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentSubsetImage(0) 6117f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett , fCurrentBRDImage(0) 61295f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentColorType(0) 613b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett , fCurrentSubsetType(0) 6147f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett , fCurrentBRDStrategy(0) 6157f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett , fCurrentBRDSampleSize(0) 616b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett , fCurrentAnimSKP(0) { 61792007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_skps.count(); i++) { 61892007583e43115998412ac8b0a06cc2780eb025cmtklein if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { 61992007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = FLAGS_skps[i]; 62092007583e43115998412ac8b0a06cc2780eb025cmtklein } else { 62192007583e43115998412ac8b0a06cc2780eb025cmtklein SkOSFile::Iter it(FLAGS_skps[i], ".skp"); 62292007583e43115998412ac8b0a06cc2780eb025cmtklein SkString path; 62392007583e43115998412ac8b0a06cc2780eb025cmtklein while (it.next(&path)) { 62492007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str()); 62592007583e43115998412ac8b0a06cc2780eb025cmtklein } 62692007583e43115998412ac8b0a06cc2780eb025cmtklein } 62792007583e43115998412ac8b0a06cc2780eb025cmtklein } 62892007583e43115998412ac8b0a06cc2780eb025cmtklein 62992007583e43115998412ac8b0a06cc2780eb025cmtklein if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d", 63092007583e43115998412ac8b0a06cc2780eb025cmtklein &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom)) { 63192007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0]); 63292007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 63392007583e43115998412ac8b0a06cc2780eb025cmtklein } 63492007583e43115998412ac8b0a06cc2780eb025cmtklein 63592007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_scales.count(); i++) { 63692007583e43115998412ac8b0a06cc2780eb025cmtklein if (1 != sscanf(FLAGS_scales[i], "%f", &fScales.push_back())) { 63792007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --scales as an SkScalar.\n", FLAGS_scales[i]); 63892007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 63992007583e43115998412ac8b0a06cc2780eb025cmtklein } 64092007583e43115998412ac8b0a06cc2780eb025cmtklein } 6415b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 64263a82855b1f0b83952b65fca330954c50ebe7a4bcdalton if (2 != sscanf(FLAGS_zoom[0], "%f,%lf", &fZoomMax, &fZoomPeriodMs)) { 64363a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SkDebugf("Can't parse %s from --zoom as a zoomMax,zoomPeriodMs.\n", FLAGS_zoom[0]); 644261c3ad7fde95748da92550735decc949dc73bf2joshualitt exit(1); 645261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 646261c3ad7fde95748da92550735decc949dc73bf2joshualitt 6475b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (FLAGS_mpd) { 6485b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fUseMPDs.push_back() = true; 6495b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 650c751ecb3681072fda53dd3cebeb2eb41fc73b314mtklein fUseMPDs.push_back() = false; 65195553d917c73ef333ede967521560957a5b6a0admtklein 65295f192d19938b98a45dd1fa4112d965f60d10516msarett // Prepare the images for decoding 65395f192d19938b98a45dd1fa4112d965f60d10516msarett for (int i = 0; i < FLAGS_images.count(); i++) { 65495f192d19938b98a45dd1fa4112d965f60d10516msarett const char* flag = FLAGS_images[i]; 65595f192d19938b98a45dd1fa4112d965f60d10516msarett if (sk_isdir(flag)) { 65695f192d19938b98a45dd1fa4112d965f60d10516msarett // If the value passed in is a directory, add all the images 65795f192d19938b98a45dd1fa4112d965f60d10516msarett SkOSFile::Iter it(flag); 65895f192d19938b98a45dd1fa4112d965f60d10516msarett SkString file; 65995f192d19938b98a45dd1fa4112d965f60d10516msarett while (it.next(&file)) { 66095f192d19938b98a45dd1fa4112d965f60d10516msarett fImages.push_back() = SkOSPath::Join(flag, file.c_str()); 66195f192d19938b98a45dd1fa4112d965f60d10516msarett } 66295f192d19938b98a45dd1fa4112d965f60d10516msarett } else if (sk_exists(flag)) { 66395f192d19938b98a45dd1fa4112d965f60d10516msarett // Also add the value if it is a single image 66495f192d19938b98a45dd1fa4112d965f60d10516msarett fImages.push_back() = flag; 66595f192d19938b98a45dd1fa4112d965f60d10516msarett } 66695f192d19938b98a45dd1fa4112d965f60d10516msarett } 66795553d917c73ef333ede967521560957a5b6a0admtklein 66895f192d19938b98a45dd1fa4112d965f60d10516msarett // Choose the candidate color types for image decoding 66995f192d19938b98a45dd1fa4112d965f60d10516msarett const SkColorType colorTypes[] = 670b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett { kN32_SkColorType, 671b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kRGB_565_SkColorType, 672b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kAlpha_8_SkColorType, 673b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kIndex_8_SkColorType, 674b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kGray_8_SkColorType }; 67574deb981d5e9c11c88fe431e78166d6cf8dacc1amsarett fColorTypes.reset(colorTypes, SK_ARRAY_COUNT(colorTypes)); 67692007583e43115998412ac8b0a06cc2780eb025cmtklein } 677e714e75c725c987fe682a1f5473224fe3e80380dmtklein 678fd731ce804cd3223318f3feee2c98404890b65f2mtklein static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) { 679fd731ce804cd3223318f3feee2c98404890b65f2mtklein // Not strictly necessary, as it will be checked again later, 680fd731ce804cd3223318f3feee2c98404890b65f2mtklein // but helps to avoid a lot of pointless work if we're going to skip it. 681fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) { 682fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 683fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 684fd731ce804cd3223318f3feee2c98404890b65f2mtklein 685a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path)); 68696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (stream.get() == nullptr) { 687fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkDebugf("Could not read %s.\n", path); 688fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 689fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 690fd731ce804cd3223318f3feee2c98404890b65f2mtklein 69157f27bdcbd328491a121918b4ab9301fbcdec642mtklein pic->reset(SkPicture::CreateFromStream(stream.get())); 69296fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (pic->get() == nullptr) { 693fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkDebugf("Could not read %s as an SkPicture.\n", path); 694fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 695fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 696fd731ce804cd3223318f3feee2c98404890b65f2mtklein return true; 697fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 698fd731ce804cd3223318f3feee2c98404890b65f2mtklein 69992007583e43115998412ac8b0a06cc2780eb025cmtklein Benchmark* next() { 700e714e75c725c987fe682a1f5473224fe3e80380dmtklein if (fBenches) { 70196fcdcc219d2a0d3579719b84b28bede76efba64halcanary Benchmark* bench = fBenches->factory()(nullptr); 702e714e75c725c987fe682a1f5473224fe3e80380dmtklein fBenches = fBenches->next(); 70392007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "bench"; 704fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "micro"; 705e714e75c725c987fe682a1f5473224fe3e80380dmtklein return bench; 706e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 70792007583e43115998412ac8b0a06cc2780eb025cmtklein 708e714e75c725c987fe682a1f5473224fe3e80380dmtklein while (fGMs) { 70996fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr)); 710e714e75c725c987fe682a1f5473224fe3e80380dmtklein fGMs = fGMs->next(); 711cf5d9c993dcbd75d4cefe2d1de25c2b9645f6957mtklein if (gm->runAsBench()) { 71292007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "gm"; 713fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "micro"; 714385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new GMBench(gm.detach()); 715e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 716e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 71792007583e43115998412ac8b0a06cc2780eb025cmtklein 718fd731ce804cd3223318f3feee2c98404890b65f2mtklein // First add all .skps as RecordingBenches. 719fd731ce804cd3223318f3feee2c98404890b65f2mtklein while (fCurrentRecording < fSKPs.count()) { 720fd731ce804cd3223318f3feee2c98404890b65f2mtklein const SkString& path = fSKPs[fCurrentRecording++]; 721fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkPicture> pic; 722fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (!ReadPicture(path.c_str(), &pic)) { 723fd731ce804cd3223318f3feee2c98404890b65f2mtklein continue; 724fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 725fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkString name = SkOSPath::Basename(path.c_str()); 726fd731ce804cd3223318f3feee2c98404890b65f2mtklein fSourceType = "skp"; 727fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "recording"; 7280aa5cea8694d3686b6742a36eab81ab9001de954bsalomon fSKPBytes = static_cast<double>(SkPictureUtils::ApproximateBytesUsed(pic)); 729051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein fSKPOps = pic->approximateOpCount(); 730385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new RecordingBench(name.c_str(), pic.get(), FLAGS_bbh); 731fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 732fd731ce804cd3223318f3feee2c98404890b65f2mtklein 733fd731ce804cd3223318f3feee2c98404890b65f2mtklein // Then once each for each scale as SKPBenches (playback). 73492007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentScale < fScales.count()) { 73592007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentSKP < fSKPs.count()) { 7365b69377507478623dcf5b11f3ecb010f87c4794frobertphillips const SkString& path = fSKPs[fCurrentSKP]; 737fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkPicture> pic; 738fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (!ReadPicture(path.c_str(), &pic)) { 7395b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentSKP++; 74092007583e43115998412ac8b0a06cc2780eb025cmtklein continue; 74192007583e43115998412ac8b0a06cc2780eb025cmtklein } 7425b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 7435b69377507478623dcf5b11f3ecb010f87c4794frobertphillips while (fCurrentUseMPD < fUseMPDs.count()) { 7445b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (FLAGS_bbh) { 7455b69377507478623dcf5b11f3ecb010f87c4794frobertphillips // The SKP we read off disk doesn't have a BBH. Re-record so it grows one. 7465b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkRTreeFactory factory; 7475b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkPictureRecorder recorder; 7485b69377507478623dcf5b11f3ecb010f87c4794frobertphillips static const int kFlags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag; 7495b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic->playback(recorder.beginRecording(pic->cullRect().width(), 7505b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic->cullRect().height(), 751748ca3bf2d170708f263693e8579e6722389d0efmtklein &factory, 752e451c4df7369c5e253ef9c9e0a8713beda25f34brobertphillips fUseMPDs[fCurrentUseMPD] ? kFlags : 0)); 7535b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic.reset(recorder.endRecording()); 7545b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 7555b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkString name = SkOSPath::Basename(path.c_str()); 7565b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fSourceType = "skp"; 7575b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fBenchType = "playback"; 758385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SKPBench(name.c_str(), pic.get(), fClip, fScales[fCurrentScale], 759385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fUseMPDs[fCurrentUseMPD++], FLAGS_loopSKP); 7602084050a33ae139d0fe9bb680f7905f91139a39fmtklein } 7615b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentUseMPD = 0; 7625b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentSKP++; 76392007583e43115998412ac8b0a06cc2780eb025cmtklein } 76492007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentSKP = 0; 76592007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentScale++; 76692007583e43115998412ac8b0a06cc2780eb025cmtklein } 76792007583e43115998412ac8b0a06cc2780eb025cmtklein 768261c3ad7fde95748da92550735decc949dc73bf2joshualitt // Now loop over each skp again if we have an animation 76963a82855b1f0b83952b65fca330954c50ebe7a4bcdalton if (fZoomMax != 1.0f && fZoomPeriodMs > 0) { 770261c3ad7fde95748da92550735decc949dc73bf2joshualitt while (fCurrentAnimSKP < fSKPs.count()) { 771261c3ad7fde95748da92550735decc949dc73bf2joshualitt const SkString& path = fSKPs[fCurrentAnimSKP]; 772261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkAutoTUnref<SkPicture> pic; 773261c3ad7fde95748da92550735decc949dc73bf2joshualitt if (!ReadPicture(path.c_str(), &pic)) { 774261c3ad7fde95748da92550735decc949dc73bf2joshualitt fCurrentAnimSKP++; 775261c3ad7fde95748da92550735decc949dc73bf2joshualitt continue; 776261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 777261c3ad7fde95748da92550735decc949dc73bf2joshualitt 778261c3ad7fde95748da92550735decc949dc73bf2joshualitt fCurrentAnimSKP++; 779261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkString name = SkOSPath::Basename(path.c_str()); 78063a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SkAutoTUnref<SKPAnimationBench::Animation> animation( 78163a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SKPAnimationBench::CreateZoomAnimation(fZoomMax, fZoomPeriodMs)); 782385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SKPAnimationBench(name.c_str(), pic.get(), fClip, animation, 783385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary FLAGS_loopSKP); 784261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 785261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 786261c3ad7fde95748da92550735decc949dc73bf2joshualitt 78760869a42a133942f852dd0f1696444c2a5c9ad83scroggo for (; fCurrentCodec < fImages.count(); fCurrentCodec++) { 788303fa350125f372bbfc29bec1235885493dab9b4scroggo fSourceType = "image"; 789303fa350125f372bbfc29bec1235885493dab9b4scroggo fBenchType = "skcodec"; 79060869a42a133942f852dd0f1696444c2a5c9ad83scroggo const SkString& path = fImages[fCurrentCodec]; 79160869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 79260869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); 79360869a42a133942f852dd0f1696444c2a5c9ad83scroggo if (!codec) { 79460869a42a133942f852dd0f1696444c2a5c9ad83scroggo // Nothing to time. 7959d9725c892743cf8fc66ea6cdd5ce21fe2df6d14msarett SkDebugf("Cannot find codec for %s\n", path.c_str()); 79660869a42a133942f852dd0f1696444c2a5c9ad83scroggo continue; 79760869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 79821027994192f395bbd1507558b84f59b3c7cf0dascroggo 79960869a42a133942f852dd0f1696444c2a5c9ad83scroggo while (fCurrentColorType < fColorTypes.count()) { 80021027994192f395bbd1507558b84f59b3c7cf0dascroggo const SkColorType colorType = fColorTypes[fCurrentColorType]; 80160869a42a133942f852dd0f1696444c2a5c9ad83scroggo fCurrentColorType++; 80221027994192f395bbd1507558b84f59b3c7cf0dascroggo 80360869a42a133942f852dd0f1696444c2a5c9ad83scroggo // Make sure we can decode to this color type. 80460869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkImageInfo info = codec->getInfo().makeColorType(colorType); 80521027994192f395bbd1507558b84f59b3c7cf0dascroggo SkAlphaType alphaType; 80621027994192f395bbd1507558b84f59b3c7cf0dascroggo if (!SkColorTypeValidateAlphaType(colorType, info.alphaType(), 80721027994192f395bbd1507558b84f59b3c7cf0dascroggo &alphaType)) { 80821027994192f395bbd1507558b84f59b3c7cf0dascroggo continue; 80921027994192f395bbd1507558b84f59b3c7cf0dascroggo } 81021027994192f395bbd1507558b84f59b3c7cf0dascroggo if (alphaType != info.alphaType()) { 81121027994192f395bbd1507558b84f59b3c7cf0dascroggo info = info.makeAlphaType(alphaType); 81221027994192f395bbd1507558b84f59b3c7cf0dascroggo } 81321027994192f395bbd1507558b84f59b3c7cf0dascroggo 81421027994192f395bbd1507558b84f59b3c7cf0dascroggo const size_t rowBytes = info.minRowBytes(); 81521027994192f395bbd1507558b84f59b3c7cf0dascroggo SkAutoMalloc storage(info.getSafeSize(rowBytes)); 81621027994192f395bbd1507558b84f59b3c7cf0dascroggo 81721027994192f395bbd1507558b84f59b3c7cf0dascroggo // Used if fCurrentColorType is kIndex_8_SkColorType 81821027994192f395bbd1507558b84f59b3c7cf0dascroggo int colorCount = 256; 81921027994192f395bbd1507558b84f59b3c7cf0dascroggo SkPMColor colors[256]; 82021027994192f395bbd1507558b84f59b3c7cf0dascroggo 821eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo const SkCodec::Result result = codec->getPixels( 82296fcdcc219d2a0d3579719b84b28bede76efba64halcanary info, storage.get(), rowBytes, nullptr, colors, 82321027994192f395bbd1507558b84f59b3c7cf0dascroggo &colorCount); 82460869a42a133942f852dd0f1696444c2a5c9ad83scroggo switch (result) { 825eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo case SkCodec::kSuccess: 826eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo case SkCodec::kIncompleteInput: 82760869a42a133942f852dd0f1696444c2a5c9ad83scroggo return new CodecBench(SkOSPath::Basename(path.c_str()), 82860869a42a133942f852dd0f1696444c2a5c9ad83scroggo encoded, colorType); 829eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo case SkCodec::kInvalidConversion: 83060869a42a133942f852dd0f1696444c2a5c9ad83scroggo // This is okay. Not all conversions are valid. 83160869a42a133942f852dd0f1696444c2a5c9ad83scroggo break; 83260869a42a133942f852dd0f1696444c2a5c9ad83scroggo default: 83360869a42a133942f852dd0f1696444c2a5c9ad83scroggo // This represents some sort of failure. 83460869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkASSERT(false); 83560869a42a133942f852dd0f1696444c2a5c9ad83scroggo break; 83660869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 83760869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 83860869a42a133942f852dd0f1696444c2a5c9ad83scroggo fCurrentColorType = 0; 83960869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 84060869a42a133942f852dd0f1696444c2a5c9ad83scroggo 84195f192d19938b98a45dd1fa4112d965f60d10516msarett // Run the DecodingBenches 84295f192d19938b98a45dd1fa4112d965f60d10516msarett while (fCurrentImage < fImages.count()) { 843303fa350125f372bbfc29bec1235885493dab9b4scroggo fSourceType = "image"; 844303fa350125f372bbfc29bec1235885493dab9b4scroggo fBenchType = "skimagedecoder"; 84595f192d19938b98a45dd1fa4112d965f60d10516msarett while (fCurrentColorType < fColorTypes.count()) { 84695f192d19938b98a45dd1fa4112d965f60d10516msarett const SkString& path = fImages[fCurrentImage]; 84795f192d19938b98a45dd1fa4112d965f60d10516msarett SkColorType colorType = fColorTypes[fCurrentColorType]; 84895f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentColorType++; 84960869a42a133942f852dd0f1696444c2a5c9ad83scroggo // Check if the image decodes to the right color type 85060869a42a133942f852dd0f1696444c2a5c9ad83scroggo // before creating the benchmark 85195f192d19938b98a45dd1fa4112d965f60d10516msarett SkBitmap bitmap; 85295f192d19938b98a45dd1fa4112d965f60d10516msarett if (SkImageDecoder::DecodeFile(path.c_str(), &bitmap, 85360869a42a133942f852dd0f1696444c2a5c9ad83scroggo colorType, SkImageDecoder::kDecodePixels_Mode) 85460869a42a133942f852dd0f1696444c2a5c9ad83scroggo && bitmap.colorType() == colorType) { 85595f192d19938b98a45dd1fa4112d965f60d10516msarett return new DecodingBench(path, colorType); 85695f192d19938b98a45dd1fa4112d965f60d10516msarett } 85795f192d19938b98a45dd1fa4112d965f60d10516msarett } 85895f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentColorType = 0; 85995f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentImage++; 86095f192d19938b98a45dd1fa4112d965f60d10516msarett } 86195f192d19938b98a45dd1fa4112d965f60d10516msarett 862b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett // Run the SubsetBenches 8630459c9425f567b6d11ca534fb13a05de9f37b7eemsarett while (fCurrentSubsetImage < fImages.count()) { 864303fa350125f372bbfc29bec1235885493dab9b4scroggo fSourceType = "image"; 8650459c9425f567b6d11ca534fb13a05de9f37b7eemsarett fBenchType = "skcodec"; 8660459c9425f567b6d11ca534fb13a05de9f37b7eemsarett const SkString& path = fImages[fCurrentSubsetImage]; 8670459c9425f567b6d11ca534fb13a05de9f37b7eemsarett if (!run_subset_bench(path)) { 8680459c9425f567b6d11ca534fb13a05de9f37b7eemsarett fCurrentSubsetImage++; 8690459c9425f567b6d11ca534fb13a05de9f37b7eemsarett continue; 8700459c9425f567b6d11ca534fb13a05de9f37b7eemsarett } 8710459c9425f567b6d11ca534fb13a05de9f37b7eemsarett while (fCurrentColorType < fColorTypes.count()) { 8720459c9425f567b6d11ca534fb13a05de9f37b7eemsarett SkColorType colorType = fColorTypes[fCurrentColorType]; 8730459c9425f567b6d11ca534fb13a05de9f37b7eemsarett while (fCurrentSubsetType <= kLast_SubsetType) { 8740459c9425f567b6d11ca534fb13a05de9f37b7eemsarett int width = 0; 8750459c9425f567b6d11ca534fb13a05de9f37b7eemsarett int height = 0; 8760459c9425f567b6d11ca534fb13a05de9f37b7eemsarett int currentSubsetType = fCurrentSubsetType++; 8770459c9425f567b6d11ca534fb13a05de9f37b7eemsarett if (valid_subset_bench(path, colorType, &width, &height)) { 8780459c9425f567b6d11ca534fb13a05de9f37b7eemsarett switch (currentSubsetType) { 8790459c9425f567b6d11ca534fb13a05de9f37b7eemsarett case kTopLeft_SubsetType: 8800459c9425f567b6d11ca534fb13a05de9f37b7eemsarett return new SubsetSingleBench(path, colorType, width/3, 8810459c9425f567b6d11ca534fb13a05de9f37b7eemsarett height/3, 0, 0); 8820459c9425f567b6d11ca534fb13a05de9f37b7eemsarett case kTopRight_SubsetType: 8830459c9425f567b6d11ca534fb13a05de9f37b7eemsarett return new SubsetSingleBench(path, colorType, width/3, 8840459c9425f567b6d11ca534fb13a05de9f37b7eemsarett height/3, 2*width/3, 0); 8850459c9425f567b6d11ca534fb13a05de9f37b7eemsarett case kMiddle_SubsetType: 8860459c9425f567b6d11ca534fb13a05de9f37b7eemsarett return new SubsetSingleBench(path, colorType, width/3, 8870459c9425f567b6d11ca534fb13a05de9f37b7eemsarett height/3, width/3, height/3); 8880459c9425f567b6d11ca534fb13a05de9f37b7eemsarett case kBottomLeft_SubsetType: 8890459c9425f567b6d11ca534fb13a05de9f37b7eemsarett return new SubsetSingleBench(path, colorType, width/3, 8900459c9425f567b6d11ca534fb13a05de9f37b7eemsarett height/3, 0, 2*height/3); 8910459c9425f567b6d11ca534fb13a05de9f37b7eemsarett case kBottomRight_SubsetType: 8920459c9425f567b6d11ca534fb13a05de9f37b7eemsarett return new SubsetSingleBench(path, colorType, width/3, 8930459c9425f567b6d11ca534fb13a05de9f37b7eemsarett height/3, 2*width/3, 2*height/3); 8940459c9425f567b6d11ca534fb13a05de9f37b7eemsarett case kTranslate_SubsetType: 8950459c9425f567b6d11ca534fb13a05de9f37b7eemsarett return new SubsetTranslateBench(path, colorType, 512, 512); 8960459c9425f567b6d11ca534fb13a05de9f37b7eemsarett case kZoom_SubsetType: 8970459c9425f567b6d11ca534fb13a05de9f37b7eemsarett return new SubsetZoomBench(path, colorType, 512, 512); 89895f192d19938b98a45dd1fa4112d965f60d10516msarett } 8990459c9425f567b6d11ca534fb13a05de9f37b7eemsarett } else { 9000459c9425f567b6d11ca534fb13a05de9f37b7eemsarett break; 90195f192d19938b98a45dd1fa4112d965f60d10516msarett } 90295f192d19938b98a45dd1fa4112d965f60d10516msarett } 9030459c9425f567b6d11ca534fb13a05de9f37b7eemsarett fCurrentSubsetType = 0; 9040459c9425f567b6d11ca534fb13a05de9f37b7eemsarett fCurrentColorType++; 90595f192d19938b98a45dd1fa4112d965f60d10516msarett } 9060459c9425f567b6d11ca534fb13a05de9f37b7eemsarett fCurrentColorType = 0; 9070459c9425f567b6d11ca534fb13a05de9f37b7eemsarett fCurrentSubsetImage++; 90895f192d19938b98a45dd1fa4112d965f60d10516msarett } 90995f192d19938b98a45dd1fa4112d965f60d10516msarett 9107f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // Run the BRDBenches 9117f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // We will benchmark multiple BRD strategies. 912303fa350125f372bbfc29bec1235885493dab9b4scroggo static const struct { 9135cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett SkBitmapRegionDecoder::Strategy fStrategy; 9140459c9425f567b6d11ca534fb13a05de9f37b7eemsarett const char* fName; 915303fa350125f372bbfc29bec1235885493dab9b4scroggo } strategies[] = { 9160459c9425f567b6d11ca534fb13a05de9f37b7eemsarett { SkBitmapRegionDecoder::kCanvas_Strategy, "BRD_canvas" }, 9175cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett { SkBitmapRegionDecoder::kAndroidCodec_Strategy, "BRD_android_codec" }, 9187f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett }; 9197f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 9207f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // We intend to create benchmarks that model the use cases in 9217f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // android/libraries/social/tiledimage. In this library, an image is decoded in 512x512 9227f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // tiles. The image can be translated freely, so the location of a tile may be anywhere in 9237f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // the image. For that reason, we will benchmark decodes in five representative locations 9247f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // in the image. Additionally, this use case utilizes power of two scaling, so we will 9257f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // test on power of two sample sizes. The output tile is always 512x512, so, when a 9267f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // sampleSize is used, the size of the subset that is decoded is always 9277f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // (sampleSize*512)x(sampleSize*512). 9287f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // There are a few good reasons to only test on power of two sample sizes at this time: 9297f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // JPEG decodes using kOriginal_Strategy are broken for non-powers of two. 9306950de6c4166fabb35e6c756fc009e0cf1c47819halcanary // https://bug.skia.org/4319 9317f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // All use cases we are aware of only scale by powers of two. 9327f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // PNG decodes use the indicated sampling strategy regardless of the sample size, so 9337f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // these tests are sufficient to provide good coverage of our scaling options. 934501b7344f116ccc821d437d324aa7883d7ce97bfscroggo const uint32_t sampleSizes[] = { 1, 2, 4, 8, 16, 32, 64 }; 9357f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett const uint32_t minOutputSize = 512; 9367f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentBRDImage < fImages.count()) { 9377f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentBRDStrategy < (int) SK_ARRAY_COUNT(strategies)) { 938303fa350125f372bbfc29bec1235885493dab9b4scroggo fSourceType = "image"; 939303fa350125f372bbfc29bec1235885493dab9b4scroggo fBenchType = strategies[fCurrentBRDStrategy].fName; 940860e8a67190e024b7375e52e270e6bd0a17af86escroggo 941860e8a67190e024b7375e52e270e6bd0a17af86escroggo const SkString& path = fImages[fCurrentBRDImage]; 9425cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett const SkBitmapRegionDecoder::Strategy strategy = 943860e8a67190e024b7375e52e270e6bd0a17af86escroggo strategies[fCurrentBRDStrategy].fStrategy; 944860e8a67190e024b7375e52e270e6bd0a17af86escroggo 9457f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentColorType < fColorTypes.count()) { 9467f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentBRDSampleSize < (int) SK_ARRAY_COUNT(sampleSizes)) { 9477f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentSubsetType <= kLastSingle_SubsetType) { 948860e8a67190e024b7375e52e270e6bd0a17af86escroggo 949860e8a67190e024b7375e52e270e6bd0a17af86escroggo 9507f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 9517f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett const SkColorType colorType = fColorTypes[fCurrentColorType]; 9527f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett uint32_t sampleSize = sampleSizes[fCurrentBRDSampleSize]; 9537f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int currentSubsetType = fCurrentSubsetType++; 9547f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 9557f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int width = 0; 9567f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int height = 0; 9577f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett if (!valid_brd_bench(encoded.get(), strategy, colorType, sampleSize, 9587f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett minOutputSize, &width, &height)) { 9597f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 9607f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 9617f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 9627f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkString basename = SkOSPath::Basename(path.c_str()); 9637f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkIRect subset; 9647f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett const uint32_t subsetSize = sampleSize * minOutputSize; 9657f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett switch (currentSubsetType) { 9667f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kTopLeft_SubsetType: 9677f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_TopLeft"); 9687f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(0, 0, subsetSize, subsetSize); 9697f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 9707f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kTopRight_SubsetType: 9717f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_TopRight"); 9727f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(width - subsetSize, 0, subsetSize, 9737f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subsetSize); 9747f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 9757f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kMiddle_SubsetType: 9767f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_Middle"); 9777f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH((width - subsetSize) / 2, 9787f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett (height - subsetSize) / 2, subsetSize, subsetSize); 9797f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 9807f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kBottomLeft_SubsetType: 9817f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_BottomLeft"); 9827f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(0, height - subsetSize, subsetSize, 9837f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subsetSize); 9847f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 9857f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kBottomRight_SubsetType: 9867f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_BottomRight"); 9877f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(width - subsetSize, 9887f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett height - subsetSize, subsetSize, subsetSize); 9897f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 9907f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett default: 9917f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkASSERT(false); 9927f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 9937f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 9947f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return new BitmapRegionDecoderBench(basename.c_str(), encoded.get(), 9957f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett strategy, colorType, sampleSize, subset); 9967f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 9977f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentSubsetType = 0; 9987f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDSampleSize++; 9997f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10007f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDSampleSize = 0; 10017f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentColorType++; 10027f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10037f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentColorType = 0; 10047f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDStrategy++; 10057f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10067f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDStrategy = 0; 10077f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDImage++; 10087f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10097f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 101096fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1011e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 101292007583e43115998412ac8b0a06cc2780eb025cmtklein 101392007583e43115998412ac8b0a06cc2780eb025cmtklein void fillCurrentOptions(ResultsWriter* log) const { 101492007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("source_type", fSourceType); 1015fd731ce804cd3223318f3feee2c98404890b65f2mtklein log->configOption("bench_type", fBenchType); 101692007583e43115998412ac8b0a06cc2780eb025cmtklein if (0 == strcmp(fSourceType, "skp")) { 101792007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("clip", 101892007583e43115998412ac8b0a06cc2780eb025cmtklein SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, 101992007583e43115998412ac8b0a06cc2780eb025cmtklein fClip.fRight, fClip.fBottom).c_str()); 10204dfdbb19ba861bbd5e1a306bb23f32464ea5e2c5mtklein SK_ALWAYSBREAK(fCurrentScale < fScales.count()); // debugging paranoia 102192007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentScale]).c_str()); 10225b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (fCurrentUseMPD > 0) { 10235b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkASSERT(1 == fCurrentUseMPD || 2 == fCurrentUseMPD); 10245b69377507478623dcf5b11f3ecb010f87c4794frobertphillips log->configOption("multi_picture_draw", fUseMPDs[fCurrentUseMPD-1] ? "true" : "false"); 10255b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 102692007583e43115998412ac8b0a06cc2780eb025cmtklein } 1027051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein if (0 == strcmp(fBenchType, "recording")) { 1028051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("bytes", fSKPBytes); 1029051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("ops", fSKPOps); 1030051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein } 103192007583e43115998412ac8b0a06cc2780eb025cmtklein } 103292007583e43115998412ac8b0a06cc2780eb025cmtklein 1033e714e75c725c987fe682a1f5473224fe3e80380dmtkleinprivate: 1034b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett enum SubsetType { 1035b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kTopLeft_SubsetType = 0, 1036b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kTopRight_SubsetType = 1, 1037ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kMiddle_SubsetType = 2, 1038ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kBottomLeft_SubsetType = 3, 1039ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kBottomRight_SubsetType = 4, 1040ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kTranslate_SubsetType = 5, 1041ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kZoom_SubsetType = 6, 10427f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett kLast_SubsetType = kZoom_SubsetType, 10437f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett kLastSingle_SubsetType = kBottomRight_SubsetType, 1044b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett }; 1045b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett 1046e714e75c725c987fe682a1f5473224fe3e80380dmtklein const BenchRegistry* fBenches; 1047e714e75c725c987fe682a1f5473224fe3e80380dmtklein const skiagm::GMRegistry* fGMs; 104892007583e43115998412ac8b0a06cc2780eb025cmtklein SkIRect fClip; 104992007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkScalar> fScales; 105092007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkString> fSKPs; 10515b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkTArray<bool> fUseMPDs; 105295f192d19938b98a45dd1fa4112d965f60d10516msarett SkTArray<SkString> fImages; 105374deb981d5e9c11c88fe431e78166d6cf8dacc1amsarett SkTArray<SkColorType, true> fColorTypes; 105463a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SkScalar fZoomMax; 105563a82855b1f0b83952b65fca330954c50ebe7a4bcdalton double fZoomPeriodMs; 105692007583e43115998412ac8b0a06cc2780eb025cmtklein 1057051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein double fSKPBytes, fSKPOps; 1058051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein 1059fd731ce804cd3223318f3feee2c98404890b65f2mtklein const char* fSourceType; // What we're benching: bench, GM, SKP, ... 1060fd731ce804cd3223318f3feee2c98404890b65f2mtklein const char* fBenchType; // How we bench it: micro, recording, playback, ... 1061fd731ce804cd3223318f3feee2c98404890b65f2mtklein int fCurrentRecording; 106292007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentScale; 106392007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentSKP; 10645b69377507478623dcf5b11f3ecb010f87c4794frobertphillips int fCurrentUseMPD; 106560869a42a133942f852dd0f1696444c2a5c9ad83scroggo int fCurrentCodec; 106695f192d19938b98a45dd1fa4112d965f60d10516msarett int fCurrentImage; 106795f192d19938b98a45dd1fa4112d965f60d10516msarett int fCurrentSubsetImage; 10687f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int fCurrentBRDImage; 106995f192d19938b98a45dd1fa4112d965f60d10516msarett int fCurrentColorType; 1070b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett int fCurrentSubsetType; 10717f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int fCurrentBRDStrategy; 10727f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int fCurrentBRDSampleSize; 1073261c3ad7fde95748da92550735decc949dc73bf2joshualitt int fCurrentAnimSKP; 1074e714e75c725c987fe682a1f5473224fe3e80380dmtklein}; 1075e714e75c725c987fe682a1f5473224fe3e80380dmtklein 10763b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorioint nanobench_main(); 107717f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclarkint nanobench_main() { 10783b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio SetupCrashHandler(); 1079f372321de3d4183de5b9ca436e677e471e358f31mtklein SkAutoGraphics ag; 1080cc29d26f5742449eb2a2bafa7bbb6ec5ee701aefmtklein SkTaskGroup::Enabler enabled(FLAGS_threads); 1081f372321de3d4183de5b9ca436e677e471e358f31mtklein 108269a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#if SK_SUPPORT_GPU 1083682c269a1511200322916af83053e26004c0ec40bsalomon GrContextOptions grContextOpts; 108412b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks; 1085385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary gGrFactory.reset(new GrContextFactory(grContextOpts)); 108669a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#endif 108769a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski 108806cddec8570cbf29f89e89736afb0487b5b95abdbsalomon if (FLAGS_veryVerbose) { 108906cddec8570cbf29f89e89736afb0487b5b95abdbsalomon FLAGS_verbose = true; 109006cddec8570cbf29f89e89736afb0487b5b95abdbsalomon } 109106cddec8570cbf29f89e89736afb0487b5b95abdbsalomon 10926eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 1093a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_samples = 1; 1094a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_gpuFrameLag = 0; 1095a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 1096a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 10976eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!FLAGS_writePath.isEmpty()) { 10986eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); 10996eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(FLAGS_writePath[0])) { 11006eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_writePath[0]); 110196fcdcc219d2a0d3579719b84b28bede76efba64halcanary FLAGS_writePath.set(0, nullptr); 11026eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 11036eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 11046eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 1105385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTDelete<ResultsWriter> log(new ResultsWriter); 110660317d0ffb5053df7b08a627d6decd11b684e80dmtklein if (!FLAGS_outResultsFile.isEmpty()) { 1107385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary log.reset(new NanoJSONResultsWriter(FLAGS_outResultsFile[0])); 110860317d0ffb5053df7b08a627d6decd11b684e80dmtklein } 1109bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 11101915b62637bea20e1471a8a358b22e9e47a4a385mtklein if (1 == FLAGS_properties.count() % 2) { 11111915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkDebugf("ERROR: --properties must be passed with an even number of arguments.\n"); 1112bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio return 1; 1113bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 11141915b62637bea20e1471a8a358b22e9e47a4a385mtklein for (int i = 1; i < FLAGS_properties.count(); i += 2) { 11151915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->property(FLAGS_properties[i-1], FLAGS_properties[i]); 1116bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 111794e51567dd691c3e1e8dfa6005a301d72cecf48emtklein 11181915b62637bea20e1471a8a358b22e9e47a4a385mtklein if (1 == FLAGS_key.count() % 2) { 11191915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkDebugf("ERROR: --key must be passed with an even number of arguments.\n"); 112094e51567dd691c3e1e8dfa6005a301d72cecf48emtklein return 1; 112194e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 11221915b62637bea20e1471a8a358b22e9e47a4a385mtklein for (int i = 1; i < FLAGS_key.count(); i += 2) { 11231915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->key(FLAGS_key[i-1], FLAGS_key[i]); 112494e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 112560317d0ffb5053df7b08a627d6decd11b684e80dmtklein 1126f372321de3d4183de5b9ca436e677e471e358f31mtklein const double overhead = estimate_timer_overhead(); 112755b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead)); 1128912947737a973421f4c58682b6171cb5ee00ad3aMike Klein 1129e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton SkTArray<double> samples; 1130bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 11316eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 11326eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Fixed number of loops; times would only be misleading so we won't print them.\n"); 1133f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 113466cfcffd5d0a430f00bf0e36bedb088a25957183mtklein SkDebugf("! -> high variance, ? -> moderate variance\n"); 113566cfcffd5d0a430f00bf0e36bedb088a25957183mtklein SkDebugf(" micros \tbench\n"); 1136bbba16878f343b232d844281fbdf056c00e20fb6mtklein } else if (FLAGS_ms) { 1137e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\n"); 1138f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 1139d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconfig\tbench\n", 11408247ec313d87afcdd4da59b1f2f0d24e0983e359qiankun.miao FLAGS_samples, "samples"); 1141f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1142f372321de3d4183de5b9ca436e677e471e358f31mtklein 1143c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon SkTDArray<Config> configs; 1144c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon create_configs(&configs); 1145c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 1146e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein int runs = 0; 114792007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream benchStream; 114892007583e43115998412ac8b0a06cc2780eb025cmtklein while (Benchmark* b = benchStream.next()) { 1149e714e75c725c987fe682a1f5473224fe3e80380dmtklein SkAutoTDelete<Benchmark> bench(b); 1150962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName())) { 1151f372321de3d4183de5b9ca436e677e471e358f31mtklein continue; 1152f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1153f372321de3d4183de5b9ca436e677e471e358f31mtklein 11543bf9206ada256277a39988c263f0379d544fc27begdaniel if (!configs.isEmpty()) { 1155962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSize().fY); 11568a6697af95b340aad6dee7e6228048fa305c1e59joshualitt bench->delayedSetup(); 1157bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 11583bf9206ada256277a39988c263f0379d544fc27begdaniel for (int i = 0; i < configs.count(); ++i) { 11593bf9206ada256277a39988c263f0379d544fc27begdaniel Target* target = is_enabled(b, configs[i]); 11603bf9206ada256277a39988c263f0379d544fc27begdaniel if (!target) { 11613bf9206ada256277a39988c263f0379d544fc27begdaniel continue; 11623bf9206ada256277a39988c263f0379d544fc27begdaniel } 11633bf9206ada256277a39988c263f0379d544fc27begdaniel 116496fcdcc219d2a0d3579719b84b28bede76efba64halcanary // During HWUI output this canvas may be nullptr. 11653bf9206ada256277a39988c263f0379d544fc27begdaniel SkCanvas* canvas = target->getCanvas(); 11663bf9206ada256277a39988c263f0379d544fc27begdaniel const char* config = target->config.name; 1167bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 11683bf9206ada256277a39988c263f0379d544fc27begdaniel target->setup(); 11695b69377507478623dcf5b11f3ecb010f87c4794frobertphillips bench->perCanvasPreDraw(canvas); 11705b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 1171e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton int maxFrameLag; 1172a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein int loops = target->needsFrameTiming(&maxFrameLag) 11733bf9206ada256277a39988c263f0379d544fc27begdaniel ? setup_gpu_bench(target, bench.get(), maxFrameLag) 11743bf9206ada256277a39988c263f0379d544fc27begdaniel : setup_cpu_bench(overhead, target, bench.get()); 1175e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton 1176bbba16878f343b232d844281fbdf056c00e20fb6mtklein if (FLAGS_ms) { 1177bbba16878f343b232d844281fbdf056c00e20fb6mtklein samples.reset(); 1178bbba16878f343b232d844281fbdf056c00e20fb6mtklein auto stop = now_ms() + FLAGS_ms; 1179bbba16878f343b232d844281fbdf056c00e20fb6mtklein do { 1180bbba16878f343b232d844281fbdf056c00e20fb6mtklein samples.push_back(time(loops, bench, target) / loops); 1181bbba16878f343b232d844281fbdf056c00e20fb6mtklein } while (now_ms() < stop); 1182bbba16878f343b232d844281fbdf056c00e20fb6mtklein } else { 1183e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton samples.reset(FLAGS_samples); 1184e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton for (int s = 0; s < FLAGS_samples; s++) { 11853bf9206ada256277a39988c263f0379d544fc27begdaniel samples[s] = time(loops, bench, target) / loops; 1186e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton } 1187e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton } 1188f372321de3d4183de5b9ca436e677e471e358f31mtklein 1189e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt#if SK_SUPPORT_GPU 1190e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt SkTArray<SkString> keys; 1191e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt SkTArray<double> values; 1192e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt bool gpuStatsDump = FLAGS_gpuStatsDump && Benchmark::kGPU_Backend == configs[i].backend; 1193e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt if (gpuStatsDump) { 1194e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt // TODO cache stats 1195e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt bench->getGpuStats(canvas, &keys, &values); 1196e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt } 1197e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt#endif 1198e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt 11995b69377507478623dcf5b11f3ecb010f87c4794frobertphillips bench->perCanvasPostDraw(canvas); 12005b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 12013bf9206ada256277a39988c263f0379d544fc27begdaniel if (Benchmark::kNonRendering_Backend != target->config.backend && 1202d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { 12036eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config); 1204962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniqueName()); 12056eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon pngFilename.append(".png"); 12063bf9206ada256277a39988c263f0379d544fc27begdaniel write_canvas_png(target, pngFilename); 12076eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 12086eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 12096eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kFailedLoops == loops) { 12102069e220034f09aad2f68b262f395e7c25b3d178mtklein // Can't be timed. A warning note has already been printed. 12113bf9206ada256277a39988c263f0379d544fc27begdaniel cleanup_run(target); 1212e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein continue; 1213e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein } 121460317d0ffb5053df7b08a627d6decd11b684e80dmtklein 1215e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton Stats stats(samples); 12161915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->config(config); 1217962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein log->configOption("name", bench->getName()); 12181915b62637bea20e1471a8a358b22e9e47a4a385mtklein benchStream.fillCurrentOptions(log.get()); 12193bf9206ada256277a39988c263f0379d544fc27begdaniel target->fillOptions(log.get()); 1220051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("min_ms", stats.min); 1221e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt#if SK_SUPPORT_GPU 1222e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt if (gpuStatsDump) { 1223e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt // dump to json, only SKPBench currently returns valid keys / values 1224e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt SkASSERT(keys.count() == values.count()); 1225e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt for (int i = 0; i < keys.count(); i++) { 1226e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt log->metric(keys[i].c_str(), values[i]); 1227e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt } 1228e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt } 1229e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt#endif 1230e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt 1231e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein if (runs++ % FLAGS_flushEvery == 0) { 1232e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein log->flush(); 1233e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein } 123460317d0ffb5053df7b08a627d6decd11b684e80dmtklein 12356eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 12363bf9206ada256277a39988c263f0379d544fc27begdaniel if (configs.count() == 1) { 1237a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein config = ""; // Only print the config if we run the same bench on more than one. 1238a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 1239d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("%4d/%-4dMB\t%s\t%s\n" 1240d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getCurrResidentSetSizeMB() 1241d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getMaxResidentSetSizeMB() 124253d2562006ee371222963750009a706cfd1a94f7mtklein , bench->getUniqueName() 124353d2562006ee371222963750009a706cfd1a94f7mtklein , config); 1244f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 124566cfcffd5d0a430f00bf0e36bedb088a25957183mtklein const char* mark = " "; 124666cfcffd5d0a430f00bf0e36bedb088a25957183mtklein const double stddev_percent = 100 * sqrt(stats.var) / stats.mean; 124766cfcffd5d0a430f00bf0e36bedb088a25957183mtklein if (stddev_percent > 5) mark = "?"; 124866cfcffd5d0a430f00bf0e36bedb088a25957183mtklein if (stddev_percent > 10) mark = "!"; 124966cfcffd5d0a430f00bf0e36bedb088a25957183mtklein 125066cfcffd5d0a430f00bf0e36bedb088a25957183mtklein SkDebugf("%10.2f %s\t%s\t%s\n", 125166cfcffd5d0a430f00bf0e36bedb088a25957183mtklein stats.median*1e3, mark, bench->getUniqueName(), config); 1252f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 1253f372321de3d4183de5b9ca436e677e471e358f31mtklein const double stddev_percent = 100 * sqrt(stats.var) / stats.mean; 1254d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("%4d/%-4dMB\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" 1255d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getCurrResidentSetSizeMB() 1256d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getMaxResidentSetSizeMB() 1257f372321de3d4183de5b9ca436e677e471e358f31mtklein , loops 125855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.min) 125955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.median) 126055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.mean) 126155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.max) 1262f372321de3d4183de5b9ca436e677e471e358f31mtklein , stddev_percent 1263bbba16878f343b232d844281fbdf056c00e20fb6mtklein , FLAGS_ms ? to_string(samples.count()).c_str() : stats.plot.c_str() 1264f372321de3d4183de5b9ca436e677e471e358f31mtklein , config 1265962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein , bench->getUniqueName() 1266f372321de3d4183de5b9ca436e677e471e358f31mtklein ); 1267f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1268e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt 1269b12ea41286ce36e085c5a14711da0cf9f240fdf1bsalomon#if SK_SUPPORT_GPU 1270e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt if (FLAGS_gpuStats && Benchmark::kGPU_Backend == configs[i].backend) { 1271a0a024e323ebf73ea4559d4b29f937902703828bbsalomon gGrFactory->get(configs[i].ctxType)->printCacheStats(); 1272a0a024e323ebf73ea4559d4b29f937902703828bbsalomon gGrFactory->get(configs[i].ctxType)->printGpuStats(); 127306cddec8570cbf29f89e89736afb0487b5b95abdbsalomon } 127406cddec8570cbf29f89e89736afb0487b5b95abdbsalomon#endif 1275e45c81c8f3bb62e45f2ff3b8772b4b23f1ddc6cajoshualitt 12762c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton if (FLAGS_verbose) { 12772c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton SkDebugf("Samples: "); 12782c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton for (int i = 0; i < samples.count(); i++) { 12792c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton SkDebugf("%s ", HUMANIZE(samples[i])); 12802c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton } 12812c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton SkDebugf("%s\n", bench->getUniqueName()); 12822c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton } 12833bf9206ada256277a39988c263f0379d544fc27begdaniel cleanup_run(target); 1284f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1285f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1286f372321de3d4183de5b9ca436e677e471e358f31mtklein 1287e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->bench("memory_usage", 0,0); 1288e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->config("meta"); 1289e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->metric("max_rss_mb", sk_tools::getMaxResidentSetSizeMB()); 1290e109145bf31d63963b3f78c6af6e404d5464a55bmtklein 1291e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt#if SK_SUPPORT_GPU 1292e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt // Make sure we clean up the global GrContextFactory here, otherwise we might race with the 1293e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt // SkEventTracer destructor 129496fcdcc219d2a0d3579719b84b28bede76efba64halcanary gGrFactory.reset(nullptr); 1295e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt#endif 1296e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt 1297f372321de3d4183de5b9ca436e677e471e358f31mtklein return 0; 1298f372321de3d4183de5b9ca436e677e471e358f31mtklein} 1299f372321de3d4183de5b9ca436e677e471e358f31mtklein 13003b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio#if !defined SK_BUILD_FOR_IOS 13013b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorioint main(int argc, char** argv) { 13023b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio SkCommandLineFlags::Parse(argc, argv); 13033b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio return nanobench_main(); 13043b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio} 13053b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio#endif 1306