nanobench.cpp revision 5cb4885b4cd1ac5eb3fc92dac5f5509d7c810464
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?"); 1102da1a854b0836001533aa29ade89d87f420cbbc3scroggoDEFINE_bool(pngBuildTileIndex, false, "If supported, use png buildTileIndex/decodeSubset."); 111860e8a67190e024b7375e52e270e6bd0a17af86escroggoDEFINE_bool(jpgBuildTileIndex, false, "If supported, use jpg buildTileIndex/decodeSubset."); 11292007583e43115998412ac8b0a06cc2780eb025cmtklein 113bbba16878f343b232d844281fbdf056c00e20fb6mtkleinstatic double now_ms() { return SkTime::GetNSecs() * 1e-6; } 114bbba16878f343b232d844281fbdf056c00e20fb6mtklein 115f372321de3d4183de5b9ca436e677e471e358f31mtkleinstatic SkString humanize(double ms) { 116dc5bbab138bfffc85d6ba525d990aad09c322ff6mtklein if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); 117748ca3bf2d170708f263693e8579e6722389d0efmtklein return HumanizeMs(ms); 118f372321de3d4183de5b9ca436e677e471e358f31mtklein} 11955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein#define HUMANIZE(ms) humanize(ms).c_str() 120f372321de3d4183de5b9ca436e677e471e358f31mtklein 121d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonbool Target::init(SkImageInfo info, Benchmark* bench) { 122d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (Benchmark::kRaster_Backend == config.backend) { 123d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->surface.reset(SkSurface::NewRaster(info)); 124d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!this->surface.get()) { 125d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 126d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 127d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 128d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 129d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson} 130d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonbool Target::capturePixels(SkBitmap* bmp) { 13175a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson SkCanvas* canvas = this->getCanvas(); 132d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!canvas) { 133d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 134d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 135d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson bmp->setInfo(canvas->imageInfo()); 136d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!canvas->readPixels(bmp, 0, 0)) { 137d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkDebugf("Can't read canvas pixels.\n"); 138d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 139d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 140d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 141d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson} 142d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 143d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#if SK_SUPPORT_GPU 144d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonstruct GPUTarget : public Target { 14596fcdcc219d2a0d3579719b84b28bede76efba64halcanary explicit GPUTarget(const Config& c) : Target(c), gl(nullptr) { } 146d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkGLContext* gl; 147d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 148d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void setup() override { 149d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->gl->makeCurrent(); 150d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson // Make sure we're done with whatever came before. 151d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Finish()); 152d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 153d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void endTiming() override { 154d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (this->gl) { 155d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Flush()); 156d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->gl->swapBuffers(); 157d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 158d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 159d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void fence() override { 160d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Finish()); 161d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 162d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein 163d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton bool needsFrameTiming(int* maxFrameLag) const override { 164d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton if (!this->gl->getMaxGpuFrameLag(maxFrameLag)) { 165d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton // Frame lag is unknown. 166d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton *maxFrameLag = FLAGS_gpuFrameLag; 167d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton } 168d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton return true; 169d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton } 170d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson bool init(SkImageInfo info, Benchmark* bench) override { 171afcd7cd32497cc79035e61fd64b0baa03ed04bccbsalomon uint32_t flags = this->config.useDFText ? SkSurfaceProps::kUseDeviceIndependentFonts_Flag : 172afcd7cd32497cc79035e61fd64b0baa03ed04bccbsalomon 0; 173d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); 174d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(this->config.ctxType), 175d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkSurface::kNo_Budgeted, info, 176d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->config.samples, &props)); 177d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->gl = gGrFactory->getGLContext(this->config.ctxType); 178d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!this->surface.get()) { 179d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 180d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 181d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton if (!this->gl->fenceSyncSupport()) { 182d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton SkDebugf("WARNING: GL context for config \"%s\" does not support fence sync. " 183d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton "Timings might not be accurate.\n", this->config.name); 184d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton } 185d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 186d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 187d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void fillOptions(ResultsWriter* log) override { 188d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson const GrGLubyte* version; 189d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_VERSION)); 190d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_VERSION", (const char*)(version)); 191d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 192d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_RENDERER)); 193d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_RENDERER", (const char*) version); 194d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 195d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_VENDOR)); 196d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_VENDOR", (const char*) version); 197d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 198d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); 199d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version); 200d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 201d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson}; 202d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein 203d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 204d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 20575a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudsonstatic double time(int loops, Benchmark* bench, Target* target) { 20675a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson SkCanvas* canvas = target->getCanvas(); 2076eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (canvas) { 2086eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon canvas->clear(SK_ColorWHITE); 2096eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2108a6697af95b340aad6dee7e6228048fa305c1e59joshualitt bench->preDraw(canvas); 211bbba16878f343b232d844281fbdf056c00e20fb6mtklein double start = now_ms(); 21275a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson canvas = target->beginTiming(canvas); 21375a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson bench->draw(loops, canvas); 214f372321de3d4183de5b9ca436e677e471e358f31mtklein if (canvas) { 215f372321de3d4183de5b9ca436e677e471e358f31mtklein canvas->flush(); 216f372321de3d4183de5b9ca436e677e471e358f31mtklein } 21775a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson target->endTiming(); 218bbba16878f343b232d844281fbdf056c00e20fb6mtklein double elapsed = now_ms() - start; 2198a6697af95b340aad6dee7e6228048fa305c1e59joshualitt bench->postDraw(canvas); 220bbba16878f343b232d844281fbdf056c00e20fb6mtklein return elapsed; 221f372321de3d4183de5b9ca436e677e471e358f31mtklein} 222f372321de3d4183de5b9ca436e677e471e358f31mtklein 223bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic double estimate_timer_overhead() { 224bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein double overhead = 0; 225bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_overheadLoops; i++) { 226bbba16878f343b232d844281fbdf056c00e20fb6mtklein double start = now_ms(); 227bbba16878f343b232d844281fbdf056c00e20fb6mtklein overhead += now_ms() - start; 228bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 229bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return overhead / FLAGS_overheadLoops; 230bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 231f372321de3d4183de5b9ca436e677e471e358f31mtklein 2325324978a88677ac6b758324321816427814e7793reedstatic int detect_forever_loops(int loops) { 2335324978a88677ac6b758324321816427814e7793reed // look for a magic run-forever value 2345324978a88677ac6b758324321816427814e7793reed if (loops < 0) { 2355324978a88677ac6b758324321816427814e7793reed loops = SK_MaxS32; 2365324978a88677ac6b758324321816427814e7793reed } 2375324978a88677ac6b758324321816427814e7793reed return loops; 2385324978a88677ac6b758324321816427814e7793reed} 2395324978a88677ac6b758324321816427814e7793reed 24055b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinstatic int clamp_loops(int loops) { 24155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops < 1) { 242527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein SkDebugf("ERROR: clamping loops from %d to 1. " 243527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein "There's probably something wrong with the bench.\n", loops); 24455b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return 1; 24555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 24655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops > FLAGS_maxLoops) { 24755b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("WARNING: clamping loops from %d to FLAGS_maxLoops, %d.\n", loops, FLAGS_maxLoops); 24855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return FLAGS_maxLoops; 24955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 25055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return loops; 25155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein} 25255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein 253d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonstatic bool write_canvas_png(Target* target, const SkString& filename) { 254d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2556eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (filename.isEmpty()) { 2566eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2576eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 25875a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson if (target->getCanvas() && 25975a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson kUnknown_SkColorType == target->getCanvas()->imageInfo().colorType()) { 2606eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2616eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 262d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2636eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkBitmap bmp; 264d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 265d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!target->capturePixels(&bmp)) { 2666eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2676eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 268d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2696eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString dir = SkOSPath::Dirname(filename.c_str()); 2706eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(dir.c_str())) { 2716eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't make dir %s.\n", dir.c_str()); 2726eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2736eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2746eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkFILEWStream stream(filename.c_str()); 2756eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!stream.isValid()) { 2766eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't write %s.\n", filename.c_str()); 2776eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2786eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2796eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!SkImageEncoder::EncodeStream(&stream, bmp, SkImageEncoder::kPNG_Type, 100)) { 2806eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't encode a PNG.\n"); 2816eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2826eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2836eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return true; 2846eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 2856eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 2866eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic int kFailedLoops = -2; 287e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdaltonstatic int setup_cpu_bench(const double overhead, Target* target, Benchmark* bench) { 288bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First figure out approximately how many loops of bench it takes to make overhead negligible. 2892069e220034f09aad2f68b262f395e7c25b3d178mtklein double bench_plus_overhead = 0.0; 29055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein int round = 0; 291b4022965a280dd1ed64d6103dd29e2189abe6e00cdalton int loops = bench->calculateLoops(FLAGS_loops); 292b4022965a280dd1ed64d6103dd29e2189abe6e00cdalton if (kAutoTuneLoops == loops) { 2936eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon while (bench_plus_overhead < overhead) { 2946eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (round++ == FLAGS_maxCalibrationAttempts) { 2956eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skipping.\n", 296962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein bench->getUniqueName(), HUMANIZE(bench_plus_overhead), HUMANIZE(overhead)); 2976eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return kFailedLoops; 2986eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 29975a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson bench_plus_overhead = time(1, bench, target); 30055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 3012069e220034f09aad2f68b262f395e7c25b3d178mtklein } 302f372321de3d4183de5b9ca436e677e471e358f31mtklein 303bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Later we'll just start and stop the timer once but loop N times. 304f372321de3d4183de5b9ca436e677e471e358f31mtklein // We'll pick N to make timer overhead negligible: 305f372321de3d4183de5b9ca436e677e471e358f31mtklein // 306bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead 307bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------- < FLAGS_overheadGoal 308bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead + N * Bench Time 309f372321de3d4183de5b9ca436e677e471e358f31mtklein // 310bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // where bench_plus_overhead ≈ overhead + Bench Time. 311f372321de3d4183de5b9ca436e677e471e358f31mtklein // 312f372321de3d4183de5b9ca436e677e471e358f31mtklein // Doing some math, we get: 313f372321de3d4183de5b9ca436e677e471e358f31mtklein // 314bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // (overhead / FLAGS_overheadGoal) - overhead 315bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------------------------ < N 316bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // bench_plus_overhead - overhead) 317f372321de3d4183de5b9ca436e677e471e358f31mtklein // 318f372321de3d4183de5b9ca436e677e471e358f31mtklein // Luckily, this also works well in practice. :) 3196eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 3206eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double numer = overhead / FLAGS_overheadGoal - overhead; 3216eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double denom = bench_plus_overhead - overhead; 3226eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = (int)ceil(numer / denom); 3235324978a88677ac6b758324321816427814e7793reed loops = clamp_loops(loops); 3245324978a88677ac6b758324321816427814e7793reed } else { 3255324978a88677ac6b758324321816427814e7793reed loops = detect_forever_loops(loops); 3266eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 327bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 328bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 329f372321de3d4183de5b9ca436e677e471e358f31mtklein} 330f372321de3d4183de5b9ca436e677e471e358f31mtklein 331e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdaltonstatic int setup_gpu_bench(Target* target, Benchmark* bench, int maxGpuFrameLag) { 332bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First, figure out how many loops it'll take to get a frame up to FLAGS_gpuMs. 333b4022965a280dd1ed64d6103dd29e2189abe6e00cdalton int loops = bench->calculateLoops(FLAGS_loops); 3346eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 3356eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = 1; 336a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein double elapsed = 0; 337a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein do { 338527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein if (1<<30 == loops) { 339527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein // We're about to wrap. Something's wrong with the bench. 340527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein loops = 0; 341527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein break; 342527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein } 343a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops *= 2; 344a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // If the GPU lets frames lag at all, we need to make sure we're timing 345d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton // _this_ round, not still timing last round. 346d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton for (int i = 0; i < maxGpuFrameLag; i++) { 34775a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson elapsed = time(loops, bench, target); 348a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 349a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } while (elapsed < FLAGS_gpuMs); 350a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 351a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // We've overshot at least a little. Scale back linearly. 352a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); 3535324978a88677ac6b758324321816427814e7793reed loops = clamp_loops(loops); 354a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 355d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson // Make sure we're not still timing our calibration. 356d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target->fence(); 3575324978a88677ac6b758324321816427814e7793reed } else { 3585324978a88677ac6b758324321816427814e7793reed loops = detect_forever_loops(loops); 359a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 360bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 361bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Pretty much the same deal as the calibration: do some warmup to make 362bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // sure we're timing steady-state pipelined frames. 363d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton for (int i = 0; i < maxGpuFrameLag - 1; i++) { 36475a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson time(loops, bench, target); 365f372321de3d4183de5b9ca436e677e471e358f31mtklein } 366bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 367bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 368f372321de3d4183de5b9ca436e677e471e358f31mtklein} 369bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 370bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic SkString to_lower(const char* str) { 371bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkString lower(str); 372bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (size_t i = 0; i < lower.size(); i++) { 373bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein lower[i] = tolower(lower[i]); 374bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 375bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return lower; 376bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 377bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 378c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic bool is_cpu_config_allowed(const char* name) { 379bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_config.count(); i++) { 380c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (to_lower(FLAGS_config[i]).equals(name)) { 381c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return true; 382bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 383f372321de3d4183de5b9ca436e677e471e358f31mtklein } 384c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 385bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 386f372321de3d4183de5b9ca436e677e471e358f31mtklein 387c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 388c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextType ctxType, 389c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon int sampleCnt) { 390c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!is_cpu_config_allowed(name)) { 391c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 392c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 39369a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski if (const GrContext* ctx = gGrFactory->get(ctxType)) { 394762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon return sampleCnt <= ctx->caps()->maxSampleCount(); 395c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 396c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 397c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 398c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 399c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 400c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 401c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType GrContextFactory::kNative_GLContextType 402c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#else 403c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType 0 404e714e75c725c987fe682a1f5473224fe3e80380dmtklein#endif 405c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 406c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// Append all configs that are enabled and supported. 407c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic void create_configs(SkTDArray<Config>* configs) { 4084736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth #define CPU_CONFIG(name, backend, color, alpha) \ 4094736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth if (is_cpu_config_allowed(#name)) { \ 4104736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth Config config = { #name, Benchmark::backend, color, alpha, 0, \ 4114736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth kBogusGLContextType, false }; \ 4124736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth configs->push(config); \ 413f372321de3d4183de5b9ca436e677e471e358f31mtklein } 414e714e75c725c987fe682a1f5473224fe3e80380dmtklein 41540b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_cpu) { 416c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(nonrendering, kNonRendering_Backend, kUnknown_SkColorType, kUnpremul_SkAlphaType) 417c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(8888, kRaster_Backend, kN32_SkColorType, kPremul_SkAlphaType) 418c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(565, kRaster_Backend, kRGB_565_SkColorType, kOpaque_SkAlphaType) 41940b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 420f372321de3d4183de5b9ca436e677e471e358f31mtklein 421bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 4224736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth #define GPU_CONFIG(name, ctxType, samples, useDFText) \ 423c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, samples)) { \ 424c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Config config = { \ 425c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon #name, \ 426c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Benchmark::kGPU_Backend, \ 427c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon kN32_SkColorType, \ 428c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon kPremul_SkAlphaType, \ 429c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon samples, \ 4304736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GrContextFactory::ctxType, \ 4314736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth useDFText }; \ 432c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon configs->push(config); \ 433f372321de3d4183de5b9ca436e677e471e358f31mtklein } 434e714e75c725c987fe682a1f5473224fe3e80380dmtklein 43540b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_gpu) { 4364736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(gpu, kNative_GLContextType, 0, false) 4374736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(msaa4, kNative_GLContextType, 4, false) 4384736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(msaa16, kNative_GLContextType, 16, false) 4394736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4, false) 4404736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16, false) 4414736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(gpudft, kNative_GLContextType, 0, true) 4424736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(debug, kDebug_GLContextType, 0, false) 4434736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(nullgpu, kNull_GLContextType, 0, false) 4443b4d077fba1ad037536db198608a940c47d91888bsalomon#ifdef SK_ANGLE 4454736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(angle, kANGLE_GLContextType, 0, false) 446eddbefb4a5794b1d9f4e58a7cdf4e768b837c17fhendrikw GPU_CONFIG(angle-gl, kANGLE_GL_GLContextType, 0, false) 4473b4d077fba1ad037536db198608a940c47d91888bsalomon#endif 448885bf0925514b9dfe3365bab227d36897d866b5dhendrikw#ifdef SK_COMMAND_BUFFER 449885bf0925514b9dfe3365bab227d36897d866b5dhendrikw GPU_CONFIG(commandbuffer, kCommandBuffer_GLContextType, 0, false) 450885bf0925514b9dfe3365bab227d36897d866b5dhendrikw#endif 451d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton#if SK_MESA 452d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton GPU_CONFIG(mesa, kMESA_GLContextType, 0, false) 453d416a5b10ff9e6d4f55a1f5b0419722132d68ff3cdalton#endif 45440b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 455bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 456d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 457d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 458d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (is_cpu_config_allowed("hwui")) { 459d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson Config config = { "hwui", Benchmark::kHWUI_Backend, kRGBA_8888_SkColorType, 460d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson kPremul_SkAlphaType, 0, kBogusGLContextType, false }; 461d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson configs->push(config); 462d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 463d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 464f372321de3d4183de5b9ca436e677e471e358f31mtklein} 465f372321de3d4183de5b9ca436e677e471e358f31mtklein 46696fcdcc219d2a0d3579719b84b28bede76efba64halcanary// If bench is enabled for config, returns a Target* for it, otherwise nullptr. 467c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic Target* is_enabled(Benchmark* bench, const Config& config) { 468c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!bench->isSuitableFor(config.backend)) { 46996fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 470c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 471c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 472e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkImageInfo info = SkImageInfo::Make(bench->getSize().fX, bench->getSize().fY, 473e5ea500d4714a7d84de2bf913e81be3b65d2de68reed config.color, config.alpha); 474c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 47596fcdcc219d2a0d3579719b84b28bede76efba64halcanary Target* target = nullptr; 476c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 477d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson switch (config.backend) { 478c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 479d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson case Benchmark::kGPU_Backend: 480d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new GPUTarget(config); 481d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 482d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 483d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 484d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson case Benchmark::kHWUI_Backend: 485d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new HWUITarget(config, bench); 486d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 487c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 488d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson default: 489d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new Target(config); 490d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 491d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 492c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 493d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!target->init(info, bench)) { 494c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon delete target; 49596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 496c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 497c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return target; 498c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 499c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 500b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett/* 501ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo * We only run our subset benches on files that are supported by BitmapRegionDecoder: 502ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo * i.e. PNG, JPEG, and WEBP. We do *not* test WEBP when using codec, since we do not 503ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo * have a scanline decoder for WEBP, which is necessary for running the subset bench. 504ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo * (Another bench must be used to test WEBP, which decodes subsets natively.) 505ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo */ 506ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggostatic bool run_subset_bench(const SkString& path, bool useCodec) { 507ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo static const char* const exts[] = { 5082da1a854b0836001533aa29ade89d87f420cbbc3scroggo "jpg", "jpeg", 5092da1a854b0836001533aa29ade89d87f420cbbc3scroggo "JPG", "JPEG", 510ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo }; 511ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo 512860e8a67190e024b7375e52e270e6bd0a17af86escroggo if (useCodec || FLAGS_jpgBuildTileIndex) { 513860e8a67190e024b7375e52e270e6bd0a17af86escroggo for (uint32_t i = 0; i < SK_ARRAY_COUNT(exts); i++) { 514860e8a67190e024b7375e52e270e6bd0a17af86escroggo if (path.endsWith(exts[i])) { 515860e8a67190e024b7375e52e270e6bd0a17af86escroggo return true; 516860e8a67190e024b7375e52e270e6bd0a17af86escroggo } 517ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo } 518ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo } 519ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo 5202da1a854b0836001533aa29ade89d87f420cbbc3scroggo // Test png in SkCodec, and optionally on SkImageDecoder. SkImageDecoder is 5212da1a854b0836001533aa29ade89d87f420cbbc3scroggo // disabled by default because it leaks memory. 5222da1a854b0836001533aa29ade89d87f420cbbc3scroggo // skbug.com/4360 5232da1a854b0836001533aa29ade89d87f420cbbc3scroggo if ((useCodec || FLAGS_pngBuildTileIndex) && (path.endsWith("png") || path.endsWith("PNG"))) { 5242da1a854b0836001533aa29ade89d87f420cbbc3scroggo return true; 5252da1a854b0836001533aa29ade89d87f420cbbc3scroggo } 5262da1a854b0836001533aa29ade89d87f420cbbc3scroggo 5272da1a854b0836001533aa29ade89d87f420cbbc3scroggo if (!useCodec && (path.endsWith("webp") || path.endsWith("WEBP"))) { 5282da1a854b0836001533aa29ade89d87f420cbbc3scroggo return true; 5292da1a854b0836001533aa29ade89d87f420cbbc3scroggo } 5302da1a854b0836001533aa29ade89d87f420cbbc3scroggo 5312da1a854b0836001533aa29ade89d87f420cbbc3scroggo return false; 532ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo} 533ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo 534ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo/* 535b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett * Returns true if set up for a subset decode succeeds, false otherwise 536b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett * If the set-up succeeds, the width and height parameters will be set 537b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett */ 538b23e6aa6767816ac4bc6c191e78ef62d6e765671msarettstatic bool valid_subset_bench(const SkString& path, SkColorType colorType, bool useCodec, 539b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett int* width, int* height) { 540b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 541b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkAutoTDelete<SkMemoryStream> stream(new SkMemoryStream(encoded)); 542b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett 543ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett // Check that we can create a codec or image decoder. 544b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett if (useCodec) { 545b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkAutoTDelete<SkCodec> codec(SkCodec::NewFromStream(stream.detach())); 54696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == codec) { 547b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkDebugf("Could not create codec for %s. Skipping bench.\n", path.c_str()); 548b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett return false; 549b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett } 550b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett 551b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett // These will be initialized by SkCodec if the color type is kIndex8 and 552b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett // unused otherwise. 553b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkPMColor colors[256]; 554b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett int colorCount; 555b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett const SkImageInfo info = codec->getInfo().makeColorType(colorType); 55646c574725676b26ada63ac15e42cda309dcd5090scroggo if (codec->startScanlineDecode(info, nullptr, colors, &colorCount) != SkCodec::kSuccess) 5571c005e4a38e29d648ecebada25d3a718155043a3scroggo { 558b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkDebugf("Could not create scanline decoder for %s with color type %s. " 5597f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett "Skipping bench.\n", path.c_str(), color_type_to_str(colorType)); 560b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett return false; 561b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett } 562b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett *width = info.width(); 563b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett *height = info.height(); 564b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett } else { 565b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream)); 56696fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (nullptr == decoder) { 567b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkDebugf("Could not create decoder for %s. Skipping bench.\n", path.c_str()); 568b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett return false; 569b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett } 570b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett //FIXME: See skbug.com/3921 571b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett if (kIndex_8_SkColorType == colorType || kGray_8_SkColorType == colorType) { 572b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkDebugf("Cannot use image subset decoder for %s with color type %s. " 5737f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett "Skipping bench.\n", path.c_str(), color_type_to_str(colorType)); 574b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett return false; 575b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett } 576b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett if (!decoder->buildTileIndex(stream.detach(), width, height)) { 577b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkDebugf("Could not build tile index for %s. Skipping bench.\n", path.c_str()); 578b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett return false; 579b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett } 580b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett } 581ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett 582ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett // Check if the image is large enough for a meaningful subset benchmark. 583ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett if (*width <= 512 && *height <= 512) { 584ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett // This should not print a message since it is not an error. 585ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett return false; 586ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett } 587ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett 588b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett return true; 589b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett} 590bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 5915cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarettstatic bool valid_brd_bench(SkData* encoded, SkBitmapRegionDecoder::Strategy strategy, 5927f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkColorType colorType, uint32_t sampleSize, uint32_t minOutputSize, int* width, 5937f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int* height) { 5945cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett SkAutoTDelete<SkBitmapRegionDecoder> brd( 5955cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett SkBitmapRegionDecoder::Create(encoded, strategy)); 5967f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett if (nullptr == brd.get()) { 5977f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // This is indicates that subset decoding is not supported for a particular image format. 5987f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return false; 5997f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 6007f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 60135e5d1b4495478ca3bede66914ae07f50a447c4dmsarett SkBitmap bitmap; 60235e5d1b4495478ca3bede66914ae07f50a447c4dmsarett if (!brd->decodeRegion(&bitmap, nullptr, SkIRect::MakeXYWH(0, 0, brd->width(), brd->height()), 60335e5d1b4495478ca3bede66914ae07f50a447c4dmsarett 1, colorType, false)) { 60435e5d1b4495478ca3bede66914ae07f50a447c4dmsarett return false; 60535e5d1b4495478ca3bede66914ae07f50a447c4dmsarett } 60635e5d1b4495478ca3bede66914ae07f50a447c4dmsarett if (colorType != bitmap.colorType()) { 6077f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // This indicates that conversion to the requested color type is not supported for the 6087f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // particular image. 6097f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return false; 6107f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 6117f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 6127f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett if (sampleSize * minOutputSize > (uint32_t) brd->width() || sampleSize * minOutputSize > 6137f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett (uint32_t) brd->height()) { 6147f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // This indicates that the image is not large enough to decode a 6157f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // minOutputSize x minOutputSize subset at the given sampleSize. 6167f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return false; 6177f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 6187f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 6197f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // Set the image width and height. The calling code will use this to choose subsets to decode. 6207f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett *width = brd->width(); 6217f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett *height = brd->height(); 6227f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return true; 6237f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett} 6247f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 6253bf9206ada256277a39988c263f0379d544fc27begdanielstatic void cleanup_run(Target* target) { 626385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary delete target; 6273bf9206ada256277a39988c263f0379d544fc27begdaniel#if SK_SUPPORT_GPU 6283bf9206ada256277a39988c263f0379d544fc27begdaniel if (FLAGS_abandonGpuContext) { 6293bf9206ada256277a39988c263f0379d544fc27begdaniel gGrFactory->abandonContexts(); 6303bf9206ada256277a39988c263f0379d544fc27begdaniel } 6313bf9206ada256277a39988c263f0379d544fc27begdaniel if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { 6323bf9206ada256277a39988c263f0379d544fc27begdaniel gGrFactory->destroyContexts(); 6333bf9206ada256277a39988c263f0379d544fc27begdaniel } 6343bf9206ada256277a39988c263f0379d544fc27begdaniel#endif 6353bf9206ada256277a39988c263f0379d544fc27begdaniel} 6363bf9206ada256277a39988c263f0379d544fc27begdaniel 637e714e75c725c987fe682a1f5473224fe3e80380dmtkleinclass BenchmarkStream { 638e714e75c725c987fe682a1f5473224fe3e80380dmtkleinpublic: 63992007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream() : fBenches(BenchRegistry::Head()) 64092007583e43115998412ac8b0a06cc2780eb025cmtklein , fGMs(skiagm::GMRegistry::Head()) 641fd731ce804cd3223318f3feee2c98404890b65f2mtklein , fCurrentRecording(0) 64292007583e43115998412ac8b0a06cc2780eb025cmtklein , fCurrentScale(0) 6435b69377507478623dcf5b11f3ecb010f87c4794frobertphillips , fCurrentSKP(0) 64495f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentUseMPD(0) 64560869a42a133942f852dd0f1696444c2a5c9ad83scroggo , fCurrentCodec(0) 64695f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentImage(0) 64795f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentSubsetImage(0) 6487f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett , fCurrentBRDImage(0) 64995f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentColorType(0) 650b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett , fCurrentSubsetType(0) 651b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett , fUseCodec(0) 6527f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett , fCurrentBRDStrategy(0) 6537f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett , fCurrentBRDSampleSize(0) 654b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett , fCurrentAnimSKP(0) { 65592007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_skps.count(); i++) { 65692007583e43115998412ac8b0a06cc2780eb025cmtklein if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { 65792007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = FLAGS_skps[i]; 65892007583e43115998412ac8b0a06cc2780eb025cmtklein } else { 65992007583e43115998412ac8b0a06cc2780eb025cmtklein SkOSFile::Iter it(FLAGS_skps[i], ".skp"); 66092007583e43115998412ac8b0a06cc2780eb025cmtklein SkString path; 66192007583e43115998412ac8b0a06cc2780eb025cmtklein while (it.next(&path)) { 66292007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str()); 66392007583e43115998412ac8b0a06cc2780eb025cmtklein } 66492007583e43115998412ac8b0a06cc2780eb025cmtklein } 66592007583e43115998412ac8b0a06cc2780eb025cmtklein } 66692007583e43115998412ac8b0a06cc2780eb025cmtklein 66792007583e43115998412ac8b0a06cc2780eb025cmtklein if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d", 66892007583e43115998412ac8b0a06cc2780eb025cmtklein &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom)) { 66992007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0]); 67092007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 67192007583e43115998412ac8b0a06cc2780eb025cmtklein } 67292007583e43115998412ac8b0a06cc2780eb025cmtklein 67392007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_scales.count(); i++) { 67492007583e43115998412ac8b0a06cc2780eb025cmtklein if (1 != sscanf(FLAGS_scales[i], "%f", &fScales.push_back())) { 67592007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --scales as an SkScalar.\n", FLAGS_scales[i]); 67692007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 67792007583e43115998412ac8b0a06cc2780eb025cmtklein } 67892007583e43115998412ac8b0a06cc2780eb025cmtklein } 6795b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 68063a82855b1f0b83952b65fca330954c50ebe7a4bcdalton if (2 != sscanf(FLAGS_zoom[0], "%f,%lf", &fZoomMax, &fZoomPeriodMs)) { 68163a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SkDebugf("Can't parse %s from --zoom as a zoomMax,zoomPeriodMs.\n", FLAGS_zoom[0]); 682261c3ad7fde95748da92550735decc949dc73bf2joshualitt exit(1); 683261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 684261c3ad7fde95748da92550735decc949dc73bf2joshualitt 6855b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (FLAGS_mpd) { 6865b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fUseMPDs.push_back() = true; 6875b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 688c751ecb3681072fda53dd3cebeb2eb41fc73b314mtklein fUseMPDs.push_back() = false; 68995553d917c73ef333ede967521560957a5b6a0admtklein 69095f192d19938b98a45dd1fa4112d965f60d10516msarett // Prepare the images for decoding 69195f192d19938b98a45dd1fa4112d965f60d10516msarett for (int i = 0; i < FLAGS_images.count(); i++) { 69295f192d19938b98a45dd1fa4112d965f60d10516msarett const char* flag = FLAGS_images[i]; 69395f192d19938b98a45dd1fa4112d965f60d10516msarett if (sk_isdir(flag)) { 69495f192d19938b98a45dd1fa4112d965f60d10516msarett // If the value passed in is a directory, add all the images 69595f192d19938b98a45dd1fa4112d965f60d10516msarett SkOSFile::Iter it(flag); 69695f192d19938b98a45dd1fa4112d965f60d10516msarett SkString file; 69795f192d19938b98a45dd1fa4112d965f60d10516msarett while (it.next(&file)) { 69895f192d19938b98a45dd1fa4112d965f60d10516msarett fImages.push_back() = SkOSPath::Join(flag, file.c_str()); 69995f192d19938b98a45dd1fa4112d965f60d10516msarett } 70095f192d19938b98a45dd1fa4112d965f60d10516msarett } else if (sk_exists(flag)) { 70195f192d19938b98a45dd1fa4112d965f60d10516msarett // Also add the value if it is a single image 70295f192d19938b98a45dd1fa4112d965f60d10516msarett fImages.push_back() = flag; 70395f192d19938b98a45dd1fa4112d965f60d10516msarett } 70495f192d19938b98a45dd1fa4112d965f60d10516msarett } 70595553d917c73ef333ede967521560957a5b6a0admtklein 70695f192d19938b98a45dd1fa4112d965f60d10516msarett // Choose the candidate color types for image decoding 70795f192d19938b98a45dd1fa4112d965f60d10516msarett const SkColorType colorTypes[] = 708b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett { kN32_SkColorType, 709b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kRGB_565_SkColorType, 710b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kAlpha_8_SkColorType, 711b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kIndex_8_SkColorType, 712b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kGray_8_SkColorType }; 71374deb981d5e9c11c88fe431e78166d6cf8dacc1amsarett fColorTypes.reset(colorTypes, SK_ARRAY_COUNT(colorTypes)); 71492007583e43115998412ac8b0a06cc2780eb025cmtklein } 715e714e75c725c987fe682a1f5473224fe3e80380dmtklein 716fd731ce804cd3223318f3feee2c98404890b65f2mtklein static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) { 717fd731ce804cd3223318f3feee2c98404890b65f2mtklein // Not strictly necessary, as it will be checked again later, 718fd731ce804cd3223318f3feee2c98404890b65f2mtklein // but helps to avoid a lot of pointless work if we're going to skip it. 719fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) { 720fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 721fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 722fd731ce804cd3223318f3feee2c98404890b65f2mtklein 723a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path)); 72496fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (stream.get() == nullptr) { 725fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkDebugf("Could not read %s.\n", path); 726fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 727fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 728fd731ce804cd3223318f3feee2c98404890b65f2mtklein 72957f27bdcbd328491a121918b4ab9301fbcdec642mtklein pic->reset(SkPicture::CreateFromStream(stream.get())); 73096fcdcc219d2a0d3579719b84b28bede76efba64halcanary if (pic->get() == nullptr) { 731fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkDebugf("Could not read %s as an SkPicture.\n", path); 732fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 733fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 734fd731ce804cd3223318f3feee2c98404890b65f2mtklein return true; 735fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 736fd731ce804cd3223318f3feee2c98404890b65f2mtklein 73792007583e43115998412ac8b0a06cc2780eb025cmtklein Benchmark* next() { 738e714e75c725c987fe682a1f5473224fe3e80380dmtklein if (fBenches) { 73996fcdcc219d2a0d3579719b84b28bede76efba64halcanary Benchmark* bench = fBenches->factory()(nullptr); 740e714e75c725c987fe682a1f5473224fe3e80380dmtklein fBenches = fBenches->next(); 74192007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "bench"; 742fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "micro"; 743e714e75c725c987fe682a1f5473224fe3e80380dmtklein return bench; 744e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 74592007583e43115998412ac8b0a06cc2780eb025cmtklein 746e714e75c725c987fe682a1f5473224fe3e80380dmtklein while (fGMs) { 74796fcdcc219d2a0d3579719b84b28bede76efba64halcanary SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(nullptr)); 748e714e75c725c987fe682a1f5473224fe3e80380dmtklein fGMs = fGMs->next(); 749cf5d9c993dcbd75d4cefe2d1de25c2b9645f6957mtklein if (gm->runAsBench()) { 75092007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "gm"; 751fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "micro"; 752385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new GMBench(gm.detach()); 753e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 754e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 75592007583e43115998412ac8b0a06cc2780eb025cmtklein 756fd731ce804cd3223318f3feee2c98404890b65f2mtklein // First add all .skps as RecordingBenches. 757fd731ce804cd3223318f3feee2c98404890b65f2mtklein while (fCurrentRecording < fSKPs.count()) { 758fd731ce804cd3223318f3feee2c98404890b65f2mtklein const SkString& path = fSKPs[fCurrentRecording++]; 759fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkPicture> pic; 760fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (!ReadPicture(path.c_str(), &pic)) { 761fd731ce804cd3223318f3feee2c98404890b65f2mtklein continue; 762fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 763fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkString name = SkOSPath::Basename(path.c_str()); 764fd731ce804cd3223318f3feee2c98404890b65f2mtklein fSourceType = "skp"; 765fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "recording"; 7660aa5cea8694d3686b6742a36eab81ab9001de954bsalomon fSKPBytes = static_cast<double>(SkPictureUtils::ApproximateBytesUsed(pic)); 767051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein fSKPOps = pic->approximateOpCount(); 768385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new RecordingBench(name.c_str(), pic.get(), FLAGS_bbh); 769fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 770fd731ce804cd3223318f3feee2c98404890b65f2mtklein 771fd731ce804cd3223318f3feee2c98404890b65f2mtklein // Then once each for each scale as SKPBenches (playback). 77292007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentScale < fScales.count()) { 77392007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentSKP < fSKPs.count()) { 7745b69377507478623dcf5b11f3ecb010f87c4794frobertphillips const SkString& path = fSKPs[fCurrentSKP]; 775fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkPicture> pic; 776fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (!ReadPicture(path.c_str(), &pic)) { 7775b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentSKP++; 77892007583e43115998412ac8b0a06cc2780eb025cmtklein continue; 77992007583e43115998412ac8b0a06cc2780eb025cmtklein } 7805b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 7815b69377507478623dcf5b11f3ecb010f87c4794frobertphillips while (fCurrentUseMPD < fUseMPDs.count()) { 7825b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (FLAGS_bbh) { 7835b69377507478623dcf5b11f3ecb010f87c4794frobertphillips // The SKP we read off disk doesn't have a BBH. Re-record so it grows one. 7845b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkRTreeFactory factory; 7855b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkPictureRecorder recorder; 7865b69377507478623dcf5b11f3ecb010f87c4794frobertphillips static const int kFlags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag; 7875b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic->playback(recorder.beginRecording(pic->cullRect().width(), 7885b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic->cullRect().height(), 789748ca3bf2d170708f263693e8579e6722389d0efmtklein &factory, 790e451c4df7369c5e253ef9c9e0a8713beda25f34brobertphillips fUseMPDs[fCurrentUseMPD] ? kFlags : 0)); 7915b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic.reset(recorder.endRecording()); 7925b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 7935b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkString name = SkOSPath::Basename(path.c_str()); 7945b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fSourceType = "skp"; 7955b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fBenchType = "playback"; 796385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SKPBench(name.c_str(), pic.get(), fClip, fScales[fCurrentScale], 797385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary fUseMPDs[fCurrentUseMPD++], FLAGS_loopSKP); 7982084050a33ae139d0fe9bb680f7905f91139a39fmtklein } 7995b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentUseMPD = 0; 8005b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentSKP++; 80192007583e43115998412ac8b0a06cc2780eb025cmtklein } 80292007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentSKP = 0; 80392007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentScale++; 80492007583e43115998412ac8b0a06cc2780eb025cmtklein } 80592007583e43115998412ac8b0a06cc2780eb025cmtklein 806261c3ad7fde95748da92550735decc949dc73bf2joshualitt // Now loop over each skp again if we have an animation 80763a82855b1f0b83952b65fca330954c50ebe7a4bcdalton if (fZoomMax != 1.0f && fZoomPeriodMs > 0) { 808261c3ad7fde95748da92550735decc949dc73bf2joshualitt while (fCurrentAnimSKP < fSKPs.count()) { 809261c3ad7fde95748da92550735decc949dc73bf2joshualitt const SkString& path = fSKPs[fCurrentAnimSKP]; 810261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkAutoTUnref<SkPicture> pic; 811261c3ad7fde95748da92550735decc949dc73bf2joshualitt if (!ReadPicture(path.c_str(), &pic)) { 812261c3ad7fde95748da92550735decc949dc73bf2joshualitt fCurrentAnimSKP++; 813261c3ad7fde95748da92550735decc949dc73bf2joshualitt continue; 814261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 815261c3ad7fde95748da92550735decc949dc73bf2joshualitt 816261c3ad7fde95748da92550735decc949dc73bf2joshualitt fCurrentAnimSKP++; 817261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkString name = SkOSPath::Basename(path.c_str()); 81863a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SkAutoTUnref<SKPAnimationBench::Animation> animation( 81963a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SKPAnimationBench::CreateZoomAnimation(fZoomMax, fZoomPeriodMs)); 820385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary return new SKPAnimationBench(name.c_str(), pic.get(), fClip, animation, 821385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary FLAGS_loopSKP); 822261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 823261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 824261c3ad7fde95748da92550735decc949dc73bf2joshualitt 82560869a42a133942f852dd0f1696444c2a5c9ad83scroggo for (; fCurrentCodec < fImages.count(); fCurrentCodec++) { 826303fa350125f372bbfc29bec1235885493dab9b4scroggo fSourceType = "image"; 827303fa350125f372bbfc29bec1235885493dab9b4scroggo fBenchType = "skcodec"; 82860869a42a133942f852dd0f1696444c2a5c9ad83scroggo const SkString& path = fImages[fCurrentCodec]; 82960869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 83060869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); 83160869a42a133942f852dd0f1696444c2a5c9ad83scroggo if (!codec) { 83260869a42a133942f852dd0f1696444c2a5c9ad83scroggo // Nothing to time. 8339d9725c892743cf8fc66ea6cdd5ce21fe2df6d14msarett SkDebugf("Cannot find codec for %s\n", path.c_str()); 83460869a42a133942f852dd0f1696444c2a5c9ad83scroggo continue; 83560869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 83621027994192f395bbd1507558b84f59b3c7cf0dascroggo 83760869a42a133942f852dd0f1696444c2a5c9ad83scroggo while (fCurrentColorType < fColorTypes.count()) { 83821027994192f395bbd1507558b84f59b3c7cf0dascroggo const SkColorType colorType = fColorTypes[fCurrentColorType]; 83960869a42a133942f852dd0f1696444c2a5c9ad83scroggo fCurrentColorType++; 84021027994192f395bbd1507558b84f59b3c7cf0dascroggo 84160869a42a133942f852dd0f1696444c2a5c9ad83scroggo // Make sure we can decode to this color type. 84260869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkImageInfo info = codec->getInfo().makeColorType(colorType); 84321027994192f395bbd1507558b84f59b3c7cf0dascroggo SkAlphaType alphaType; 84421027994192f395bbd1507558b84f59b3c7cf0dascroggo if (!SkColorTypeValidateAlphaType(colorType, info.alphaType(), 84521027994192f395bbd1507558b84f59b3c7cf0dascroggo &alphaType)) { 84621027994192f395bbd1507558b84f59b3c7cf0dascroggo continue; 84721027994192f395bbd1507558b84f59b3c7cf0dascroggo } 84821027994192f395bbd1507558b84f59b3c7cf0dascroggo if (alphaType != info.alphaType()) { 84921027994192f395bbd1507558b84f59b3c7cf0dascroggo info = info.makeAlphaType(alphaType); 85021027994192f395bbd1507558b84f59b3c7cf0dascroggo } 85121027994192f395bbd1507558b84f59b3c7cf0dascroggo 85221027994192f395bbd1507558b84f59b3c7cf0dascroggo const size_t rowBytes = info.minRowBytes(); 85321027994192f395bbd1507558b84f59b3c7cf0dascroggo SkAutoMalloc storage(info.getSafeSize(rowBytes)); 85421027994192f395bbd1507558b84f59b3c7cf0dascroggo 85521027994192f395bbd1507558b84f59b3c7cf0dascroggo // Used if fCurrentColorType is kIndex_8_SkColorType 85621027994192f395bbd1507558b84f59b3c7cf0dascroggo int colorCount = 256; 85721027994192f395bbd1507558b84f59b3c7cf0dascroggo SkPMColor colors[256]; 85821027994192f395bbd1507558b84f59b3c7cf0dascroggo 859eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo const SkCodec::Result result = codec->getPixels( 86096fcdcc219d2a0d3579719b84b28bede76efba64halcanary info, storage.get(), rowBytes, nullptr, colors, 86121027994192f395bbd1507558b84f59b3c7cf0dascroggo &colorCount); 86260869a42a133942f852dd0f1696444c2a5c9ad83scroggo switch (result) { 863eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo case SkCodec::kSuccess: 864eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo case SkCodec::kIncompleteInput: 86560869a42a133942f852dd0f1696444c2a5c9ad83scroggo return new CodecBench(SkOSPath::Basename(path.c_str()), 86660869a42a133942f852dd0f1696444c2a5c9ad83scroggo encoded, colorType); 867eb602a5c94078fb2956c9bdc64bbf47a31b9c0e5scroggo case SkCodec::kInvalidConversion: 86860869a42a133942f852dd0f1696444c2a5c9ad83scroggo // This is okay. Not all conversions are valid. 86960869a42a133942f852dd0f1696444c2a5c9ad83scroggo break; 87060869a42a133942f852dd0f1696444c2a5c9ad83scroggo default: 87160869a42a133942f852dd0f1696444c2a5c9ad83scroggo // This represents some sort of failure. 87260869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkASSERT(false); 87360869a42a133942f852dd0f1696444c2a5c9ad83scroggo break; 87460869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 87560869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 87660869a42a133942f852dd0f1696444c2a5c9ad83scroggo fCurrentColorType = 0; 87760869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 87860869a42a133942f852dd0f1696444c2a5c9ad83scroggo 87995f192d19938b98a45dd1fa4112d965f60d10516msarett // Run the DecodingBenches 88095f192d19938b98a45dd1fa4112d965f60d10516msarett while (fCurrentImage < fImages.count()) { 881303fa350125f372bbfc29bec1235885493dab9b4scroggo fSourceType = "image"; 882303fa350125f372bbfc29bec1235885493dab9b4scroggo fBenchType = "skimagedecoder"; 88395f192d19938b98a45dd1fa4112d965f60d10516msarett while (fCurrentColorType < fColorTypes.count()) { 88495f192d19938b98a45dd1fa4112d965f60d10516msarett const SkString& path = fImages[fCurrentImage]; 88595f192d19938b98a45dd1fa4112d965f60d10516msarett SkColorType colorType = fColorTypes[fCurrentColorType]; 88695f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentColorType++; 88760869a42a133942f852dd0f1696444c2a5c9ad83scroggo // Check if the image decodes to the right color type 88860869a42a133942f852dd0f1696444c2a5c9ad83scroggo // before creating the benchmark 88995f192d19938b98a45dd1fa4112d965f60d10516msarett SkBitmap bitmap; 89095f192d19938b98a45dd1fa4112d965f60d10516msarett if (SkImageDecoder::DecodeFile(path.c_str(), &bitmap, 89160869a42a133942f852dd0f1696444c2a5c9ad83scroggo colorType, SkImageDecoder::kDecodePixels_Mode) 89260869a42a133942f852dd0f1696444c2a5c9ad83scroggo && bitmap.colorType() == colorType) { 89395f192d19938b98a45dd1fa4112d965f60d10516msarett return new DecodingBench(path, colorType); 89495f192d19938b98a45dd1fa4112d965f60d10516msarett } 89595f192d19938b98a45dd1fa4112d965f60d10516msarett } 89695f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentColorType = 0; 89795f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentImage++; 89895f192d19938b98a45dd1fa4112d965f60d10516msarett } 89995f192d19938b98a45dd1fa4112d965f60d10516msarett 900b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett // Run the SubsetBenches 901b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett bool useCodecOpts[] = { true, false }; 902b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett while (fUseCodec < 2) { 903b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett bool useCodec = useCodecOpts[fUseCodec]; 904303fa350125f372bbfc29bec1235885493dab9b4scroggo fSourceType = "image"; 905303fa350125f372bbfc29bec1235885493dab9b4scroggo fBenchType = useCodec ? "skcodec" : "skimagedecoder"; 906b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett while (fCurrentSubsetImage < fImages.count()) { 907ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo const SkString& path = fImages[fCurrentSubsetImage]; 908ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo if (!run_subset_bench(path, useCodec)) { 909ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo fCurrentSubsetImage++; 910ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo continue; 911ab12c2715886e7f04c415028a7db49fb0b1e67f3scroggo } 912b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett while (fCurrentColorType < fColorTypes.count()) { 913b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett SkColorType colorType = fColorTypes[fCurrentColorType]; 914b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett while (fCurrentSubsetType <= kLast_SubsetType) { 915b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett int width = 0; 916b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett int height = 0; 917b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett int currentSubsetType = fCurrentSubsetType++; 918b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett if (valid_subset_bench(path, colorType, useCodec, &width, &height)) { 919b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett switch (currentSubsetType) { 920b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett case kTopLeft_SubsetType: 921ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett return new SubsetSingleBench(path, colorType, width/3, 922ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett height/3, 0, 0, useCodec); 923b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett case kTopRight_SubsetType: 924ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett return new SubsetSingleBench(path, colorType, width/3, 925ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett height/3, 2*width/3, 0, useCodec); 926ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett case kMiddle_SubsetType: 927ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett return new SubsetSingleBench(path, colorType, width/3, 928ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett height/3, width/3, height/3, useCodec); 929b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett case kBottomLeft_SubsetType: 930ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett return new SubsetSingleBench(path, colorType, width/3, 931ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett height/3, 0, 2*height/3, useCodec); 932b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett case kBottomRight_SubsetType: 933ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett return new SubsetSingleBench(path, colorType, width/3, 934ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett height/3, 2*width/3, 2*height/3, useCodec); 935b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett case kTranslate_SubsetType: 936b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett return new SubsetTranslateBench(path, colorType, 512, 512, 937b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett useCodec); 938b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett case kZoom_SubsetType: 939b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett return new SubsetZoomBench(path, colorType, 512, 512, 940b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett useCodec); 94195f192d19938b98a45dd1fa4112d965f60d10516msarett } 942b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett } else { 943b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett break; 94495f192d19938b98a45dd1fa4112d965f60d10516msarett } 94595f192d19938b98a45dd1fa4112d965f60d10516msarett } 946b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett fCurrentSubsetType = 0; 947b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett fCurrentColorType++; 94895f192d19938b98a45dd1fa4112d965f60d10516msarett } 949b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett fCurrentColorType = 0; 950b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett fCurrentSubsetImage++; 95195f192d19938b98a45dd1fa4112d965f60d10516msarett } 952b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett fCurrentSubsetImage = 0; 953b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett fUseCodec++; 95495f192d19938b98a45dd1fa4112d965f60d10516msarett } 95595f192d19938b98a45dd1fa4112d965f60d10516msarett 9567f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // Run the BRDBenches 9577f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // We will benchmark multiple BRD strategies. 958303fa350125f372bbfc29bec1235885493dab9b4scroggo static const struct { 9595cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett SkBitmapRegionDecoder::Strategy fStrategy; 960303fa350125f372bbfc29bec1235885493dab9b4scroggo const char* fName; 961303fa350125f372bbfc29bec1235885493dab9b4scroggo } strategies[] = { 9625cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett { SkBitmapRegionDecoder::kOriginal_Strategy, "BRD" }, 9635cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett { SkBitmapRegionDecoder::kCanvas_Strategy, "BRD_canvas" }, 9645cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett { SkBitmapRegionDecoder::kAndroidCodec_Strategy, "BRD_android_codec" }, 9657f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett }; 9667f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 9677f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // We intend to create benchmarks that model the use cases in 9687f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // android/libraries/social/tiledimage. In this library, an image is decoded in 512x512 9697f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // tiles. The image can be translated freely, so the location of a tile may be anywhere in 9707f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // the image. For that reason, we will benchmark decodes in five representative locations 9717f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // in the image. Additionally, this use case utilizes power of two scaling, so we will 9727f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // test on power of two sample sizes. The output tile is always 512x512, so, when a 9737f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // sampleSize is used, the size of the subset that is decoded is always 9747f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // (sampleSize*512)x(sampleSize*512). 9757f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // There are a few good reasons to only test on power of two sample sizes at this time: 9767f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // JPEG decodes using kOriginal_Strategy are broken for non-powers of two. 9777f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // skbug.com/4319 9787f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // All use cases we are aware of only scale by powers of two. 9797f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // PNG decodes use the indicated sampling strategy regardless of the sample size, so 9807f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett // these tests are sufficient to provide good coverage of our scaling options. 981501b7344f116ccc821d437d324aa7883d7ce97bfscroggo const uint32_t sampleSizes[] = { 1, 2, 4, 8, 16, 32, 64 }; 9827f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett const uint32_t minOutputSize = 512; 9837f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentBRDImage < fImages.count()) { 9847f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentBRDStrategy < (int) SK_ARRAY_COUNT(strategies)) { 985303fa350125f372bbfc29bec1235885493dab9b4scroggo fSourceType = "image"; 986303fa350125f372bbfc29bec1235885493dab9b4scroggo fBenchType = strategies[fCurrentBRDStrategy].fName; 987860e8a67190e024b7375e52e270e6bd0a17af86escroggo 988860e8a67190e024b7375e52e270e6bd0a17af86escroggo const SkString& path = fImages[fCurrentBRDImage]; 9895cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett const SkBitmapRegionDecoder::Strategy strategy = 990860e8a67190e024b7375e52e270e6bd0a17af86escroggo strategies[fCurrentBRDStrategy].fStrategy; 991860e8a67190e024b7375e52e270e6bd0a17af86escroggo 9925cb4885b4cd1ac5eb3fc92dac5f5509d7c810464msarett if (SkBitmapRegionDecoder::kOriginal_Strategy == strategy) { 993860e8a67190e024b7375e52e270e6bd0a17af86escroggo // Disable png and jpeg for SkImageDecoder: 994860e8a67190e024b7375e52e270e6bd0a17af86escroggo if (!FLAGS_jpgBuildTileIndex) { 995860e8a67190e024b7375e52e270e6bd0a17af86escroggo if (path.endsWith("JPEG") || path.endsWith("JPG") || 996860e8a67190e024b7375e52e270e6bd0a17af86escroggo path.endsWith("jpeg") || path.endsWith("jpg")) 997860e8a67190e024b7375e52e270e6bd0a17af86escroggo { 998860e8a67190e024b7375e52e270e6bd0a17af86escroggo fCurrentBRDStrategy++; 999860e8a67190e024b7375e52e270e6bd0a17af86escroggo continue; 1000860e8a67190e024b7375e52e270e6bd0a17af86escroggo } 1001860e8a67190e024b7375e52e270e6bd0a17af86escroggo } 1002860e8a67190e024b7375e52e270e6bd0a17af86escroggo if (!FLAGS_pngBuildTileIndex) { 1003860e8a67190e024b7375e52e270e6bd0a17af86escroggo if (path.endsWith("PNG") || path.endsWith("png")) { 1004860e8a67190e024b7375e52e270e6bd0a17af86escroggo fCurrentBRDStrategy++; 1005860e8a67190e024b7375e52e270e6bd0a17af86escroggo continue; 1006860e8a67190e024b7375e52e270e6bd0a17af86escroggo } 1007860e8a67190e024b7375e52e270e6bd0a17af86escroggo } 1008860e8a67190e024b7375e52e270e6bd0a17af86escroggo } 1009860e8a67190e024b7375e52e270e6bd0a17af86escroggo 10107f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentColorType < fColorTypes.count()) { 10117f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentBRDSampleSize < (int) SK_ARRAY_COUNT(sampleSizes)) { 10127f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett while (fCurrentSubsetType <= kLastSingle_SubsetType) { 1013860e8a67190e024b7375e52e270e6bd0a17af86escroggo 1014860e8a67190e024b7375e52e270e6bd0a17af86escroggo 10157f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 10167f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett const SkColorType colorType = fColorTypes[fCurrentColorType]; 10177f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett uint32_t sampleSize = sampleSizes[fCurrentBRDSampleSize]; 10187f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int currentSubsetType = fCurrentSubsetType++; 10197f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 10207f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int width = 0; 10217f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int height = 0; 10227f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett if (!valid_brd_bench(encoded.get(), strategy, colorType, sampleSize, 10237f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett minOutputSize, &width, &height)) { 10247f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 10257f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10267f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 10277f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkString basename = SkOSPath::Basename(path.c_str()); 10287f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkIRect subset; 10297f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett const uint32_t subsetSize = sampleSize * minOutputSize; 10307f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett switch (currentSubsetType) { 10317f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kTopLeft_SubsetType: 10327f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_TopLeft"); 10337f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(0, 0, subsetSize, subsetSize); 10347f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 10357f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kTopRight_SubsetType: 10367f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_TopRight"); 10377f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(width - subsetSize, 0, subsetSize, 10387f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subsetSize); 10397f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 10407f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kMiddle_SubsetType: 10417f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_Middle"); 10427f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH((width - subsetSize) / 2, 10437f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett (height - subsetSize) / 2, subsetSize, subsetSize); 10447f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 10457f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kBottomLeft_SubsetType: 10467f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_BottomLeft"); 10477f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(0, height - subsetSize, subsetSize, 10487f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subsetSize); 10497f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 10507f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett case kBottomRight_SubsetType: 10517f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett basename.append("_BottomRight"); 10527f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett subset = SkIRect::MakeXYWH(width - subsetSize, 10537f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett height - subsetSize, subsetSize, subsetSize); 10547f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett break; 10557f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett default: 10567f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett SkASSERT(false); 10577f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10587f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 10597f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett return new BitmapRegionDecoderBench(basename.c_str(), encoded.get(), 10607f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett strategy, colorType, sampleSize, subset); 10617f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10627f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentSubsetType = 0; 10637f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDSampleSize++; 10647f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10657f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDSampleSize = 0; 10667f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentColorType++; 10677f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10687f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentColorType = 0; 10697f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDStrategy++; 10707f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10717f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDStrategy = 0; 10727f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett fCurrentBRDImage++; 10737f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett } 10747f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett 107596fcdcc219d2a0d3579719b84b28bede76efba64halcanary return nullptr; 1076e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 107792007583e43115998412ac8b0a06cc2780eb025cmtklein 107892007583e43115998412ac8b0a06cc2780eb025cmtklein void fillCurrentOptions(ResultsWriter* log) const { 107992007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("source_type", fSourceType); 1080fd731ce804cd3223318f3feee2c98404890b65f2mtklein log->configOption("bench_type", fBenchType); 108192007583e43115998412ac8b0a06cc2780eb025cmtklein if (0 == strcmp(fSourceType, "skp")) { 108292007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("clip", 108392007583e43115998412ac8b0a06cc2780eb025cmtklein SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, 108492007583e43115998412ac8b0a06cc2780eb025cmtklein fClip.fRight, fClip.fBottom).c_str()); 10854dfdbb19ba861bbd5e1a306bb23f32464ea5e2c5mtklein SK_ALWAYSBREAK(fCurrentScale < fScales.count()); // debugging paranoia 108692007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentScale]).c_str()); 10875b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (fCurrentUseMPD > 0) { 10885b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkASSERT(1 == fCurrentUseMPD || 2 == fCurrentUseMPD); 10895b69377507478623dcf5b11f3ecb010f87c4794frobertphillips log->configOption("multi_picture_draw", fUseMPDs[fCurrentUseMPD-1] ? "true" : "false"); 10905b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 109192007583e43115998412ac8b0a06cc2780eb025cmtklein } 1092051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein if (0 == strcmp(fBenchType, "recording")) { 1093051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("bytes", fSKPBytes); 1094051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("ops", fSKPOps); 1095051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein } 109692007583e43115998412ac8b0a06cc2780eb025cmtklein } 109792007583e43115998412ac8b0a06cc2780eb025cmtklein 1098e714e75c725c987fe682a1f5473224fe3e80380dmtkleinprivate: 1099b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett enum SubsetType { 1100b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kTopLeft_SubsetType = 0, 1101b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett kTopRight_SubsetType = 1, 1102ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kMiddle_SubsetType = 2, 1103ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kBottomLeft_SubsetType = 3, 1104ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kBottomRight_SubsetType = 4, 1105ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kTranslate_SubsetType = 5, 1106ab80e35fbddd5b534b486cf9d331b5da00e5aa4fmsarett kZoom_SubsetType = 6, 11077f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett kLast_SubsetType = kZoom_SubsetType, 11087f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett kLastSingle_SubsetType = kBottomRight_SubsetType, 1109b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett }; 1110b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett 1111e714e75c725c987fe682a1f5473224fe3e80380dmtklein const BenchRegistry* fBenches; 1112e714e75c725c987fe682a1f5473224fe3e80380dmtklein const skiagm::GMRegistry* fGMs; 111392007583e43115998412ac8b0a06cc2780eb025cmtklein SkIRect fClip; 111492007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkScalar> fScales; 111592007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkString> fSKPs; 11165b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkTArray<bool> fUseMPDs; 111795f192d19938b98a45dd1fa4112d965f60d10516msarett SkTArray<SkString> fImages; 111874deb981d5e9c11c88fe431e78166d6cf8dacc1amsarett SkTArray<SkColorType, true> fColorTypes; 111963a82855b1f0b83952b65fca330954c50ebe7a4bcdalton SkScalar fZoomMax; 112063a82855b1f0b83952b65fca330954c50ebe7a4bcdalton double fZoomPeriodMs; 112192007583e43115998412ac8b0a06cc2780eb025cmtklein 1122051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein double fSKPBytes, fSKPOps; 1123051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein 1124fd731ce804cd3223318f3feee2c98404890b65f2mtklein const char* fSourceType; // What we're benching: bench, GM, SKP, ... 1125fd731ce804cd3223318f3feee2c98404890b65f2mtklein const char* fBenchType; // How we bench it: micro, recording, playback, ... 1126fd731ce804cd3223318f3feee2c98404890b65f2mtklein int fCurrentRecording; 112792007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentScale; 112892007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentSKP; 11295b69377507478623dcf5b11f3ecb010f87c4794frobertphillips int fCurrentUseMPD; 113060869a42a133942f852dd0f1696444c2a5c9ad83scroggo int fCurrentCodec; 113195f192d19938b98a45dd1fa4112d965f60d10516msarett int fCurrentImage; 113295f192d19938b98a45dd1fa4112d965f60d10516msarett int fCurrentSubsetImage; 11337f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int fCurrentBRDImage; 113495f192d19938b98a45dd1fa4112d965f60d10516msarett int fCurrentColorType; 1135b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett int fCurrentSubsetType; 1136b23e6aa6767816ac4bc6c191e78ef62d6e765671msarett int fUseCodec; 11377f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int fCurrentBRDStrategy; 11387f69144aaabbedf51ad2a1feddc9e0689f2c5ee9msarett int fCurrentBRDSampleSize; 1139261c3ad7fde95748da92550735decc949dc73bf2joshualitt int fCurrentAnimSKP; 1140e714e75c725c987fe682a1f5473224fe3e80380dmtklein}; 1141e714e75c725c987fe682a1f5473224fe3e80380dmtklein 11423b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorioint nanobench_main(); 114317f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclarkint nanobench_main() { 11443b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio SetupCrashHandler(); 1145f372321de3d4183de5b9ca436e677e471e358f31mtklein SkAutoGraphics ag; 1146cc29d26f5742449eb2a2bafa7bbb6ec5ee701aefmtklein SkTaskGroup::Enabler enabled(FLAGS_threads); 1147f372321de3d4183de5b9ca436e677e471e358f31mtklein 114869a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#if SK_SUPPORT_GPU 1149682c269a1511200322916af83053e26004c0ec40bsalomon GrContextOptions grContextOpts; 115012b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks; 1151385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary gGrFactory.reset(new GrContextFactory(grContextOpts)); 115269a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#endif 115369a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski 115406cddec8570cbf29f89e89736afb0487b5b95abdbsalomon if (FLAGS_veryVerbose) { 115506cddec8570cbf29f89e89736afb0487b5b95abdbsalomon FLAGS_verbose = true; 115606cddec8570cbf29f89e89736afb0487b5b95abdbsalomon } 115706cddec8570cbf29f89e89736afb0487b5b95abdbsalomon 11586eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 1159a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_samples = 1; 1160a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_gpuFrameLag = 0; 1161a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 1162a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 11636eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!FLAGS_writePath.isEmpty()) { 11646eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); 11656eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(FLAGS_writePath[0])) { 11666eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_writePath[0]); 116796fcdcc219d2a0d3579719b84b28bede76efba64halcanary FLAGS_writePath.set(0, nullptr); 11686eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 11696eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 11706eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 1171385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary SkAutoTDelete<ResultsWriter> log(new ResultsWriter); 117260317d0ffb5053df7b08a627d6decd11b684e80dmtklein if (!FLAGS_outResultsFile.isEmpty()) { 1173385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary log.reset(new NanoJSONResultsWriter(FLAGS_outResultsFile[0])); 117460317d0ffb5053df7b08a627d6decd11b684e80dmtklein } 1175bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 11761915b62637bea20e1471a8a358b22e9e47a4a385mtklein if (1 == FLAGS_properties.count() % 2) { 11771915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkDebugf("ERROR: --properties must be passed with an even number of arguments.\n"); 1178bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio return 1; 1179bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 11801915b62637bea20e1471a8a358b22e9e47a4a385mtklein for (int i = 1; i < FLAGS_properties.count(); i += 2) { 11811915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->property(FLAGS_properties[i-1], FLAGS_properties[i]); 1182bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 118394e51567dd691c3e1e8dfa6005a301d72cecf48emtklein 11841915b62637bea20e1471a8a358b22e9e47a4a385mtklein if (1 == FLAGS_key.count() % 2) { 11851915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkDebugf("ERROR: --key must be passed with an even number of arguments.\n"); 118694e51567dd691c3e1e8dfa6005a301d72cecf48emtklein return 1; 118794e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 11881915b62637bea20e1471a8a358b22e9e47a4a385mtklein for (int i = 1; i < FLAGS_key.count(); i += 2) { 11891915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->key(FLAGS_key[i-1], FLAGS_key[i]); 119094e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 119160317d0ffb5053df7b08a627d6decd11b684e80dmtklein 1192f372321de3d4183de5b9ca436e677e471e358f31mtklein const double overhead = estimate_timer_overhead(); 119355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead)); 1194912947737a973421f4c58682b6171cb5ee00ad3aMike Klein 1195e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton SkTArray<double> samples; 1196bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 11976eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 11986eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Fixed number of loops; times would only be misleading so we won't print them.\n"); 1199f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 120040b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein SkDebugf("median\tbench\tconfig\n"); 1201bbba16878f343b232d844281fbdf056c00e20fb6mtklein } else if (FLAGS_ms) { 1202e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\n"); 1203f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 1204d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconfig\tbench\n", 12058247ec313d87afcdd4da59b1f2f0d24e0983e359qiankun.miao FLAGS_samples, "samples"); 1206f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1207f372321de3d4183de5b9ca436e677e471e358f31mtklein 1208c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon SkTDArray<Config> configs; 1209c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon create_configs(&configs); 1210c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 1211e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein int runs = 0; 121292007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream benchStream; 121392007583e43115998412ac8b0a06cc2780eb025cmtklein while (Benchmark* b = benchStream.next()) { 1214e714e75c725c987fe682a1f5473224fe3e80380dmtklein SkAutoTDelete<Benchmark> bench(b); 1215962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName())) { 1216f372321de3d4183de5b9ca436e677e471e358f31mtklein continue; 1217f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1218f372321de3d4183de5b9ca436e677e471e358f31mtklein 12193bf9206ada256277a39988c263f0379d544fc27begdaniel if (!configs.isEmpty()) { 1220962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSize().fY); 12218a6697af95b340aad6dee7e6228048fa305c1e59joshualitt bench->delayedSetup(); 1222bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 12233bf9206ada256277a39988c263f0379d544fc27begdaniel for (int i = 0; i < configs.count(); ++i) { 12243bf9206ada256277a39988c263f0379d544fc27begdaniel Target* target = is_enabled(b, configs[i]); 12253bf9206ada256277a39988c263f0379d544fc27begdaniel if (!target) { 12263bf9206ada256277a39988c263f0379d544fc27begdaniel continue; 12273bf9206ada256277a39988c263f0379d544fc27begdaniel } 12283bf9206ada256277a39988c263f0379d544fc27begdaniel 122996fcdcc219d2a0d3579719b84b28bede76efba64halcanary // During HWUI output this canvas may be nullptr. 12303bf9206ada256277a39988c263f0379d544fc27begdaniel SkCanvas* canvas = target->getCanvas(); 12313bf9206ada256277a39988c263f0379d544fc27begdaniel const char* config = target->config.name; 1232bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 12333bf9206ada256277a39988c263f0379d544fc27begdaniel target->setup(); 12345b69377507478623dcf5b11f3ecb010f87c4794frobertphillips bench->perCanvasPreDraw(canvas); 12355b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 1236e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton int maxFrameLag; 1237a1ebeb25e9acfcd801e089e063311d716b83b8a5mtklein int loops = target->needsFrameTiming(&maxFrameLag) 12383bf9206ada256277a39988c263f0379d544fc27begdaniel ? setup_gpu_bench(target, bench.get(), maxFrameLag) 12393bf9206ada256277a39988c263f0379d544fc27begdaniel : setup_cpu_bench(overhead, target, bench.get()); 1240e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton 1241bbba16878f343b232d844281fbdf056c00e20fb6mtklein if (FLAGS_ms) { 1242bbba16878f343b232d844281fbdf056c00e20fb6mtklein samples.reset(); 1243bbba16878f343b232d844281fbdf056c00e20fb6mtklein auto stop = now_ms() + FLAGS_ms; 1244bbba16878f343b232d844281fbdf056c00e20fb6mtklein do { 1245bbba16878f343b232d844281fbdf056c00e20fb6mtklein samples.push_back(time(loops, bench, target) / loops); 1246bbba16878f343b232d844281fbdf056c00e20fb6mtklein } while (now_ms() < stop); 1247bbba16878f343b232d844281fbdf056c00e20fb6mtklein } else { 1248e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton samples.reset(FLAGS_samples); 1249e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton for (int s = 0; s < FLAGS_samples; s++) { 12503bf9206ada256277a39988c263f0379d544fc27begdaniel samples[s] = time(loops, bench, target) / loops; 1251e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton } 1252e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton } 1253f372321de3d4183de5b9ca436e677e471e358f31mtklein 12545b69377507478623dcf5b11f3ecb010f87c4794frobertphillips bench->perCanvasPostDraw(canvas); 12555b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 12563bf9206ada256277a39988c263f0379d544fc27begdaniel if (Benchmark::kNonRendering_Backend != target->config.backend && 1257d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { 12586eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config); 1259962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniqueName()); 12606eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon pngFilename.append(".png"); 12613bf9206ada256277a39988c263f0379d544fc27begdaniel write_canvas_png(target, pngFilename); 12626eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 12636eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 12646eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kFailedLoops == loops) { 12652069e220034f09aad2f68b262f395e7c25b3d178mtklein // Can't be timed. A warning note has already been printed. 12663bf9206ada256277a39988c263f0379d544fc27begdaniel cleanup_run(target); 1267e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein continue; 1268e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein } 126960317d0ffb5053df7b08a627d6decd11b684e80dmtklein 1270e1b8958877a512bf83cbc2c72bb31e7d71b06f43cdalton Stats stats(samples); 12711915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->config(config); 1272962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein log->configOption("name", bench->getName()); 12731915b62637bea20e1471a8a358b22e9e47a4a385mtklein benchStream.fillCurrentOptions(log.get()); 12743bf9206ada256277a39988c263f0379d544fc27begdaniel target->fillOptions(log.get()); 1275051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("min_ms", stats.min); 1276e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein if (runs++ % FLAGS_flushEvery == 0) { 1277e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein log->flush(); 1278e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein } 127960317d0ffb5053df7b08a627d6decd11b684e80dmtklein 12806eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 12813bf9206ada256277a39988c263f0379d544fc27begdaniel if (configs.count() == 1) { 1282a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein config = ""; // Only print the config if we run the same bench on more than one. 1283a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 1284d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("%4d/%-4dMB\t%s\t%s\n" 1285d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getCurrResidentSetSizeMB() 1286d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getMaxResidentSetSizeMB() 128753d2562006ee371222963750009a706cfd1a94f7mtklein , bench->getUniqueName() 128853d2562006ee371222963750009a706cfd1a94f7mtklein , config); 1289f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 12903bf9206ada256277a39988c263f0379d544fc27begdaniel if (configs.count() == 1) { 1291f372321de3d4183de5b9ca436e677e471e358f31mtklein config = ""; // Only print the config if we run the same bench on more than one. 1292f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1293962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein SkDebugf("%s\t%s\t%s\n", HUMANIZE(stats.median), bench->getUniqueName(), config); 1294f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 1295f372321de3d4183de5b9ca436e677e471e358f31mtklein const double stddev_percent = 100 * sqrt(stats.var) / stats.mean; 1296d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("%4d/%-4dMB\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" 1297d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getCurrResidentSetSizeMB() 1298d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getMaxResidentSetSizeMB() 1299f372321de3d4183de5b9ca436e677e471e358f31mtklein , loops 130055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.min) 130155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.median) 130255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.mean) 130355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.max) 1304f372321de3d4183de5b9ca436e677e471e358f31mtklein , stddev_percent 1305bbba16878f343b232d844281fbdf056c00e20fb6mtklein , FLAGS_ms ? to_string(samples.count()).c_str() : stats.plot.c_str() 1306f372321de3d4183de5b9ca436e677e471e358f31mtklein , config 1307962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein , bench->getUniqueName() 1308f372321de3d4183de5b9ca436e677e471e358f31mtklein ); 1309f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1310b12ea41286ce36e085c5a14711da0cf9f240fdf1bsalomon#if SK_SUPPORT_GPU 1311b12ea41286ce36e085c5a14711da0cf9f240fdf1bsalomon if (FLAGS_gpuStats && 13123bf9206ada256277a39988c263f0379d544fc27begdaniel Benchmark::kGPU_Backend == configs[i].backend) { 13133bf9206ada256277a39988c263f0379d544fc27begdaniel gGrFactory->get(configs[i].ctxType)->printCacheStats(); 13143bf9206ada256277a39988c263f0379d544fc27begdaniel gGrFactory->get(configs[i].ctxType)->printGpuStats(); 131506cddec8570cbf29f89e89736afb0487b5b95abdbsalomon } 131606cddec8570cbf29f89e89736afb0487b5b95abdbsalomon#endif 13172c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton if (FLAGS_verbose) { 13182c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton SkDebugf("Samples: "); 13192c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton for (int i = 0; i < samples.count(); i++) { 13202c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton SkDebugf("%s ", HUMANIZE(samples[i])); 13212c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton } 13222c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton SkDebugf("%s\n", bench->getUniqueName()); 13232c56ba5cde25a5cdbeca2afd660b497b428e8f07cdalton } 13243bf9206ada256277a39988c263f0379d544fc27begdaniel cleanup_run(target); 1325f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1326f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1327f372321de3d4183de5b9ca436e677e471e358f31mtklein 1328e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->bench("memory_usage", 0,0); 1329e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->config("meta"); 1330e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->metric("max_rss_mb", sk_tools::getMaxResidentSetSizeMB()); 1331e109145bf31d63963b3f78c6af6e404d5464a55bmtklein 1332e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt#if SK_SUPPORT_GPU 1333e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt // Make sure we clean up the global GrContextFactory here, otherwise we might race with the 1334e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt // SkEventTracer destructor 133596fcdcc219d2a0d3579719b84b28bede76efba64halcanary gGrFactory.reset(nullptr); 1336e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt#endif 1337e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt 1338f372321de3d4183de5b9ca436e677e471e358f31mtklein return 0; 1339f372321de3d4183de5b9ca436e677e471e358f31mtklein} 1340f372321de3d4183de5b9ca436e677e471e358f31mtklein 13413b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio#if !defined SK_BUILD_FOR_IOS 13423b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorioint main(int argc, char** argv) { 13433b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio SkCommandLineFlags::Parse(argc, argv); 13443b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio return nanobench_main(); 13453b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio} 13463b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio#endif 1347