nanobench.cpp revision dc5bbab138bfffc85d6ba525d990aad09c322ff6
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 10f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Benchmark.h" 11f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "CrashHandler.h" 12e714e75c725c987fe682a1f5473224fe3e80380dmtklein#include "GMBench.h" 13afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein#include "ProcStats.h" 1460317d0ffb5053df7b08a627d6decd11b684e80dmtklein#include "ResultsWriter.h" 15fd731ce804cd3223318f3feee2c98404890b65f2mtklein#include "RecordingBench.h" 1692007583e43115998412ac8b0a06cc2780eb025cmtklein#include "SKPBench.h" 17f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Stats.h" 18f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Timer.h" 19f372321de3d4183de5b9ca436e677e471e358f31mtklein 202084050a33ae139d0fe9bb680f7905f91139a39fmtklein#include "SkBBHFactory.h" 21f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkCanvas.h" 2217f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclark#include "SkCommonFlags.h" 23f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkForceLinking.h" 24f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkGraphics.h" 252084050a33ae139d0fe9bb680f7905f91139a39fmtklein#include "SkOSFile.h" 262084050a33ae139d0fe9bb680f7905f91139a39fmtklein#include "SkPictureRecorder.h" 27f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkString.h" 28f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkSurface.h" 29f372321de3d4183de5b9ca436e677e471e358f31mtklein 30bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 31bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio #include "gl/GrGLDefines.h" 32bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein #include "GrContextFactory.h" 3369a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski SkAutoTDelete<GrContextFactory> gGrFactory; 34bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 35bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 36f372321de3d4183de5b9ca436e677e471e358f31mtklein__SK_FORCE_IMAGE_DECODER_LINKING; 37f372321de3d4183de5b9ca436e677e471e358f31mtklein 386eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic const int kAutoTuneLoops = -1; 396eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 40b511042bb07a6a289b0d1146cb57f6e8b80580d6mtkleinstatic const int kDefaultLoops = 416eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon#ifdef SK_DEBUG 426eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 1; 43a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein#else 446eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon kAutoTuneLoops; 45a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein#endif 46a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 476eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic SkString loops_help_txt() { 486eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString help; 496eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon help.printf("Number of times to run each bench. Set this to %d to auto-" 506eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon "tune for each bench. Timings are only reported when auto-tuning.", 516eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon kAutoTuneLoops); 526eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return help; 536eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 546eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 556eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonDEFINE_int32(loops, kDefaultLoops, loops_help_txt().c_str()); 566eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 57f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_int32(samples, 10, "Number of samples to measure for each bench."); 58f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_int32(overheadLoops, 100000, "Loops to estimate timer overhead."); 59f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_double(overheadGoal, 0.0001, 60f372321de3d4183de5b9ca436e677e471e358f31mtklein "Loop until timer overhead is at most this fraction of our measurments."); 61bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinDEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); 62bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinDEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allows to lag."); 6312b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevskiDEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling back to " 6412b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski "software path rendering."); 65f372321de3d4183de5b9ca436e677e471e358f31mtklein 6660317d0ffb5053df7b08a627d6decd11b684e80dmtkleinDEFINE_string(outResultsFile, "", "If given, write results here as JSON."); 6755b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinDEFINE_int32(maxCalibrationAttempts, 3, 6855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein "Try up to this many times to guess loops for a bench, or skip the bench."); 6955b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinDEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this."); 7092007583e43115998412ac8b0a06cc2780eb025cmtkleinDEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs."); 7192007583e43115998412ac8b0a06cc2780eb025cmtkleinDEFINE_string(scales, "1.0", "Space-separated scales for SKPs."); 722084050a33ae139d0fe9bb680f7905f91139a39fmtkleinDEFINE_bool(bbh, true, "Build a BBH for SKPs?"); 7392007583e43115998412ac8b0a06cc2780eb025cmtklein 74f372321de3d4183de5b9ca436e677e471e358f31mtkleinstatic SkString humanize(double ms) { 75dc5bbab138bfffc85d6ba525d990aad09c322ff6mtklein if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); 76dc5bbab138bfffc85d6ba525d990aad09c322ff6mtklein if (ms > 1e+3) return SkStringPrintf("%.3gs", ms/1e3); 77dc5bbab138bfffc85d6ba525d990aad09c322ff6mtklein if (ms < 1e-3) return SkStringPrintf("%.3gns", ms*1e6); 786238688af0d758660d344ec047243d4efefd6f4dmtklein#ifdef SK_BUILD_FOR_WIN 79dc5bbab138bfffc85d6ba525d990aad09c322ff6mtklein if (ms < 1) return SkStringPrintf("%.3gus", ms*1e3); 806238688af0d758660d344ec047243d4efefd6f4dmtklein#else 81dc5bbab138bfffc85d6ba525d990aad09c322ff6mtklein if (ms < 1) return SkStringPrintf("%.3gµs", ms*1e3); 826238688af0d758660d344ec047243d4efefd6f4dmtklein#endif 83f372321de3d4183de5b9ca436e677e471e358f31mtklein return SkStringPrintf("%.3gms", ms); 84f372321de3d4183de5b9ca436e677e471e358f31mtklein} 8555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein#define HUMANIZE(ms) humanize(ms).c_str() 86f372321de3d4183de5b9ca436e677e471e358f31mtklein 87bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic double time(int loops, Benchmark* bench, SkCanvas* canvas, SkGLContextHelper* gl) { 886eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (canvas) { 896eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon canvas->clear(SK_ColorWHITE); 906eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 91f372321de3d4183de5b9ca436e677e471e358f31mtklein WallTimer timer; 92bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein timer.start(); 93bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein if (bench) { 94bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein bench->draw(loops, canvas); 95f372321de3d4183de5b9ca436e677e471e358f31mtklein } 96f372321de3d4183de5b9ca436e677e471e358f31mtklein if (canvas) { 97f372321de3d4183de5b9ca436e677e471e358f31mtklein canvas->flush(); 98f372321de3d4183de5b9ca436e677e471e358f31mtklein } 99bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 100bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein if (gl) { 101bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SK_GL(*gl, Flush()); 102bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein gl->swapBuffers(); 103bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 104bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 105bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein timer.end(); 106bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return timer.fWall; 107f372321de3d4183de5b9ca436e677e471e358f31mtklein} 108f372321de3d4183de5b9ca436e677e471e358f31mtklein 109bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic double estimate_timer_overhead() { 110bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein double overhead = 0; 111bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_overheadLoops; i++) { 112bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein overhead += time(1, NULL, NULL, NULL); 113bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 114bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return overhead / FLAGS_overheadLoops; 115bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 116f372321de3d4183de5b9ca436e677e471e358f31mtklein 11755b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinstatic int clamp_loops(int loops) { 11855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops < 1) { 11955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("ERROR: clamping loops from %d to 1.\n", loops); 12055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return 1; 12155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 12255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops > FLAGS_maxLoops) { 12355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("WARNING: clamping loops from %d to FLAGS_maxLoops, %d.\n", loops, FLAGS_maxLoops); 12455b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return FLAGS_maxLoops; 12555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 12655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return loops; 12755b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein} 12855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein 1296eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic bool write_canvas_png(SkCanvas* canvas, const SkString& filename) { 1306eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (filename.isEmpty()) { 1316eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1326eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 133e5ea500d4714a7d84de2bf913e81be3b65d2de68reed if (kUnknown_SkColorType == canvas->imageInfo().colorType()) { 1346eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1356eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1366eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkBitmap bmp; 1376eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon bmp.setInfo(canvas->imageInfo()); 1386eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!canvas->readPixels(&bmp, 0, 0)) { 1396eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't read canvas pixels.\n"); 1406eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1416eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1426eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString dir = SkOSPath::Dirname(filename.c_str()); 1436eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(dir.c_str())) { 1446eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't make dir %s.\n", dir.c_str()); 1456eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1466eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1476eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkFILEWStream stream(filename.c_str()); 1486eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!stream.isValid()) { 1496eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't write %s.\n", filename.c_str()); 1506eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1516eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1526eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!SkImageEncoder::EncodeStream(&stream, bmp, SkImageEncoder::kPNG_Type, 100)) { 1536eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't encode a PNG.\n"); 1546eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1556eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1566eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return true; 1576eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 1586eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 1596eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic int kFailedLoops = -2; 160bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic int cpu_bench(const double overhead, Benchmark* bench, SkCanvas* canvas, double* samples) { 161bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First figure out approximately how many loops of bench it takes to make overhead negligible. 1622069e220034f09aad2f68b262f395e7c25b3d178mtklein double bench_plus_overhead = 0.0; 16355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein int round = 0; 1646eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == FLAGS_loops) { 1656eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon while (bench_plus_overhead < overhead) { 1666eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (round++ == FLAGS_maxCalibrationAttempts) { 1676eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skipping.\n", 168962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein bench->getUniqueName(), HUMANIZE(bench_plus_overhead), HUMANIZE(overhead)); 1696eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return kFailedLoops; 1706eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1716eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon bench_plus_overhead = time(1, bench, canvas, NULL); 17255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 1732069e220034f09aad2f68b262f395e7c25b3d178mtklein } 174f372321de3d4183de5b9ca436e677e471e358f31mtklein 175bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Later we'll just start and stop the timer once but loop N times. 176f372321de3d4183de5b9ca436e677e471e358f31mtklein // We'll pick N to make timer overhead negligible: 177f372321de3d4183de5b9ca436e677e471e358f31mtklein // 178bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead 179bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------- < FLAGS_overheadGoal 180bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead + N * Bench Time 181f372321de3d4183de5b9ca436e677e471e358f31mtklein // 182bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // where bench_plus_overhead ≈ overhead + Bench Time. 183f372321de3d4183de5b9ca436e677e471e358f31mtklein // 184f372321de3d4183de5b9ca436e677e471e358f31mtklein // Doing some math, we get: 185f372321de3d4183de5b9ca436e677e471e358f31mtklein // 186bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // (overhead / FLAGS_overheadGoal) - overhead 187bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------------------------ < N 188bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // bench_plus_overhead - overhead) 189f372321de3d4183de5b9ca436e677e471e358f31mtklein // 190f372321de3d4183de5b9ca436e677e471e358f31mtklein // Luckily, this also works well in practice. :) 1916eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon int loops = FLAGS_loops; 1926eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 1936eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double numer = overhead / FLAGS_overheadGoal - overhead; 1946eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double denom = bench_plus_overhead - overhead; 1956eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = (int)ceil(numer / denom); 1966eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1976eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = clamp_loops(loops); 198bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 199bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_samples; i++) { 200bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein samples[i] = time(loops, bench, canvas, NULL) / loops; 201bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 202bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 203f372321de3d4183de5b9ca436e677e471e358f31mtklein} 204f372321de3d4183de5b9ca436e677e471e358f31mtklein 205bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 206bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic int gpu_bench(SkGLContextHelper* gl, 207bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein Benchmark* bench, 208bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkCanvas* canvas, 209bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein double* samples) { 210c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon gl->makeCurrent(); 211bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Make sure we're done with whatever came before. 2129bc86ed0523e154f6f4329f43c15012f930e06d7mtklein SK_GL(*gl, Finish()); 213bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 214bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First, figure out how many loops it'll take to get a frame up to FLAGS_gpuMs. 2156eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon int loops = FLAGS_loops; 2166eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 2176eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = 1; 218a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein double elapsed = 0; 219a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein do { 220a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops *= 2; 221a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // If the GPU lets frames lag at all, we need to make sure we're timing 222a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // _this_ round, not still timing last round. We force this by looping 223a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // more times than any reasonable GPU will allow frames to lag. 224a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein for (int i = 0; i < FLAGS_gpuFrameLag; i++) { 225a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein elapsed = time(loops, bench, canvas, gl); 226a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 227a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } while (elapsed < FLAGS_gpuMs); 228a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 229a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // We've overshot at least a little. Scale back linearly. 230a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); 231a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 232a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // Might as well make sure we're not still timing our calibration. 233a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein SK_GL(*gl, Finish()); 234a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 23555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein loops = clamp_loops(loops); 236bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 237bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Pretty much the same deal as the calibration: do some warmup to make 238bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // sure we're timing steady-state pipelined frames. 239bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_gpuFrameLag; i++) { 240bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein time(loops, bench, canvas, gl); 241f372321de3d4183de5b9ca436e677e471e358f31mtklein } 242bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 243bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Now, actually do the timing! 244bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_samples; i++) { 245bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein samples[i] = time(loops, bench, canvas, gl) / loops; 246bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 247bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 248f372321de3d4183de5b9ca436e677e471e358f31mtklein} 249bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 250bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 251bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic SkString to_lower(const char* str) { 252bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkString lower(str); 253bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (size_t i = 0; i < lower.size(); i++) { 254bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein lower[i] = tolower(lower[i]); 255bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 256bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return lower; 257bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 258bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 259c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstruct Config { 260c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon const char* name; 261bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein Benchmark::Backend backend; 262c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon SkColorType color; 263c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon SkAlphaType alpha; 264c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon int samples; 265c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 266c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GrContextFactory::GLContextType ctxType; 267c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#else 268c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon int bogusInt; 269c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 270c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon}; 271c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 272c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstruct Target { 273c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon explicit Target(const Config& c) : config(c) {} 274c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon const Config config; 275bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkAutoTDelete<SkSurface> surface; 276bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 277bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkGLContextHelper* gl; 278bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 279bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein}; 280f372321de3d4183de5b9ca436e677e471e358f31mtklein 281c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic bool is_cpu_config_allowed(const char* name) { 282bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_config.count(); i++) { 283c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (to_lower(FLAGS_config[i]).equals(name)) { 284c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return true; 285bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 286f372321de3d4183de5b9ca436e677e471e358f31mtklein } 287c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 288bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 289f372321de3d4183de5b9ca436e677e471e358f31mtklein 290c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 291c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextType ctxType, 292c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon int sampleCnt) { 293c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!is_cpu_config_allowed(name)) { 294c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 295c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 29669a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski if (const GrContext* ctx = gGrFactory->get(ctxType)) { 297c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return sampleCnt <= ctx->getMaxSampleCount(); 298c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 299c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 300c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 301c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 302c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 303c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 304c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType GrContextFactory::kNative_GLContextType 305c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#else 306c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType 0 307e714e75c725c987fe682a1f5473224fe3e80380dmtklein#endif 308c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 309c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// Append all configs that are enabled and supported. 310c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic void create_configs(SkTDArray<Config>* configs) { 311c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon #define CPU_CONFIG(name, backend, color, alpha) \ 312c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (is_cpu_config_allowed(#name)) { \ 313c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Config config = { #name, Benchmark::backend, color, alpha, 0, kBogusGLContextType }; \ 314c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon configs->push(config); \ 315f372321de3d4183de5b9ca436e677e471e358f31mtklein } 316e714e75c725c987fe682a1f5473224fe3e80380dmtklein 31740b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_cpu) { 318c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(nonrendering, kNonRendering_Backend, kUnknown_SkColorType, kUnpremul_SkAlphaType) 319c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(8888, kRaster_Backend, kN32_SkColorType, kPremul_SkAlphaType) 320c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(565, kRaster_Backend, kRGB_565_SkColorType, kOpaque_SkAlphaType) 32140b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 322f372321de3d4183de5b9ca436e677e471e358f31mtklein 323bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 324c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon #define GPU_CONFIG(name, ctxType, samples) \ 325c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, samples)) { \ 326c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Config config = { \ 327c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon #name, \ 328c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Benchmark::kGPU_Backend, \ 329c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon kN32_SkColorType, \ 330c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon kPremul_SkAlphaType, \ 331c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon samples, \ 332c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GrContextFactory::ctxType }; \ 333c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon configs->push(config); \ 334f372321de3d4183de5b9ca436e677e471e358f31mtklein } 335e714e75c725c987fe682a1f5473224fe3e80380dmtklein 33640b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_gpu) { 337c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(gpu, kNative_GLContextType, 0) 338c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(msaa4, kNative_GLContextType, 4) 339c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(msaa16, kNative_GLContextType, 16) 340c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4) 341c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16) 342c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(debug, kDebug_GLContextType, 0) 343c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(nullgpu, kNull_GLContextType, 0) 3443b4d077fba1ad037536db198608a940c47d91888bsalomon#ifdef SK_ANGLE 3453b4d077fba1ad037536db198608a940c47d91888bsalomon GPU_CONFIG(angle, kANGLE_GLContextType, 0) 3463b4d077fba1ad037536db198608a940c47d91888bsalomon#endif 34740b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 348bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 349f372321de3d4183de5b9ca436e677e471e358f31mtklein} 350f372321de3d4183de5b9ca436e677e471e358f31mtklein 351c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// If bench is enabled for config, returns a Target* for it, otherwise NULL. 352c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic Target* is_enabled(Benchmark* bench, const Config& config) { 353c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!bench->isSuitableFor(config.backend)) { 354c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return NULL; 355c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 356c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 357e5ea500d4714a7d84de2bf913e81be3b65d2de68reed SkImageInfo info = SkImageInfo::Make(bench->getSize().fX, bench->getSize().fY, 358e5ea500d4714a7d84de2bf913e81be3b65d2de68reed config.color, config.alpha); 359c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 360c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Target* target = new Target(config); 361c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 362c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (Benchmark::kRaster_Backend == config.backend) { 363c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon target->surface.reset(SkSurface::NewRaster(info)); 364c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 365c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 366c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon else if (Benchmark::kGPU_Backend == config.backend) { 36769a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski target->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(config.ctxType), info, 368c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon config.samples)); 36969a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski target->gl = gGrFactory->getGLContext(config.ctxType); 370c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 371c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 372c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 373c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (Benchmark::kNonRendering_Backend != config.backend && !target->surface.get()) { 374c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon delete target; 375c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return NULL; 376c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 377c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return target; 378c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 379c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 380c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// Creates targets for a benchmark and a set of configs. 381c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic void create_targets(SkTDArray<Target*>* targets, Benchmark* b, 382c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon const SkTDArray<Config>& configs) { 383c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon for (int i = 0; i < configs.count(); ++i) { 384c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (Target* t = is_enabled(b, configs[i])) { 385c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon targets->push(t); 386c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 387e714e75c725c987fe682a1f5473224fe3e80380dmtklein 388c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 389c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 390c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 391bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio#if SK_SUPPORT_GPU 392bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregoriostatic void fill_gpu_options(ResultsWriter* log, SkGLContextHelper* ctx) { 39305c4560ab36447895d510655f927fcf123330497jcgregorio const GrGLubyte* version; 394bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SK_GL_RET(*ctx, version, GetString(GR_GL_VERSION)); 395bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio log->configOption("GL_VERSION", (const char*)(version)); 396bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 397bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SK_GL_RET(*ctx, version, GetString(GR_GL_RENDERER)); 398bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio log->configOption("GL_RENDERER", (const char*) version); 399bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 400bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SK_GL_RET(*ctx, version, GetString(GR_GL_VENDOR)); 401bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio log->configOption("GL_VENDOR", (const char*) version); 402bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 403bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SK_GL_RET(*ctx, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); 404bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version); 405bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio} 406bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio#endif 407bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 408e714e75c725c987fe682a1f5473224fe3e80380dmtkleinclass BenchmarkStream { 409e714e75c725c987fe682a1f5473224fe3e80380dmtkleinpublic: 41092007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream() : fBenches(BenchRegistry::Head()) 41192007583e43115998412ac8b0a06cc2780eb025cmtklein , fGMs(skiagm::GMRegistry::Head()) 412fd731ce804cd3223318f3feee2c98404890b65f2mtklein , fCurrentRecording(0) 41392007583e43115998412ac8b0a06cc2780eb025cmtklein , fCurrentScale(0) 41492007583e43115998412ac8b0a06cc2780eb025cmtklein , fCurrentSKP(0) { 41592007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_skps.count(); i++) { 41692007583e43115998412ac8b0a06cc2780eb025cmtklein if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { 41792007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = FLAGS_skps[i]; 41892007583e43115998412ac8b0a06cc2780eb025cmtklein } else { 41992007583e43115998412ac8b0a06cc2780eb025cmtklein SkOSFile::Iter it(FLAGS_skps[i], ".skp"); 42092007583e43115998412ac8b0a06cc2780eb025cmtklein SkString path; 42192007583e43115998412ac8b0a06cc2780eb025cmtklein while (it.next(&path)) { 42292007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str()); 42392007583e43115998412ac8b0a06cc2780eb025cmtklein } 42492007583e43115998412ac8b0a06cc2780eb025cmtklein } 42592007583e43115998412ac8b0a06cc2780eb025cmtklein } 42692007583e43115998412ac8b0a06cc2780eb025cmtklein 42792007583e43115998412ac8b0a06cc2780eb025cmtklein if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d", 42892007583e43115998412ac8b0a06cc2780eb025cmtklein &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom)) { 42992007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0]); 43092007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 43192007583e43115998412ac8b0a06cc2780eb025cmtklein } 43292007583e43115998412ac8b0a06cc2780eb025cmtklein 43392007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_scales.count(); i++) { 43492007583e43115998412ac8b0a06cc2780eb025cmtklein if (1 != sscanf(FLAGS_scales[i], "%f", &fScales.push_back())) { 43592007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --scales as an SkScalar.\n", FLAGS_scales[i]); 43692007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 43792007583e43115998412ac8b0a06cc2780eb025cmtklein } 43892007583e43115998412ac8b0a06cc2780eb025cmtklein } 43992007583e43115998412ac8b0a06cc2780eb025cmtklein } 440e714e75c725c987fe682a1f5473224fe3e80380dmtklein 441fd731ce804cd3223318f3feee2c98404890b65f2mtklein static bool ReadPicture(const char* path, SkAutoTUnref<SkPicture>* pic) { 442fd731ce804cd3223318f3feee2c98404890b65f2mtklein // Not strictly necessary, as it will be checked again later, 443fd731ce804cd3223318f3feee2c98404890b65f2mtklein // but helps to avoid a lot of pointless work if we're going to skip it. 444fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path)) { 445fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 446fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 447fd731ce804cd3223318f3feee2c98404890b65f2mtklein 448fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); 449fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (stream.get() == NULL) { 450fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkDebugf("Could not read %s.\n", path); 451fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 452fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 453fd731ce804cd3223318f3feee2c98404890b65f2mtklein 454963504bd0a8ced7e1177ae136da03a9cc343d886mtklein pic->reset(SkPicture::CreateFromStream(stream.get())); 455fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (pic->get() == NULL) { 456fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkDebugf("Could not read %s as an SkPicture.\n", path); 457fd731ce804cd3223318f3feee2c98404890b65f2mtklein return false; 458fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 459fd731ce804cd3223318f3feee2c98404890b65f2mtklein return true; 460fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 461fd731ce804cd3223318f3feee2c98404890b65f2mtklein 46292007583e43115998412ac8b0a06cc2780eb025cmtklein Benchmark* next() { 463e714e75c725c987fe682a1f5473224fe3e80380dmtklein if (fBenches) { 464e714e75c725c987fe682a1f5473224fe3e80380dmtklein Benchmark* bench = fBenches->factory()(NULL); 465e714e75c725c987fe682a1f5473224fe3e80380dmtklein fBenches = fBenches->next(); 46692007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "bench"; 467fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "micro"; 468e714e75c725c987fe682a1f5473224fe3e80380dmtklein return bench; 469e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 47092007583e43115998412ac8b0a06cc2780eb025cmtklein 471e714e75c725c987fe682a1f5473224fe3e80380dmtklein while (fGMs) { 472e714e75c725c987fe682a1f5473224fe3e80380dmtklein SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(NULL)); 473e714e75c725c987fe682a1f5473224fe3e80380dmtklein fGMs = fGMs->next(); 474e714e75c725c987fe682a1f5473224fe3e80380dmtklein if (gm->getFlags() & skiagm::GM::kAsBench_Flag) { 47592007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "gm"; 476fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "micro"; 477e714e75c725c987fe682a1f5473224fe3e80380dmtklein return SkNEW_ARGS(GMBench, (gm.detach())); 478e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 479e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 48092007583e43115998412ac8b0a06cc2780eb025cmtklein 481fd731ce804cd3223318f3feee2c98404890b65f2mtklein // First add all .skps as RecordingBenches. 482fd731ce804cd3223318f3feee2c98404890b65f2mtklein while (fCurrentRecording < fSKPs.count()) { 483fd731ce804cd3223318f3feee2c98404890b65f2mtklein const SkString& path = fSKPs[fCurrentRecording++]; 484fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkPicture> pic; 485fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (!ReadPicture(path.c_str(), &pic)) { 486fd731ce804cd3223318f3feee2c98404890b65f2mtklein continue; 487fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 488fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkString name = SkOSPath::Basename(path.c_str()); 489fd731ce804cd3223318f3feee2c98404890b65f2mtklein fSourceType = "skp"; 490fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "recording"; 491fd731ce804cd3223318f3feee2c98404890b65f2mtklein return SkNEW_ARGS(RecordingBench, (name.c_str(), pic.get(), FLAGS_bbh)); 492fd731ce804cd3223318f3feee2c98404890b65f2mtklein } 493fd731ce804cd3223318f3feee2c98404890b65f2mtklein 494fd731ce804cd3223318f3feee2c98404890b65f2mtklein // Then once each for each scale as SKPBenches (playback). 49592007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentScale < fScales.count()) { 49692007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentSKP < fSKPs.count()) { 49792007583e43115998412ac8b0a06cc2780eb025cmtklein const SkString& path = fSKPs[fCurrentSKP++]; 498fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkAutoTUnref<SkPicture> pic; 499fd731ce804cd3223318f3feee2c98404890b65f2mtklein if (!ReadPicture(path.c_str(), &pic)) { 50092007583e43115998412ac8b0a06cc2780eb025cmtklein continue; 50192007583e43115998412ac8b0a06cc2780eb025cmtklein } 5022084050a33ae139d0fe9bb680f7905f91139a39fmtklein if (FLAGS_bbh) { 5032084050a33ae139d0fe9bb680f7905f91139a39fmtklein // The SKP we read off disk doesn't have a BBH. Re-record so it grows one. 5042084050a33ae139d0fe9bb680f7905f91139a39fmtklein // Here we use an SkTileGrid with parameters optimized for FLAGS_clip. 5052084050a33ae139d0fe9bb680f7905f91139a39fmtklein const SkTileGridFactory::TileGridInfo info = { 5062084050a33ae139d0fe9bb680f7905f91139a39fmtklein SkISize::Make(fClip.width(), fClip.height()), // tile interval 5072084050a33ae139d0fe9bb680f7905f91139a39fmtklein SkISize::Make(0,0), // margin 5082084050a33ae139d0fe9bb680f7905f91139a39fmtklein SkIPoint::Make(fClip.left(), fClip.top()), // offset 5092084050a33ae139d0fe9bb680f7905f91139a39fmtklein }; 5102084050a33ae139d0fe9bb680f7905f91139a39fmtklein SkTileGridFactory factory(info); 5112084050a33ae139d0fe9bb680f7905f91139a39fmtklein SkPictureRecorder recorder; 512c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips pic->playback(recorder.beginRecording(pic->cullRect().width(), 513ea65bfa8ded918b908287e3e3474aaf5cbd12feamtklein pic->cullRect().height(), 514c5ba71d2e5cd426def66fa49dcf003e5b2c98dc7robertphillips &factory)); 5152084050a33ae139d0fe9bb680f7905f91139a39fmtklein pic.reset(recorder.endRecording()); 5162084050a33ae139d0fe9bb680f7905f91139a39fmtklein } 517fd731ce804cd3223318f3feee2c98404890b65f2mtklein SkString name = SkOSPath::Basename(path.c_str()); 51892007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "skp"; 519fd731ce804cd3223318f3feee2c98404890b65f2mtklein fBenchType = "playback"; 52092007583e43115998412ac8b0a06cc2780eb025cmtklein return SkNEW_ARGS(SKPBench, 52192007583e43115998412ac8b0a06cc2780eb025cmtklein (name.c_str(), pic.get(), fClip, fScales[fCurrentScale])); 52292007583e43115998412ac8b0a06cc2780eb025cmtklein } 52392007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentSKP = 0; 52492007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentScale++; 52592007583e43115998412ac8b0a06cc2780eb025cmtklein } 52692007583e43115998412ac8b0a06cc2780eb025cmtklein 527e714e75c725c987fe682a1f5473224fe3e80380dmtklein return NULL; 528e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 52992007583e43115998412ac8b0a06cc2780eb025cmtklein 53092007583e43115998412ac8b0a06cc2780eb025cmtklein void fillCurrentOptions(ResultsWriter* log) const { 53192007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("source_type", fSourceType); 532fd731ce804cd3223318f3feee2c98404890b65f2mtklein log->configOption("bench_type", fBenchType); 53392007583e43115998412ac8b0a06cc2780eb025cmtklein if (0 == strcmp(fSourceType, "skp")) { 53492007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("clip", 53592007583e43115998412ac8b0a06cc2780eb025cmtklein SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, 53692007583e43115998412ac8b0a06cc2780eb025cmtklein fClip.fRight, fClip.fBottom).c_str()); 53792007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentScale]).c_str()); 53892007583e43115998412ac8b0a06cc2780eb025cmtklein } 53992007583e43115998412ac8b0a06cc2780eb025cmtklein } 54092007583e43115998412ac8b0a06cc2780eb025cmtklein 541e714e75c725c987fe682a1f5473224fe3e80380dmtkleinprivate: 542e714e75c725c987fe682a1f5473224fe3e80380dmtklein const BenchRegistry* fBenches; 543e714e75c725c987fe682a1f5473224fe3e80380dmtklein const skiagm::GMRegistry* fGMs; 54492007583e43115998412ac8b0a06cc2780eb025cmtklein SkIRect fClip; 54592007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkScalar> fScales; 54692007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkString> fSKPs; 54792007583e43115998412ac8b0a06cc2780eb025cmtklein 548fd731ce804cd3223318f3feee2c98404890b65f2mtklein const char* fSourceType; // What we're benching: bench, GM, SKP, ... 549fd731ce804cd3223318f3feee2c98404890b65f2mtklein const char* fBenchType; // How we bench it: micro, recording, playback, ... 550fd731ce804cd3223318f3feee2c98404890b65f2mtklein int fCurrentRecording; 55192007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentScale; 55292007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentSKP; 553e714e75c725c987fe682a1f5473224fe3e80380dmtklein}; 554e714e75c725c987fe682a1f5473224fe3e80380dmtklein 55517f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclarkint nanobench_main(); 55617f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclarkint nanobench_main() { 557f372321de3d4183de5b9ca436e677e471e358f31mtklein SetupCrashHandler(); 558f372321de3d4183de5b9ca436e677e471e358f31mtklein SkAutoGraphics ag; 559f372321de3d4183de5b9ca436e677e471e358f31mtklein 56069a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#if SK_SUPPORT_GPU 56112b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski GrContext::Options grContextOpts; 56212b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks; 56312b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski gGrFactory.reset(SkNEW_ARGS(GrContextFactory, (grContextOpts))); 56469a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#endif 56569a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski 5666eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 567a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_samples = 1; 568a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_gpuFrameLag = 0; 569a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 570a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 5716eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!FLAGS_writePath.isEmpty()) { 5726eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); 5736eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(FLAGS_writePath[0])) { 5746eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_writePath[0]); 5756eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon FLAGS_writePath.set(0, NULL); 5766eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 5776eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 5786eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 5791915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkAutoTDelete<ResultsWriter> log(SkNEW(ResultsWriter)); 58060317d0ffb5053df7b08a627d6decd11b684e80dmtklein if (!FLAGS_outResultsFile.isEmpty()) { 5811915b62637bea20e1471a8a358b22e9e47a4a385mtklein log.reset(SkNEW(NanoJSONResultsWriter(FLAGS_outResultsFile[0]))); 58260317d0ffb5053df7b08a627d6decd11b684e80dmtklein } 583bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 5841915b62637bea20e1471a8a358b22e9e47a4a385mtklein if (1 == FLAGS_properties.count() % 2) { 5851915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkDebugf("ERROR: --properties must be passed with an even number of arguments.\n"); 586bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio return 1; 587bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 5881915b62637bea20e1471a8a358b22e9e47a4a385mtklein for (int i = 1; i < FLAGS_properties.count(); i += 2) { 5891915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->property(FLAGS_properties[i-1], FLAGS_properties[i]); 590bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 59194e51567dd691c3e1e8dfa6005a301d72cecf48emtklein 5921915b62637bea20e1471a8a358b22e9e47a4a385mtklein if (1 == FLAGS_key.count() % 2) { 5931915b62637bea20e1471a8a358b22e9e47a4a385mtklein SkDebugf("ERROR: --key must be passed with an even number of arguments.\n"); 59494e51567dd691c3e1e8dfa6005a301d72cecf48emtklein return 1; 59594e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 5961915b62637bea20e1471a8a358b22e9e47a4a385mtklein for (int i = 1; i < FLAGS_key.count(); i += 2) { 5971915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->key(FLAGS_key[i-1], FLAGS_key[i]); 59894e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 59960317d0ffb5053df7b08a627d6decd11b684e80dmtklein 600f372321de3d4183de5b9ca436e677e471e358f31mtklein const double overhead = estimate_timer_overhead(); 60155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead)); 602912947737a973421f4c58682b6171cb5ee00ad3aMike Klein 603bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkAutoTMalloc<double> samples(FLAGS_samples); 604bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 6056eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 6066eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Fixed number of loops; times would only be misleading so we won't print them.\n"); 607a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } else if (FLAGS_verbose) { 608f372321de3d4183de5b9ca436e677e471e358f31mtklein // No header. 609f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 61040b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein SkDebugf("median\tbench\tconfig\n"); 611f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 6128247ec313d87afcdd4da59b1f2f0d24e0983e359qiankun.miao SkDebugf("maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\t%-*s\tconfig\tbench\n", 6138247ec313d87afcdd4da59b1f2f0d24e0983e359qiankun.miao FLAGS_samples, "samples"); 614f372321de3d4183de5b9ca436e677e471e358f31mtklein } 615f372321de3d4183de5b9ca436e677e471e358f31mtklein 616c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon SkTDArray<Config> configs; 617c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon create_configs(&configs); 618c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 61992007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream benchStream; 62092007583e43115998412ac8b0a06cc2780eb025cmtklein while (Benchmark* b = benchStream.next()) { 621e714e75c725c987fe682a1f5473224fe3e80380dmtklein SkAutoTDelete<Benchmark> bench(b); 622962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getUniqueName())) { 623f372321de3d4183de5b9ca436e677e471e358f31mtklein continue; 624f372321de3d4183de5b9ca436e677e471e358f31mtklein } 625f372321de3d4183de5b9ca436e677e471e358f31mtklein 626bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkTDArray<Target*> targets; 627c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon create_targets(&targets, bench.get(), configs); 628f372321de3d4183de5b9ca436e677e471e358f31mtklein 629bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio if (!targets.isEmpty()) { 630962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSize().fY); 631bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio bench->preDraw(); 632bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 633bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int j = 0; j < targets.count(); j++) { 634bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->getCanvas() : NULL; 635c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon const char* config = targets[j]->config.name; 636bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 637bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein const int loops = 638bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 639c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Benchmark::kGPU_Backend == targets[j]->config.backend 640bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein ? gpu_bench(targets[j]->gl, bench.get(), canvas, samples.get()) 641bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein : 642bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 643bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein cpu_bench( overhead, bench.get(), canvas, samples.get()); 644f372321de3d4183de5b9ca436e677e471e358f31mtklein 64549f085dddff10473b6ebf832a974288300224e60bsalomon if (canvas && !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { 6466eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config); 647962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniqueName()); 6486eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon pngFilename.append(".png"); 6496eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon write_canvas_png(canvas, pngFilename); 6506eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 6516eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 6526eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kFailedLoops == loops) { 6532069e220034f09aad2f68b262f395e7c25b3d178mtklein // Can't be timed. A warning note has already been printed. 654e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein continue; 655e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein } 65660317d0ffb5053df7b08a627d6decd11b684e80dmtklein 657e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein Stats stats(samples.get(), FLAGS_samples); 6581915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->config(config); 659962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein log->configOption("name", bench->getName()); 6601915b62637bea20e1471a8a358b22e9e47a4a385mtklein benchStream.fillCurrentOptions(log.get()); 661bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio#if SK_SUPPORT_GPU 662c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (Benchmark::kGPU_Backend == targets[j]->config.backend) { 6631915b62637bea20e1471a8a358b22e9e47a4a385mtklein fill_gpu_options(log.get(), targets[j]->gl); 664bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 665bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio#endif 6661915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->timer("min_ms", stats.min); 6671915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->timer("median_ms", stats.median); 6681915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->timer("mean_ms", stats.mean); 6691915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->timer("max_ms", stats.max); 6701915b62637bea20e1471a8a358b22e9e47a4a385mtklein log->timer("stddev_ms", sqrt(stats.var)); 67160317d0ffb5053df7b08a627d6decd11b684e80dmtklein 6726eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 673a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein if (targets.count() == 1) { 674a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein config = ""; // Only print the config if we run the same bench on more than one. 675a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 67653d2562006ee371222963750009a706cfd1a94f7mtklein SkDebugf("%4dM\t%s\t%s\n" 67753d2562006ee371222963750009a706cfd1a94f7mtklein , sk_tools::getMaxResidentSetSizeMB() 67853d2562006ee371222963750009a706cfd1a94f7mtklein , bench->getUniqueName() 67953d2562006ee371222963750009a706cfd1a94f7mtklein , config); 680a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } else if (FLAGS_verbose) { 681f372321de3d4183de5b9ca436e677e471e358f31mtklein for (int i = 0; i < FLAGS_samples; i++) { 68255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("%s ", HUMANIZE(samples[i])); 683f372321de3d4183de5b9ca436e677e471e358f31mtklein } 684962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein SkDebugf("%s\n", bench->getUniqueName()); 685f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 686bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein if (targets.count() == 1) { 687f372321de3d4183de5b9ca436e677e471e358f31mtklein config = ""; // Only print the config if we run the same bench on more than one. 688f372321de3d4183de5b9ca436e677e471e358f31mtklein } 689962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein SkDebugf("%s\t%s\t%s\n", HUMANIZE(stats.median), bench->getUniqueName(), config); 690f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 691f372321de3d4183de5b9ca436e677e471e358f31mtklein const double stddev_percent = 100 * sqrt(stats.var) / stats.mean; 692afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein SkDebugf("%4dM\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" 693afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein , sk_tools::getMaxResidentSetSizeMB() 694f372321de3d4183de5b9ca436e677e471e358f31mtklein , loops 69555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.min) 69655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.median) 69755b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.mean) 69855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.max) 699f372321de3d4183de5b9ca436e677e471e358f31mtklein , stddev_percent 7005d9d10e8217d2138b5514a4d4216f95373240942mtklein , stats.plot.c_str() 701f372321de3d4183de5b9ca436e677e471e358f31mtklein , config 702962890568ddac03d8eb8467a2e81b6f2b7f046f0mtklein , bench->getUniqueName() 703f372321de3d4183de5b9ca436e677e471e358f31mtklein ); 704f372321de3d4183de5b9ca436e677e471e358f31mtklein } 705f372321de3d4183de5b9ca436e677e471e358f31mtklein } 706bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein targets.deleteAll(); 7073944a1d2374d2de8622b0192aa080dba6fb92c76Mike Klein 7083944a1d2374d2de8622b0192aa080dba6fb92c76Mike Klein #if SK_SUPPORT_GPU 7092354f8432a7205571f04f9638a0018fb0b1fb282bsalomon if (FLAGS_abandonGpuContext) { 71069a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski gGrFactory->abandonContexts(); 7112354f8432a7205571f04f9638a0018fb0b1fb282bsalomon } 7122354f8432a7205571f04f9638a0018fb0b1fb282bsalomon if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { 71369a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski gGrFactory->destroyContexts(); 7143944a1d2374d2de8622b0192aa080dba6fb92c76Mike Klein } 7153944a1d2374d2de8622b0192aa080dba6fb92c76Mike Klein #endif 716f372321de3d4183de5b9ca436e677e471e358f31mtklein } 717f372321de3d4183de5b9ca436e677e471e358f31mtklein 718f372321de3d4183de5b9ca436e677e471e358f31mtklein return 0; 719f372321de3d4183de5b9ca436e677e471e358f31mtklein} 720f372321de3d4183de5b9ca436e677e471e358f31mtklein 721f372321de3d4183de5b9ca436e677e471e358f31mtklein#if !defined SK_BUILD_FOR_IOS 72217f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclarkint main(int argc, char** argv) { 72317f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclark SkCommandLineFlags::Parse(argc, argv); 72417f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclark return nanobench_main(); 725f372321de3d4183de5b9ca436e677e471e358f31mtklein} 726f372321de3d4183de5b9ca436e677e471e358f31mtklein#endif 727