benchmain.cpp revision c732f259fa9cb0045623f3e0e3f033c20f06be8c
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
9971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
10971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "BenchTimer.h"
11971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
12cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
13971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrContext.h"
14cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#include "GrContextFactory.h"
15fe1b536bb7af523995549b64ad19de6685e11411robertphillips@google.com#include "gl/GrGLDefines.h"
16971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrRenderTarget.h"
17cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "SkGpuDevice.h"
1841809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.com#else
1941809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.comclass GrContext;
20cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
21971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
229a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com#include "SkBenchLogger.h"
23971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "SkBenchmark.h"
24bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkCanvas.h"
2582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com#include "SkDeferredCanvas.h"
2644b67b2ed16ecb6fe001b785498e20b13fa42d0cjunov@chromium.org#include "SkDevice.h"
27f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com#include "SkColorPriv.h"
283a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkGraphics.h"
29b398fe863860b072306b5297c8095c6d973aba06reed@android.com#include "SkImageEncoder.h"
306c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkNWayCanvas.h"
316c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkPicture.h"
32bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkString.h"
3341809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.com#include "SkTArray.h"
349a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com#include "TimerData.h"
3529348cb0612e19030d979156860946241e2ff4bdreed@android.com
36fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.orgenum benchModes {
37fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kNormal_benchModes,
38fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kDeferred_benchModes,
39fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    kDeferredSilent_benchModes,
40fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kRecord_benchModes,
41fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kPictureRecord_benchModes
42fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org};
43fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
44fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org///////////////////////////////////////////////////////////////////////////////
45fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
466c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic void erase(SkBitmap& bm) {
476c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
48dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com        bm.eraseColor(SK_ColorTRANSPARENT);
496c924ad46c89955e78e071c792ef00df9910b42freed@android.com    } else {
506c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm.eraseColor(SK_ColorWHITE);
516c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
526c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
536c924ad46c89955e78e071c792ef00df9910b42freed@android.com
54a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org#if 0
556c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic bool equal(const SkBitmap& bm1, const SkBitmap& bm2) {
566c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm1.width() != bm2.width() ||
576c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm1.height() != bm2.height() ||
586c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm1.config() != bm2.config()) {
596c924ad46c89955e78e071c792ef00df9910b42freed@android.com        return false;
606c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
61fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
626c924ad46c89955e78e071c792ef00df9910b42freed@android.com    size_t pixelBytes = bm1.width() * bm1.bytesPerPixel();
636c924ad46c89955e78e071c792ef00df9910b42freed@android.com    for (int y = 0; y < bm1.height(); y++) {
646c924ad46c89955e78e071c792ef00df9910b42freed@android.com        if (memcmp(bm1.getAddr(0, y), bm2.getAddr(0, y), pixelBytes)) {
656c924ad46c89955e78e071c792ef00df9910b42freed@android.com            return false;
666c924ad46c89955e78e071c792ef00df9910b42freed@android.com        }
676c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
686c924ad46c89955e78e071c792ef00df9910b42freed@android.com    return true;
696c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
70a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org#endif
716c924ad46c89955e78e071c792ef00df9910b42freed@android.com
72bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comclass Iter {
73bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.compublic:
74e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter(void* param) {
75bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        fBench = BenchRegistry::Head();
76e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com        fParam = param;
77bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
78fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
79bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* next() {
80bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        if (fBench) {
81bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            BenchRegistry::Factory f = fBench->factory();
82bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            fBench = fBench->next();
83e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            return f(fParam);
84bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
85bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        return NULL;
86bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
87d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
88bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comprivate:
89bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    const BenchRegistry* fBench;
90e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    void* fParam;
91bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com};
92bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
9330e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.comclass AutoPrePostDraw {
9430e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.compublic:
9530e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    AutoPrePostDraw(SkBenchmark* bench) : fBench(bench) {
9630e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        fBench->preDraw();
9730e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    }
9830e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    ~AutoPrePostDraw() {
9930e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        fBench->postDraw();
10030e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    }
10130e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.comprivate:
10230e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    SkBenchmark* fBench;
10330e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com};
10430e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
105bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comstatic void make_filename(const char name[], SkString* path) {
106bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    path->set(name);
107bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    for (int i = 0; name[i]; i++) {
108bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        switch (name[i]) {
109bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '/':
110bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '\\':
111bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ' ':
112bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ':':
113bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                path->writable_str()[i] = '-';
114bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
115bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            default:
116bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
117bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
118bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
119bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
120bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
1214c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void saveFile(const char name[], const char config[], const char dir[],
1224c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                     const SkBitmap& bm) {
1234c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkBitmap copy;
1244c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    if (!bm.copyTo(&copy, SkBitmap::kARGB_8888_Config)) {
1254c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        return;
1264c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
127fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
128f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
129f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        // turn alpha into gray-scale
130f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        size_t size = copy.getSize() >> 2;
131f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        SkPMColor* p = copy.getAddr32(0, 0);
132f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        for (size_t i = 0; i < size; i++) {
133f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            int c = (*p >> SK_A32_SHIFT) & 0xFF;
134f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c = 255 - c;
135f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c |= (c << 24) | (c << 16) | (c << 8);
136f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            *p++ = c | (SK_A32_MASK << SK_A32_SHIFT);
137f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        }
138f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    }
139fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1404c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkString str;
1414c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    make_filename(name, &str);
1424c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    str.appendf("_%s.png", config);
1434c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    str.prepend(dir);
1444c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    ::remove(str.c_str());
1454c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkImageEncoder::EncodeFile(str.c_str(), copy, SkImageEncoder::kPNG_Type,
1464c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                               100);
1474c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1484c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1494c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performClip(SkCanvas* canvas, int w, int h) {
1504c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkRect r;
151fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1524c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(10), SkIntToScalar(10),
1534c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
1544c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kIntersect_Op);
155fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1564c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
1574c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w-10), SkIntToScalar(h-10));
1584c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kXOR_Op);
1594c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1604c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1614c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performRotate(SkCanvas* canvas, int w, int h) {
1624c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
1634c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
164fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1654c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(x, y);
1664c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->rotate(SkIntToScalar(35));
1674c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(-x, -y);
1684c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1694c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
170387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.comstatic void performScale(SkCanvas* canvas, int w, int h) {
171387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
172387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
173fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
174387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(x, y);
175387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    // just enough so we can't take the sprite case
176387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
177387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(-x, -y);
178387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com}
179387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com
18029348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic bool parse_bool_arg(char * const* argv, char* const* stop, bool* var) {
18129348cb0612e19030d979156860946241e2ff4bdreed@android.com    if (argv < stop) {
18229348cb0612e19030d979156860946241e2ff4bdreed@android.com        *var = atoi(*argv) != 0;
18329348cb0612e19030d979156860946241e2ff4bdreed@android.com        return true;
18429348cb0612e19030d979156860946241e2ff4bdreed@android.com    }
18529348cb0612e19030d979156860946241e2ff4bdreed@android.com    return false;
18629348cb0612e19030d979156860946241e2ff4bdreed@android.com}
18729348cb0612e19030d979156860946241e2ff4bdreed@android.com
188a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgenum Backend {
189a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kRaster_Backend,
190a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kGPU_Backend,
191a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kPDF_Backend,
192a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org};
193a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
194a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgstatic SkDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
195cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                             Backend backend, GrContext* context) {
196a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkDevice* device = NULL;
197a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkBitmap bitmap;
198a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    bitmap.setConfig(config, size.fX, size.fY);
199fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
200a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    switch (backend) {
201a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kRaster_Backend:
202a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            bitmap.allocPixels();
203a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            erase(bitmap);
204cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            device = SkNEW_ARGS(SkDevice, (bitmap));
205a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
206cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
207cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        case kGPU_Backend: {
208cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrTextureDesc desc;
209cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fConfig = kSkia8888_GrPixelConfig;
210cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fFlags = kRenderTarget_GrTextureFlagBit;
211cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fWidth = size.fX;
212cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fHeight = size.fY;
213cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
214cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            if (!texture) {
215cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                return NULL;
216cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            }
217cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            device = SkNEW_ARGS(SkGpuDevice, (context, texture.get()));
218a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
219cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
220cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
221a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kPDF_Backend:
222a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        default:
223a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            SkASSERT(!"unsupported");
224a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    }
225a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    return device;
226a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org}
227a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
228cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
229cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comGrContextFactory gContextFactory;
230cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef GrContextFactory::GLContextType GLContextType;
231cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comstatic const GLContextType kDontCareGLCtxType = GrContextFactory::kNative_GLContextType;
232cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#else
233cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef int GLContextType;
234cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comstatic const GLContextType kDontCareGLCtxType = 0;
235cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
236cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com
2374bc1983e01d756ae9c91fd380758457f579d26eareed@android.comstatic const struct {
2384bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    SkBitmap::Config    fConfig;
2394bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    const char*         fName;
240a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend             fBackend;
241cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    GLContextType       fContextType;
2424bc1983e01d756ae9c91fd380758457f579d26eareed@android.com} gConfigs[] = {
243cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "8888",     kRaster_Backend, kDontCareGLCtxType },
244cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kRGB_565_Config,    "565",      kRaster_Backend, kDontCareGLCtxType },
245cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
246cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "GPU",      kGPU_Backend, GrContextFactory::kNative_GLContextType },
247d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
248cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "ANGLE",    kGPU_Backend, GrContextFactory::kANGLE_GLContextType },
249cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
250a0b63b86313694f695bf0387ee0ce31de3deabb3robertphillips@google.com#ifdef SK_DEBUG
251cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "Debug",    kGPU_Backend, GrContextFactory::kDebug_GLContextType },
252cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_DEBUG
253cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "NULLGPU",  kGPU_Backend, GrContextFactory::kNull_GLContextType },
254cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
2554bc1983e01d756ae9c91fd380758457f579d26eareed@android.com};
2564bc1983e01d756ae9c91fd380758457f579d26eareed@android.com
2574c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic int findConfig(const char config[]) {
2584c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
2594c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        if (!strcmp(config, gConfigs[i].fName)) {
2604c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            return i;
2614c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        }
2624c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
2634c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    return -1;
2644c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
2654c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
2661a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.comstatic bool skip_name(const SkTDArray<const char*> array, const char name[]) {
2671a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    if (0 == array.count()) {
2681a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        // no names, so don't skip anything
2691a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        return false;
2701a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    }
2711a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    for (int i = 0; i < array.count(); ++i) {
2721a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (strstr(name, array[i])) {
2731a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com            // found the name, so don't skip
2741a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com            return false;
2751a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        }
2761a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    }
2771a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    return true;
2781a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com}
2791a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com
28086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.comstatic void help() {
281161e1ba4c0a82e21c7d68808529699fd2394ad6cscroggo@google.com    SkDebugf("Usage: bench [-o outDir] [--repeat nr] [--logPerIter] "
2824cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                          "[--timers [wcgWC]*] [--rotate]\n"
2834cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--scale] [--clip] [--min] [--forceAA 1|0] [--forceFilter 1|0]\n"
284c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             "    [--forceDither 1|0] [--forceBlend 1|0]"
285c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#if SK_SUPPORT_GPU
286c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             " [--gpuCacheSize <bytes> <count>]"
287c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#endif
288c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             "\n"
289c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             "    [--strokeWidth width] [--match name]\n"
290c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             "    [--mode normal|deferred|deferredSilent|record|picturerecord]\n"
2914cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--config 8888|565|GPU|ANGLE|NULLGPU] [-Dfoo bar] [--logFile filename]\n"
29282a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com             "    [-h|--help]");
29386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("\n\n");
29486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -o outDir : Image of each bench will be put in outDir.\n");
2954cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --repeat nr : Each bench repeats for nr times.\n");
296161e1ba4c0a82e21c7d68808529699fd2394ad6cscroggo@google.com    SkDebugf("    --logPerIter : "
297af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com             "Log each repeat timer instead of mean, default is disabled.\n");
2984cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --timers [wcgWC]* : "
29991ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com             "Display wall, cpu, gpu, truncated wall or truncated cpu time for each bench.\n");
3004cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --rotate : Rotate before each bench runs.\n");
3014cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --scale : Scale before each bench runs.\n");
3024cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --clip : Clip before each bench runs.\n");
3034cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --min : Print the minimum times (instead of average).\n");
3044cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceAA 1|0 : "
30586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable anti-aliased, default is enabled.\n");
3064cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceFilter 1|0 : "
30786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable bitmap filtering, default is disabled.\n");
3084cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceDither 1|0 : "
30986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
3104cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceBlend 1|0 : "
31186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
312c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#if SK_SUPPORT_GPU
313c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com    SkDebugf("    --gpuCacheSize <bytes> <count>: "
314c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             "limits gpu cache to  bytes size or object count.\n");
315c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com    SkDebugf("      -1 for either value means use the default. 0 for either disables the cache.\n");
316c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#endif
3174cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --strokeWidth width : The width for path stroke.\n");
3184cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --match name : Only run bench whose name is matched.\n");
319fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    SkDebugf("    --mode normal|deferred|deferredSilent|record|picturerecord :\n"
320fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "             Run in the corresponding mode\n"
321fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 normal, Use a normal canvas to draw to;\n"
322fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 deferred, Use a deferrred canvas when drawing;\n"
323fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "                 deferredSilent, deferred with silent playback;\n"
324fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 record, Benchmark the time to record to an SkPicture;\n"
325fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 picturerecord, Benchmark the time to do record from a \n"
326fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                                SkPicture to a SkPicture.\n");
3274cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --logFile filename : destination for writing log output, in addition to stdout.\n");
328cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
3294cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --config 8888|565|GPU|ANGLE|NULLGPU : "
33086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Run bench in corresponding config mode.\n");
331cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
3324cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --config 8888|565: "
333cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com             "Run bench in corresponding config mode.\n");
334cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
33586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -Dfoo bar : Add extra definition to bench.\n");
33686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -h|--help : Show this help message.\n");
33786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com}
33886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com
3395987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv);
3405987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv) {
3414e23068b374023d43c4c725138d523721d975892bsalomon@google.com#if SK_ENABLE_INST_COUNT
34265a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com    gPrintInstCount = true;
34365a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#endif
3443a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkAutoGraphics ag;
34565a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com
346e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    SkTDict<const char*> defineDict(1024);
3474bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int repeatDraw = 1;
348af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    bool logPerIter = false;
3494bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int forceAlpha = 0xFF;
3504bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    bool forceAA = true;
35129348cb0612e19030d979156860946241e2ff4bdreed@android.com    bool forceFilter = false;
3524e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com    SkTriState::State forceDither = SkTriState::kDefault;
353be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerWall = false;
35491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com    bool truncatedTimerWall = false;
355be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerCpu = true;
35691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com    bool truncatedTimerCpu = false;
357be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerGpu = true;
358387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    bool doScale = false;
3594c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doRotate = false;
3604c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doClip = false;
3612abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com    bool printMin = false;
362652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    bool hasStrokeWidth = false;
363c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com
364c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#if SK_SUPPORT_GPU
365c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com    struct {
366c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com        size_t  fBytes;
367c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com        int     fCount;
368c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com    } gpuCacheSize = { -1, -1 }; // -1s mean use the default
369c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#endif
370c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com
371652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    float strokeWidth;
3721a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    SkTDArray<const char*> fMatches;
373fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    benchModes benchMode = kNormal_benchModes;
374fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString perIterTimeformat("%.2f");
375fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString normalTimeFormat("%6.2f");
376fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
377b398fe863860b072306b5297c8095c6d973aba06reed@android.com    SkString outDir;
378387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    SkBitmap::Config outConfig = SkBitmap::kNo_Config;
379387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const char* configName = "";
380a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend backend = kRaster_Backend;  // for warning
38113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    SkTDArray<int> configs;
38213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    bool userConfig = false;
383fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3849a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com    SkBenchLogger logger;
3859a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com
386b398fe863860b072306b5297c8095c6d973aba06reed@android.com    char* const* stop = argv + argc;
387b398fe863860b072306b5297c8095c6d973aba06reed@android.com    for (++argv; argv < stop; ++argv) {
388b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (strcmp(*argv, "-o") == 0) {
389b398fe863860b072306b5297c8095c6d973aba06reed@android.com            argv++;
390b398fe863860b072306b5297c8095c6d973aba06reed@android.com            if (argv < stop && **argv) {
391b398fe863860b072306b5297c8095c6d973aba06reed@android.com                outDir.set(*argv);
392b398fe863860b072306b5297c8095c6d973aba06reed@android.com                if (outDir.c_str()[outDir.size() - 1] != '/') {
393b398fe863860b072306b5297c8095c6d973aba06reed@android.com                    outDir.append("/");
394b398fe863860b072306b5297c8095c6d973aba06reed@android.com                }
395b398fe863860b072306b5297c8095c6d973aba06reed@android.com            }
3964cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--repeat") == 0) {
3974bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            argv++;
3984bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (argv < stop) {
3994bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                repeatDraw = atoi(*argv);
4004bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                if (repeatDraw < 1) {
4014bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                    repeatDraw = 1;
4024bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                }
4034bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            } else {
4044cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --repeat\n");
40586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
4064bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                return -1;
4074bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
4084cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--logPerIter") == 0) {
409161e1ba4c0a82e21c7d68808529699fd2394ad6cscroggo@google.com            logPerIter = true;
4104cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--timers") == 0) {
411be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            argv++;
412be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            if (argv < stop) {
413be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerWall = false;
41491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                truncatedTimerWall = false;
415be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerCpu = false;
41691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                truncatedTimerCpu = false;
417be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerGpu = false;
418be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                for (char* t = *argv; *t; ++t) {
419be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    switch (*t) {
420be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'w': timerWall = true; break;
421be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'c': timerCpu = true; break;
42291ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    case 'W': truncatedTimerWall = true; break;
42391ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    case 'C': truncatedTimerCpu = true; break;
424be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'g': timerGpu = true; break;
425be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    }
426be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
427be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            } else {
4284cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --timers\n");
42986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
430be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                return -1;
431be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            }
4324cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--rotate")) {
4334c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doRotate = true;
4344cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--scale")) {
435387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            doScale = true;
4364cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--clip")) {
4374c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doClip = true;
4384cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--min")) {
4392abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com            printMin = true;
4404cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceAA") == 0) {
44129348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceAA)) {
4424cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceAA\n");
44386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
44429348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
44529348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
4464cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceFilter") == 0) {
44729348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceFilter)) {
4484cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceFilter\n");
44986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
45029348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
45129348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
4524cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceDither") == 0) {
4534e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            bool tmp;
4544e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            if (!parse_bool_arg(++argv, stop, &tmp)) {
4554cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceDither\n");
45686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
4574e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com                return -1;
4584e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            }
4594e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            forceDither = tmp ? SkTriState::kTrue : SkTriState::kFalse;
4604cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceBlend") == 0) {
46129348cb0612e19030d979156860946241e2ff4bdreed@android.com            bool wantAlpha = false;
46229348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &wantAlpha)) {
4634cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceBlend\n");
46486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
46529348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
46629348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
46729348cb0612e19030d979156860946241e2ff4bdreed@android.com            forceAlpha = wantAlpha ? 0x80 : 0xFF;
468c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#if SK_SUPPORT_GPU
469c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com        } else if (strcmp(*argv, "--gpuCacheSize") == 0) {
470c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            if (stop - argv > 2) {
471c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                gpuCacheSize.fBytes = atoi(*++argv);
472c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                gpuCacheSize.fCount = atoi(*++argv);
473c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            } else {
474c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                SkDebugf("missing arg for --gpuCacheSize\n");
475c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                help();
476c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                return -1;
477c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            }
478c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#endif
4794cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--mode") == 0) {
480fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            argv++;
481fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            if (argv < stop) {
482fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (strcmp(*argv, "normal") == 0) {
483fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kNormal_benchModes;
484fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "deferred") == 0) {
485fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kDeferred_benchModes;
486fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else if (strcmp(*argv, "deferredSilent") == 0) {
487fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    benchMode = kDeferredSilent_benchModes;
488fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "record") == 0) {
489fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kRecord_benchModes;
490fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "picturerecord") == 0) {
491fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kPictureRecord_benchModes;
492fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
4934cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                    logger.logError("bad arg for --mode\n");
494fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    help();
495fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    return -1;
496fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
497fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            } else {
4984cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --mode\n");
49982a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                help();
50082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                return -1;
50182a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
5024cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--strokeWidth") == 0) {
503652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            argv++;
504652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            if (argv < stop) {
505652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                const char *strokeWidthStr = *argv;
506652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                if (sscanf(strokeWidthStr, "%f", &strokeWidth) != 1) {
5074cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                  logger.logError("bad arg for --strokeWidth\n");
50886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                  help();
509652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                  return -1;
510652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                }
511652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                hasStrokeWidth = true;
512652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            } else {
5134cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --strokeWidth\n");
51486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
515652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                return -1;
516652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            }
5174cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--match") == 0) {
518387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
519387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
5201a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com                *fMatches.append() = *argv;
521387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
5224cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --match\n");
52386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
524387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
525387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
5264cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--config") == 0) {
527387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
528387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
529387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                int index = findConfig(*argv);
530387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                if (index >= 0) {
53113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    *configs.append() = index;
53213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    userConfig = true;
533387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                } else {
53429348cb0612e19030d979156860946241e2ff4bdreed@android.com                    SkString str;
53529348cb0612e19030d979156860946241e2ff4bdreed@android.com                    str.printf("unrecognized config %s\n", *argv);
536a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    logger.logError(str);
53786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                    help();
538387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                    return -1;
539387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                }
540387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
5414cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --config\n");
542a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                help();
543a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                return -1;
544a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            }
5454cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--logFile") == 0) {
546a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            argv++;
547a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            if (argv < stop) {
548a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                if (!logger.SetLogFile(*argv)) {
549a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    SkString str;
550a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    str.printf("Could not open %s for writing.", *argv);
5519a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                    logger.logError(str);
552a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    return -1;
553a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                }
554a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            } else {
5554cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --logFile\n");
55686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
557387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
5584c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
5590c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com        } else if (strlen(*argv) > 2 && strncmp(*argv, "-D", 2) == 0) {
560e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            argv++;
5610c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com            if (argv < stop) {
562e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                defineDict.set(argv[-1] + 2, *argv);
563e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            } else {
564a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("incomplete '-Dfoo bar' definition\n");
56586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
566e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                return -1;
567e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            }
56886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com        } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
56986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
57086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            return 0;
571387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else {
57229348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
57329348cb0612e19030d979156860946241e2ff4bdreed@android.com            str.printf("unrecognized arg %s\n", *argv);
574a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logError(str);
57586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
576387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            return -1;
577b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
578b398fe863860b072306b5297c8095c6d973aba06reed@android.com    }
579fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)
580fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            && !outDir.isEmpty()) {
5814cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        logger.logError("'--mode record' and '--mode picturerecord' are not"
582fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                  " compatible with -o.\n");
583fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        return -1;
584fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
585fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) {
586fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        perIterTimeformat.set("%.4f");
587fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        normalTimeFormat.set("%6.4f");
588fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
58913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    if (!userConfig) {
59013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        // if no config is specified by user, we add them all.
59113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (unsigned int i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
59213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            *configs.append() = i;
59313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        }
59413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    }
595a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
5963b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    // report our current settings
5973b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    {
5983b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com        SkString str;
599fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        const char* deferredMode = benchMode == kDeferred_benchModes ? "yes" :
600fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org            (benchMode == kDeferredSilent_benchModes ? "silent" : "no");
601af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com        str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d "
602fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                   "deferred=%s logperiter=%d",
603fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                   forceAlpha, forceAA, forceFilter, deferredMode,
604fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                   logPerIter);
6052abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com        str.appendf(" rotate=%d scale=%d clip=%d min=%d",
6062abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                   doRotate, doScale, doClip, printMin);
607fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        str.appendf(" record=%d picturerecord=%d",
608fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kRecord_benchModes,
609fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kPictureRecord_benchModes);
610a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        const char * ditherName;
611a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        switch (forceDither) {
612a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kDefault: ditherName = "default"; break;
613a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kTrue: ditherName = "true"; break;
614a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kFalse: ditherName = "false"; break;
615a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            default: ditherName = "<invalid>"; break;
616a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
617a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.appendf(" dither=%s", ditherName);
618fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
619a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        if (hasStrokeWidth) {
620a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.appendf(" strokeWidth=%f", strokeWidth);
621a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        } else {
622a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.append(" strokeWidth=none");
623a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
624a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
625a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_SCALAR_IS_FLOAT)
626a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=float");
627a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_SCALAR_IS_FIXED)
628a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=fixed");
629a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
630a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
631a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_BUILD_FOR_WIN32)
632a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=WIN32");
633a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_MAC)
634a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=MAC");
635a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_ANDROID)
636a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=ANDROID");
637a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_UNIX)
638a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=UNIX");
639a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#else
640a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=other");
641a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
642a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
643a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_DEBUG)
644a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" DEBUG");
645a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
646a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append("\n");
647a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(str);
6483b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    }
649508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
650cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    SkTArray<BenchTimer*> timers(SK_ARRAY_COUNT(gConfigs));
6515c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
652cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
653c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com        SkGLContextHelper* glCtx = NULL;
654cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        if (kGPU_Backend == gConfigs[i].fBackend) {
655c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            GrContext* context = gContextFactory.get(gConfigs[i].fContextType);
656c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            if (NULL != context) {
657c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                // Set the user specified cache limits if non-default.
658c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                size_t bytes;
659c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                int count;
660c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                context->getTextureCacheLimits(&count, &bytes);
661c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                if (-1 != gpuCacheSize.fBytes) {
662c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                    bytes = gpuCacheSize.fBytes;
663c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                }
664c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                if (-1 != gpuCacheSize.fCount) {
665c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                    count = gpuCacheSize.fCount;
666c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                }
667c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                context->setTextureCacheLimits(count, bytes);
668c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            }
669c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            glCtx = gContextFactory.getGLContext(gConfigs[i].fContextType);
670cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
671c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com        timers.push_back(SkNEW_ARGS(BenchTimer, (glCtx)));
672cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#else
673cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        timers.push_back(SkNEW(BenchTimer));
674cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
675cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
67674913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com
677e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter iter(&defineDict);
678bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* bench;
679bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    while ((bench = iter.next()) != NULL) {
6807fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com        SkAutoTUnref<SkBenchmark> benchUnref(bench);
6817fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com
682b398fe863860b072306b5297c8095c6d973aba06reed@android.com        SkIPoint dim = bench->getSize();
683b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (dim.fX <= 0 || dim.fY <= 0) {
684b398fe863860b072306b5297c8095c6d973aba06reed@android.com            continue;
685b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
686fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
6874bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAlpha(forceAlpha);
6884bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAA(forceAA);
68929348cb0612e19030d979156860946241e2ff4bdreed@android.com        bench->setForceFilter(forceFilter);
6904e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com        bench->setDither(forceDither);
691652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        if (hasStrokeWidth) {
692652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            bench->setStrokeWidth(strokeWidth);
693652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        }
694fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
695387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        // only run benchmarks if their name contains matchStr
6961a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (skip_name(fMatches, bench->getName())) {
697387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            continue;
698387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        }
699fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
70029348cb0612e19030d979156860946241e2ff4bdreed@android.com        {
70129348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
702d34658a5f1b961e2852c2272ac8b47701a42e50dreed@google.com            str.printf("running bench [%d %d] %28s", dim.fX, dim.fY,
7030c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com                       bench->getName());
704a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logProgress(str);
70529348cb0612e19030d979156860946241e2ff4bdreed@android.com        }
706fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
70730e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        AutoPrePostDraw appd(bench);
70830e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
7099dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com        bool runOnce = false;
71013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (int x = 0; x < configs.count(); ++x) {
7119dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            if (!bench->isRendering() && runOnce) {
7129dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com                continue;
7139dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            }
7149dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            runOnce = true;
7159dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com
71613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            int configIndex = configs[x];
71713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com
71813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            outConfig = gConfigs[configIndex].fConfig;
71913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            configName = gConfigs[configIndex].fName;
72013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            backend = gConfigs[configIndex].fBackend;
721cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrContext* context = NULL;
722cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            BenchTimer* timer = timers[configIndex];
723508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
724cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
7259c55f801a35b0d6c39f007fae432bd13094f3c52sugoi@google.com            SkGLContextHelper* glContext = NULL;
726cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            if (kGPU_Backend == backend) {
727cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                context = gContextFactory.get(gConfigs[configIndex].fContextType);
728cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL == context) {
729cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    continue;
730cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                }
731cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                glContext = gContextFactory.getGLContext(gConfigs[configIndex].fContextType);
7324bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
733cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
734cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDevice* device = make_device(outConfig, dim, backend, context);
735fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkCanvas* canvas = NULL;
736fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordFrom;
737fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordTo;
738fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            switch(benchMode) {
7394c5ea4480341f0f663b51e9d78b948bc0a785f4dskia.committer@gmail.com                case kDeferredSilent_benchModes:
740fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kDeferred_benchModes:
741fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = new SkDeferredCanvas(device);
742fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
743fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kRecord_benchModes:
74420bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
74520bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
746fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas->ref();
747fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
748fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kPictureRecord_benchModes: {
749fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // This sets up picture-to-picture recording.
750fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // The C++ drawing calls for the benchmark are recorded into
751fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // pictureRecordFrom. As the benchmark, we will time how
752fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // long it takes to playback pictureRecordFrom into
753fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // pictureRecordTo.
75420bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    SkCanvas* tempCanvas = pictureRecordFrom.beginRecording(dim.fX, dim.fY,
75520bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
756fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(tempCanvas);
757fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.endRecording();
75820bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
75920bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
760fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas->ref();
761fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
762fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
763fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kNormal_benchModes:
764fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = new SkCanvas(device);
765fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
766fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                default:
767fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    SkASSERT(0);
76882a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
769a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            device->unref();
77082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            SkAutoUnref canvasUnref(canvas);
77182a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com
7724c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doClip) {
77382a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performClip(canvas, dim.fX, dim.fY);
7744c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
775387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (doScale) {
77682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performScale(canvas, dim.fX, dim.fY);
777387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
7784c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doRotate) {
77982a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performRotate(canvas, dim.fX, dim.fY);
7804c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
781508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
782af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // warm up caches if needed
783eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            if (repeatDraw > 1) {
78491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com#if SK_SUPPORT_GPU
785cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                // purge the GPU resources to reduce variance
786cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL != context) {
787cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    context->freeGpuResources();
78891ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                }
78991ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com#endif
79082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
791fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (benchMode == kPictureRecord_benchModes) {
792fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.draw(canvas);
793fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
794fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(canvas);
795fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
796fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
797fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                if (kDeferredSilent_benchModes == benchMode) {
798fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
799fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else {
800fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    canvas->flush();
801fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                }
802cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
803cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL != context) {
804cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    context->flush();
805cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    SK_GL(*glContext, Finish());
806d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com                }
807cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
808eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            }
809af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
810af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // record timer values for each repeat, and their sum
8119a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com            TimerData timerData(perIterTimeformat, normalTimeFormat);
8124bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            for (int i = 0; i < repeatDraw; i++) {
813fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if ((benchMode == kRecord_benchModes
814fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                     || benchMode == kPictureRecord_benchModes)) {
815fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // This will clear the recorded commands so that they do not
816cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    // accumulate.
81720bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
81820bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
819fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
820fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
821cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timer->start();
82282a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
823fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (benchMode == kPictureRecord_benchModes) {
824fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.draw(canvas);
825fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
826fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(canvas);
827fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
828fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
829fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                if (kDeferredSilent_benchModes == benchMode) {
830fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
831fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else {
832fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    canvas->flush();
833fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                }
83491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com
83591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // stop the truncated timer after the last canvas call but
83691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // don't wait for all the GL calls to complete
837cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timer->truncatedEnd();
838cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
839cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL != glContext) {
840cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    context->flush();
841cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    SK_GL(*glContext, Finish());
84225df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com                }
843cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
84491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // stop the inclusive and gpu timers once all the GL calls
84591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // have completed
846cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timer->end();
847af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
848cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timerData.appendTimes(timer, repeatDraw - 1 == i);
8492abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com
85025df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com            }
8514bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (repeatDraw > 1) {
8529a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                SkString result = timerData.getResult(logPerIter, printMin, repeatDraw, configName,
8539a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                                                      timerWall, truncatedTimerWall, timerCpu,
854cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                                                      truncatedTimerCpu,
855cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                                                      timerGpu && NULL != context);
8569a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                logger.logProgress(result);
8574bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
8584c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (outDir.size() > 0) {
859a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                saveFile(bench->getName(), configName, outDir.c_str(),
860a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                         device->accessBitmap(false));
861a543b604e425c00ca7957160e73220ca71f75e0bjvanverth@google.com                canvas->clear(SK_ColorWHITE);
8624c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
8634bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        }
864a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(SkString("\n"));
865bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
866cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
8679d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#if GR_CACHE_STATS
868cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    for (int i = 0; i <= GrContextFactory::kLastGLContextType; ++i) {
869cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        GrContextFactory::GLContextType ctxType = (GrContextFactory::GLContextType)i;
870cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        GrContext* context = gContextFactory.get(ctxType);
871cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        if (NULL != context) {
872cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDebugf("Cache Stats for %s context:\n", GrContextFactory::GLContextTypeName(ctxType));
873cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            context->printCacheStats();
874cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDebugf("\n");
875cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
876cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
8779d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#endif
878cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    // Destroy the GrContext before the inst tracking printing at main() exit occurs.
879cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    gContextFactory.destroyContexts();
880cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
8815c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
882cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        SkDELETE(timers[i]);
883cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
8849d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com
885bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    return 0;
886bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
8875987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
8887158e6acca1b1ecc321d4d514a31cba11b5ead60borenet@google.com#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
8895987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint main(int argc, char * const argv[]) {
8905987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com    return tool_main(argc, (char**) argv);
8915987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
8925987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
893