nanobench.cpp revision 762286309545c8a1e4bbc05dcd1fe3085d2a1f47
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" 1360869a42a133942f852dd0f1696444c2a5c9ad83scroggo#include "CodecBench.h" 14f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "CrashHandler.h" 1595f192d19938b98a45dd1fa4112d965f60d10516msarett#include "DecodingBench.h" 1695f192d19938b98a45dd1fa4112d965f60d10516msarett#include "DecodingSubsetBench.h" 17e714e75c725c987fe682a1f5473224fe3e80380dmtklein#include "GMBench.h" 18afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein#include "ProcStats.h" 1960317d0ffb5053df7b08a627d6decd11b684e80dmtklein#include "ResultsWriter.h" 20fd731ce804cd3223318f3feee2c98404890b65f2mtklein#include "RecordingBench.h" 21261c3ad7fde95748da92550735decc949dc73bf2joshualitt#include "SKPAnimationBench.h" 2292007583e43115998412ac8b0a06cc2780eb025cmtklein#include "SKPBench.h" 23f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Stats.h" 24f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Timer.h" 25f372321de3d4183de5b9ca436e677e471e358f31mtklein 266838d854a87e79f1fbb7b89b9f395155ad44dc0amtklein#include "SkBBoxHierarchy.h" 27f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkCanvas.h" 2860869a42a133942f852dd0f1696444c2a5c9ad83scroggo#include "SkCodec.h" 2917f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclark#include "SkCommonFlags.h" 3095f192d19938b98a45dd1fa4112d965f60d10516msarett#include "SkData.h" 31f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkForceLinking.h" 32f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkGraphics.h" 332084050a33ae139d0fe9bb680f7905f91139a39fmtklein#include "SkOSFile.h" 342084050a33ae139d0fe9bb680f7905f91139a39fmtklein#include "SkPictureRecorder.h" 35051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein#include "SkPictureUtils.h" 36f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkString.h" 37f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkSurface.h" 385b69377507478623dcf5b11f3ecb010f87c4794frobertphillips#include "SkTaskGroup.h" 39f372321de3d4183de5b9ca436e677e471e358f31mtklein 40d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 41d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson #include "nanobenchAndroid.h" 42d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 43d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 44bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 45bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio #include "gl/GrGLDefines.h" 46762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon #include "GrCaps.h" 47bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein #include "GrContextFactory.h" 4869a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski SkAutoTDelete<GrContextFactory> gGrFactory; 49bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 50bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 51682c269a1511200322916af83053e26004c0ec40bsalomon struct GrContextOptions; 52682c269a1511200322916af83053e26004c0ec40bsalomon 53f372321de3d4183de5b9ca436e677e471e358f31mtklein__SK_FORCE_IMAGE_DECODER_LINKING; 54f372321de3d4183de5b9ca436e677e471e358f31mtklein 555324978a88677ac6b758324321816427814e7793reedstatic const int kAutoTuneLoops = 0; 566eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 57b511042bb07a6a289b0d1146cb57f6e8b80580d6mtkleinstatic const int kDefaultLoops = 586eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon#ifdef SK_DEBUG 596eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 1; 60a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein#else 616eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon kAutoTuneLoops; 62a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein#endif 63a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 646eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic SkString loops_help_txt() { 656eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString help; 666eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon help.printf("Number of times to run each bench. Set this to %d to auto-" 676eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon "tune for each bench. Timings are only reported when auto-tuning.", 686eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon kAutoTuneLoops); 696eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return help; 706eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 716eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 726eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonDEFINE_int32(loops, kDefaultLoops, loops_help_txt().c_str()); 736eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 74f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_int32(samples, 10, "Number of samples to measure for each bench."); 75f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_int32(overheadLoops, 100000, "Loops to estimate timer overhead."); 76f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_double(overheadGoal, 0.0001, 77f372321de3d4183de5b9ca436e677e471e358f31mtklein "Loop until timer overhead is at most this fraction of our measurments."); 78bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinDEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); 79bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinDEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allows to lag."); 8012b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevskiDEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling back to " 8112b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski "software path rendering."); 82f372321de3d4183de5b9ca436e677e471e358f31mtklein 8360317d0ffb5053df7b08a627d6decd11b684e80dmtkleinDEFINE_string(outResultsFile, "", "If given, write results here as JSON."); 8455b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinDEFINE_int32(maxCalibrationAttempts, 3, 8555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein "Try up to this many times to guess loops for a bench, or skip the bench."); 8655b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinDEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this."); 8792007583e43115998412ac8b0a06cc2780eb025cmtkleinDEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs."); 8892007583e43115998412ac8b0a06cc2780eb025cmtkleinDEFINE_string(scales, "1.0", "Space-separated scales for SKPs."); 89261c3ad7fde95748da92550735decc949dc73bf2joshualittDEFINE_string(zoom, "1.0,1", "Comma-separated scale,step zoom factors for SKPs."); 902084050a33ae139d0fe9bb680f7905f91139a39fmtkleinDEFINE_bool(bbh, true, "Build a BBH for SKPs?"); 915b69377507478623dcf5b11f3ecb010f87c4794frobertphillipsDEFINE_bool(mpd, true, "Use MultiPictureDraw for the SKPs?"); 92e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtkleinDEFINE_int32(flushEvery, 10, "Flush --outResultsFile every Nth run."); 9355e88b226ccb85d2c712a9e3e9e1f5bdcaac05acmtkleinDEFINE_bool(resetGpuContext, true, "Reset the GrContext before running each test."); 94b12ea41286ce36e085c5a14711da0cf9f240fdf1bsalomonDEFINE_bool(gpuStats, false, "Print GPU stats after each gpu benchmark?"); 9592007583e43115998412ac8b0a06cc2780eb025cmtklein 96f372321de3d4183de5b9ca436e677e471e358f31mtkleinstatic SkString humanize(double ms) { 97dc5bbab138bfffc85d6ba525d990aad09c322ff6mtklein if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); 98748ca3bf2d170708f263693e8579e6722389d0efmtklein return HumanizeMs(ms); 99f372321de3d4183de5b9ca436e677e471e358f31mtklein} 10055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein#define HUMANIZE(ms) humanize(ms).c_str() 101f372321de3d4183de5b9ca436e677e471e358f31mtklein 102d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonbool Target::init(SkImageInfo info, Benchmark* bench) { 103d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (Benchmark::kRaster_Backend == config.backend) { 104d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->surface.reset(SkSurface::NewRaster(info)); 105d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!this->surface.get()) { 106d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 107d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 108d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 109d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 110d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson} 111d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonbool Target::capturePixels(SkBitmap* bmp) { 11275a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson SkCanvas* canvas = this->getCanvas(); 113d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!canvas) { 114d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 115d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 116d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson bmp->setInfo(canvas->imageInfo()); 117d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!canvas->readPixels(bmp, 0, 0)) { 118d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkDebugf("Can't read canvas pixels.\n"); 119d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 120d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 121d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 122d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson} 123d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 124d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#if SK_SUPPORT_GPU 125d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonstruct GPUTarget : public Target { 126d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson explicit GPUTarget(const Config& c) : Target(c), gl(NULL) { } 127d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkGLContext* gl; 128d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 129d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void setup() override { 130d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->gl->makeCurrent(); 131d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson // Make sure we're done with whatever came before. 132d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Finish()); 133d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 134d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void endTiming() override { 135d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (this->gl) { 136d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Flush()); 137d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->gl->swapBuffers(); 138d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 139d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 140d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void fence() override { 141d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL(*this->gl, Finish()); 142d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 143d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein 144d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson bool needsFrameTiming() const override { return true; } 145d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson bool init(SkImageInfo info, Benchmark* bench) override { 146d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson uint32_t flags = this->config.useDFText ? SkSurfaceProps::kUseDistanceFieldFonts_Flag : 0; 147d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); 148d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(this->config.ctxType), 149d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SkSurface::kNo_Budgeted, info, 150d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->config.samples, &props)); 151d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson this->gl = gGrFactory->getGLContext(this->config.ctxType); 152d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!this->surface.get()) { 153d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return false; 154d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 155d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson return true; 156d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 157d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson void fillOptions(ResultsWriter* log) override { 158d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson const GrGLubyte* version; 159d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_VERSION)); 160d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_VERSION", (const char*)(version)); 161d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 162d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_RENDERER)); 163d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_RENDERER", (const char*) version); 164d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 165d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_VENDOR)); 166d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_VENDOR", (const char*) version); 167d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 168d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson SK_GL_RET(*this->gl, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); 169d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version); 170d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 171d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson}; 172d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein 173d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 174d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 17575a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudsonstatic double time(int loops, Benchmark* bench, Target* target) { 17675a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson SkCanvas* canvas = target->getCanvas(); 1776eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (canvas) { 1786eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon canvas->clear(SK_ColorWHITE); 1796eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 180f372321de3d4183de5b9ca436e677e471e358f31mtklein WallTimer timer; 181bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein timer.start(); 18275a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson canvas = target->beginTiming(canvas); 18375a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson bench->draw(loops, canvas); 184f372321de3d4183de5b9ca436e677e471e358f31mtklein if (canvas) { 185f372321de3d4183de5b9ca436e677e471e358f31mtklein canvas->flush(); 186f372321de3d4183de5b9ca436e677e471e358f31mtklein } 18775a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson target->endTiming(); 188bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein timer.end(); 189bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return timer.fWall; 190f372321de3d4183de5b9ca436e677e471e358f31mtklein} 191f372321de3d4183de5b9ca436e677e471e358f31mtklein 192bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic double estimate_timer_overhead() { 193bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein double overhead = 0; 194bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_overheadLoops; i++) { 19575a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson WallTimer timer; 19675a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson timer.start(); 19775a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson timer.end(); 19875a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson overhead += timer.fWall; 199bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 200bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return overhead / FLAGS_overheadLoops; 201bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 202f372321de3d4183de5b9ca436e677e471e358f31mtklein 2035324978a88677ac6b758324321816427814e7793reedstatic int detect_forever_loops(int loops) { 2045324978a88677ac6b758324321816427814e7793reed // look for a magic run-forever value 2055324978a88677ac6b758324321816427814e7793reed if (loops < 0) { 2065324978a88677ac6b758324321816427814e7793reed loops = SK_MaxS32; 2075324978a88677ac6b758324321816427814e7793reed } 2085324978a88677ac6b758324321816427814e7793reed return loops; 2095324978a88677ac6b758324321816427814e7793reed} 2105324978a88677ac6b758324321816427814e7793reed 21155b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinstatic int clamp_loops(int loops) { 21255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops < 1) { 213527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein SkDebugf("ERROR: clamping loops from %d to 1. " 214527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein "There's probably something wrong with the bench.\n", loops); 21555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return 1; 21655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 21755b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops > FLAGS_maxLoops) { 21855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("WARNING: clamping loops from %d to FLAGS_maxLoops, %d.\n", loops, FLAGS_maxLoops); 21955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return FLAGS_maxLoops; 22055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 22155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return loops; 22255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein} 22355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein 224d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonstatic bool write_canvas_png(Target* target, const SkString& filename) { 225d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2266eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (filename.isEmpty()) { 2276eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2286eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 22975a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson if (target->getCanvas() && 23075a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson kUnknown_SkColorType == target->getCanvas()->imageInfo().colorType()) { 2316eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2326eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 233d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2346eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkBitmap bmp; 235d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 236d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!target->capturePixels(&bmp)) { 2376eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2386eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 239d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 2406eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString dir = SkOSPath::Dirname(filename.c_str()); 2416eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(dir.c_str())) { 2426eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't make dir %s.\n", dir.c_str()); 2436eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2446eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2456eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkFILEWStream stream(filename.c_str()); 2466eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!stream.isValid()) { 2476eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't write %s.\n", filename.c_str()); 2486eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2496eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2506eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!SkImageEncoder::EncodeStream(&stream, bmp, SkImageEncoder::kPNG_Type, 100)) { 2516eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't encode a PNG.\n"); 2526eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 2536eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 2546eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return true; 2556eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 2566eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 2576eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic int kFailedLoops = -2; 25875a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudsonstatic int cpu_bench(const double overhead, Target* target, Benchmark* bench, double* samples) { 259bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First figure out approximately how many loops of bench it takes to make overhead negligible. 2602069e220034f09aad2f68b262f395e7c25b3d178mtklein double bench_plus_overhead = 0.0; 26155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein int round = 0; 2626eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == FLAGS_loops) { 2636eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon while (bench_plus_overhead < overhead) { 2646eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (round++ == FLAGS_maxCalibrationAttempts) { 2656eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skipping.\n", 266962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein bench->getUniqueName(), HUMANIZE(bench_plus_overhead), HUMANIZE(overhead)); 2676eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return kFailedLoops; 2686eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 26975a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson bench_plus_overhead = time(1, bench, target); 27055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 2712069e220034f09aad2f68b262f395e7c25b3d178mtklein } 272f372321de3d4183de5b9ca436e677e471e358f31mtklein 273bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Later we'll just start and stop the timer once but loop N times. 274f372321de3d4183de5b9ca436e677e471e358f31mtklein // We'll pick N to make timer overhead negligible: 275f372321de3d4183de5b9ca436e677e471e358f31mtklein // 276bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead 277bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------- < FLAGS_overheadGoal 278bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead + N * Bench Time 279f372321de3d4183de5b9ca436e677e471e358f31mtklein // 280bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // where bench_plus_overhead ≈ overhead + Bench Time. 281f372321de3d4183de5b9ca436e677e471e358f31mtklein // 282f372321de3d4183de5b9ca436e677e471e358f31mtklein // Doing some math, we get: 283f372321de3d4183de5b9ca436e677e471e358f31mtklein // 284bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // (overhead / FLAGS_overheadGoal) - overhead 285bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------------------------ < N 286bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // bench_plus_overhead - overhead) 287f372321de3d4183de5b9ca436e677e471e358f31mtklein // 288f372321de3d4183de5b9ca436e677e471e358f31mtklein // Luckily, this also works well in practice. :) 2896eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon int loops = FLAGS_loops; 2906eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 2916eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double numer = overhead / FLAGS_overheadGoal - overhead; 2926eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double denom = bench_plus_overhead - overhead; 2936eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = (int)ceil(numer / denom); 2945324978a88677ac6b758324321816427814e7793reed loops = clamp_loops(loops); 2955324978a88677ac6b758324321816427814e7793reed } else { 2965324978a88677ac6b758324321816427814e7793reed loops = detect_forever_loops(loops); 2976eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 298bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 299bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_samples; i++) { 30075a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson samples[i] = time(loops, bench, target) / loops; 301bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 302bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 303f372321de3d4183de5b9ca436e677e471e358f31mtklein} 304f372321de3d4183de5b9ca436e677e471e358f31mtklein 305d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudsonstatic int gpu_bench(Target* target, 3065b69377507478623dcf5b11f3ecb010f87c4794frobertphillips Benchmark* bench, 3075b69377507478623dcf5b11f3ecb010f87c4794frobertphillips double* samples) { 308bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First, figure out how many loops it'll take to get a frame up to FLAGS_gpuMs. 3096eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon int loops = FLAGS_loops; 3106eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 3116eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = 1; 312a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein double elapsed = 0; 313a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein do { 314527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein if (1<<30 == loops) { 315527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein // We're about to wrap. Something's wrong with the bench. 316527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein loops = 0; 317527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein break; 318527930fdbbba2a20f98b43821c6b72367e7b2d64mtklein } 319a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops *= 2; 320a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // If the GPU lets frames lag at all, we need to make sure we're timing 321a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // _this_ round, not still timing last round. We force this by looping 322a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // more times than any reasonable GPU will allow frames to lag. 323a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein for (int i = 0; i < FLAGS_gpuFrameLag; i++) { 32475a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson elapsed = time(loops, bench, target); 325a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 326a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } while (elapsed < FLAGS_gpuMs); 327a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 328a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // We've overshot at least a little. Scale back linearly. 329a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); 3305324978a88677ac6b758324321816427814e7793reed loops = clamp_loops(loops); 331a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 332d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson // Make sure we're not still timing our calibration. 333d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target->fence(); 3345324978a88677ac6b758324321816427814e7793reed } else { 3355324978a88677ac6b758324321816427814e7793reed loops = detect_forever_loops(loops); 336a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 337bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 338bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Pretty much the same deal as the calibration: do some warmup to make 339bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // sure we're timing steady-state pipelined frames. 340bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_gpuFrameLag; i++) { 34175a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson time(loops, bench, target); 342f372321de3d4183de5b9ca436e677e471e358f31mtklein } 343bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 344bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Now, actually do the timing! 345bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_samples; i++) { 34675a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson samples[i] = time(loops, bench, target) / loops; 347bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 348d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 349bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 350f372321de3d4183de5b9ca436e677e471e358f31mtklein} 351bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 352bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic SkString to_lower(const char* str) { 353bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkString lower(str); 354bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (size_t i = 0; i < lower.size(); i++) { 355bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein lower[i] = tolower(lower[i]); 356bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 357bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return lower; 358bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 359bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 360c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic bool is_cpu_config_allowed(const char* name) { 361bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_config.count(); i++) { 362c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (to_lower(FLAGS_config[i]).equals(name)) { 363c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return true; 364bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 365f372321de3d4183de5b9ca436e677e471e358f31mtklein } 366c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 367bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 368f372321de3d4183de5b9ca436e677e471e358f31mtklein 369c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 370c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextType ctxType, 371c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon int sampleCnt) { 372c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!is_cpu_config_allowed(name)) { 373c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 374c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 37569a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski if (const GrContext* ctx = gGrFactory->get(ctxType)) { 376762286309545c8a1e4bbc05dcd1fe3085d2a1f47bsalomon return sampleCnt <= ctx->caps()->maxSampleCount(); 377c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 378c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 379c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 380c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 381c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 382c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 383c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType GrContextFactory::kNative_GLContextType 384c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#else 385c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType 0 386e714e75c725c987fe682a1f5473224fe3e80380dmtklein#endif 387c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 388c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// Append all configs that are enabled and supported. 389c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic void create_configs(SkTDArray<Config>* configs) { 3904736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth #define CPU_CONFIG(name, backend, color, alpha) \ 3914736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth if (is_cpu_config_allowed(#name)) { \ 3924736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth Config config = { #name, Benchmark::backend, color, alpha, 0, \ 3934736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth kBogusGLContextType, false }; \ 3944736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth configs->push(config); \ 395f372321de3d4183de5b9ca436e677e471e358f31mtklein } 396e714e75c725c987fe682a1f5473224fe3e80380dmtklein 39740b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_cpu) { 398c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(nonrendering, kNonRendering_Backend, kUnknown_SkColorType, kUnpremul_SkAlphaType) 399c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(8888, kRaster_Backend, kN32_SkColorType, kPremul_SkAlphaType) 400c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(565, kRaster_Backend, kRGB_565_SkColorType, kOpaque_SkAlphaType) 40140b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 402f372321de3d4183de5b9ca436e677e471e358f31mtklein 403bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 4044736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth #define GPU_CONFIG(name, ctxType, samples, useDFText) \ 405c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, samples)) { \ 406c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Config config = { \ 407c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon #name, \ 408c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Benchmark::kGPU_Backend, \ 409c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon kN32_SkColorType, \ 410c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon kPremul_SkAlphaType, \ 411c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon samples, \ 4124736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GrContextFactory::ctxType, \ 4134736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth useDFText }; \ 414c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon configs->push(config); \ 415f372321de3d4183de5b9ca436e677e471e358f31mtklein } 416e714e75c725c987fe682a1f5473224fe3e80380dmtklein 41740b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_gpu) { 4184736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(gpu, kNative_GLContextType, 0, false) 4194736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(msaa4, kNative_GLContextType, 4, false) 4204736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(msaa16, kNative_GLContextType, 16, false) 4214736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4, false) 4224736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16, false) 4234736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(gpudft, kNative_GLContextType, 0, true) 4244736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(debug, kDebug_GLContextType, 0, false) 4254736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(nullgpu, kNull_GLContextType, 0, false) 4263b4d077fba1ad037536db198608a940c47d91888bsalomon#ifdef SK_ANGLE 4274736e1434ae329e3a737dfd9504c22b3fc13dc72jvanverth GPU_CONFIG(angle, kANGLE_GLContextType, 0, false) 4283b4d077fba1ad037536db198608a940c47d91888bsalomon#endif 42940b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 430bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 431d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson 432d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 433d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (is_cpu_config_allowed("hwui")) { 434d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson Config config = { "hwui", Benchmark::kHWUI_Backend, kRGBA_8888_SkColorType, 435d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson kPremul_SkAlphaType, 0, kBogusGLContextType, false }; 436d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson configs->push(config); 437d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 438d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 439f372321de3d4183de5b9ca436e677e471e358f31mtklein} 440f372321de3d4183de5b9ca436e677e471e358f31mtklein 441c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// If bench is enabled for config, returns a Target* for it, otherwise NULL. 442c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic Target* is_enabled(Benchmark* bench, const Config& config) { 443c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!bench->isSuitableFor(config.backend)) { 444c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return NULL; 445c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 446c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 447e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkImageInfo info = SkImageInfo::Make(bench->getSize().fX, bench->getSize().fY, 448e5ea500d4714a7d84de2bf913e81be3b65d2de68reed config.color, config.alpha); 449c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 450d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson Target* target = NULL; 451c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 452d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson switch (config.backend) { 453c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 454d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson case Benchmark::kGPU_Backend: 455d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new GPUTarget(config); 456d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 457d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#endif 458d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK 459d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson case Benchmark::kHWUI_Backend: 460d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new HWUITarget(config, bench); 461d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 462c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 463d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson default: 464d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson target = new Target(config); 465d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson break; 466d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson } 467c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 468d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (!target->init(info, bench)) { 469c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon delete target; 470c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return NULL; 471c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 472c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return target; 473c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 474c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 475c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// Creates targets for a benchmark and a set of configs. 476c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic void create_targets(SkTDArray<Target*>* targets, Benchmark* b, 477c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon const SkTDArray<Config>& configs) { 478c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon for (int i = 0; i < configs.count(); ++i) { 479c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (Target* t = is_enabled(b, configs[i])) { 480c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon targets->push(t); 481c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 482e714e75c725c987fe682a1f5473224fe3e80380dmtklein 483c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 484c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 485c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 486bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 487e714e75c725c987fe682a1f5473224fe3e80380dmtkleinclass BenchmarkStream { 488e714e75c725c987fe682a1f5473224fe3e80380dmtkleinpublic: 48992007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream() : fBenches(BenchRegistry::Head()) 49092007583e43115998412ac8b0a06cc2780eb025cmtklein , fGMs(skiagm::GMRegistry::Head()) 491fd731ce804cd3223318f3feee2c98404890b65f2mtklein , fCurrentRecording(0) 49292007583e43115998412ac8b0a06cc2780eb025cmtklein , fCurrentScale(0) 4935b69377507478623dcf5b11f3ecb010f87c4794frobertphillips , fCurrentSKP(0) 49495f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentUseMPD(0) 49560869a42a133942f852dd0f1696444c2a5c9ad83scroggo , fCurrentCodec(0) 49695f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentImage(0) 49795f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentSubsetImage(0) 49895f192d19938b98a45dd1fa4112d965f60d10516msarett , fCurrentColorType(0) 499261c3ad7fde95748da92550735decc949dc73bf2joshualitt , fCurrentAnimSKP(0) 50095f192d19938b98a45dd1fa4112d965f60d10516msarett , fDivisor(2) { 50192007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_skps.count(); i++) { 50292007583e43115998412ac8b0a06cc2780eb025cmtklein if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { 50392007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = FLAGS_skps[i]; 50492007583e43115998412ac8b0a06cc2780eb025cmtklein } else { 50592007583e43115998412ac8b0a06cc2780eb025cmtklein SkOSFile::Iter it(FLAGS_skps[i], ".skp"); 50692007583e43115998412ac8b0a06cc2780eb025cmtklein SkString path; 50792007583e43115998412ac8b0a06cc2780eb025cmtklein while (it.next(&path)) { 50892007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str()); 50992007583e43115998412ac8b0a06cc2780eb025cmtklein } 51092007583e43115998412ac8b0a06cc2780eb025cmtklein } 51192007583e43115998412ac8b0a06cc2780eb025cmtklein } 51292007583e43115998412ac8b0a06cc2780eb025cmtklein 51392007583e43115998412ac8b0a06cc2780eb025cmtklein if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d", 51492007583e43115998412ac8b0a06cc2780eb025cmtklein &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom)) { 51592007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0]); 51692007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 51792007583e43115998412ac8b0a06cc2780eb025cmtklein } 51892007583e43115998412ac8b0a06cc2780eb025cmtklein 51992007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_scales.count(); i++) { 52092007583e43115998412ac8b0a06cc2780eb025cmtklein if (1 != sscanf(FLAGS_scales[i], "%f", &fScales.push_back())) { 52192007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --scales as an SkScalar.\n", FLAGS_scales[i]); 52292007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 52392007583e43115998412ac8b0a06cc2780eb025cmtklein } 52492007583e43115998412ac8b0a06cc2780eb025cmtklein } 5255b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 526261c3ad7fde95748da92550735decc949dc73bf2joshualitt if (2 != sscanf(FLAGS_zoom[0], "%f,%d", &fZoomScale, &fZoomSteps)) { 527261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkDebugf("Can't parse %s from --zoom as a scale,step.\n", FLAGS_zoom[0]); 528261c3ad7fde95748da92550735decc949dc73bf2joshualitt exit(1); 529261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 530261c3ad7fde95748da92550735decc949dc73bf2joshualitt 5315b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fUseMPDs.push_back() = false; 5325b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (FLAGS_mpd) { 5335b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fUseMPDs.push_back() = true; 5345b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 53595553d917c73ef333ede967521560957a5b6a0admtklein 53695f192d19938b98a45dd1fa4112d965f60d10516msarett // Prepare the images for decoding 53795f192d19938b98a45dd1fa4112d965f60d10516msarett for (int i = 0; i < FLAGS_images.count(); i++) { 53895f192d19938b98a45dd1fa4112d965f60d10516msarett const char* flag = FLAGS_images[i]; 53995f192d19938b98a45dd1fa4112d965f60d10516msarett if (sk_isdir(flag)) { 54095f192d19938b98a45dd1fa4112d965f60d10516msarett // If the value passed in is a directory, add all the images 54195f192d19938b98a45dd1fa4112d965f60d10516msarett SkOSFile::Iter it(flag); 54295f192d19938b98a45dd1fa4112d965f60d10516msarett SkString file; 54395f192d19938b98a45dd1fa4112d965f60d10516msarett while (it.next(&file)) { 54495f192d19938b98a45dd1fa4112d965f60d10516msarett fImages.push_back() = SkOSPath::Join(flag, file.c_str()); 54595f192d19938b98a45dd1fa4112d965f60d10516msarett } 54695f192d19938b98a45dd1fa4112d965f60d10516msarett } else if (sk_exists(flag)) { 54795f192d19938b98a45dd1fa4112d965f60d10516msarett // Also add the value if it is a single image 54895f192d19938b98a45dd1fa4112d965f60d10516msarett fImages.push_back() = flag; 54995f192d19938b98a45dd1fa4112d965f60d10516msarett } 55095f192d19938b98a45dd1fa4112d965f60d10516msarett } 55195553d917c73ef333ede967521560957a5b6a0admtklein 55295f192d19938b98a45dd1fa4112d965f60d10516msarett // Choose the candidate color types for image decoding 55395f192d19938b98a45dd1fa4112d965f60d10516msarett const SkColorType colorTypes[] = 55421027994192f395bbd1507558b84f59b3c7cf0dascroggo { kN32_SkColorType, kRGB_565_SkColorType, kAlpha_8_SkColorType, kIndex_8_SkColorType }; 55595f192d19938b98a45dd1fa4112d965f60d10516msarett fColorTypes.push_back_n(SK_ARRAY_COUNT(colorTypes), colorTypes); 55692007583e43115998412ac8b0a06cc2780eb025cmtklein } 557e714e75c725c987fe682a1f5473224fe3e80380dmtklein 558fd731ce804cd3223318f3feee2c98404890b65f2mtklein static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) { 559fd731ce804cd3223318f3feee2c98404890b65f2mtklein // Not strictly necessary, as it will be checked again later, 560fd731ce804cd3223318f3feee2c98404890b65f2mtklein // but helps to avoid a lot of pointless work if we're going to skip it. 561fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) { 562fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 563fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 564fd731ce804cd3223318f3feee2c98404890b65f2mtklein 565a1193e4b0e34a7e4e1bd33e9708d7341679f8321scroggo SkAutoTDelete<SkStream> stream(SkStream::NewFromFile(path)); 566fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (stream.get() == NULL) { 567fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkDebugf("Could not read %s.\n", path); 568fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 569fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 570fd731ce804cd3223318f3feee2c98404890b65f2mtklein 57157f27bdcbd328491a121918b4ab9301fbcdec642mtklein pic->reset(SkPicture::CreateFromStream(stream.get())); 572fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (pic->get() == NULL) { 573fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkDebugf("Could not read %s as an SkPicture.\n", path); 574fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 575fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 576fd731ce804cd3223318f3feee2c98404890b65f2mtklein return true; 577fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 578fd731ce804cd3223318f3feee2c98404890b65f2mtklein 57992007583e43115998412ac8b0a06cc2780eb025cmtklein Benchmark* next() { 580e714e75c725c987fe682a1f5473224fe3e80380dmtklein if (fBenches) { 581e714e75c725c987fe682a1f5473224fe3e80380dmtklein Benchmark* bench = fBenches->factory()(NULL); 582e714e75c725c987fe682a1f5473224fe3e80380dmtklein fBenches = fBenches->next(); 58392007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "bench"; 584fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "micro"; 585e714e75c725c987fe682a1f5473224fe3e80380dmtklein return bench; 586e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 58792007583e43115998412ac8b0a06cc2780eb025cmtklein 588e714e75c725c987fe682a1f5473224fe3e80380dmtklein while (fGMs) { 589e714e75c725c987fe682a1f5473224fe3e80380dmtklein SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(NULL)); 590e714e75c725c987fe682a1f5473224fe3e80380dmtklein fGMs = fGMs->next(); 591cf5d9c993dcbd75d4cefe2d1de25c2b9645f6957mtklein if (gm->runAsBench()) { 59292007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "gm"; 593fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "micro"; 594e714e75c725c987fe682a1f5473224fe3e80380dmtklein return SkNEW_ARGS(GMBench, (gm.detach())); 595e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 596e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 59792007583e43115998412ac8b0a06cc2780eb025cmtklein 598fd731ce804cd3223318f3feee2c98404890b65f2mtklein // First add all .skps as RecordingBenches. 599fd731ce804cd3223318f3feee2c98404890b65f2mtklein while (fCurrentRecording < fSKPs.count()) { 600fd731ce804cd3223318f3feee2c98404890b65f2mtklein const SkString& path = fSKPs[fCurrentRecording++]; 601fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkPicture> pic; 602fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (!ReadPicture(path.c_str(), &pic)) { 603fd731ce804cd3223318f3feee2c98404890b65f2mtklein continue; 604fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 605fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkString name = SkOSPath::Basename(path.c_str()); 606fd731ce804cd3223318f3feee2c98404890b65f2mtklein fSourceType = "skp"; 607fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "recording"; 6080aa5cea8694d3686b6742a36eab81ab9001de954bsalomon fSKPBytes = static_cast<double>(SkPictureUtils::ApproximateBytesUsed(pic)); 609051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein fSKPOps = pic->approximateOpCount(); 610fd731ce804cd3223318f3feee2c98404890b65f2mtklein return SkNEW_ARGS(RecordingBench, (name.c_str(), pic.get(), FLAGS_bbh)); 611fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 612fd731ce804cd3223318f3feee2c98404890b65f2mtklein 613fd731ce804cd3223318f3feee2c98404890b65f2mtklein // Then once each for each scale as SKPBenches (playback). 61492007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentScale < fScales.count()) { 61592007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentSKP < fSKPs.count()) { 6165b69377507478623dcf5b11f3ecb010f87c4794frobertphillips const SkString& path = fSKPs[fCurrentSKP]; 617fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkPicture> pic; 618fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (!ReadPicture(path.c_str(), &pic)) { 6195b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentSKP++; 62092007583e43115998412ac8b0a06cc2780eb025cmtklein continue; 62192007583e43115998412ac8b0a06cc2780eb025cmtklein } 6225b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 6235b69377507478623dcf5b11f3ecb010f87c4794frobertphillips while (fCurrentUseMPD < fUseMPDs.count()) { 6245b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (FLAGS_bbh) { 6255b69377507478623dcf5b11f3ecb010f87c4794frobertphillips // The SKP we read off disk doesn't have a BBH. Re-record so it grows one. 6265b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkRTreeFactory factory; 6275b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkPictureRecorder recorder; 6285b69377507478623dcf5b11f3ecb010f87c4794frobertphillips static const int kFlags = SkPictureRecorder::kComputeSaveLayerInfo_RecordFlag; 6295b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic->playback(recorder.beginRecording(pic->cullRect().width(), 6305b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic->cullRect().height(), 631748ca3bf2d170708f263693e8579e6722389d0efmtklein &factory, 632e451c4df7369c5e253ef9c9e0a8713beda25f34brobertphillips fUseMPDs[fCurrentUseMPD] ? kFlags : 0)); 6335b69377507478623dcf5b11f3ecb010f87c4794frobertphillips pic.reset(recorder.endRecording()); 6345b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 6355b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkString name = SkOSPath::Basename(path.c_str()); 6365b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fSourceType = "skp"; 6375b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fBenchType = "playback"; 6385b69377507478623dcf5b11f3ecb010f87c4794frobertphillips return SkNEW_ARGS(SKPBench, 639261c3ad7fde95748da92550735decc949dc73bf2joshualitt (name.c_str(), pic.get(), fClip, 640261c3ad7fde95748da92550735decc949dc73bf2joshualitt fScales[fCurrentScale], fUseMPDs[fCurrentUseMPD++])); 641261c3ad7fde95748da92550735decc949dc73bf2joshualitt 6422084050a33ae139d0fe9bb680f7905f91139a39fmtklein } 6435b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentUseMPD = 0; 6445b69377507478623dcf5b11f3ecb010f87c4794frobertphillips fCurrentSKP++; 64592007583e43115998412ac8b0a06cc2780eb025cmtklein } 64692007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentSKP = 0; 64792007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentScale++; 64892007583e43115998412ac8b0a06cc2780eb025cmtklein } 64992007583e43115998412ac8b0a06cc2780eb025cmtklein 650261c3ad7fde95748da92550735decc949dc73bf2joshualitt // Now loop over each skp again if we have an animation 651261c3ad7fde95748da92550735decc949dc73bf2joshualitt if (fZoomScale != 1.0f && fZoomSteps != 1) { 652261c3ad7fde95748da92550735decc949dc73bf2joshualitt while (fCurrentAnimSKP < fSKPs.count()) { 653261c3ad7fde95748da92550735decc949dc73bf2joshualitt const SkString& path = fSKPs[fCurrentAnimSKP]; 654261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkAutoTUnref<SkPicture> pic; 655261c3ad7fde95748da92550735decc949dc73bf2joshualitt if (!ReadPicture(path.c_str(), &pic)) { 656261c3ad7fde95748da92550735decc949dc73bf2joshualitt fCurrentAnimSKP++; 657261c3ad7fde95748da92550735decc949dc73bf2joshualitt continue; 658261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 659261c3ad7fde95748da92550735decc949dc73bf2joshualitt 660261c3ad7fde95748da92550735decc949dc73bf2joshualitt fCurrentAnimSKP++; 661261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkString name = SkOSPath::Basename(path.c_str()); 662261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkMatrix anim = SkMatrix::I(); 663261c3ad7fde95748da92550735decc949dc73bf2joshualitt anim.setScale(fZoomScale, fZoomScale); 664261c3ad7fde95748da92550735decc949dc73bf2joshualitt return SkNEW_ARGS(SKPAnimationBench, (name.c_str(), pic.get(), fClip, anim, 665261c3ad7fde95748da92550735decc949dc73bf2joshualitt fZoomSteps)); 666261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 667261c3ad7fde95748da92550735decc949dc73bf2joshualitt } 668261c3ad7fde95748da92550735decc949dc73bf2joshualitt 669261c3ad7fde95748da92550735decc949dc73bf2joshualitt 67060869a42a133942f852dd0f1696444c2a5c9ad83scroggo for (; fCurrentCodec < fImages.count(); fCurrentCodec++) { 67160869a42a133942f852dd0f1696444c2a5c9ad83scroggo const SkString& path = fImages[fCurrentCodec]; 67260869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkAutoTUnref<SkData> encoded(SkData::NewFromFileName(path.c_str())); 67360869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(encoded)); 67460869a42a133942f852dd0f1696444c2a5c9ad83scroggo if (!codec) { 67560869a42a133942f852dd0f1696444c2a5c9ad83scroggo // Nothing to time. 6769d9725c892743cf8fc66ea6cdd5ce21fe2df6d14msarett SkDebugf("Cannot find codec for %s\n", path.c_str()); 67760869a42a133942f852dd0f1696444c2a5c9ad83scroggo continue; 67860869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 67921027994192f395bbd1507558b84f59b3c7cf0dascroggo 68060869a42a133942f852dd0f1696444c2a5c9ad83scroggo while (fCurrentColorType < fColorTypes.count()) { 68121027994192f395bbd1507558b84f59b3c7cf0dascroggo const SkColorType colorType = fColorTypes[fCurrentColorType]; 68260869a42a133942f852dd0f1696444c2a5c9ad83scroggo fCurrentColorType++; 68321027994192f395bbd1507558b84f59b3c7cf0dascroggo 68460869a42a133942f852dd0f1696444c2a5c9ad83scroggo // Make sure we can decode to this color type. 68560869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkImageInfo info = codec->getInfo().makeColorType(colorType); 68621027994192f395bbd1507558b84f59b3c7cf0dascroggo SkAlphaType alphaType; 68721027994192f395bbd1507558b84f59b3c7cf0dascroggo if (!SkColorTypeValidateAlphaType(colorType, info.alphaType(), 68821027994192f395bbd1507558b84f59b3c7cf0dascroggo &alphaType)) { 68921027994192f395bbd1507558b84f59b3c7cf0dascroggo continue; 69021027994192f395bbd1507558b84f59b3c7cf0dascroggo } 69121027994192f395bbd1507558b84f59b3c7cf0dascroggo if (alphaType != info.alphaType()) { 69221027994192f395bbd1507558b84f59b3c7cf0dascroggo info = info.makeAlphaType(alphaType); 69321027994192f395bbd1507558b84f59b3c7cf0dascroggo } 69421027994192f395bbd1507558b84f59b3c7cf0dascroggo 69521027994192f395bbd1507558b84f59b3c7cf0dascroggo const size_t rowBytes = info.minRowBytes(); 69621027994192f395bbd1507558b84f59b3c7cf0dascroggo SkAutoMalloc storage(info.getSafeSize(rowBytes)); 69721027994192f395bbd1507558b84f59b3c7cf0dascroggo 69821027994192f395bbd1507558b84f59b3c7cf0dascroggo // Used if fCurrentColorType is kIndex_8_SkColorType 69921027994192f395bbd1507558b84f59b3c7cf0dascroggo int colorCount = 256; 70021027994192f395bbd1507558b84f59b3c7cf0dascroggo SkPMColor colors[256]; 70121027994192f395bbd1507558b84f59b3c7cf0dascroggo 70260869a42a133942f852dd0f1696444c2a5c9ad83scroggo const SkImageGenerator::Result result = codec->getPixels( 70321027994192f395bbd1507558b84f59b3c7cf0dascroggo info, storage.get(), rowBytes, NULL, colors, 70421027994192f395bbd1507558b84f59b3c7cf0dascroggo &colorCount); 70560869a42a133942f852dd0f1696444c2a5c9ad83scroggo switch (result) { 70660869a42a133942f852dd0f1696444c2a5c9ad83scroggo case SkImageGenerator::kSuccess: 70760869a42a133942f852dd0f1696444c2a5c9ad83scroggo case SkImageGenerator::kIncompleteInput: 70860869a42a133942f852dd0f1696444c2a5c9ad83scroggo return new CodecBench(SkOSPath::Basename(path.c_str()), 70960869a42a133942f852dd0f1696444c2a5c9ad83scroggo encoded, colorType); 71060869a42a133942f852dd0f1696444c2a5c9ad83scroggo case SkImageGenerator::kInvalidConversion: 71160869a42a133942f852dd0f1696444c2a5c9ad83scroggo // This is okay. Not all conversions are valid. 71260869a42a133942f852dd0f1696444c2a5c9ad83scroggo break; 71360869a42a133942f852dd0f1696444c2a5c9ad83scroggo default: 71460869a42a133942f852dd0f1696444c2a5c9ad83scroggo // This represents some sort of failure. 71560869a42a133942f852dd0f1696444c2a5c9ad83scroggo SkASSERT(false); 71660869a42a133942f852dd0f1696444c2a5c9ad83scroggo break; 71760869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 71860869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 71960869a42a133942f852dd0f1696444c2a5c9ad83scroggo fCurrentColorType = 0; 72060869a42a133942f852dd0f1696444c2a5c9ad83scroggo } 72160869a42a133942f852dd0f1696444c2a5c9ad83scroggo 72295f192d19938b98a45dd1fa4112d965f60d10516msarett // Run the DecodingBenches 72395f192d19938b98a45dd1fa4112d965f60d10516msarett while (fCurrentImage < fImages.count()) { 72495f192d19938b98a45dd1fa4112d965f60d10516msarett while (fCurrentColorType < fColorTypes.count()) { 72595f192d19938b98a45dd1fa4112d965f60d10516msarett const SkString& path = fImages[fCurrentImage]; 72695f192d19938b98a45dd1fa4112d965f60d10516msarett SkColorType colorType = fColorTypes[fCurrentColorType]; 72795f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentColorType++; 72860869a42a133942f852dd0f1696444c2a5c9ad83scroggo // Check if the image decodes to the right color type 72960869a42a133942f852dd0f1696444c2a5c9ad83scroggo // before creating the benchmark 73095f192d19938b98a45dd1fa4112d965f60d10516msarett SkBitmap bitmap; 73195f192d19938b98a45dd1fa4112d965f60d10516msarett if (SkImageDecoder::DecodeFile(path.c_str(), &bitmap, 73260869a42a133942f852dd0f1696444c2a5c9ad83scroggo colorType, SkImageDecoder::kDecodePixels_Mode) 73360869a42a133942f852dd0f1696444c2a5c9ad83scroggo && bitmap.colorType() == colorType) { 73495f192d19938b98a45dd1fa4112d965f60d10516msarett return new DecodingBench(path, colorType); 73595f192d19938b98a45dd1fa4112d965f60d10516msarett } 73695f192d19938b98a45dd1fa4112d965f60d10516msarett } 73795f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentColorType = 0; 73895f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentImage++; 73995f192d19938b98a45dd1fa4112d965f60d10516msarett } 74095f192d19938b98a45dd1fa4112d965f60d10516msarett 74195f192d19938b98a45dd1fa4112d965f60d10516msarett // Run the DecodingSubsetBenches 74295f192d19938b98a45dd1fa4112d965f60d10516msarett while (fCurrentSubsetImage < fImages.count()) { 74395f192d19938b98a45dd1fa4112d965f60d10516msarett while (fCurrentColorType < fColorTypes.count()) { 74495f192d19938b98a45dd1fa4112d965f60d10516msarett const SkString& path = fImages[fCurrentSubsetImage]; 74595f192d19938b98a45dd1fa4112d965f60d10516msarett SkColorType colorType = fColorTypes[fCurrentColorType]; 74695f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentColorType++; 74795f192d19938b98a45dd1fa4112d965f60d10516msarett // Check if the image decodes before creating the benchmark 74895f192d19938b98a45dd1fa4112d965f60d10516msarett SkAutoTUnref<SkData> encoded( 74995f192d19938b98a45dd1fa4112d965f60d10516msarett SkData::NewFromFileName(path.c_str())); 75095f192d19938b98a45dd1fa4112d965f60d10516msarett SkAutoTDelete<SkMemoryStream> stream( 75195f192d19938b98a45dd1fa4112d965f60d10516msarett new SkMemoryStream(encoded)); 75295f192d19938b98a45dd1fa4112d965f60d10516msarett SkAutoTDelete<SkImageDecoder> 75395f192d19938b98a45dd1fa4112d965f60d10516msarett decoder(SkImageDecoder::Factory(stream.get())); 75495f192d19938b98a45dd1fa4112d965f60d10516msarett if (!decoder) { 75595f192d19938b98a45dd1fa4112d965f60d10516msarett SkDebugf("Cannot find decoder for %s\n", path.c_str()); 75695f192d19938b98a45dd1fa4112d965f60d10516msarett } else { 75795f192d19938b98a45dd1fa4112d965f60d10516msarett stream->rewind(); 75895f192d19938b98a45dd1fa4112d965f60d10516msarett int w, h; 75995f192d19938b98a45dd1fa4112d965f60d10516msarett bool success; 76095f192d19938b98a45dd1fa4112d965f60d10516msarett if (!decoder->buildTileIndex(stream.detach(), &w, &h) 76195f192d19938b98a45dd1fa4112d965f60d10516msarett || w*h == 1) { 76295f192d19938b98a45dd1fa4112d965f60d10516msarett // This is not an error, but in this case we still 76395f192d19938b98a45dd1fa4112d965f60d10516msarett // do not want to run the benchmark. 76495f192d19938b98a45dd1fa4112d965f60d10516msarett success = false; 76595f192d19938b98a45dd1fa4112d965f60d10516msarett } else if (fDivisor > w || fDivisor > h) { 76695f192d19938b98a45dd1fa4112d965f60d10516msarett SkDebugf("Divisor %d is too big for %s %dx%d\n", 76795f192d19938b98a45dd1fa4112d965f60d10516msarett fDivisor, path.c_str(), w, h); 76895f192d19938b98a45dd1fa4112d965f60d10516msarett success = false; 76995f192d19938b98a45dd1fa4112d965f60d10516msarett } else { 77095f192d19938b98a45dd1fa4112d965f60d10516msarett const int sW = w / fDivisor; 77195f192d19938b98a45dd1fa4112d965f60d10516msarett const int sH = h / fDivisor; 77295f192d19938b98a45dd1fa4112d965f60d10516msarett SkBitmap bitmap; 77395f192d19938b98a45dd1fa4112d965f60d10516msarett success = true; 77495f192d19938b98a45dd1fa4112d965f60d10516msarett for (int y = 0; y < h; y += sH) { 77595f192d19938b98a45dd1fa4112d965f60d10516msarett for (int x = 0; x < w; x += sW) { 77695f192d19938b98a45dd1fa4112d965f60d10516msarett SkIRect rect = SkIRect::MakeXYWH(x, y, sW, sH); 77795f192d19938b98a45dd1fa4112d965f60d10516msarett success &= decoder->decodeSubset(&bitmap, rect, 77895f192d19938b98a45dd1fa4112d965f60d10516msarett colorType); 77995f192d19938b98a45dd1fa4112d965f60d10516msarett } 78095f192d19938b98a45dd1fa4112d965f60d10516msarett } 78195f192d19938b98a45dd1fa4112d965f60d10516msarett } 78295f192d19938b98a45dd1fa4112d965f60d10516msarett // Create the benchmark if successful 78395f192d19938b98a45dd1fa4112d965f60d10516msarett if (success) { 78495f192d19938b98a45dd1fa4112d965f60d10516msarett return new DecodingSubsetBench(path, colorType, 78595f192d19938b98a45dd1fa4112d965f60d10516msarett fDivisor); 78695f192d19938b98a45dd1fa4112d965f60d10516msarett } 78795f192d19938b98a45dd1fa4112d965f60d10516msarett } 78895f192d19938b98a45dd1fa4112d965f60d10516msarett } 78995f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentColorType = 0; 79095f192d19938b98a45dd1fa4112d965f60d10516msarett fCurrentSubsetImage++; 79195f192d19938b98a45dd1fa4112d965f60d10516msarett } 79295f192d19938b98a45dd1fa4112d965f60d10516msarett 793e714e75c725c987fe682a1f5473224fe3e80380dmtklein return NULL; 794e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 79592007583e43115998412ac8b0a06cc2780eb025cmtklein 79692007583e43115998412ac8b0a06cc2780eb025cmtklein void fillCurrentOptions(ResultsWriter* log) const { 79792007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("source_type", fSourceType); 798fd731ce804cd3223318f3feee2c98404890b65f2mtklein log->configOption("bench_type", fBenchType); 79992007583e43115998412ac8b0a06cc2780eb025cmtklein if (0 == strcmp(fSourceType, "skp")) { 80092007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("clip", 80192007583e43115998412ac8b0a06cc2780eb025cmtklein SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, 80292007583e43115998412ac8b0a06cc2780eb025cmtklein fClip.fRight, fClip.fBottom).c_str()); 80392007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentScale]).c_str()); 8045b69377507478623dcf5b11f3ecb010f87c4794frobertphillips if (fCurrentUseMPD > 0) { 8055b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkASSERT(1 == fCurrentUseMPD || 2 == fCurrentUseMPD); 8065b69377507478623dcf5b11f3ecb010f87c4794frobertphillips log->configOption("multi_picture_draw", fUseMPDs[fCurrentUseMPD-1] ? "true" : "false"); 8075b69377507478623dcf5b11f3ecb010f87c4794frobertphillips } 80892007583e43115998412ac8b0a06cc2780eb025cmtklein } 809051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein if (0 == strcmp(fBenchType, "recording")) { 810051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("bytes", fSKPBytes); 811051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("ops", fSKPOps); 812051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein } 81392007583e43115998412ac8b0a06cc2780eb025cmtklein } 81492007583e43115998412ac8b0a06cc2780eb025cmtklein 815e714e75c725c987fe682a1f5473224fe3e80380dmtkleinprivate: 816e714e75c725c987fe682a1f5473224fe3e80380dmtklein const BenchRegistry* fBenches; 817e714e75c725c987fe682a1f5473224fe3e80380dmtklein const skiagm::GMRegistry* fGMs; 81892007583e43115998412ac8b0a06cc2780eb025cmtklein SkIRect fClip; 81992007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkScalar> fScales; 82092007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkString> fSKPs; 8215b69377507478623dcf5b11f3ecb010f87c4794frobertphillips SkTArray<bool> fUseMPDs; 82295f192d19938b98a45dd1fa4112d965f60d10516msarett SkTArray<SkString> fImages; 82395f192d19938b98a45dd1fa4112d965f60d10516msarett SkTArray<SkColorType> fColorTypes; 824261c3ad7fde95748da92550735decc949dc73bf2joshualitt SkScalar fZoomScale; 825261c3ad7fde95748da92550735decc949dc73bf2joshualitt int fZoomSteps; 82692007583e43115998412ac8b0a06cc2780eb025cmtklein 827051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein double fSKPBytes, fSKPOps; 828051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein 829fd731ce804cd3223318f3feee2c98404890b65f2mtklein const char* fSourceType; // What we're benching: bench, GM, SKP, ... 830fd731ce804cd3223318f3feee2c98404890b65f2mtklein const char* fBenchType; // How we bench it: micro, recording, playback, ... 831fd731ce804cd3223318f3feee2c98404890b65f2mtklein int fCurrentRecording; 83292007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentScale; 83392007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentSKP; 8345b69377507478623dcf5b11f3ecb010f87c4794frobertphillips int fCurrentUseMPD; 83560869a42a133942f852dd0f1696444c2a5c9ad83scroggo int fCurrentCodec; 83695f192d19938b98a45dd1fa4112d965f60d10516msarett int fCurrentImage; 83795f192d19938b98a45dd1fa4112d965f60d10516msarett int fCurrentSubsetImage; 83895f192d19938b98a45dd1fa4112d965f60d10516msarett int fCurrentColorType; 839261c3ad7fde95748da92550735decc949dc73bf2joshualitt int fCurrentAnimSKP; 84095f192d19938b98a45dd1fa4112d965f60d10516msarett const int fDivisor; 841e714e75c725c987fe682a1f5473224fe3e80380dmtklein}; 842e714e75c725c987fe682a1f5473224fe3e80380dmtklein 8433b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorioint nanobench_main(); 84417f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclarkint nanobench_main() { 8453b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio SetupCrashHandler(); 846f372321de3d4183de5b9ca436e677e471e358f31mtklein SkAutoGraphics ag; 8474f10844149bbc05f0259a1b3199c2f995756ed60mtklein SkTaskGroup::Enabler enabled; 848f372321de3d4183de5b9ca436e677e471e358f31mtklein 84969a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#if SK_SUPPORT_GPU 850682c269a1511200322916af83053e26004c0ec40bsalomon GrContextOptions grContextOpts; 85112b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks; 85212b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski gGrFactory.reset(SkNEW_ARGS(GrContextFactory, (grContextOpts))); 85369a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#endif 85469a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski 85506cddec8570cbf29f89e89736afb0487b5b95abdbsalomon if (FLAGS_veryVerbose) { 85606cddec8570cbf29f89e89736afb0487b5b95abdbsalomon FLAGS_verbose = true; 85706cddec8570cbf29f89e89736afb0487b5b95abdbsalomon } 85806cddec8570cbf29f89e89736afb0487b5b95abdbsalomon 8596eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 860a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_samples = 1; 861a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_gpuFrameLag = 0; 862a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 863a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 8646eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!FLAGS_writePath.isEmpty()) { 8656eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); 8666eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(FLAGS_writePath[0])) { 8676eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_writePath[0]); 8686eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon FLAGS_writePath.set(0, NULL); 8696eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 8706eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 8716eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 8721915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkAutoTDelete<ResultsWriter> log(SkNEW(ResultsWriter)); 87360317d0ffb5053df7b08a627d6decd11b684e80dmtklein if (!FLAGS_outResultsFile.isEmpty()) { 8741915b62637bea20e1471a8a358b22e9e47a4a385mtklein log.reset(SkNEW(NanoJSONResultsWriter(FLAGS_outResultsFile[0]))); 87560317d0ffb5053df7b08a627d6decd11b684e80dmtklein } 876bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 8771915b62637bea20e1471a8a358b22e9e47a4a385mtklein if (1 == FLAGS_properties.count() % 2) { 8781915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkDebugf("ERROR: --properties must be passed with an even number of arguments.\n"); 879bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio return 1; 880bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 8811915b62637bea20e1471a8a358b22e9e47a4a385mtklein for (int i = 1; i < FLAGS_properties.count(); i += 2) { 8821915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->property(FLAGS_properties[i-1], FLAGS_properties[i]); 883bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 88494e51567dd691c3e1e8dfa6005a301d72cecf48emtklein 8851915b62637bea20e1471a8a358b22e9e47a4a385mtklein if (1 == FLAGS_key.count() % 2) { 8861915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkDebugf("ERROR: --key must be passed with an even number of arguments.\n"); 88794e51567dd691c3e1e8dfa6005a301d72cecf48emtklein return 1; 88894e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 8891915b62637bea20e1471a8a358b22e9e47a4a385mtklein for (int i = 1; i < FLAGS_key.count(); i += 2) { 8901915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->key(FLAGS_key[i-1], FLAGS_key[i]); 89194e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 89260317d0ffb5053df7b08a627d6decd11b684e80dmtklein 893f372321de3d4183de5b9ca436e677e471e358f31mtklein const double overhead = estimate_timer_overhead(); 89455b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead)); 895912947737a973421f4c58682b6171cb5ee00ad3aMike Klein 896bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkAutoTMalloc<double> samples(FLAGS_samples); 897bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 8986eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 8996eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Fixed number of loops; times would only be misleading so we won't print them.\n"); 900a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } else if (FLAGS_verbose) { 901f372321de3d4183de5b9ca436e677e471e358f31mtklein // No header. 902f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 90340b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein SkDebugf("median\tbench\tconfig\n"); 904f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 905d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("curr/maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconfig\tbench\n", 9068247ec313d87afcdd4da59b1f2f0d24e0983e359qiankun.miao FLAGS_samples, "samples"); 907f372321de3d4183de5b9ca436e677e471e358f31mtklein } 908f372321de3d4183de5b9ca436e677e471e358f31mtklein 909c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon SkTDArray<Config> configs; 910c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon create_configs(&configs); 911c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 912e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein int runs = 0; 91392007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream benchStream; 91492007583e43115998412ac8b0a06cc2780eb025cmtklein while (Benchmark* b = benchStream.next()) { 915e714e75c725c987fe682a1f5473224fe3e80380dmtklein SkAutoTDelete<Benchmark> bench(b); 916962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName())) { 917f372321de3d4183de5b9ca436e677e471e358f31mtklein continue; 918f372321de3d4183de5b9ca436e677e471e358f31mtklein } 919f372321de3d4183de5b9ca436e677e471e358f31mtklein 920bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkTDArray<Target*> targets; 921c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon create_targets(&targets, bench.get(), configs); 922f372321de3d4183de5b9ca436e677e471e358f31mtklein 923bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio if (!targets.isEmpty()) { 924962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSize().fY); 925bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio bench->preDraw(); 926bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 927bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int j = 0; j < targets.count(); j++) { 928d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson // During HWUI output this canvas may be NULL. 92975a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson SkCanvas* canvas = targets[j]->getCanvas(); 930c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon const char* config = targets[j]->config.name; 931bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 932d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson targets[j]->setup(); 9335b69377507478623dcf5b11f3ecb010f87c4794frobertphillips bench->perCanvasPreDraw(canvas); 9345b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 935bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein const int loops = 936d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson targets[j]->needsFrameTiming() 93775a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson ? gpu_bench(targets[j], bench.get(), samples.get()) 93875a0ebb0d0bd852e3b068bf14370c6689242a89ctomhudson : cpu_bench(overhead, targets[j], bench.get(), samples.get()); 939f372321de3d4183de5b9ca436e677e471e358f31mtklein 9405b69377507478623dcf5b11f3ecb010f87c4794frobertphillips bench->perCanvasPostDraw(canvas); 9415b69377507478623dcf5b11f3ecb010f87c4794frobertphillips 942d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson if (Benchmark::kNonRendering_Backend != targets[j]->config.backend && 943d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { 9446eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config); 945962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniqueName()); 9466eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon pngFilename.append(".png"); 947d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson write_canvas_png(targets[j], pngFilename); 9486eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 9496eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 9506eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kFailedLoops == loops) { 9512069e220034f09aad2f68b262f395e7c25b3d178mtklein // Can't be timed. A warning note has already been printed. 952e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein continue; 953e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein } 95460317d0ffb5053df7b08a627d6decd11b684e80dmtklein 955e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein Stats stats(samples.get(), FLAGS_samples); 9561915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->config(config); 957962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein log->configOption("name", bench->getName()); 9581915b62637bea20e1471a8a358b22e9e47a4a385mtklein benchStream.fillCurrentOptions(log.get()); 959d968a6f29e92230ee118ec9cdfff0329bf83d602tomhudson targets[j]->fillOptions(log.get()); 960051e56df8f14fae68f0e990f78b85494c2ce4a6bmtklein log->metric("min_ms", stats.min); 961e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein if (runs++ % FLAGS_flushEvery == 0) { 962e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein log->flush(); 963e070c2bf54c451f0126d4ffb3a48bffe1fbfa437mtklein } 96460317d0ffb5053df7b08a627d6decd11b684e80dmtklein 9656eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 966a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein if (targets.count() == 1) { 967a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein config = ""; // Only print the config if we run the same bench on more than one. 968a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 969d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("%4d/%-4dMB\t%s\t%s\n" 970d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getCurrResidentSetSizeMB() 971d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getMaxResidentSetSizeMB() 97253d2562006ee371222963750009a706cfd1a94f7mtklein , bench->getUniqueName() 97353d2562006ee371222963750009a706cfd1a94f7mtklein , config); 974a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } else if (FLAGS_verbose) { 975f372321de3d4183de5b9ca436e677e471e358f31mtklein for (int i = 0; i < FLAGS_samples; i++) { 97655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("%s ", HUMANIZE(samples[i])); 977f372321de3d4183de5b9ca436e677e471e358f31mtklein } 978962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein SkDebugf("%s\n", bench->getUniqueName()); 979f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 980bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein if (targets.count() == 1) { 981f372321de3d4183de5b9ca436e677e471e358f31mtklein config = ""; // Only print the config if we run the same bench on more than one. 982f372321de3d4183de5b9ca436e677e471e358f31mtklein } 983962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein SkDebugf("%s\t%s\t%s\n", HUMANIZE(stats.median), bench->getUniqueName(), config); 984f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 985f372321de3d4183de5b9ca436e677e471e358f31mtklein const double stddev_percent = 100 * sqrt(stats.var) / stats.mean; 986d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein SkDebugf("%4d/%-4dMB\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" 987d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getCurrResidentSetSizeMB() 988d75c466ef57ef4dbdf96390b2c01121e4de36f23mtklein , sk_tools::getMaxResidentSetSizeMB() 989f372321de3d4183de5b9ca436e677e471e358f31mtklein , loops 99055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.min) 99155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.median) 99255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.mean) 99355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.max) 994f372321de3d4183de5b9ca436e677e471e358f31mtklein , stddev_percent 9955d9d10e8217d2138b5514a4d4216f95373240942mtklein , stats.plot.c_str() 996f372321de3d4183de5b9ca436e677e471e358f31mtklein , config 997962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein , bench->getUniqueName() 998f372321de3d4183de5b9ca436e677e471e358f31mtklein ); 999f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1000b12ea41286ce36e085c5a14711da0cf9f240fdf1bsalomon#if SK_SUPPORT_GPU 1001b12ea41286ce36e085c5a14711da0cf9f240fdf1bsalomon if (FLAGS_gpuStats && 100206cddec8570cbf29f89e89736afb0487b5b95abdbsalomon Benchmark::kGPU_Backend == targets[j]->config.backend) { 10036838d854a87e79f1fbb7b89b9f395155ad44dc0amtklein gGrFactory->get(targets[j]->config.ctxType)->printCacheStats(); 1004b12ea41286ce36e085c5a14711da0cf9f240fdf1bsalomon gGrFactory->get(targets[j]->config.ctxType)->printGpuStats(); 100506cddec8570cbf29f89e89736afb0487b5b95abdbsalomon } 100606cddec8570cbf29f89e89736afb0487b5b95abdbsalomon#endif 1007f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1008bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein targets.deleteAll(); 10093944a1d2374d2de8622b0192aa080dba6fb92c76Mike Klein 101006cddec8570cbf29f89e89736afb0487b5b95abdbsalomon#if SK_SUPPORT_GPU 10112354f8432a7205571f04f9638a0018fb0b1fb282bsalomon if (FLAGS_abandonGpuContext) { 101269a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski gGrFactory->abandonContexts(); 10132354f8432a7205571f04f9638a0018fb0b1fb282bsalomon } 10142354f8432a7205571f04f9638a0018fb0b1fb282bsalomon if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { 101569a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski gGrFactory->destroyContexts(); 10163944a1d2374d2de8622b0192aa080dba6fb92c76Mike Klein } 101706cddec8570cbf29f89e89736afb0487b5b95abdbsalomon#endif 1018f372321de3d4183de5b9ca436e677e471e358f31mtklein } 1019f372321de3d4183de5b9ca436e677e471e358f31mtklein 1020e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->bench("memory_usage", 0,0); 1021e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->config("meta"); 1022e109145bf31d63963b3f78c6af6e404d5464a55bmtklein log->metric("max_rss_mb", sk_tools::getMaxResidentSetSizeMB()); 1023e109145bf31d63963b3f78c6af6e404d5464a55bmtklein 1024e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt#if SK_SUPPORT_GPU 1025e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt // Make sure we clean up the global GrContextFactory here, otherwise we might race with the 1026e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt // SkEventTracer destructor 1027e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt gGrFactory.reset(NULL); 1028e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt#endif 1029e0b19d4985846d64bb581013828a9dc5af401a5djoshualitt 1030f372321de3d4183de5b9ca436e677e471e358f31mtklein return 0; 1031f372321de3d4183de5b9ca436e677e471e358f31mtklein} 1032f372321de3d4183de5b9ca436e677e471e358f31mtklein 10333b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio#if !defined SK_BUILD_FOR_IOS 10343b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorioint main(int argc, char** argv) { 10353b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio SkCommandLineFlags::Parse(argc, argv); 10363b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio return nanobench_main(); 10373b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio} 10383b27adef0a52f6d321fdee7412ef69e7a7284bccjcgregorio#endif 1039