nanobench.cpp revision afb4379dbca4d4d3824ace183a7348d24bc1589f
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" 1592007583e43115998412ac8b0a06cc2780eb025cmtklein#include "SKPBench.h" 16f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Stats.h" 17f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "Timer.h" 18f372321de3d4183de5b9ca436e677e471e358f31mtklein 1992007583e43115998412ac8b0a06cc2780eb025cmtklein#include "SkOSFile.h" 20f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkCanvas.h" 2117f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclark#include "SkCommonFlags.h" 22f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkForceLinking.h" 23f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkGraphics.h" 24f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkString.h" 25f372321de3d4183de5b9ca436e677e471e358f31mtklein#include "SkSurface.h" 26f372321de3d4183de5b9ca436e677e471e358f31mtklein 27bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 28bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio #include "gl/GrGLDefines.h" 29bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein #include "GrContextFactory.h" 3069a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski SkAutoTDelete<GrContextFactory> gGrFactory; 31bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 32bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 33f372321de3d4183de5b9ca436e677e471e358f31mtklein__SK_FORCE_IMAGE_DECODER_LINKING; 34f372321de3d4183de5b9ca436e677e471e358f31mtklein 356eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic const int kAutoTuneLoops = -1; 366eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 37b511042bb07a6a289b0d1146cb57f6e8b80580d6mtkleinstatic const int kDefaultLoops = 386eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon#ifdef SK_DEBUG 396eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 1; 40a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein#else 416eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon kAutoTuneLoops; 42a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein#endif 43a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 446eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic SkString loops_help_txt() { 456eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString help; 466eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon help.printf("Number of times to run each bench. Set this to %d to auto-" 476eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon "tune for each bench. Timings are only reported when auto-tuning.", 486eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon kAutoTuneLoops); 496eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return help; 506eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 516eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 526eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonDEFINE_int32(loops, kDefaultLoops, loops_help_txt().c_str()); 536eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 54f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_int32(samples, 10, "Number of samples to measure for each bench."); 55f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_int32(overheadLoops, 100000, "Loops to estimate timer overhead."); 56f372321de3d4183de5b9ca436e677e471e358f31mtkleinDEFINE_double(overheadGoal, 0.0001, 57f372321de3d4183de5b9ca436e677e471e358f31mtklein "Loop until timer overhead is at most this fraction of our measurments."); 58bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinDEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); 59bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinDEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allows to lag."); 6012b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevskiDEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling back to " 6112b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski "software path rendering."); 62f372321de3d4183de5b9ca436e677e471e358f31mtklein 6360317d0ffb5053df7b08a627d6decd11b684e80dmtkleinDEFINE_string(outResultsFile, "", "If given, write results here as JSON."); 6455b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinDEFINE_int32(maxCalibrationAttempts, 3, 6555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein "Try up to this many times to guess loops for a bench, or skip the bench."); 6655b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinDEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this."); 6794e51567dd691c3e1e8dfa6005a301d72cecf48emtkleinDEFINE_string(key, "", 6894e51567dd691c3e1e8dfa6005a301d72cecf48emtklein "Space-separated key/value pairs to add to JSON identifying this bench config."); 6994e51567dd691c3e1e8dfa6005a301d72cecf48emtkleinDEFINE_string(options, "", 7094e51567dd691c3e1e8dfa6005a301d72cecf48emtklein "Space-separated option/value pairs to add to JSON, logging extra info."); 71bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorioDEFINE_string(gitHash, "", "Git hash to add to JSON."); 7260317d0ffb5053df7b08a627d6decd11b684e80dmtklein 7392007583e43115998412ac8b0a06cc2780eb025cmtkleinDEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs."); 7492007583e43115998412ac8b0a06cc2780eb025cmtkleinDEFINE_string(scales, "1.0", "Space-separated scales for SKPs."); 7592007583e43115998412ac8b0a06cc2780eb025cmtklein 76f372321de3d4183de5b9ca436e677e471e358f31mtkleinstatic SkString humanize(double ms) { 77f372321de3d4183de5b9ca436e677e471e358f31mtklein if (ms > 1e+3) return SkStringPrintf("%.3gs", ms/1e3); 78f372321de3d4183de5b9ca436e677e471e358f31mtklein if (ms < 1e-3) return SkStringPrintf("%.3gns", ms*1e6); 796238688af0d758660d344ec047243d4efefd6f4dmtklein#ifdef SK_BUILD_FOR_WIN 806238688af0d758660d344ec047243d4efefd6f4dmtklein if (ms < 1) return SkStringPrintf("%.3gus", ms*1e3); 816238688af0d758660d344ec047243d4efefd6f4dmtklein#else 82f372321de3d4183de5b9ca436e677e471e358f31mtklein if (ms < 1) return SkStringPrintf("%.3gµs", ms*1e3); 836238688af0d758660d344ec047243d4efefd6f4dmtklein#endif 84f372321de3d4183de5b9ca436e677e471e358f31mtklein return SkStringPrintf("%.3gms", ms); 85f372321de3d4183de5b9ca436e677e471e358f31mtklein} 8655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein#define HUMANIZE(ms) humanize(ms).c_str() 87f372321de3d4183de5b9ca436e677e471e358f31mtklein 88bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic double time(int loops, Benchmark* bench, SkCanvas* canvas, SkGLContextHelper* gl) { 896eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (canvas) { 906eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon canvas->clear(SK_ColorWHITE); 916eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 92f372321de3d4183de5b9ca436e677e471e358f31mtklein WallTimer timer; 93bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein timer.start(); 94bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein if (bench) { 95bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein bench->draw(loops, canvas); 96f372321de3d4183de5b9ca436e677e471e358f31mtklein } 97f372321de3d4183de5b9ca436e677e471e358f31mtklein if (canvas) { 98f372321de3d4183de5b9ca436e677e471e358f31mtklein canvas->flush(); 99f372321de3d4183de5b9ca436e677e471e358f31mtklein } 100bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 101bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein if (gl) { 102bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SK_GL(*gl, Flush()); 103bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein gl->swapBuffers(); 104bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 105bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 106bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein timer.end(); 107bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return timer.fWall; 108f372321de3d4183de5b9ca436e677e471e358f31mtklein} 109f372321de3d4183de5b9ca436e677e471e358f31mtklein 110bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic double estimate_timer_overhead() { 111bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein double overhead = 0; 112bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_overheadLoops; i++) { 113bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein overhead += time(1, NULL, NULL, NULL); 114bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 115bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return overhead / FLAGS_overheadLoops; 116bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 117f372321de3d4183de5b9ca436e677e471e358f31mtklein 11855b0ffc4861e940d8bcf767ff9abf44ff18545eamtkleinstatic int clamp_loops(int loops) { 11955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops < 1) { 12055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("ERROR: clamping loops from %d to 1.\n", loops); 12155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return 1; 12255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 12355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein if (loops > FLAGS_maxLoops) { 12455b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("WARNING: clamping loops from %d to FLAGS_maxLoops, %d.\n", loops, FLAGS_maxLoops); 12555b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return FLAGS_maxLoops; 12655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 12755b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein return loops; 12855b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein} 12955b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein 1306eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic bool write_canvas_png(SkCanvas* canvas, const SkString& filename) { 1316eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (filename.isEmpty()) { 1326eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1336eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1346eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kUnknown_SkColorType == canvas->imageInfo().fColorType) { 1356eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1366eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1376eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkBitmap bmp; 1386eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon bmp.setInfo(canvas->imageInfo()); 1396eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!canvas->readPixels(&bmp, 0, 0)) { 1406eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't read canvas pixels.\n"); 1416eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1426eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1436eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString dir = SkOSPath::Dirname(filename.c_str()); 1446eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(dir.c_str())) { 1456eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't make dir %s.\n", dir.c_str()); 1466eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1476eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1486eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkFILEWStream stream(filename.c_str()); 1496eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!stream.isValid()) { 1506eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't write %s.\n", filename.c_str()); 1516eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1526eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1536eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!SkImageEncoder::EncodeStream(&stream, bmp, SkImageEncoder::kPNG_Type, 100)) { 1546eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Can't encode a PNG.\n"); 1556eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return false; 1566eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1576eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return true; 1586eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon} 1596eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 1606eb03cc06d0bc60da5277a83aa0251a475794b04bsalomonstatic int kFailedLoops = -2; 161bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic int cpu_bench(const double overhead, Benchmark* bench, SkCanvas* canvas, double* samples) { 162bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First figure out approximately how many loops of bench it takes to make overhead negligible. 1632069e220034f09aad2f68b262f395e7c25b3d178mtklein double bench_plus_overhead = 0.0; 16455b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein int round = 0; 1656eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == FLAGS_loops) { 1666eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon while (bench_plus_overhead < overhead) { 1676eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (round++ == FLAGS_maxCalibrationAttempts) { 1686eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("WARNING: Can't estimate loops for %s (%s vs. %s); skipping.\n", 1696eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon bench->getName(), HUMANIZE(bench_plus_overhead), HUMANIZE(overhead)); 1706eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon return kFailedLoops; 1716eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1726eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon bench_plus_overhead = time(1, bench, canvas, NULL); 17355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein } 1742069e220034f09aad2f68b262f395e7c25b3d178mtklein } 175f372321de3d4183de5b9ca436e677e471e358f31mtklein 176bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Later we'll just start and stop the timer once but loop N times. 177f372321de3d4183de5b9ca436e677e471e358f31mtklein // We'll pick N to make timer overhead negligible: 178f372321de3d4183de5b9ca436e677e471e358f31mtklein // 179bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead 180bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------- < FLAGS_overheadGoal 181bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // overhead + N * Bench Time 182f372321de3d4183de5b9ca436e677e471e358f31mtklein // 183bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // where bench_plus_overhead ≈ overhead + Bench Time. 184f372321de3d4183de5b9ca436e677e471e358f31mtklein // 185f372321de3d4183de5b9ca436e677e471e358f31mtklein // Doing some math, we get: 186f372321de3d4183de5b9ca436e677e471e358f31mtklein // 187bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // (overhead / FLAGS_overheadGoal) - overhead 188bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // ------------------------------------------ < N 189bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // bench_plus_overhead - overhead) 190f372321de3d4183de5b9ca436e677e471e358f31mtklein // 191f372321de3d4183de5b9ca436e677e471e358f31mtklein // Luckily, this also works well in practice. :) 1926eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon int loops = FLAGS_loops; 1936eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 1946eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double numer = overhead / FLAGS_overheadGoal - overhead; 1956eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon const double denom = bench_plus_overhead - overhead; 1966eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = (int)ceil(numer / denom); 1976eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 1986eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = clamp_loops(loops); 199bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 200bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_samples; i++) { 201bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein samples[i] = time(loops, bench, canvas, NULL) / loops; 202bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 203bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 204f372321de3d4183de5b9ca436e677e471e358f31mtklein} 205f372321de3d4183de5b9ca436e677e471e358f31mtklein 206bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 207bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic int gpu_bench(SkGLContextHelper* gl, 208bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein Benchmark* bench, 209bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkCanvas* canvas, 210bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein double* samples) { 211c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon gl->makeCurrent(); 212bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Make sure we're done with whatever came before. 2139bc86ed0523e154f6f4329f43c15012f930e06d7mtklein SK_GL(*gl, Finish()); 214bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 215bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // First, figure out how many loops it'll take to get a frame up to FLAGS_gpuMs. 2166eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon int loops = FLAGS_loops; 2176eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops == loops) { 2186eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon loops = 1; 219a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein double elapsed = 0; 220a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein do { 221a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops *= 2; 222a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // If the GPU lets frames lag at all, we need to make sure we're timing 223a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // _this_ round, not still timing last round. We force this by looping 224a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // more times than any reasonable GPU will allow frames to lag. 225a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein for (int i = 0; i < FLAGS_gpuFrameLag; i++) { 226a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein elapsed = time(loops, bench, canvas, gl); 227a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 228a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } while (elapsed < FLAGS_gpuMs); 229a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 230a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // We've overshot at least a little. Scale back linearly. 231a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); 232a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 233a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein // Might as well make sure we're not still timing our calibration. 234a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein SK_GL(*gl, Finish()); 235a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 23655b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein loops = clamp_loops(loops); 237bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 238bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Pretty much the same deal as the calibration: do some warmup to make 239bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // sure we're timing steady-state pipelined frames. 240bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_gpuFrameLag; i++) { 241bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein time(loops, bench, canvas, gl); 242f372321de3d4183de5b9ca436e677e471e358f31mtklein } 243bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 244bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein // Now, actually do the timing! 245bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_samples; i++) { 246bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein samples[i] = time(loops, bench, canvas, gl) / loops; 247bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 248bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return loops; 249f372321de3d4183de5b9ca436e677e471e358f31mtklein} 250bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 251bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 252bb6a02823929584231c8e080ee69e7fb1178cbfbmtkleinstatic SkString to_lower(const char* str) { 253bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkString lower(str); 254bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (size_t i = 0; i < lower.size(); i++) { 255bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein lower[i] = tolower(lower[i]); 256bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 257bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein return lower; 258bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 259bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 260c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstruct Config { 261c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon const char* name; 262bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein Benchmark::Backend backend; 263c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon SkColorType color; 264c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon SkAlphaType alpha; 265c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon int samples; 266c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 267c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GrContextFactory::GLContextType ctxType; 268c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#else 269c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon int bogusInt; 270c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 271c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon}; 272c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 273c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstruct Target { 274c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon explicit Target(const Config& c) : config(c) {} 275c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon const Config config; 276bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkAutoTDelete<SkSurface> surface; 277bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 278bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkGLContextHelper* gl; 279bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 280bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein}; 281f372321de3d4183de5b9ca436e677e471e358f31mtklein 282c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic bool is_cpu_config_allowed(const char* name) { 283bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int i = 0; i < FLAGS_config.count(); i++) { 284c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (to_lower(FLAGS_config[i]).equals(name)) { 285c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return true; 286bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein } 287f372321de3d4183de5b9ca436e677e471e358f31mtklein } 288c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 289bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein} 290f372321de3d4183de5b9ca436e677e471e358f31mtklein 291c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 292c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextType ctxType, 293c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon int sampleCnt) { 294c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!is_cpu_config_allowed(name)) { 295c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 296c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 29769a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski if (const GrContext* ctx = gGrFactory->get(ctxType)) { 298c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return sampleCnt <= ctx->getMaxSampleCount(); 299c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 300c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return false; 301c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 302c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 303c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 304c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 305c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType GrContextFactory::kNative_GLContextType 306c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#else 307c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#define kBogusGLContextType 0 308e714e75c725c987fe682a1f5473224fe3e80380dmtklein#endif 309c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 310c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// Append all configs that are enabled and supported. 311c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic void create_configs(SkTDArray<Config>* configs) { 312c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon #define CPU_CONFIG(name, backend, color, alpha) \ 313c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (is_cpu_config_allowed(#name)) { \ 314c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Config config = { #name, Benchmark::backend, color, alpha, 0, kBogusGLContextType }; \ 315c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon configs->push(config); \ 316f372321de3d4183de5b9ca436e677e471e358f31mtklein } 317e714e75c725c987fe682a1f5473224fe3e80380dmtklein 31840b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_cpu) { 319c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(nonrendering, kNonRendering_Backend, kUnknown_SkColorType, kUnpremul_SkAlphaType) 320c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(8888, kRaster_Backend, kN32_SkColorType, kPremul_SkAlphaType) 321c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon CPU_CONFIG(565, kRaster_Backend, kRGB_565_SkColorType, kOpaque_SkAlphaType) 32240b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 323f372321de3d4183de5b9ca436e677e471e358f31mtklein 324bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 325c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon #define GPU_CONFIG(name, ctxType, samples) \ 326c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, samples)) { \ 327c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Config config = { \ 328c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon #name, \ 329c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Benchmark::kGPU_Backend, \ 330c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon kN32_SkColorType, \ 331c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon kPremul_SkAlphaType, \ 332c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon samples, \ 333c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GrContextFactory::ctxType }; \ 334c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon configs->push(config); \ 335f372321de3d4183de5b9ca436e677e471e358f31mtklein } 336e714e75c725c987fe682a1f5473224fe3e80380dmtklein 33740b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein if (FLAGS_gpu) { 338c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(gpu, kNative_GLContextType, 0) 339c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(msaa4, kNative_GLContextType, 4) 340c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(msaa16, kNative_GLContextType, 16) 341c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4) 342c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16) 343c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(debug, kDebug_GLContextType, 0) 344c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon GPU_CONFIG(nullgpu, kNull_GLContextType, 0) 3453b4d077fba1ad037536db198608a940c47d91888bsalomon#ifdef SK_ANGLE 3463b4d077fba1ad037536db198608a940c47d91888bsalomon GPU_CONFIG(angle, kANGLE_GLContextType, 0) 3473b4d077fba1ad037536db198608a940c47d91888bsalomon#endif 34840b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein } 349bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 350f372321de3d4183de5b9ca436e677e471e358f31mtklein} 351f372321de3d4183de5b9ca436e677e471e358f31mtklein 352c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// If bench is enabled for config, returns a Target* for it, otherwise NULL. 353c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic Target* is_enabled(Benchmark* bench, const Config& config) { 354c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (!bench->isSuitableFor(config.backend)) { 355c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return NULL; 356c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 357c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 358c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon SkImageInfo info; 359c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon info.fAlphaType = config.alpha; 360c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon info.fColorType = config.color; 361c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon info.fWidth = bench->getSize().fX; 362c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon info.fHeight = bench->getSize().fY; 363c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 364c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Target* target = new Target(config); 365c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 366c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (Benchmark::kRaster_Backend == config.backend) { 367c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon target->surface.reset(SkSurface::NewRaster(info)); 368c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 369c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#if SK_SUPPORT_GPU 370c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon else if (Benchmark::kGPU_Backend == config.backend) { 37169a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski target->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(config.ctxType), info, 372c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon config.samples)); 37369a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski target->gl = gGrFactory->getGLContext(config.ctxType); 374c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 375c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon#endif 376c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 377c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (Benchmark::kNonRendering_Backend != config.backend && !target->surface.get()) { 378c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon delete target; 379c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return NULL; 380c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 381c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon return target; 382c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 383c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 384c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon// Creates targets for a benchmark and a set of configs. 385c2553373ee982b6c7c753e7e5035523bc01a7291bsalomonstatic void create_targets(SkTDArray<Target*>* targets, Benchmark* b, 386c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon const SkTDArray<Config>& configs) { 387c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon for (int i = 0; i < configs.count(); ++i) { 388c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (Target* t = is_enabled(b, configs[i])) { 389c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon targets->push(t); 390c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 391e714e75c725c987fe682a1f5473224fe3e80380dmtklein 392c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon } 393c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon} 394c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 39560317d0ffb5053df7b08a627d6decd11b684e80dmtkleinstatic void fill_static_options(ResultsWriter* log) { 39660317d0ffb5053df7b08a627d6decd11b684e80dmtklein#if defined(SK_BUILD_FOR_WIN32) 39760317d0ffb5053df7b08a627d6decd11b684e80dmtklein log->option("system", "WIN32"); 39860317d0ffb5053df7b08a627d6decd11b684e80dmtklein#elif defined(SK_BUILD_FOR_MAC) 39960317d0ffb5053df7b08a627d6decd11b684e80dmtklein log->option("system", "MAC"); 40060317d0ffb5053df7b08a627d6decd11b684e80dmtklein#elif defined(SK_BUILD_FOR_ANDROID) 40160317d0ffb5053df7b08a627d6decd11b684e80dmtklein log->option("system", "ANDROID"); 40260317d0ffb5053df7b08a627d6decd11b684e80dmtklein#elif defined(SK_BUILD_FOR_UNIX) 40360317d0ffb5053df7b08a627d6decd11b684e80dmtklein log->option("system", "UNIX"); 40460317d0ffb5053df7b08a627d6decd11b684e80dmtklein#else 40560317d0ffb5053df7b08a627d6decd11b684e80dmtklein log->option("system", "other"); 40660317d0ffb5053df7b08a627d6decd11b684e80dmtklein#endif 40760317d0ffb5053df7b08a627d6decd11b684e80dmtklein} 40860317d0ffb5053df7b08a627d6decd11b684e80dmtklein 409bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio#if SK_SUPPORT_GPU 410bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregoriostatic void fill_gpu_options(ResultsWriter* log, SkGLContextHelper* ctx) { 41105c4560ab36447895d510655f927fcf123330497jcgregorio const GrGLubyte* version; 412bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SK_GL_RET(*ctx, version, GetString(GR_GL_VERSION)); 413bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio log->configOption("GL_VERSION", (const char*)(version)); 414bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 415bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SK_GL_RET(*ctx, version, GetString(GR_GL_RENDERER)); 416bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio log->configOption("GL_RENDERER", (const char*) version); 417bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 418bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SK_GL_RET(*ctx, version, GetString(GR_GL_VENDOR)); 419bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio log->configOption("GL_VENDOR", (const char*) version); 420bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 421bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SK_GL_RET(*ctx, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); 422bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version); 423bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio} 424bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio#endif 425bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 426e714e75c725c987fe682a1f5473224fe3e80380dmtkleinclass BenchmarkStream { 427e714e75c725c987fe682a1f5473224fe3e80380dmtkleinpublic: 42892007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream() : fBenches(BenchRegistry::Head()) 42992007583e43115998412ac8b0a06cc2780eb025cmtklein , fGMs(skiagm::GMRegistry::Head()) 43092007583e43115998412ac8b0a06cc2780eb025cmtklein , fCurrentScale(0) 43192007583e43115998412ac8b0a06cc2780eb025cmtklein , fCurrentSKP(0) { 43292007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_skps.count(); i++) { 43392007583e43115998412ac8b0a06cc2780eb025cmtklein if (SkStrEndsWith(FLAGS_skps[i], ".skp")) { 43492007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = FLAGS_skps[i]; 43592007583e43115998412ac8b0a06cc2780eb025cmtklein } else { 43692007583e43115998412ac8b0a06cc2780eb025cmtklein SkOSFile::Iter it(FLAGS_skps[i], ".skp"); 43792007583e43115998412ac8b0a06cc2780eb025cmtklein SkString path; 43892007583e43115998412ac8b0a06cc2780eb025cmtklein while (it.next(&path)) { 43992007583e43115998412ac8b0a06cc2780eb025cmtklein fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str()); 44092007583e43115998412ac8b0a06cc2780eb025cmtklein } 44192007583e43115998412ac8b0a06cc2780eb025cmtklein } 44292007583e43115998412ac8b0a06cc2780eb025cmtklein } 44392007583e43115998412ac8b0a06cc2780eb025cmtklein 44492007583e43115998412ac8b0a06cc2780eb025cmtklein if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d", 44592007583e43115998412ac8b0a06cc2780eb025cmtklein &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom)) { 44692007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0]); 44792007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 44892007583e43115998412ac8b0a06cc2780eb025cmtklein } 44992007583e43115998412ac8b0a06cc2780eb025cmtklein 45092007583e43115998412ac8b0a06cc2780eb025cmtklein for (int i = 0; i < FLAGS_scales.count(); i++) { 45192007583e43115998412ac8b0a06cc2780eb025cmtklein if (1 != sscanf(FLAGS_scales[i], "%f", &fScales.push_back())) { 45292007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Can't parse %s from --scales as an SkScalar.\n", FLAGS_scales[i]); 45392007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 45492007583e43115998412ac8b0a06cc2780eb025cmtklein } 45592007583e43115998412ac8b0a06cc2780eb025cmtklein } 45692007583e43115998412ac8b0a06cc2780eb025cmtklein } 457e714e75c725c987fe682a1f5473224fe3e80380dmtklein 45892007583e43115998412ac8b0a06cc2780eb025cmtklein Benchmark* next() { 459e714e75c725c987fe682a1f5473224fe3e80380dmtklein if (fBenches) { 460e714e75c725c987fe682a1f5473224fe3e80380dmtklein Benchmark* bench = fBenches->factory()(NULL); 461e714e75c725c987fe682a1f5473224fe3e80380dmtklein fBenches = fBenches->next(); 46292007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "bench"; 463e714e75c725c987fe682a1f5473224fe3e80380dmtklein return bench; 464e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 46592007583e43115998412ac8b0a06cc2780eb025cmtklein 466e714e75c725c987fe682a1f5473224fe3e80380dmtklein while (fGMs) { 467e714e75c725c987fe682a1f5473224fe3e80380dmtklein SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(NULL)); 468e714e75c725c987fe682a1f5473224fe3e80380dmtklein fGMs = fGMs->next(); 469e714e75c725c987fe682a1f5473224fe3e80380dmtklein if (gm->getFlags() & skiagm::GM::kAsBench_Flag) { 47092007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "gm"; 471e714e75c725c987fe682a1f5473224fe3e80380dmtklein return SkNEW_ARGS(GMBench, (gm.detach())); 472e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 473e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 47492007583e43115998412ac8b0a06cc2780eb025cmtklein 47592007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentScale < fScales.count()) { 47692007583e43115998412ac8b0a06cc2780eb025cmtklein while (fCurrentSKP < fSKPs.count()) { 47792007583e43115998412ac8b0a06cc2780eb025cmtklein const SkString& path = fSKPs[fCurrentSKP++]; 47892007583e43115998412ac8b0a06cc2780eb025cmtklein 47992007583e43115998412ac8b0a06cc2780eb025cmtklein // Not strictly necessary, as it will be checked again later, 48092007583e43115998412ac8b0a06cc2780eb025cmtklein // but helps to avoid a lot of pointless work if we're going to skip it. 48192007583e43115998412ac8b0a06cc2780eb025cmtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path.c_str())) { 48292007583e43115998412ac8b0a06cc2780eb025cmtklein continue; 48392007583e43115998412ac8b0a06cc2780eb025cmtklein } 48492007583e43115998412ac8b0a06cc2780eb025cmtklein 48592007583e43115998412ac8b0a06cc2780eb025cmtklein SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path.c_str())); 48692007583e43115998412ac8b0a06cc2780eb025cmtklein if (stream.get() == NULL) { 48792007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Could not read %s.\n", path.c_str()); 48892007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 48992007583e43115998412ac8b0a06cc2780eb025cmtklein } 49092007583e43115998412ac8b0a06cc2780eb025cmtklein 49192007583e43115998412ac8b0a06cc2780eb025cmtklein SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream.get())); 49292007583e43115998412ac8b0a06cc2780eb025cmtklein if (pic.get() == NULL) { 49392007583e43115998412ac8b0a06cc2780eb025cmtklein SkDebugf("Could not read %s as an SkPicture.\n", path.c_str()); 49492007583e43115998412ac8b0a06cc2780eb025cmtklein exit(1); 49592007583e43115998412ac8b0a06cc2780eb025cmtklein } 49692007583e43115998412ac8b0a06cc2780eb025cmtklein 49792007583e43115998412ac8b0a06cc2780eb025cmtklein SkString name = SkOSPath::Basename(path.c_str()); 49892007583e43115998412ac8b0a06cc2780eb025cmtklein 49992007583e43115998412ac8b0a06cc2780eb025cmtklein fSourceType = "skp"; 50092007583e43115998412ac8b0a06cc2780eb025cmtklein return SkNEW_ARGS(SKPBench, 50192007583e43115998412ac8b0a06cc2780eb025cmtklein (name.c_str(), pic.get(), fClip, fScales[fCurrentScale])); 50292007583e43115998412ac8b0a06cc2780eb025cmtklein } 50392007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentSKP = 0; 50492007583e43115998412ac8b0a06cc2780eb025cmtklein fCurrentScale++; 50592007583e43115998412ac8b0a06cc2780eb025cmtklein } 50692007583e43115998412ac8b0a06cc2780eb025cmtklein 507e714e75c725c987fe682a1f5473224fe3e80380dmtklein return NULL; 508e714e75c725c987fe682a1f5473224fe3e80380dmtklein } 50992007583e43115998412ac8b0a06cc2780eb025cmtklein 51092007583e43115998412ac8b0a06cc2780eb025cmtklein void fillCurrentOptions(ResultsWriter* log) const { 51192007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("source_type", fSourceType); 51292007583e43115998412ac8b0a06cc2780eb025cmtklein if (0 == strcmp(fSourceType, "skp")) { 51392007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("clip", 51492007583e43115998412ac8b0a06cc2780eb025cmtklein SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, 51592007583e43115998412ac8b0a06cc2780eb025cmtklein fClip.fRight, fClip.fBottom).c_str()); 51692007583e43115998412ac8b0a06cc2780eb025cmtklein log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentScale]).c_str()); 51792007583e43115998412ac8b0a06cc2780eb025cmtklein } 51892007583e43115998412ac8b0a06cc2780eb025cmtklein } 51992007583e43115998412ac8b0a06cc2780eb025cmtklein 520e714e75c725c987fe682a1f5473224fe3e80380dmtkleinprivate: 521e714e75c725c987fe682a1f5473224fe3e80380dmtklein const BenchRegistry* fBenches; 522e714e75c725c987fe682a1f5473224fe3e80380dmtklein const skiagm::GMRegistry* fGMs; 52392007583e43115998412ac8b0a06cc2780eb025cmtklein SkIRect fClip; 52492007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkScalar> fScales; 52592007583e43115998412ac8b0a06cc2780eb025cmtklein SkTArray<SkString> fSKPs; 52692007583e43115998412ac8b0a06cc2780eb025cmtklein 52792007583e43115998412ac8b0a06cc2780eb025cmtklein const char* fSourceType; 52892007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentScale; 52992007583e43115998412ac8b0a06cc2780eb025cmtklein int fCurrentSKP; 530e714e75c725c987fe682a1f5473224fe3e80380dmtklein}; 531e714e75c725c987fe682a1f5473224fe3e80380dmtklein 53217f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclarkint nanobench_main(); 53317f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclarkint nanobench_main() { 534f372321de3d4183de5b9ca436e677e471e358f31mtklein SetupCrashHandler(); 535f372321de3d4183de5b9ca436e677e471e358f31mtklein SkAutoGraphics ag; 536f372321de3d4183de5b9ca436e677e471e358f31mtklein 53769a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#if SK_SUPPORT_GPU 53812b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski GrContext::Options grContextOpts; 53912b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski grContextOpts.fDrawPathToCompressedTexture = FLAGS_gpuCompressAlphaMasks; 54012b3544028e74712c6c095ed3a2e8a78de6b2ed8krajcevski gGrFactory.reset(SkNEW_ARGS(GrContextFactory, (grContextOpts))); 54169a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski#endif 54269a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski 5436eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 544a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_samples = 1; 545a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein FLAGS_gpuFrameLag = 0; 546a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 547a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein 5486eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!FLAGS_writePath.isEmpty()) { 5496eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); 5506eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (!sk_mkdir(FLAGS_writePath[0])) { 5516eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_writePath[0]); 5526eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon FLAGS_writePath.set(0, NULL); 5536eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 5546eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 5556eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 55660317d0ffb5053df7b08a627d6decd11b684e80dmtklein MultiResultsWriter log; 557bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SkAutoTDelete<NanoJSONResultsWriter> json; 55860317d0ffb5053df7b08a627d6decd11b684e80dmtklein if (!FLAGS_outResultsFile.isEmpty()) { 559bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio const char* gitHash = FLAGS_gitHash.isEmpty() ? "unknown-revision" : FLAGS_gitHash[0]; 560bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio json.reset(SkNEW(NanoJSONResultsWriter(FLAGS_outResultsFile[0], gitHash))); 56160317d0ffb5053df7b08a627d6decd11b684e80dmtklein log.add(json.get()); 56260317d0ffb5053df7b08a627d6decd11b684e80dmtklein } 56360317d0ffb5053df7b08a627d6decd11b684e80dmtklein CallEnd<MultiResultsWriter> ender(log); 564bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio 565bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio if (1 == FLAGS_key.count() % 2) { 566bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio SkDebugf("ERROR: --key must be passed with an even number of arguments.\n"); 567bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio return 1; 568bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 569bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio for (int i = 1; i < FLAGS_key.count(); i += 2) { 570bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio log.key(FLAGS_key[i-1], FLAGS_key[i]); 571bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 57294e51567dd691c3e1e8dfa6005a301d72cecf48emtklein 57360317d0ffb5053df7b08a627d6decd11b684e80dmtklein fill_static_options(&log); 57494e51567dd691c3e1e8dfa6005a301d72cecf48emtklein if (1 == FLAGS_options.count() % 2) { 57594e51567dd691c3e1e8dfa6005a301d72cecf48emtklein SkDebugf("ERROR: --options must be passed with an even number of arguments.\n"); 57694e51567dd691c3e1e8dfa6005a301d72cecf48emtklein return 1; 57794e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 57894e51567dd691c3e1e8dfa6005a301d72cecf48emtklein for (int i = 1; i < FLAGS_options.count(); i += 2) { 57994e51567dd691c3e1e8dfa6005a301d72cecf48emtklein log.option(FLAGS_options[i-1], FLAGS_options[i]); 58094e51567dd691c3e1e8dfa6005a301d72cecf48emtklein } 58160317d0ffb5053df7b08a627d6decd11b684e80dmtklein 582f372321de3d4183de5b9ca436e677e471e358f31mtklein const double overhead = estimate_timer_overhead(); 58355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead)); 584912947737a973421f4c58682b6171cb5ee00ad3aMike Klein 585bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkAutoTMalloc<double> samples(FLAGS_samples); 586bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 5876eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 5886eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkDebugf("Fixed number of loops; times would only be misleading so we won't print them.\n"); 589a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } else if (FLAGS_verbose) { 590f372321de3d4183de5b9ca436e677e471e358f31mtklein // No header. 591f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 59240b32be3718f0f2e01c4a21bb0004b7f93670c42mtklein SkDebugf("median\tbench\tconfig\n"); 593f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 594afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein SkDebugf("maxrss\tloops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\n"); 595f372321de3d4183de5b9ca436e677e471e358f31mtklein } 596f372321de3d4183de5b9ca436e677e471e358f31mtklein 597c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon SkTDArray<Config> configs; 598c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon create_configs(&configs); 599c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon 60092007583e43115998412ac8b0a06cc2780eb025cmtklein BenchmarkStream benchStream; 60192007583e43115998412ac8b0a06cc2780eb025cmtklein while (Benchmark* b = benchStream.next()) { 602e714e75c725c987fe682a1f5473224fe3e80380dmtklein SkAutoTDelete<Benchmark> bench(b); 603f372321de3d4183de5b9ca436e677e471e358f31mtklein if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { 604f372321de3d4183de5b9ca436e677e471e358f31mtklein continue; 605f372321de3d4183de5b9ca436e677e471e358f31mtklein } 606f372321de3d4183de5b9ca436e677e471e358f31mtklein 607bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkTDArray<Target*> targets; 608c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon create_targets(&targets, bench.get(), configs); 609f372321de3d4183de5b9ca436e677e471e358f31mtklein 610bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio if (!targets.isEmpty()) { 611bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio log.bench(bench->getName(), bench->getSize().fX, bench->getSize().fY); 612bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio bench->preDraw(); 613bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 614bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein for (int j = 0; j < targets.count(); j++) { 615bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->getCanvas() : NULL; 616c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon const char* config = targets[j]->config.name; 617bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein 61892007583e43115998412ac8b0a06cc2780eb025cmtklein#if SK_DEBUG 61992007583e43115998412ac8b0a06cc2780eb025cmtklein // skia:2797 Some SKPs SkASSERT in debug mode. Skip them for now. 6206e33e232df34d74c62e51e7e30d3ce90f14b46damtklein if (0 == strcmp("565", config) && SkStrContains(bench->getName(), ".skp")) { 6216e33e232df34d74c62e51e7e30d3ce90f14b46damtklein SkDebugf("Skipping 565 %s. See skia:2797\n", bench->getName()); 62292007583e43115998412ac8b0a06cc2780eb025cmtklein continue; 62392007583e43115998412ac8b0a06cc2780eb025cmtklein } 62492007583e43115998412ac8b0a06cc2780eb025cmtklein#endif 62592007583e43115998412ac8b0a06cc2780eb025cmtklein 626bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein const int loops = 627bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#if SK_SUPPORT_GPU 628c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon Benchmark::kGPU_Backend == targets[j]->config.backend 629bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein ? gpu_bench(targets[j]->gl, bench.get(), canvas, samples.get()) 630bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein : 631bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein#endif 632bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein cpu_bench( overhead, bench.get(), canvas, samples.get()); 633f372321de3d4183de5b9ca436e677e471e358f31mtklein 6346eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (canvas && !FLAGS_writePath.isEmpty() && NULL != FLAGS_writePath[0]) { 6356eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config); 6366eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getName()); 6376eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon pngFilename.append(".png"); 6386eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon write_canvas_png(canvas, pngFilename); 6396eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon } 6406eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon 6416eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kFailedLoops == loops) { 6422069e220034f09aad2f68b262f395e7c25b3d178mtklein // Can't be timed. A warning note has already been printed. 643e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein continue; 644e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein } 64560317d0ffb5053df7b08a627d6decd11b684e80dmtklein 646e3631364e93ee9164f3ce322778d5a50c33f63a6Mike Klein Stats stats(samples.get(), FLAGS_samples); 64760317d0ffb5053df7b08a627d6decd11b684e80dmtklein log.config(config); 64892007583e43115998412ac8b0a06cc2780eb025cmtklein benchStream.fillCurrentOptions(&log); 649bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio#if SK_SUPPORT_GPU 650c2553373ee982b6c7c753e7e5035523bc01a7291bsalomon if (Benchmark::kGPU_Backend == targets[j]->config.backend) { 651bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio fill_gpu_options(&log, targets[j]->gl); 652bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio } 653bf5e5237b8f5dc9288d72e90864d6ba8d4bfbb72jcgregorio#endif 65460317d0ffb5053df7b08a627d6decd11b684e80dmtklein log.timer("min_ms", stats.min); 65560317d0ffb5053df7b08a627d6decd11b684e80dmtklein log.timer("median_ms", stats.median); 65660317d0ffb5053df7b08a627d6decd11b684e80dmtklein log.timer("mean_ms", stats.mean); 65760317d0ffb5053df7b08a627d6decd11b684e80dmtklein log.timer("max_ms", stats.max); 65860317d0ffb5053df7b08a627d6decd11b684e80dmtklein log.timer("stddev_ms", sqrt(stats.var)); 65960317d0ffb5053df7b08a627d6decd11b684e80dmtklein 6606eb03cc06d0bc60da5277a83aa0251a475794b04bsalomon if (kAutoTuneLoops != FLAGS_loops) { 661a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein if (targets.count() == 1) { 662a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein config = ""; // Only print the config if we run the same bench on more than one. 663a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } 664a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein SkDebugf("%s\t%s\n", bench->getName(), config); 665a189ccdb4d5efdbbfa34a26c08656634b615f930mtklein } else if (FLAGS_verbose) { 666f372321de3d4183de5b9ca436e677e471e358f31mtklein for (int i = 0; i < FLAGS_samples; i++) { 66755b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("%s ", HUMANIZE(samples[i])); 668f372321de3d4183de5b9ca436e677e471e358f31mtklein } 669f372321de3d4183de5b9ca436e677e471e358f31mtklein SkDebugf("%s\n", bench->getName()); 670f372321de3d4183de5b9ca436e677e471e358f31mtklein } else if (FLAGS_quiet) { 671bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein if (targets.count() == 1) { 672f372321de3d4183de5b9ca436e677e471e358f31mtklein config = ""; // Only print the config if we run the same bench on more than one. 673f372321de3d4183de5b9ca436e677e471e358f31mtklein } 67455b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein SkDebugf("%s\t%s\t%s\n", HUMANIZE(stats.median), bench->getName(), config); 675f372321de3d4183de5b9ca436e677e471e358f31mtklein } else { 676f372321de3d4183de5b9ca436e677e471e358f31mtklein const double stddev_percent = 100 * sqrt(stats.var) / stats.mean; 677afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein SkDebugf("%4dM\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\t%s\t%s\n" 678afb4379dbca4d4d3824ace183a7348d24bc1589fmtklein , sk_tools::getMaxResidentSetSizeMB() 679f372321de3d4183de5b9ca436e677e471e358f31mtklein , loops 68055b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.min) 68155b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.median) 68255b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.mean) 68355b0ffc4861e940d8bcf767ff9abf44ff18545eamtklein , HUMANIZE(stats.max) 684f372321de3d4183de5b9ca436e677e471e358f31mtklein , stddev_percent 6855d9d10e8217d2138b5514a4d4216f95373240942mtklein , stats.plot.c_str() 686f372321de3d4183de5b9ca436e677e471e358f31mtklein , config 687bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein , bench->getName() 688f372321de3d4183de5b9ca436e677e471e358f31mtklein ); 689f372321de3d4183de5b9ca436e677e471e358f31mtklein } 690f372321de3d4183de5b9ca436e677e471e358f31mtklein } 691bb6a02823929584231c8e080ee69e7fb1178cbfbmtklein targets.deleteAll(); 6923944a1d2374d2de8622b0192aa080dba6fb92c76Mike Klein 6933944a1d2374d2de8622b0192aa080dba6fb92c76Mike Klein #if SK_SUPPORT_GPU 6942354f8432a7205571f04f9638a0018fb0b1fb282bsalomon if (FLAGS_abandonGpuContext) { 69569a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski gGrFactory->abandonContexts(); 6962354f8432a7205571f04f9638a0018fb0b1fb282bsalomon } 6972354f8432a7205571f04f9638a0018fb0b1fb282bsalomon if (FLAGS_resetGpuContext || FLAGS_abandonGpuContext) { 69869a5560ea5a8d26b120f5158e506a163d32b4a27krajcevski gGrFactory->destroyContexts(); 6993944a1d2374d2de8622b0192aa080dba6fb92c76Mike Klein } 7003944a1d2374d2de8622b0192aa080dba6fb92c76Mike Klein #endif 701f372321de3d4183de5b9ca436e677e471e358f31mtklein } 702f372321de3d4183de5b9ca436e677e471e358f31mtklein 703f372321de3d4183de5b9ca436e677e471e358f31mtklein return 0; 704f372321de3d4183de5b9ca436e677e471e358f31mtklein} 705f372321de3d4183de5b9ca436e677e471e358f31mtklein 706f372321de3d4183de5b9ca436e677e471e358f31mtklein#if !defined SK_BUILD_FOR_IOS 70717f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclarkint main(int argc, char** argv) { 70817f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclark SkCommandLineFlags::Parse(argc, argv); 70917f0b6df7248b9bbdaddacc3a6c9c6efe4ae278ecaryclark return nanobench_main(); 710f372321de3d4183de5b9ca436e677e471e358f31mtklein} 711f372321de3d4183de5b9ca436e677e471e358f31mtklein#endif 712