benchmain.cpp revision f168b86d7fafc5c20c87bebc6fd393cb17e120ca
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
7971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
8f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "BenchLogger.h"
9c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#include "BenchTimer.h"
10f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "Benchmark.h"
1130e6e2af14e84216b1c113fd7500d0822bc81daamtklein#include "CrashHandler.h"
12f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina#include "GMBench.h"
13e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#include "ResultsWriter.h"
1473672254a3e498081967d00d27b17ada443e2ab2robertphillips@google.com#include "SkBitmapDevice.h"
15bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkCanvas.h"
1678d0379dcc777b4bc4965cff0c2b3fc44ccaef56mtklein@google.com#include "SkColorPriv.h"
17586db93c447b753364d50fadc5426de4fef9a759sglez@google.com#include "SkCommandLineFlags.h"
181bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com#include "SkData.h"
1982a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com#include "SkDeferredCanvas.h"
203a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkGraphics.h"
21b398fe863860b072306b5297c8095c6d973aba06reed@android.com#include "SkImageEncoder.h"
22c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#include "SkOSFile.h"
236c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkPicture.h"
24770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com#include "SkPictureRecorder.h"
25bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkString.h"
261bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com#include "SkSurface.h"
27fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
28db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#if SK_SUPPORT_GPU
29db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#include "GrContext.h"
30db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#include "GrContextFactory.h"
31db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#include "GrRenderTarget.h"
32db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#include "SkGpuDevice.h"
33db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#include "gl/GrGLDefines.h"
34db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#else
35db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.comclass GrContext;
36db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#endif // SK_SUPPORT_GPU
37db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com
389ef1d21dc8edd167ebbf1ec35f25769f9f6b683bmtklein@google.com#include <limits>
399ef1d21dc8edd167ebbf1ec35f25769f9f6b683bmtklein@google.com
40c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comenum BenchMode {
41c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kNormal_BenchMode,
42c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kDeferred_BenchMode,
43c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kDeferredSilent_BenchMode,
44c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kRecord_BenchMode,
45c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kPictureRecord_BenchMode
46c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com};
47dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comconst char* BenchMode_Name[] = {
48dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    "normal", "deferred", "deferredSilent", "record", "picturerecord"
49dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com};
50515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org
514e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.comstatic const char kDefaultsConfigStr[] = "defaults";
524e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com
53fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org///////////////////////////////////////////////////////////////////////////////
54fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
55bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comclass Iter {
56bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.compublic:
57575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org    Iter() : fBenches(BenchRegistry::Head()), fGMs(skiagm::GMRegistry::Head()) {}
58fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
59f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    Benchmark* next() {
60575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org        if (fBenches) {
61575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            BenchRegistry::Factory f = fBenches->factory();
62575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            fBenches = fBenches->next();
6338aeb0fd7a2bdab5e44531d96045dffe25c8e2b0commit-bot@chromium.org            return (*f)(NULL);
64bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
65575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org
66575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org        while (fGMs) {
67575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(NULL));
68575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            fGMs = fGMs->next();
69575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            if (gm->getFlags() & skiagm::GM::kAsBench_Flag) {
70f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina                return SkNEW_ARGS(GMBench, (gm.detach()));
71575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            }
72575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org        }
73575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org
74bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        return NULL;
75bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
76d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
77bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comprivate:
78575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org    const BenchRegistry* fBenches;
79575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org    const skiagm::GMRegistry* fGMs;
80bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com};
81bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
82bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comstatic void make_filename(const char name[], SkString* path) {
83bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    path->set(name);
84bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    for (int i = 0; name[i]; i++) {
85bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        switch (name[i]) {
86bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '/':
87bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '\\':
88bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ' ':
89bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ':':
90bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                path->writable_str()[i] = '-';
91bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
92bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            default:
93bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
94bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
95bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
96bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
97bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
984c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void saveFile(const char name[], const char config[], const char dir[],
991bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                     const SkImage* image) {
1001bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    SkAutoTUnref<SkData> data(image->encode(SkImageEncoder::kPNG_Type, 100));
1011bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    if (NULL == data.get()) {
1024c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        return;
1034c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
104fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
105c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkString filename;
106c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    make_filename(name, &filename);
107c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    filename.appendf("_%s.png", config);
108c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkString path = SkOSPath::SkPathJoin(dir, filename.c_str());
109c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    ::remove(path.c_str());
1101bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com
111ace135453db02cfe83d7c7bbeaa679f98d18fbe2reed@google.com    SkFILEWStream   stream(path.c_str());
1121bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    stream.write(data->data(), data->size());
1134c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1144c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
11584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.comstatic void perform_clip(SkCanvas* canvas, int w, int h) {
1164c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkRect r;
117fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1184c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(10), SkIntToScalar(10),
1194c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
1204c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kIntersect_Op);
121fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1224c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
1234c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w-10), SkIntToScalar(h-10));
1244c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kXOR_Op);
1254c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1264c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
12784b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.comstatic void perform_rotate(SkCanvas* canvas, int w, int h) {
1284c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
1294c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
130fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1314c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(x, y);
1324c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->rotate(SkIntToScalar(35));
1334c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(-x, -y);
1344c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1354c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
13684b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.comstatic void perform_scale(SkCanvas* canvas, int w, int h) {
137387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
138387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
139fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
140387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(x, y);
141387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    // just enough so we can't take the sprite case
142387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
143387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(-x, -y);
144387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com}
145387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com
1461bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.comstatic SkSurface* make_surface(SkColorType colorType, const SkIPoint& size,
147f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina                               Benchmark::Backend backend, int sampleCount,
1481bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                               GrContext* context) {
1491bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    SkSurface* surface = NULL;
1501bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    SkImageInfo info = SkImageInfo::Make(size.fX, size.fY, colorType,
1511bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                                         kPremul_SkAlphaType);
152fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
153a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    switch (backend) {
154f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina        case Benchmark::kRaster_Backend:
1551bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com            surface = SkSurface::NewRaster(info);
1561bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com            surface->getCanvas()->clear(SK_ColorWHITE);
157a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
158cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
159f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina        case Benchmark::kGPU_Backend: {
1601bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com            surface = SkSurface::NewRenderTarget(context, info, sampleCount);
161a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
162cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
163cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
164f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina        case Benchmark::kPDF_Backend:
165a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        default:
166330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com            SkDEBUGFAIL("unsupported");
167a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    }
1681bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    return surface;
169a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org}
170a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
171cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
172cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comGrContextFactory gContextFactory;
173cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef GrContextFactory::GLContextType GLContextType;
174c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kNative = GrContextFactory::kNative_GLContextType;
175e8989578cd05d4bf6ebe35f0d49afbc3d3bef2edcommit-bot@chromium.orgstatic const GLContextType kNVPR   = GrContextFactory::kNVPR_GLContextType;
176c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#if SK_ANGLE
177c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kANGLE  = GrContextFactory::kANGLE_GLContextType;
178c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#endif
179c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kDebug  = GrContextFactory::kDebug_GLContextType;
180c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kNull   = GrContextFactory::kNull_GLContextType;
181cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#else
182cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef int GLContextType;
183c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kNative = 0, kANGLE = 0, kDebug = 0, kNull = 0;
184c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#endif
185c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
186c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#ifdef SK_DEBUG
187c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const bool kIsDebug = true;
188c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#else
189c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const bool kIsDebug = false;
190cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
191cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com
192c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const struct Config {
1931bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    SkColorType         fColorType;
194c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    const char*         name;
195c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    int                 sampleCount;
196f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    Benchmark::Backend  backend;
197c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    GLContextType       contextType;
198c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    bool                runByDefault;
1994bc1983e01d756ae9c91fd380758457f579d26eareed@android.com} gConfigs[] = {
200f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kN32_SkColorType,     "NONRENDERING", 0, Benchmark::kNonRendering_Backend, kNative, true},
201f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kN32_SkColorType,     "8888",         0, Benchmark::kRaster_Backend,       kNative, true},
202f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kRGB_565_SkColorType, "565",          0, Benchmark::kRaster_Backend,       kNative, true},
203cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
204f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kN32_SkColorType,     "GPU",          0, Benchmark::kGPU_Backend,          kNative, true},
205f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kN32_SkColorType,     "MSAA4",        4, Benchmark::kGPU_Backend,          kNative, false},
206f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kN32_SkColorType,     "MSAA16",      16, Benchmark::kGPU_Backend,          kNative, false},
207f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kN32_SkColorType,     "NVPRMSAA4",    4, Benchmark::kGPU_Backend,          kNVPR,   true},
208f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kN32_SkColorType,     "NVPRMSAA16",  16, Benchmark::kGPU_Backend,          kNVPR,   false},
209d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
210f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kN32_SkColorType,     "ANGLE",        0, Benchmark::kGPU_Backend,          kANGLE,  true},
211cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
212f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kN32_SkColorType,     "Debug",        0, Benchmark::kGPU_Backend,          kDebug,  kIsDebug},
213f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    { kN32_SkColorType,     "NULLGPU",      0, Benchmark::kGPU_Backend,          kNull,   true},
214cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
2154bc1983e01d756ae9c91fd380758457f579d26eareed@android.com};
2164bc1983e01d756ae9c91fd380758457f579d26eareed@android.com
217c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(outDir, "", "If given, image of each bench will be put in outDir.");
218c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(timers, "cg", "Timers to display. "
219c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com              "Options: w(all) W(all, truncated) c(pu) C(pu, truncated) g(pu)");
220c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
221c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(rotate, false,  "Rotate canvas before bench run?");
222c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(scale,  false,  "Scale canvas before bench run?");
223c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(clip,   false,  "Clip canvas before bench run?");
224c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
225c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(forceAA,        true,     "Force anti-aliasing?");
226c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(forceFilter,    false,    "Force bitmap filtering?");
227c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(forceDither, "default", "Force dithering: true, false, or default?");
228c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(forceBlend,     false,    "Force alpha blending?");
229c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
230c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_int32(gpuCacheBytes, -1, "GPU cache size limit in bytes.  0 to disable cache.");
231c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_int32(gpuCacheCount, -1, "GPU cache size limit in object count.  0 to disable cache.");
232c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
2336dda827913a3dbdb84934f4f1d79c0b702169e5ccommit-bot@chromium.orgDEFINE_bool2(leaks, l, false, "show leaked ref cnt'd objects.");
234c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(match, "",  "[~][^]substring[$] [...] of test name to run.\n"
235c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "Multiple matches may be separated by spaces.\n"
236c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "~ causes a matching test to always be skipped\n"
237c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "^ requires the start of the test to match\n"
238c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "$ requires the end of the test to match\n"
239c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "^ and $ requires an exact match\n"
240c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "If a test does not match any list entry,\n"
241c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "it is skipped unless some list entry starts with ~\n");
242c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(mode, "normal",
243c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "normal:         draw to a normal canvas;\n"
244c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "deferred:       draw to a deferred canvas;\n"
245c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "deferredSilent: deferred with silent playback;\n"
246c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "record:         draw to an SkPicture;\n"
247c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "picturerecord:  draw from an SkPicture to an SkPicture.\n");
2484e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.comDEFINE_string(config, kDefaultsConfigStr,
2494e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com              "Run configs given.  By default, runs the configs marked \"runByDefault\" in gConfigs.");
250c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(logFile, "", "Also write stdout here.");
251dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_int32(minMs, 20,  "Shortest time we'll allow a benchmark to run.");
252dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_int32(maxMs, 4000, "Longest time we'll allow a benchmark to run.");
2534bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.orgDEFINE_bool(runOnce, kIsDebug, "Run each bench exactly once and don't report timings.");
254dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_double(error, 0.01,
255dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com              "Ratio of subsequent bench measurements must drop within 1±error to converge.");
256c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per 1000 loops.");
257dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_bool2(verbose, v, false, "Print more.");
258e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.orgDEFINE_string(outResultsFile, "", "If given, the results will be written to the file in JSON format.");
25956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.orgDEFINE_bool(dryRun, false, "Don't actually run the tests, just print what would have been done.");
26056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org
261dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com// Has this bench converged?  First arguments are milliseconds / loop iteration,
262dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com// last is overall runtime in milliseconds.
263dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comstatic bool HasConverged(double prevPerLoop, double currPerLoop, double currRaw) {
264dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    if (currRaw < FLAGS_minMs) {
265dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com        return false;
266dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    }
267dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    const double low = 1 - FLAGS_error, high = 1 + FLAGS_error;
268dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    const double ratio = currPerLoop / prevPerLoop;
269dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    return low < ratio && ratio < high;
270dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com}
27186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com
2725987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv);
2735987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv) {
27430e6e2af14e84216b1c113fd7500d0822bc81daamtklein    SetupCrashHandler();
2756dda827913a3dbdb84934f4f1d79c0b702169e5ccommit-bot@chromium.org    SkCommandLineFlags::Parse(argc, argv);
2764e23068b374023d43c4c725138d523721d975892bsalomon@google.com#if SK_ENABLE_INST_COUNT
2776dda827913a3dbdb84934f4f1d79c0b702169e5ccommit-bot@chromium.org    if (FLAGS_leaks) {
2786dda827913a3dbdb84934f4f1d79c0b702169e5ccommit-bot@chromium.org        gPrintInstCount = true;
2796dda827913a3dbdb84934f4f1d79c0b702169e5ccommit-bot@chromium.org    }
28065a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#endif
2813a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkAutoGraphics ag;
28265a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com
283c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // First, parse some flags.
284f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    BenchLogger logger;
285c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    if (FLAGS_logFile.count()) {
286c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        logger.SetLogFile(FLAGS_logFile[0]);
287c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
28855fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org
289e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    LoggerResultsWriter logWriter(logger, FLAGS_timeFormat[0]);
290e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    MultiResultsWriter writer;
291e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.add(&logWriter);
29261744ec1d2b0e287a652a419dac285c6a803e270commit-bot@chromium.org
293e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    SkAutoTDelete<JSONResultsWriter> jsonWriter;
294e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    if (FLAGS_outResultsFile.count()) {
295e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org        jsonWriter.reset(SkNEW(JSONResultsWriter(FLAGS_outResultsFile[0])));
296e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org        writer.add(jsonWriter.get());
297e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    }
29861744ec1d2b0e287a652a419dac285c6a803e270commit-bot@chromium.org
299e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    // Instantiate after all the writers have been added to writer so that we
300e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    // call close() before their destructors are called on the way out.
301e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    CallEnd<MultiResultsWriter> ender(writer);
302e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org
303c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF;
304c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkTriState::State dither = SkTriState::kDefault;
305c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    for (size_t i = 0; i < 3; i++) {
306c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) {
307c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            dither = static_cast<SkTriState::State>(i);
308c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
309c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
310c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com
311c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    BenchMode benchMode = kNormal_BenchMode;
312c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) {
313c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (strcmp(FLAGS_mode[0], BenchMode_Name[i]) == 0) {
314c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            benchMode = static_cast<BenchMode>(i);
315c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
316c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
317c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com
31813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    SkTDArray<int> configs;
3194e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com    bool runDefaultConfigs = false;
320c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Try user-given configs first.
321c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    for (int i = 0; i < FLAGS_config.count(); i++) {
322e9cd27d4a3c92393cc6c79d4d6f93d266411d95erobertphillips@google.com        for (int j = 0; j < static_cast<int>(SK_ARRAY_COUNT(gConfigs)); ++j) {
323c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (0 == strcmp(FLAGS_config[i], gConfigs[j].name)) {
324c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                *configs.append() = j;
3254e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com            } else if (0 == strcmp(FLAGS_config[i], kDefaultsConfigStr)) {
3264e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com                runDefaultConfigs = true;
327e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            }
328b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
329b398fe863860b072306b5297c8095c6d973aba06reed@android.com    }
330c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // If there weren't any, fill in with defaults.
3314e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com    if (runDefaultConfigs) {
332e9cd27d4a3c92393cc6c79d4d6f93d266411d95erobertphillips@google.com        for (int i = 0; i < static_cast<int>(SK_ARRAY_COUNT(gConfigs)); ++i) {
333c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (gConfigs[i].runByDefault) {
3348a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                *configs.append() = i;
3358a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
33613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        }
33713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    }
338c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Filter out things we can't run.
339c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    if (kNormal_BenchMode != benchMode) {
340604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        // Non-rendering configs only run in normal mode
341604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        for (int i = 0; i < configs.count(); ++i) {
342c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const Config& config = gConfigs[configs[i]];
343f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina            if (Benchmark::kNonRendering_Backend == config.backend) {
344604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                configs.remove(i, 1);
345604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                --i;
346604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            }
347604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        }
348604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com    }
349111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
3508a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com#if SK_SUPPORT_GPU
3518a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    for (int i = 0; i < configs.count(); ++i) {
352c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        const Config& config = gConfigs[configs[i]];
3538a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com
354f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina        if (Benchmark::kGPU_Backend == config.backend) {
355c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            GrContext* context = gContextFactory.get(config.contextType);
3568a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            if (NULL == context) {
3570f298cc12561ce1d59317be0b7ab6938baeaebcdcommit-bot@chromium.org                SkDebugf("GrContext could not be created for config %s. Config will be skipped.\n",
3580f298cc12561ce1d59317be0b7ab6938baeaebcdcommit-bot@chromium.org                    config.name);
3598a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                configs.remove(i);
3608a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                --i;
3618a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                continue;
3628a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
363c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (config.sampleCount > context->getMaxSampleCount()){
3640f298cc12561ce1d59317be0b7ab6938baeaebcdcommit-bot@chromium.org                SkDebugf(
3650f298cc12561ce1d59317be0b7ab6938baeaebcdcommit-bot@chromium.org                    "Sample count (%d) for config %s is not supported. Config will be skipped.\n",
3660f298cc12561ce1d59317be0b7ab6938baeaebcdcommit-bot@chromium.org                    config.sampleCount, config.name);
3678a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                configs.remove(i);
3688a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                --i;
3698a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                continue;
3708a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
3718a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com        }
3728a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    }
3738a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com#endif
3748a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com
375c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // All flags should be parsed now.  Report our settings.
3764bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org    if (FLAGS_runOnce) {
3774bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org        logger.logError("bench was run with --runOnce, so we're going to hide the times."
3784bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org                        " It's for your own good!\n");
379c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
380e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("mode", FLAGS_mode[0]);
381e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("alpha", SkStringPrintf("0x%02X", alpha).c_str());
382e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("antialias", SkStringPrintf("%d", FLAGS_forceAA).c_str());
383e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("filter", SkStringPrintf("%d", FLAGS_forceFilter).c_str());
384e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("dither",  SkTriState::Name[dither]);
385e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org
386e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("rotate", SkStringPrintf("%d", FLAGS_rotate).c_str());
387e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("scale", SkStringPrintf("%d", FLAGS_scale).c_str());
388e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("clip", SkStringPrintf("%d", FLAGS_clip).c_str());
389c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
390a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_BUILD_FOR_WIN32)
391e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("system", "WIN32");
392a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_MAC)
393e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("system", "MAC");
394a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_ANDROID)
395e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("system", "ANDROID");
396a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_UNIX)
397e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("system", "UNIX");
398a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#else
399e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("system", "other");
400a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
401a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
402a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_DEBUG)
403e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("build", "DEBUG");
404e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#else
405e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("build", "RELEASE");
406a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
407508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
408c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Set texture cache limits if non-default.
4095c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
410cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
411c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        const Config& config = gConfigs[i];
412f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina        if (Benchmark::kGPU_Backend != config.backend) {
413c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            continue;
414cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
415c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        GrContext* context = gContextFactory.get(config.contextType);
416c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (NULL == context) {
417c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            continue;
418c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
419c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
420c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        size_t bytes;
421c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        int count;
42295c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org        context->getResourceCacheLimits(&count, &bytes);
423c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (-1 != FLAGS_gpuCacheBytes) {
424c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            bytes = static_cast<size_t>(FLAGS_gpuCacheBytes);
425c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
426c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (-1 != FLAGS_gpuCacheCount) {
427c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            count = FLAGS_gpuCacheCount;
428c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
42995c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org        context->setResourceCacheLimits(count, bytes);
430cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
431cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
43274913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com
433c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Run each bench in each configuration it supports and we asked for.
434c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    Iter iter;
435f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina    Benchmark* bench;
436c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    while ((bench = iter.next()) != NULL) {
437f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina        SkAutoTUnref<Benchmark> benchUnref(bench);
438c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
439387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            continue;
440387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        }
441fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
442c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setForceAlpha(alpha);
443c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setForceAA(FLAGS_forceAA);
444c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setForceFilter(FLAGS_forceFilter);
445c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setDither(dither);
446683e90611c8a536c3c5feedea27bbbefedf746d2mtklein        bench->preDraw();
44730e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
448c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bool loggedBenchName = false;
449c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        for (int i = 0; i < configs.count(); ++i) {
450c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const int configIndex = configs[i];
451c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const Config& config = gConfigs[configIndex];
4527495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org
453644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org            if (!bench->isSuitableFor(config.backend)) {
454c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                continue;
455604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            }
456604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com
457cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrContext* context = NULL;
458cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
4599c55f801a35b0d6c39f007fae432bd13094f3c52sugoi@google.com            SkGLContextHelper* glContext = NULL;
460f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina            if (Benchmark::kGPU_Backend == config.backend) {
461c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                context = gContextFactory.get(config.contextType);
462cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL == context) {
463cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    continue;
464cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                }
465c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                glContext = gContextFactory.getGLContext(config.contextType);
4664bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
467cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
4681bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com
469c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            SkAutoTUnref<SkCanvas> canvas;
47084b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com            SkAutoTUnref<SkPicture> recordFrom;
47184b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com            SkPictureRecorder recorderTo;
472c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const SkIPoint dim = bench->getSize();
473c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
4741bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com            SkAutoTUnref<SkSurface> surface;
475f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina            if (Benchmark::kNonRendering_Backend != config.backend) {
4761bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                surface.reset(make_surface(config.fColorType,
4771bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                                           dim,
4781bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                                           config.backend,
4791bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                                           config.sampleCount,
4801bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                                           context));
4811bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                if (!surface.get()) {
482dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                    logger.logError(SkStringPrintf(
483dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                        "Device creation failure for config %s. Will skip.\n", config.name));
484c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    continue;
485604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                }
486604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com
487c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                switch(benchMode) {
488c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kDeferredSilent_BenchMode:
489c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kDeferred_BenchMode:
4901bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                        canvas.reset(SkDeferredCanvas::Create(surface.get()));
491c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
492c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kRecord_BenchMode:
4939f1c241e0d8a756fca1ec2dacb565eec83166d5frobertphillips                        canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY)));
494c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
49584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                    case kPictureRecord_BenchMode: {
49684b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                        SkPictureRecorder recorderFrom;
4979f1c241e0d8a756fca1ec2dacb565eec83166d5frobertphillips                        bench->draw(1, recorderFrom.beginRecording(dim.fX, dim.fY));
49884b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                        recordFrom.reset(recorderFrom.endRecording());
4999f1c241e0d8a756fca1ec2dacb565eec83166d5frobertphillips                        canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY)));
500c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
50184b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                    }
502c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kNormal_BenchMode:
5031bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                        canvas.reset(SkRef(surface->getCanvas()));
504c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
505c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    default:
506c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        SkASSERT(false);
5077495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                }
508c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
509508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
510c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (NULL != canvas) {
511c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                canvas->clear(SK_ColorWHITE);
5125199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                if (FLAGS_clip)   {
5135199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                    perform_clip(canvas, dim.fX, dim.fY);
51484b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                }
5155199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                if (FLAGS_scale)  {
5165199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                    perform_scale(canvas, dim.fX, dim.fY);
51784b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                }
5185199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                if (FLAGS_rotate) {
5195199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                    perform_rotate(canvas, dim.fX, dim.fY);
52084b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                }
521c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
522c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
523c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (!loggedBenchName) {
524c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                loggedBenchName = true;
525e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org                writer.bench(bench->getName(), dim.fX, dim.fY);
526c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
527fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
528cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
529c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            SkGLContextHelper* contextHelper = NULL;
530f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina            if (Benchmark::kGPU_Backend == config.backend) {
531c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                contextHelper = gContextFactory.getGLContext(config.contextType);
532c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
533c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            BenchTimer timer(contextHelper);
534c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#else
535c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            BenchTimer timer;
536cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
537af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
5389ef1d21dc8edd167ebbf1ec35f25769f9f6b683bmtklein@google.com            double previous = std::numeric_limits<double>::infinity();
539dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com            bool converged = false;
54070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
54170de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            // variables used to compute loopsPerFrame
54270de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            double frameIntervalTime = 0.0f;
54370de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            int frameIntervalTotalLoops = 0;
54470de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
54570de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            bool frameIntervalComputed = false;
54670de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            int loopsPerFrame = 0;
54770de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            int loopsPerIter = 0;
548dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com            if (FLAGS_verbose) { SkDebugf("%s %s: ", bench->getName(), config.name); }
54956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org            if (!FLAGS_dryRun) {
55056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                do {
55156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // Ramp up 1 -> 2 -> 4 -> 8 -> 16 -> ... -> ~1 billion.
55256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    loopsPerIter = (loopsPerIter == 0) ? 1 : loopsPerIter * 2;
55356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if (loopsPerIter >= (1<<30) || timer.fWall > FLAGS_maxMs) {
55456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // If you find it takes more than a billion loops to get up to 20ms of runtime,
55556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // you've got a computer clocked at several THz or have a broken benchmark.  ;)
55656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        //     "1B ought to be enough for anybody."
55756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        logger.logError(SkStringPrintf(
55856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            "\nCan't get %s %s to converge in %dms (%d loops)",
55956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                             bench->getName(), config.name, FLAGS_maxMs, loopsPerIter));
56056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        break;
56170de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
56270de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
56356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if ((benchMode == kRecord_BenchMode || benchMode == kPictureRecord_BenchMode)) {
56456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // Clear the recorded commands so that they do not accumulate.
5659f1c241e0d8a756fca1ec2dacb565eec83166d5frobertphillips                        canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY)));
56670de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
56770de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
56856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    timer.start();
56956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // Inner loop that allows us to break the run into smaller
57056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // chunks (e.g. frames). This is especially useful for the GPU
57156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // as we can flush and/or swap buffers to keep the GPU from
57256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // queuing up too much work.
57356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    for (int loopCount = loopsPerIter; loopCount > 0; ) {
57456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // Save and restore around each call to draw() to guarantee a pristine canvas.
57556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        SkAutoCanvasRestore saveRestore(canvas, true/*also save*/);
57656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org
57756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        int loops;
57856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        if (frameIntervalComputed && loopCount > loopsPerFrame) {
57956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            loops = loopsPerFrame;
58056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            loopCount -= loopsPerFrame;
58156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        } else {
58256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            loops = loopCount;
58356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            loopCount = 0;
58456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        }
58570de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
58656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        if (benchMode == kPictureRecord_BenchMode) {
58784b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                            recordFrom->draw(canvas);
58856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        } else {
58956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            bench->draw(loops, canvas);
59056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        }
59156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org
59256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        if (kDeferredSilent_BenchMode == benchMode) {
59356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            static_cast<SkDeferredCanvas*>(canvas.get())->silentFlush();
59456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        } else if (NULL != canvas) {
59556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            canvas->flush();
59656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        }
59756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org
59856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    #if SK_SUPPORT_GPU
59956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // swap drawing buffers on each frame to prevent the GPU
60056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // from queuing up too much work
60156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        if (NULL != glContext) {
60256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            glContext->swapBuffers();
60356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        }
60456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    #endif
60570de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
606c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
607c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
608c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
60956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // Stop truncated timers before GL calls complete, and stop the full timers after.
61056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    timer.truncatedEnd();
61156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    #if SK_SUPPORT_GPU
61256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if (NULL != glContext) {
61356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        context->flush();
61456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        SK_GL(*glContext, Finish());
61556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    }
61656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    #endif
61756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    timer.end();
61856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org
61956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // setup the frame interval for subsequent iterations
62056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if (!frameIntervalComputed) {
62156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        frameIntervalTime += timer.fWall;
62256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        frameIntervalTotalLoops += loopsPerIter;
62356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        if (frameIntervalTime >= FLAGS_minMs) {
62456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            frameIntervalComputed = true;
62556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            loopsPerFrame =
62656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                              (int)(((double)frameIntervalTotalLoops / frameIntervalTime) * FLAGS_minMs);
62756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            if (loopsPerFrame < 1) {
62856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                                loopsPerFrame = 1;
62956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            }
63056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    //                        SkDebugf("  %s has %d loops in %f ms (normalized to %d)\n",
63156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    //                                 bench->getName(), frameIntervalTotalLoops,
63256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    //                                 timer.fWall, loopsPerFrame);
63370de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        }
63470de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
635dcfed6cecfde7a6e4983c1caf7ffb417c891667fdjsollen@google.com
63656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    const double current = timer.fWall / loopsPerIter;
63756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if (FLAGS_verbose && current > previous) { SkDebugf("↑"); }
63856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if (FLAGS_verbose) { SkDebugf("%.3g ", current); }
63956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    converged = HasConverged(previous, current, timer.fWall);
64056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    previous = current;
6414bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org                } while (!FLAGS_runOnce && !converged);
64256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org            }
643dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com            if (FLAGS_verbose) { SkDebugf("\n"); }
644c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
645f168b86d7fafc5c20c87bebc6fd393cb17e120catfarina            if (!FLAGS_dryRun && FLAGS_outDir.count() && Benchmark::kNonRendering_Backend != config.backend) {
6461bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
6471bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                if (image.get()) {
6481bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                    saveFile(bench->getName(), config.name, FLAGS_outDir[0],
6491bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                             image);
6501bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                }
651c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
652c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
6534bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org            if (FLAGS_runOnce) {
6544bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org                // Let's not mislead ourselves by looking at Debug build or single iteration bench times!
655c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                continue;
656c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
657c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
658c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            // Normalize to ms per 1000 iterations.
65970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            const double normalize = 1000.0 / loopsPerIter;
660c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const struct { char shortName; const char* longName; double ms; } times[] = {
661c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'w', "msecs",  normalize * timer.fWall},
662c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'W', "Wmsecs", normalize * timer.fTruncatedWall},
663c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'c', "cmsecs", normalize * timer.fCpu},
664c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'C', "Cmsecs", normalize * timer.fTruncatedCpu},
665c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'g', "gmsecs", normalize * timer.fGpu},
666c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            };
667c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
668e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org            writer.config(config.name);
669c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) {
670c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms > 0) {
671e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org                    writer.timer(times[i].longName, times[i].ms);
6727495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                }
67325df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com            }
6744bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        }
675bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
676cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
677cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    gContextFactory.destroyContexts();
678cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
679bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    return 0;
680bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
6815987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
6827158e6acca1b1ecc321d4d514a31cba11b5ead60borenet@google.com#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
6835987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint main(int argc, char * const argv[]) {
6845987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com    return tool_main(argc, (char**) argv);
6855987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
6865987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
687