benchmain.cpp revision 683e90611c8a536c3c5feedea27bbbefedf746d2
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
8c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#include "BenchTimer.h"
9e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#include "ResultsWriter.h"
109a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com#include "SkBenchLogger.h"
11971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "SkBenchmark.h"
1273672254a3e498081967d00d27b17ada443e2ab2robertphillips@google.com#include "SkBitmapDevice.h"
13bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkCanvas.h"
1478d0379dcc777b4bc4965cff0c2b3fc44ccaef56mtklein@google.com#include "SkColorPriv.h"
15586db93c447b753364d50fadc5426de4fef9a759sglez@google.com#include "SkCommandLineFlags.h"
161bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com#include "SkData.h"
1782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com#include "SkDeferredCanvas.h"
186adce6783c5d7cbef276d04cc08a2b19789a0156commit-bot@chromium.org#include "SkGMBench.h"
193a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkGraphics.h"
20b398fe863860b072306b5297c8095c6d973aba06reed@android.com#include "SkImageEncoder.h"
21c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#include "SkOSFile.h"
226c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkPicture.h"
23770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com#include "SkPictureRecorder.h"
24bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkString.h"
251bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com#include "SkSurface.h"
26fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
27db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#if SK_SUPPORT_GPU
28db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#include "GrContext.h"
29db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#include "GrContextFactory.h"
30db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#include "GrRenderTarget.h"
31db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#include "SkGpuDevice.h"
32db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#include "gl/GrGLDefines.h"
33db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#else
34db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.comclass GrContext;
35db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com#endif // SK_SUPPORT_GPU
36db490e99715c000ed15fd8211698f3e50ee2dc30djsollen@google.com
379ef1d21dc8edd167ebbf1ec35f25769f9f6b683bmtklein@google.com#include <limits>
389ef1d21dc8edd167ebbf1ec35f25769f9f6b683bmtklein@google.com
39c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comenum BenchMode {
40c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kNormal_BenchMode,
41c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kDeferred_BenchMode,
42c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kDeferredSilent_BenchMode,
43c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kRecord_BenchMode,
44c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kPictureRecord_BenchMode
45c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com};
46dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comconst char* BenchMode_Name[] = {
47dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    "normal", "deferred", "deferredSilent", "record", "picturerecord"
48dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com};
49515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org
504e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.comstatic const char kDefaultsConfigStr[] = "defaults";
514e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com
52fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org///////////////////////////////////////////////////////////////////////////////
53fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
54bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comclass Iter {
55bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.compublic:
56575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org    Iter() : fBenches(BenchRegistry::Head()), fGMs(skiagm::GMRegistry::Head()) {}
57fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
58bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* next() {
59575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org        if (fBenches) {
60575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            BenchRegistry::Factory f = fBenches->factory();
61575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            fBenches = fBenches->next();
6238aeb0fd7a2bdab5e44531d96045dffe25c8e2b0commit-bot@chromium.org            return (*f)(NULL);
63bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
64575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org
65575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org        while (fGMs) {
66575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(NULL));
67575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            fGMs = fGMs->next();
68575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            if (gm->getFlags() & skiagm::GM::kAsBench_Flag) {
69575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org                return SkNEW_ARGS(SkGMBench, (gm.detach()));
70575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org            }
71575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org        }
72575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org
73bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        return NULL;
74bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
75d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
76bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comprivate:
77575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org    const BenchRegistry* fBenches;
78575d9cd27032f6a43d30d9ddb4bc5b2f8091ba5dcommit-bot@chromium.org    const skiagm::GMRegistry* fGMs;
79bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com};
80bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
81bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comstatic void make_filename(const char name[], SkString* path) {
82bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    path->set(name);
83bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    for (int i = 0; name[i]; i++) {
84bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        switch (name[i]) {
85bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '/':
86bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '\\':
87bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ' ':
88bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ':':
89bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                path->writable_str()[i] = '-';
90bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
91bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            default:
92bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
93bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
94bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
95bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
96bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
974c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void saveFile(const char name[], const char config[], const char dir[],
981bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                     const SkImage* image) {
991bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    SkAutoTUnref<SkData> data(image->encode(SkImageEncoder::kPNG_Type, 100));
1001bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    if (NULL == data.get()) {
1014c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        return;
1024c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
103fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
104c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkString filename;
105c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    make_filename(name, &filename);
106c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    filename.appendf("_%s.png", config);
107c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkString path = SkOSPath::SkPathJoin(dir, filename.c_str());
108c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    ::remove(path.c_str());
1091bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com
110ace135453db02cfe83d7c7bbeaa679f98d18fbe2reed@google.com    SkFILEWStream   stream(path.c_str());
1111bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    stream.write(data->data(), data->size());
1124c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1134c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
11484b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.comstatic void perform_clip(SkCanvas* canvas, int w, int h) {
1154c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkRect r;
116fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1174c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(10), SkIntToScalar(10),
1184c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
1194c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kIntersect_Op);
120fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1214c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
1224c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w-10), SkIntToScalar(h-10));
1234c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kXOR_Op);
1244c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1254c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
12684b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.comstatic void perform_rotate(SkCanvas* canvas, int w, int h) {
1274c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
1284c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
129fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1304c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(x, y);
1314c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->rotate(SkIntToScalar(35));
1324c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(-x, -y);
1334c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1344c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
13584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.comstatic void perform_scale(SkCanvas* canvas, int w, int h) {
136387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
137387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
138fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
139387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(x, y);
140387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    // just enough so we can't take the sprite case
141387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
142387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(-x, -y);
143387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com}
144387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com
1451bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.comstatic SkSurface* make_surface(SkColorType colorType, const SkIPoint& size,
1461bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                               SkBenchmark::Backend backend, int sampleCount,
1471bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                               GrContext* context) {
1481bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    SkSurface* surface = NULL;
1491bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    SkImageInfo info = SkImageInfo::Make(size.fX, size.fY, colorType,
1501bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                                         kPremul_SkAlphaType);
151fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
152a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    switch (backend) {
153644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org        case SkBenchmark::kRaster_Backend:
1541bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com            surface = SkSurface::NewRaster(info);
1551bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com            surface->getCanvas()->clear(SK_ColorWHITE);
156a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
157cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
158644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org        case SkBenchmark::kGPU_Backend: {
1591bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com            surface = SkSurface::NewRenderTarget(context, info, sampleCount);
160a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
161cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
162cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
163644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org        case SkBenchmark::kPDF_Backend:
164a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        default:
165330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com            SkDEBUGFAIL("unsupported");
166a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    }
1671bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    return surface;
168a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org}
169a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
170cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
171cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comGrContextFactory gContextFactory;
172cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef GrContextFactory::GLContextType GLContextType;
173c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kNative = GrContextFactory::kNative_GLContextType;
174e8989578cd05d4bf6ebe35f0d49afbc3d3bef2edcommit-bot@chromium.orgstatic const GLContextType kNVPR   = GrContextFactory::kNVPR_GLContextType;
175c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#if SK_ANGLE
176c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kANGLE  = GrContextFactory::kANGLE_GLContextType;
177c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#endif
178c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kDebug  = GrContextFactory::kDebug_GLContextType;
179c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kNull   = GrContextFactory::kNull_GLContextType;
180cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#else
181cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef int GLContextType;
182c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kNative = 0, kANGLE = 0, kDebug = 0, kNull = 0;
183c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#endif
184c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
185c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#ifdef SK_DEBUG
186c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const bool kIsDebug = true;
187c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#else
188c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const bool kIsDebug = false;
189cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
190cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com
191c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const struct Config {
1921bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    SkColorType         fColorType;
193c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    const char*         name;
194c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    int                 sampleCount;
195644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org    SkBenchmark::Backend backend;
196c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    GLContextType       contextType;
197c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    bool                runByDefault;
1984bc1983e01d756ae9c91fd380758457f579d26eareed@android.com} gConfigs[] = {
19928fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    { kN32_SkColorType,     "NONRENDERING", 0, SkBenchmark::kNonRendering_Backend, kNative, true},
20028fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    { kN32_SkColorType,     "8888",         0, SkBenchmark::kRaster_Backend,       kNative, true},
2011bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com    { kRGB_565_SkColorType, "565",          0, SkBenchmark::kRaster_Backend,       kNative, true},
202cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
20328fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    { kN32_SkColorType,     "GPU",          0, SkBenchmark::kGPU_Backend,          kNative, true},
20428fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    { kN32_SkColorType,     "MSAA4",        4, SkBenchmark::kGPU_Backend,          kNative, false},
20528fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    { kN32_SkColorType,     "MSAA16",      16, SkBenchmark::kGPU_Backend,          kNative, false},
20628fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    { kN32_SkColorType,     "NVPRMSAA4",    4, SkBenchmark::kGPU_Backend,          kNVPR,   true},
20728fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    { kN32_SkColorType,     "NVPRMSAA16",  16, SkBenchmark::kGPU_Backend,          kNVPR,   false},
208d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
20928fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    { kN32_SkColorType,     "ANGLE",        0, SkBenchmark::kGPU_Backend,          kANGLE,  true},
210cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
21128fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    { kN32_SkColorType,     "Debug",        0, SkBenchmark::kGPU_Backend,          kDebug,  kIsDebug},
21228fcae2ec77eb16a79e155f8d788b20457f1c951commit-bot@chromium.org    { kN32_SkColorType,     "NULLGPU",      0, SkBenchmark::kGPU_Backend,          kNull,   true},
213cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
2144bc1983e01d756ae9c91fd380758457f579d26eareed@android.com};
2154bc1983e01d756ae9c91fd380758457f579d26eareed@android.com
216c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(outDir, "", "If given, image of each bench will be put in outDir.");
217c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(timers, "cg", "Timers to display. "
218c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com              "Options: w(all) W(all, truncated) c(pu) C(pu, truncated) g(pu)");
219c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
220c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(rotate, false,  "Rotate canvas before bench run?");
221c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(scale,  false,  "Scale canvas before bench run?");
222c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(clip,   false,  "Clip canvas before bench run?");
223c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
224c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(forceAA,        true,     "Force anti-aliasing?");
225c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(forceFilter,    false,    "Force bitmap filtering?");
226c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(forceDither, "default", "Force dithering: true, false, or default?");
227c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(forceBlend,     false,    "Force alpha blending?");
228c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
229c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_int32(gpuCacheBytes, -1, "GPU cache size limit in bytes.  0 to disable cache.");
230c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_int32(gpuCacheCount, -1, "GPU cache size limit in object count.  0 to disable cache.");
231c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
2326dda827913a3dbdb84934f4f1d79c0b702169e5ccommit-bot@chromium.orgDEFINE_bool2(leaks, l, false, "show leaked ref cnt'd objects.");
233c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(match, "",  "[~][^]substring[$] [...] of test name to run.\n"
234c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "Multiple matches may be separated by spaces.\n"
235c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "~ causes a matching test to always be skipped\n"
236c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "^ requires the start of the test to match\n"
237c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "$ requires the end of the test to match\n"
238c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "^ and $ requires an exact match\n"
239c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "If a test does not match any list entry,\n"
240c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "it is skipped unless some list entry starts with ~\n");
241c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(mode, "normal",
242c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "normal:         draw to a normal canvas;\n"
243c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "deferred:       draw to a deferred canvas;\n"
244c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "deferredSilent: deferred with silent playback;\n"
245c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "record:         draw to an SkPicture;\n"
246c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "picturerecord:  draw from an SkPicture to an SkPicture.\n");
2474e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.comDEFINE_string(config, kDefaultsConfigStr,
2484e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com              "Run configs given.  By default, runs the configs marked \"runByDefault\" in gConfigs.");
249c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(logFile, "", "Also write stdout here.");
250dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_int32(minMs, 20,  "Shortest time we'll allow a benchmark to run.");
251dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_int32(maxMs, 4000, "Longest time we'll allow a benchmark to run.");
2524bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.orgDEFINE_bool(runOnce, kIsDebug, "Run each bench exactly once and don't report timings.");
253dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_double(error, 0.01,
254dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com              "Ratio of subsequent bench measurements must drop within 1±error to converge.");
255c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per 1000 loops.");
256dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_bool2(verbose, v, false, "Print more.");
257725a64cf89605680ebb0f56cd6727f29d8b9899btfarina@chromium.orgDEFINE_string2(resourcePath, i, "resources", "directory for test resources.");
25861744ec1d2b0e287a652a419dac285c6a803e270commit-bot@chromium.org#ifdef SK_BUILD_JSON_WRITER
259e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.orgDEFINE_string(outResultsFile, "", "If given, the results will be written to the file in JSON format.");
26061744ec1d2b0e287a652a419dac285c6a803e270commit-bot@chromium.org#endif
26156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.orgDEFINE_bool(dryRun, false, "Don't actually run the tests, just print what would have been done.");
26256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org
263dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com// Has this bench converged?  First arguments are milliseconds / loop iteration,
264dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com// last is overall runtime in milliseconds.
265dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comstatic bool HasConverged(double prevPerLoop, double currPerLoop, double currRaw) {
266dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    if (currRaw < FLAGS_minMs) {
267dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com        return false;
268dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    }
269dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    const double low = 1 - FLAGS_error, high = 1 + FLAGS_error;
270dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    const double ratio = currPerLoop / prevPerLoop;
271dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    return low < ratio && ratio < high;
272dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com}
27386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com
2745987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv);
2755987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv) {
2766dda827913a3dbdb84934f4f1d79c0b702169e5ccommit-bot@chromium.org    SkCommandLineFlags::Parse(argc, argv);
2774e23068b374023d43c4c725138d523721d975892bsalomon@google.com#if SK_ENABLE_INST_COUNT
2786dda827913a3dbdb84934f4f1d79c0b702169e5ccommit-bot@chromium.org    if (FLAGS_leaks) {
2796dda827913a3dbdb84934f4f1d79c0b702169e5ccommit-bot@chromium.org        gPrintInstCount = true;
2806dda827913a3dbdb84934f4f1d79c0b702169e5ccommit-bot@chromium.org    }
28165a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#endif
2823a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkAutoGraphics ag;
28365a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com
284c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // First, parse some flags.
285c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkBenchLogger logger;
286c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    if (FLAGS_logFile.count()) {
287c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        logger.SetLogFile(FLAGS_logFile[0]);
288c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
28955fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org
290e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    LoggerResultsWriter logWriter(logger, FLAGS_timeFormat[0]);
291e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    MultiResultsWriter writer;
292e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.add(&logWriter);
29361744ec1d2b0e287a652a419dac285c6a803e270commit-bot@chromium.org
29461744ec1d2b0e287a652a419dac285c6a803e270commit-bot@chromium.org#ifdef SK_BUILD_JSON_WRITER
295e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    SkAutoTDelete<JSONResultsWriter> jsonWriter;
296e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    if (FLAGS_outResultsFile.count()) {
297e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org        jsonWriter.reset(SkNEW(JSONResultsWriter(FLAGS_outResultsFile[0])));
298e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org        writer.add(jsonWriter.get());
299e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    }
30061744ec1d2b0e287a652a419dac285c6a803e270commit-bot@chromium.org#endif
30161744ec1d2b0e287a652a419dac285c6a803e270commit-bot@chromium.org
302e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    // Instantiate after all the writers have been added to writer so that we
303e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    // call close() before their destructors are called on the way out.
304e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    CallEnd<MultiResultsWriter> ender(writer);
305e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org
306c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF;
307c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkTriState::State dither = SkTriState::kDefault;
308c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    for (size_t i = 0; i < 3; i++) {
309c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) {
310c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            dither = static_cast<SkTriState::State>(i);
311c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
312c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
313c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com
314c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    BenchMode benchMode = kNormal_BenchMode;
315c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) {
316c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (strcmp(FLAGS_mode[0], BenchMode_Name[i]) == 0) {
317c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            benchMode = static_cast<BenchMode>(i);
318c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
319c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
320c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com
32113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    SkTDArray<int> configs;
3224e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com    bool runDefaultConfigs = false;
323c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Try user-given configs first.
324c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    for (int i = 0; i < FLAGS_config.count(); i++) {
325e9cd27d4a3c92393cc6c79d4d6f93d266411d95erobertphillips@google.com        for (int j = 0; j < static_cast<int>(SK_ARRAY_COUNT(gConfigs)); ++j) {
326c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (0 == strcmp(FLAGS_config[i], gConfigs[j].name)) {
327c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                *configs.append() = j;
3284e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com            } else if (0 == strcmp(FLAGS_config[i], kDefaultsConfigStr)) {
3294e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com                runDefaultConfigs = true;
330e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            }
331b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
332b398fe863860b072306b5297c8095c6d973aba06reed@android.com    }
333c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // If there weren't any, fill in with defaults.
3344e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com    if (runDefaultConfigs) {
335e9cd27d4a3c92393cc6c79d4d6f93d266411d95erobertphillips@google.com        for (int i = 0; i < static_cast<int>(SK_ARRAY_COUNT(gConfigs)); ++i) {
336c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (gConfigs[i].runByDefault) {
3378a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                *configs.append() = i;
3388a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
33913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        }
34013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    }
341c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Filter out things we can't run.
342c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    if (kNormal_BenchMode != benchMode) {
343604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        // Non-rendering configs only run in normal mode
344604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        for (int i = 0; i < configs.count(); ++i) {
345c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const Config& config = gConfigs[configs[i]];
346644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org            if (SkBenchmark::kNonRendering_Backend == config.backend) {
347604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                configs.remove(i, 1);
348604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                --i;
349604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            }
350604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        }
351604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com    }
352111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    // Set the resource path.
353111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    if (!FLAGS_resourcePath.isEmpty()) {
354111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        SkBenchmark::SetResourcePath(FLAGS_resourcePath[0]);
355111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    }
356111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
3578a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com#if SK_SUPPORT_GPU
3588a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    for (int i = 0; i < configs.count(); ++i) {
359c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        const Config& config = gConfigs[configs[i]];
3608a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com
361644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org        if (SkBenchmark::kGPU_Backend == config.backend) {
362c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            GrContext* context = gContextFactory.get(config.contextType);
3638a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            if (NULL == context) {
3640f298cc12561ce1d59317be0b7ab6938baeaebcdcommit-bot@chromium.org                SkDebugf("GrContext could not be created for config %s. Config will be skipped.\n",
3650f298cc12561ce1d59317be0b7ab6938baeaebcdcommit-bot@chromium.org                    config.name);
3668a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                configs.remove(i);
3678a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                --i;
3688a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                continue;
3698a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
370c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (config.sampleCount > context->getMaxSampleCount()){
3710f298cc12561ce1d59317be0b7ab6938baeaebcdcommit-bot@chromium.org                SkDebugf(
3720f298cc12561ce1d59317be0b7ab6938baeaebcdcommit-bot@chromium.org                    "Sample count (%d) for config %s is not supported. Config will be skipped.\n",
3730f298cc12561ce1d59317be0b7ab6938baeaebcdcommit-bot@chromium.org                    config.sampleCount, config.name);
3748a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                configs.remove(i);
3758a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                --i;
3768a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                continue;
3778a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
3788a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com        }
3798a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    }
3808a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com#endif
3818a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com
382c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // All flags should be parsed now.  Report our settings.
3834bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org    if (FLAGS_runOnce) {
3844bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org        logger.logError("bench was run with --runOnce, so we're going to hide the times."
3854bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org                        " It's for your own good!\n");
386c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
387e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("mode", FLAGS_mode[0]);
388e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("alpha", SkStringPrintf("0x%02X", alpha).c_str());
389e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("antialias", SkStringPrintf("%d", FLAGS_forceAA).c_str());
390e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("filter", SkStringPrintf("%d", FLAGS_forceFilter).c_str());
391e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("dither",  SkTriState::Name[dither]);
392e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org
393e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("rotate", SkStringPrintf("%d", FLAGS_rotate).c_str());
394e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("scale", SkStringPrintf("%d", FLAGS_scale).c_str());
395e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("clip", SkStringPrintf("%d", FLAGS_clip).c_str());
396c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
397a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_BUILD_FOR_WIN32)
398e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("system", "WIN32");
399a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_MAC)
400e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("system", "MAC");
401a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_ANDROID)
402e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("system", "ANDROID");
403a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_UNIX)
404e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("system", "UNIX");
405a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#else
406e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("system", "other");
407a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
408a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
409a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_DEBUG)
410e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("build", "DEBUG");
411e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org#else
412e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    writer.option("build", "RELEASE");
413a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
414508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
415c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Set texture cache limits if non-default.
4165c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
417cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
418c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        const Config& config = gConfigs[i];
419644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org        if (SkBenchmark::kGPU_Backend != config.backend) {
420c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            continue;
421cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
422c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        GrContext* context = gContextFactory.get(config.contextType);
423c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (NULL == context) {
424c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            continue;
425c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
426c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
427c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        size_t bytes;
428c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        int count;
42995c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org        context->getResourceCacheLimits(&count, &bytes);
430c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (-1 != FLAGS_gpuCacheBytes) {
431c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            bytes = static_cast<size_t>(FLAGS_gpuCacheBytes);
432c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
433c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (-1 != FLAGS_gpuCacheCount) {
434c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            count = FLAGS_gpuCacheCount;
435c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
43695c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.org        context->setResourceCacheLimits(count, bytes);
437cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
438cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
43974913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com
440c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Run each bench in each configuration it supports and we asked for.
441c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    Iter iter;
442e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org    SkBenchmark* bench;
443c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    while ((bench = iter.next()) != NULL) {
444c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        SkAutoTUnref<SkBenchmark> benchUnref(bench);
445c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
446387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            continue;
447387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        }
448fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
449c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setForceAlpha(alpha);
450c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setForceAA(FLAGS_forceAA);
451c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setForceFilter(FLAGS_forceFilter);
452c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setDither(dither);
453683e90611c8a536c3c5feedea27bbbefedf746d2mtklein        bench->preDraw();
45430e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
455c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bool loggedBenchName = false;
456c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        for (int i = 0; i < configs.count(); ++i) {
457c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const int configIndex = configs[i];
458c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const Config& config = gConfigs[configIndex];
4597495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org
460644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org            if (!bench->isSuitableFor(config.backend)) {
461c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                continue;
462604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            }
463604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com
464cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrContext* context = NULL;
465cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
4669c55f801a35b0d6c39f007fae432bd13094f3c52sugoi@google.com            SkGLContextHelper* glContext = NULL;
467644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org            if (SkBenchmark::kGPU_Backend == config.backend) {
468c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                context = gContextFactory.get(config.contextType);
469cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL == context) {
470cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    continue;
471cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                }
472c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                glContext = gContextFactory.getGLContext(config.contextType);
4734bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
474cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
4751bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com
476c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            SkAutoTUnref<SkCanvas> canvas;
47784b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com            SkAutoTUnref<SkPicture> recordFrom;
47884b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com            SkPictureRecorder recorderTo;
479c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const SkIPoint dim = bench->getSize();
480c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
4811bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com            SkAutoTUnref<SkSurface> surface;
482644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org            if (SkBenchmark::kNonRendering_Backend != config.backend) {
4831bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                surface.reset(make_surface(config.fColorType,
4841bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                                           dim,
4851bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                                           config.backend,
4861bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                                           config.sampleCount,
4871bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                                           context));
4881bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                if (!surface.get()) {
489dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                    logger.logError(SkStringPrintf(
490dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                        "Device creation failure for config %s. Will skip.\n", config.name));
491c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    continue;
492604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                }
493604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com
494c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                switch(benchMode) {
495c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kDeferredSilent_BenchMode:
496c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kDeferred_BenchMode:
4971bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                        canvas.reset(SkDeferredCanvas::Create(surface.get()));
498c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
499c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kRecord_BenchMode:
5009f1c241e0d8a756fca1ec2dacb565eec83166d5frobertphillips                        canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY)));
501c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
50284b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                    case kPictureRecord_BenchMode: {
50384b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                        SkPictureRecorder recorderFrom;
5049f1c241e0d8a756fca1ec2dacb565eec83166d5frobertphillips                        bench->draw(1, recorderFrom.beginRecording(dim.fX, dim.fY));
50584b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                        recordFrom.reset(recorderFrom.endRecording());
5069f1c241e0d8a756fca1ec2dacb565eec83166d5frobertphillips                        canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY)));
507c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
50884b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                    }
509c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kNormal_BenchMode:
5101bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                        canvas.reset(SkRef(surface->getCanvas()));
511c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
512c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    default:
513c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        SkASSERT(false);
5147495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                }
515c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
516508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
517c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (NULL != canvas) {
518c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                canvas->clear(SK_ColorWHITE);
5195199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                if (FLAGS_clip)   {
5205199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                    perform_clip(canvas, dim.fX, dim.fY);
52184b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                }
5225199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                if (FLAGS_scale)  {
5235199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                    perform_scale(canvas, dim.fX, dim.fY);
52484b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                }
5255199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                if (FLAGS_rotate) {
5265199701acbf386cdc315de440eeafcc10fd0cdc3skia.committer@gmail.com                    perform_rotate(canvas, dim.fX, dim.fY);
52784b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                }
528c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
529c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
530c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (!loggedBenchName) {
531c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                loggedBenchName = true;
532e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org                writer.bench(bench->getName(), dim.fX, dim.fY);
533c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
534fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
535cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
536c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            SkGLContextHelper* contextHelper = NULL;
537644629c1c7913a43ced172b98d56e0f471bc348bcommit-bot@chromium.org            if (SkBenchmark::kGPU_Backend == config.backend) {
538c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                contextHelper = gContextFactory.getGLContext(config.contextType);
539c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
540c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            BenchTimer timer(contextHelper);
541c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#else
542c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            BenchTimer timer;
543cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
544af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
5459ef1d21dc8edd167ebbf1ec35f25769f9f6b683bmtklein@google.com            double previous = std::numeric_limits<double>::infinity();
546dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com            bool converged = false;
54770de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
54870de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            // variables used to compute loopsPerFrame
54970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            double frameIntervalTime = 0.0f;
55070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            int frameIntervalTotalLoops = 0;
55170de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
55270de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            bool frameIntervalComputed = false;
55370de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            int loopsPerFrame = 0;
55470de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            int loopsPerIter = 0;
555dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com            if (FLAGS_verbose) { SkDebugf("%s %s: ", bench->getName(), config.name); }
55656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org            if (!FLAGS_dryRun) {
55756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                do {
55856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // Ramp up 1 -> 2 -> 4 -> 8 -> 16 -> ... -> ~1 billion.
55956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    loopsPerIter = (loopsPerIter == 0) ? 1 : loopsPerIter * 2;
56056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if (loopsPerIter >= (1<<30) || timer.fWall > FLAGS_maxMs) {
56156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // If you find it takes more than a billion loops to get up to 20ms of runtime,
56256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // you've got a computer clocked at several THz or have a broken benchmark.  ;)
56356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        //     "1B ought to be enough for anybody."
56456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        logger.logError(SkStringPrintf(
56556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            "\nCan't get %s %s to converge in %dms (%d loops)",
56656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                             bench->getName(), config.name, FLAGS_maxMs, loopsPerIter));
56756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        break;
56870de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
56970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
57056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if ((benchMode == kRecord_BenchMode || benchMode == kPictureRecord_BenchMode)) {
57156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // Clear the recorded commands so that they do not accumulate.
5729f1c241e0d8a756fca1ec2dacb565eec83166d5frobertphillips                        canvas.reset(SkRef(recorderTo.beginRecording(dim.fX, dim.fY)));
57370de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
57470de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
57556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    timer.start();
57656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // Inner loop that allows us to break the run into smaller
57756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // chunks (e.g. frames). This is especially useful for the GPU
57856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // as we can flush and/or swap buffers to keep the GPU from
57956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // queuing up too much work.
58056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    for (int loopCount = loopsPerIter; loopCount > 0; ) {
58156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // Save and restore around each call to draw() to guarantee a pristine canvas.
58256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        SkAutoCanvasRestore saveRestore(canvas, true/*also save*/);
58356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org
58456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        int loops;
58556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        if (frameIntervalComputed && loopCount > loopsPerFrame) {
58656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            loops = loopsPerFrame;
58756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            loopCount -= loopsPerFrame;
58856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        } else {
58956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            loops = loopCount;
59056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            loopCount = 0;
59156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        }
59270de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
59356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        if (benchMode == kPictureRecord_BenchMode) {
59484b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com                            recordFrom->draw(canvas);
59556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        } else {
59656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            bench->draw(loops, canvas);
59756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        }
59856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org
59956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        if (kDeferredSilent_BenchMode == benchMode) {
60056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            static_cast<SkDeferredCanvas*>(canvas.get())->silentFlush();
60156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        } else if (NULL != canvas) {
60256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            canvas->flush();
60356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        }
60456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org
60556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    #if SK_SUPPORT_GPU
60656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // swap drawing buffers on each frame to prevent the GPU
60756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        // from queuing up too much work
60856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        if (NULL != glContext) {
60956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            glContext->swapBuffers();
61056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        }
61156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    #endif
61270de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
613c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
614c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
615c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
61656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // Stop truncated timers before GL calls complete, and stop the full timers after.
61756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    timer.truncatedEnd();
61856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    #if SK_SUPPORT_GPU
61956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if (NULL != glContext) {
62056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        context->flush();
62156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        SK_GL(*glContext, Finish());
62256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    }
62356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    #endif
62456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    timer.end();
62556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org
62656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    // setup the frame interval for subsequent iterations
62756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if (!frameIntervalComputed) {
62856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        frameIntervalTime += timer.fWall;
62956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        frameIntervalTotalLoops += loopsPerIter;
63056b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                        if (frameIntervalTime >= FLAGS_minMs) {
63156b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            frameIntervalComputed = true;
63256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            loopsPerFrame =
63356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                              (int)(((double)frameIntervalTotalLoops / frameIntervalTime) * FLAGS_minMs);
63456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            if (loopsPerFrame < 1) {
63556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                                loopsPerFrame = 1;
63656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                            }
63756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    //                        SkDebugf("  %s has %d loops in %f ms (normalized to %d)\n",
63856b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    //                                 bench->getName(), frameIntervalTotalLoops,
63956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org    //                                 timer.fWall, loopsPerFrame);
64070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        }
64170de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
642dcfed6cecfde7a6e4983c1caf7ffb417c891667fdjsollen@google.com
64356b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    const double current = timer.fWall / loopsPerIter;
64456b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if (FLAGS_verbose && current > previous) { SkDebugf("↑"); }
64556b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    if (FLAGS_verbose) { SkDebugf("%.3g ", current); }
64656b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    converged = HasConverged(previous, current, timer.fWall);
64756b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org                    previous = current;
6484bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org                } while (!FLAGS_runOnce && !converged);
64956b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org            }
650dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com            if (FLAGS_verbose) { SkDebugf("\n"); }
651c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
65256b7a6d52ceaed3927ec4346f431495c32f519e2commit-bot@chromium.org            if (!FLAGS_dryRun && FLAGS_outDir.count() && SkBenchmark::kNonRendering_Backend != config.backend) {
6531bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                SkAutoTUnref<SkImage> image(surface->newImageSnapshot());
6541bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                if (image.get()) {
6551bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                    saveFile(bench->getName(), config.name, FLAGS_outDir[0],
6561bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                             image);
6571bc6c6aa7e1e0fd6a1b80f654a27a7638018f4e7reed@google.com                }
658c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
659c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
6604bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org            if (FLAGS_runOnce) {
6614bbe2e552a8eb823f71dd9c63a54fcb65efca6bbcommit-bot@chromium.org                // Let's not mislead ourselves by looking at Debug build or single iteration bench times!
662c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                continue;
663c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
664c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
665c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            // Normalize to ms per 1000 iterations.
66670de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            const double normalize = 1000.0 / loopsPerIter;
667c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const struct { char shortName; const char* longName; double ms; } times[] = {
668c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'w', "msecs",  normalize * timer.fWall},
669c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'W', "Wmsecs", normalize * timer.fTruncatedWall},
670c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'c', "cmsecs", normalize * timer.fCpu},
671c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'C', "Cmsecs", normalize * timer.fTruncatedCpu},
672c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'g', "gmsecs", normalize * timer.fGpu},
673c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            };
674c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
675e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org            writer.config(config.name);
676c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) {
677c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms > 0) {
678e3bb3bce3e9c1f3bc8ee779b1b3383c18e560bcecommit-bot@chromium.org                    writer.timer(times[i].longName, times[i].ms);
6797495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                }
68025df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com            }
6814bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        }
682bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
683cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
684cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    gContextFactory.destroyContexts();
685cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
686bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    return 0;
687bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
6885987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
6897158e6acca1b1ecc321d4d514a31cba11b5ead60borenet@google.com#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
6905987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint main(int argc, char * const argv[]) {
6915987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com    return tool_main(argc, (char**) argv);
6925987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
6935987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
694