benchmain.cpp revision 5c90e291425b2788f47679266d9584845ceefc2e
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() {
2814cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("Usage: bench [-o outDir] [--repeat nr] [--logPerIter 1|0] "
2824cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                          "[--timers [wcgWC]*] [--rotate]\n"
2834cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--scale] [--clip] [--min] [--forceAA 1|0] [--forceFilter 1|0]\n"
2844cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--forceDither 1|0] [--forceBlend 1|0] [--strokeWidth width]\n"
285fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "    [--match name] [--mode normal|deferred|deferredSilent|record|picturerecord]\n"
2864cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--config 8888|565|GPU|ANGLE|NULLGPU] [-Dfoo bar] [--logFile filename]\n"
28782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com             "    [-h|--help]");
28886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("\n\n");
28986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -o outDir : Image of each bench will be put in outDir.\n");
2904cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --repeat nr : Each bench repeats for nr times.\n");
2914cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --logPerIter 1|0 : "
292af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com             "Log each repeat timer instead of mean, default is disabled.\n");
2934cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --timers [wcgWC]* : "
29491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com             "Display wall, cpu, gpu, truncated wall or truncated cpu time for each bench.\n");
2954cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --rotate : Rotate before each bench runs.\n");
2964cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --scale : Scale before each bench runs.\n");
2974cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --clip : Clip before each bench runs.\n");
2984cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --min : Print the minimum times (instead of average).\n");
2994cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceAA 1|0 : "
30086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable anti-aliased, default is enabled.\n");
3014cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceFilter 1|0 : "
30286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable bitmap filtering, default is disabled.\n");
3034cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceDither 1|0 : "
30486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
3054cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceBlend 1|0 : "
30686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
3074cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --strokeWidth width : The width for path stroke.\n");
3084cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --match name : Only run bench whose name is matched.\n");
309fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    SkDebugf("    --mode normal|deferred|deferredSilent|record|picturerecord :\n"
310fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "             Run in the corresponding mode\n"
311fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 normal, Use a normal canvas to draw to;\n"
312fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 deferred, Use a deferrred canvas when drawing;\n"
313fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "                 deferredSilent, deferred with silent playback;\n"
314fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 record, Benchmark the time to record to an SkPicture;\n"
315fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 picturerecord, Benchmark the time to do record from a \n"
316fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                                SkPicture to a SkPicture.\n");
3174cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --logFile filename : destination for writing log output, in addition to stdout.\n");
318cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
3194cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --config 8888|565|GPU|ANGLE|NULLGPU : "
32086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Run bench in corresponding config mode.\n");
321cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
3224cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --config 8888|565: "
323cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com             "Run bench in corresponding config mode.\n");
324cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
32586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -Dfoo bar : Add extra definition to bench.\n");
32686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -h|--help : Show this help message.\n");
32786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com}
32886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com
3295987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv);
3305987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv) {
3314e23068b374023d43c4c725138d523721d975892bsalomon@google.com#if SK_ENABLE_INST_COUNT
33265a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com    gPrintInstCount = true;
33365a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#endif
3343a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkAutoGraphics ag;
33565a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com
336e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    SkTDict<const char*> defineDict(1024);
3374bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int repeatDraw = 1;
338af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    bool logPerIter = false;
3394bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int forceAlpha = 0xFF;
3404bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    bool forceAA = true;
34129348cb0612e19030d979156860946241e2ff4bdreed@android.com    bool forceFilter = false;
3424e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com    SkTriState::State forceDither = SkTriState::kDefault;
343be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerWall = false;
34491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com    bool truncatedTimerWall = false;
345be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerCpu = true;
34691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com    bool truncatedTimerCpu = false;
347be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerGpu = true;
348387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    bool doScale = false;
3494c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doRotate = false;
3504c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doClip = false;
3512abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com    bool printMin = false;
352652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    bool hasStrokeWidth = false;
353652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    float strokeWidth;
3541a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    SkTDArray<const char*> fMatches;
355fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    benchModes benchMode = kNormal_benchModes;
356fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString perIterTimeformat("%.2f");
357fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString normalTimeFormat("%6.2f");
358fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
359b398fe863860b072306b5297c8095c6d973aba06reed@android.com    SkString outDir;
360387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    SkBitmap::Config outConfig = SkBitmap::kNo_Config;
361387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const char* configName = "";
362a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend backend = kRaster_Backend;  // for warning
36313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    SkTDArray<int> configs;
36413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    bool userConfig = false;
365fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3669a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com    SkBenchLogger logger;
3679a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com
368b398fe863860b072306b5297c8095c6d973aba06reed@android.com    char* const* stop = argv + argc;
369b398fe863860b072306b5297c8095c6d973aba06reed@android.com    for (++argv; argv < stop; ++argv) {
370b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (strcmp(*argv, "-o") == 0) {
371b398fe863860b072306b5297c8095c6d973aba06reed@android.com            argv++;
372b398fe863860b072306b5297c8095c6d973aba06reed@android.com            if (argv < stop && **argv) {
373b398fe863860b072306b5297c8095c6d973aba06reed@android.com                outDir.set(*argv);
374b398fe863860b072306b5297c8095c6d973aba06reed@android.com                if (outDir.c_str()[outDir.size() - 1] != '/') {
375b398fe863860b072306b5297c8095c6d973aba06reed@android.com                    outDir.append("/");
376b398fe863860b072306b5297c8095c6d973aba06reed@android.com                }
377b398fe863860b072306b5297c8095c6d973aba06reed@android.com            }
3784cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--repeat") == 0) {
3794bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            argv++;
3804bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (argv < stop) {
3814bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                repeatDraw = atoi(*argv);
3824bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                if (repeatDraw < 1) {
3834bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                    repeatDraw = 1;
3844bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                }
3854bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            } else {
3864cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --repeat\n");
38786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
3884bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                return -1;
3894bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
3904cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--logPerIter") == 0) {
391af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            if (!parse_bool_arg(++argv, stop, &logPerIter)) {
3924cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --logPerIter\n");
393af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                help();
394af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                return -1;
395af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            }
3964cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--timers") == 0) {
397be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            argv++;
398be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            if (argv < stop) {
399be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerWall = false;
40091ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                truncatedTimerWall = false;
401be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerCpu = false;
40291ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                truncatedTimerCpu = false;
403be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerGpu = false;
404be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                for (char* t = *argv; *t; ++t) {
405be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    switch (*t) {
406be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'w': timerWall = true; break;
407be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'c': timerCpu = true; break;
40891ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    case 'W': truncatedTimerWall = true; break;
40991ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    case 'C': truncatedTimerCpu = true; break;
410be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'g': timerGpu = true; break;
411be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    }
412be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
413be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            } else {
4144cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --timers\n");
41586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
416be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                return -1;
417be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            }
4184cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--rotate")) {
4194c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doRotate = true;
4204cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--scale")) {
421387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            doScale = true;
4224cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--clip")) {
4234c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doClip = true;
4244cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--min")) {
4252abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com            printMin = true;
4264cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceAA") == 0) {
42729348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceAA)) {
4284cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceAA\n");
42986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
43029348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
43129348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
4324cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceFilter") == 0) {
43329348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceFilter)) {
4344cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceFilter\n");
43586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
43629348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
43729348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
4384cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceDither") == 0) {
4394e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            bool tmp;
4404e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            if (!parse_bool_arg(++argv, stop, &tmp)) {
4414cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceDither\n");
44286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
4434e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com                return -1;
4444e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            }
4454e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            forceDither = tmp ? SkTriState::kTrue : SkTriState::kFalse;
4464cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceBlend") == 0) {
44729348cb0612e19030d979156860946241e2ff4bdreed@android.com            bool wantAlpha = false;
44829348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &wantAlpha)) {
4494cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceBlend\n");
45086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
45129348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
45229348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
45329348cb0612e19030d979156860946241e2ff4bdreed@android.com            forceAlpha = wantAlpha ? 0x80 : 0xFF;
4544cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--mode") == 0) {
455fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            argv++;
456fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            if (argv < stop) {
457fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (strcmp(*argv, "normal") == 0) {
458fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kNormal_benchModes;
459fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "deferred") == 0) {
460fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kDeferred_benchModes;
461fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else if (strcmp(*argv, "deferredSilent") == 0) {
462fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    benchMode = kDeferredSilent_benchModes;
463fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "record") == 0) {
464fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kRecord_benchModes;
465fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "picturerecord") == 0) {
466fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kPictureRecord_benchModes;
467fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
4684cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                    logger.logError("bad arg for --mode\n");
469fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    help();
470fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    return -1;
471fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
472fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            } else {
4734cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --mode\n");
47482a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                help();
47582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                return -1;
47682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
4774cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--strokeWidth") == 0) {
478652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            argv++;
479652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            if (argv < stop) {
480652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                const char *strokeWidthStr = *argv;
481652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                if (sscanf(strokeWidthStr, "%f", &strokeWidth) != 1) {
4824cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                  logger.logError("bad arg for --strokeWidth\n");
48386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                  help();
484652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                  return -1;
485652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                }
486652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                hasStrokeWidth = true;
487652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            } else {
4884cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --strokeWidth\n");
48986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
490652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                return -1;
491652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            }
4924cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--match") == 0) {
493387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
494387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
4951a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com                *fMatches.append() = *argv;
496387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
4974cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --match\n");
49886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
499387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
500387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
5014cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--config") == 0) {
502387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
503387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
504387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                int index = findConfig(*argv);
505387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                if (index >= 0) {
50613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    *configs.append() = index;
50713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    userConfig = true;
508387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                } else {
50929348cb0612e19030d979156860946241e2ff4bdreed@android.com                    SkString str;
51029348cb0612e19030d979156860946241e2ff4bdreed@android.com                    str.printf("unrecognized config %s\n", *argv);
511a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    logger.logError(str);
51286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                    help();
513387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                    return -1;
514387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                }
515387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
5164cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --config\n");
517a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                help();
518a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                return -1;
519a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            }
5204cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--logFile") == 0) {
521a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            argv++;
522a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            if (argv < stop) {
523a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                if (!logger.SetLogFile(*argv)) {
524a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    SkString str;
525a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    str.printf("Could not open %s for writing.", *argv);
5269a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                    logger.logError(str);
527a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    return -1;
528a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                }
529a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            } else {
5304cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --logFile\n");
53186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
532387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
5334c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
5340c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com        } else if (strlen(*argv) > 2 && strncmp(*argv, "-D", 2) == 0) {
535e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            argv++;
5360c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com            if (argv < stop) {
537e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                defineDict.set(argv[-1] + 2, *argv);
538e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            } else {
539a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("incomplete '-Dfoo bar' definition\n");
54086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
541e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                return -1;
542e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            }
54386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com        } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
54486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
54586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            return 0;
546387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else {
54729348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
54829348cb0612e19030d979156860946241e2ff4bdreed@android.com            str.printf("unrecognized arg %s\n", *argv);
549a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logError(str);
55086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
551387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            return -1;
552b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
553b398fe863860b072306b5297c8095c6d973aba06reed@android.com    }
554fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)
555fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            && !outDir.isEmpty()) {
5564cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        logger.logError("'--mode record' and '--mode picturerecord' are not"
557fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                  " compatible with -o.\n");
558fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        return -1;
559fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
560fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) {
561fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        perIterTimeformat.set("%.4f");
562fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        normalTimeFormat.set("%6.4f");
563fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
56413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    if (!userConfig) {
56513eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        // if no config is specified by user, we add them all.
56613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (unsigned int i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
56713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            *configs.append() = i;
56813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        }
56913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    }
570a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
5713b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    // report our current settings
5723b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    {
5733b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com        SkString str;
574fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        const char* deferredMode = benchMode == kDeferred_benchModes ? "yes" :
575fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org            (benchMode == kDeferredSilent_benchModes ? "silent" : "no");
576af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com        str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d "
577fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                   "deferred=%s logperiter=%d",
578fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                   forceAlpha, forceAA, forceFilter, deferredMode,
579fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                   logPerIter);
5802abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com        str.appendf(" rotate=%d scale=%d clip=%d min=%d",
5812abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                   doRotate, doScale, doClip, printMin);
582fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        str.appendf(" record=%d picturerecord=%d",
583fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kRecord_benchModes,
584fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kPictureRecord_benchModes);
585a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        const char * ditherName;
586a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        switch (forceDither) {
587a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kDefault: ditherName = "default"; break;
588a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kTrue: ditherName = "true"; break;
589a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kFalse: ditherName = "false"; break;
590a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            default: ditherName = "<invalid>"; break;
591a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
592a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.appendf(" dither=%s", ditherName);
593fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
594a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        if (hasStrokeWidth) {
595a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.appendf(" strokeWidth=%f", strokeWidth);
596a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        } else {
597a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.append(" strokeWidth=none");
598a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
599a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
600a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_SCALAR_IS_FLOAT)
601a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=float");
602a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_SCALAR_IS_FIXED)
603a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=fixed");
604a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
605a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
606a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_BUILD_FOR_WIN32)
607a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=WIN32");
608a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_MAC)
609a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=MAC");
610a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_ANDROID)
611a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=ANDROID");
612a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_UNIX)
613a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=UNIX");
614a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#else
615a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=other");
616a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
617a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
618a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_DEBUG)
619a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" DEBUG");
620a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
621a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append("\n");
622a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(str);
6233b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    }
624508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
625cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    SkTArray<BenchTimer*> timers(SK_ARRAY_COUNT(gConfigs));
6265c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
627cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
628cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        SkGLContext* ctx = NULL;
629cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        if (kGPU_Backend == gConfigs[i].fBackend) {
630cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            ctx = gContextFactory.getGLContext(gConfigs[i].fContextType);
631cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
632cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        timers.push_back(SkNEW_ARGS(BenchTimer, (ctx)));
633cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#else
634cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        timers.push_back(SkNEW(BenchTimer));
635cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
636cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
63774913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com
638e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter iter(&defineDict);
639bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* bench;
640bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    while ((bench = iter.next()) != NULL) {
6417fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com        SkAutoTUnref<SkBenchmark> benchUnref(bench);
6427fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com
643b398fe863860b072306b5297c8095c6d973aba06reed@android.com        SkIPoint dim = bench->getSize();
644b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (dim.fX <= 0 || dim.fY <= 0) {
645b398fe863860b072306b5297c8095c6d973aba06reed@android.com            continue;
646b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
647fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
6484bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAlpha(forceAlpha);
6494bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAA(forceAA);
65029348cb0612e19030d979156860946241e2ff4bdreed@android.com        bench->setForceFilter(forceFilter);
6514e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com        bench->setDither(forceDither);
652652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        if (hasStrokeWidth) {
653652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            bench->setStrokeWidth(strokeWidth);
654652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        }
655fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
656387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        // only run benchmarks if their name contains matchStr
6571a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (skip_name(fMatches, bench->getName())) {
658387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            continue;
659387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        }
660fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
66129348cb0612e19030d979156860946241e2ff4bdreed@android.com        {
66229348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
663d34658a5f1b961e2852c2272ac8b47701a42e50dreed@google.com            str.printf("running bench [%d %d] %28s", dim.fX, dim.fY,
6640c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com                       bench->getName());
665a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logProgress(str);
66629348cb0612e19030d979156860946241e2ff4bdreed@android.com        }
667fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
66830e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        AutoPrePostDraw appd(bench);
66930e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
6709dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com        bool runOnce = false;
67113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (int x = 0; x < configs.count(); ++x) {
6729dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            if (!bench->isRendering() && runOnce) {
6739dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com                continue;
6749dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            }
6759dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            runOnce = true;
6769dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com
67713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            int configIndex = configs[x];
67813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com
67913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            outConfig = gConfigs[configIndex].fConfig;
68013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            configName = gConfigs[configIndex].fName;
68113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            backend = gConfigs[configIndex].fBackend;
682cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrContext* context = NULL;
683cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkGLContext* glContext = NULL;
684cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            BenchTimer* timer = timers[configIndex];
685508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
686cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
687cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            if (kGPU_Backend == backend) {
688cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                context = gContextFactory.get(gConfigs[configIndex].fContextType);
689cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL == context) {
690cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    continue;
691cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                }
692cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                glContext = gContextFactory.getGLContext(gConfigs[configIndex].fContextType);
6934bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
694cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
695cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDevice* device = make_device(outConfig, dim, backend, context);
696fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkCanvas* canvas = NULL;
697fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordFrom;
698fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordTo;
699fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            switch(benchMode) {
7004c5ea4480341f0f663b51e9d78b948bc0a785f4dskia.committer@gmail.com                case kDeferredSilent_benchModes:
701fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kDeferred_benchModes:
702fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = new SkDeferredCanvas(device);
703fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
704fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kRecord_benchModes:
70520bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
70620bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
707fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas->ref();
708fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
709fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kPictureRecord_benchModes: {
710fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // This sets up picture-to-picture recording.
711fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // The C++ drawing calls for the benchmark are recorded into
712fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // pictureRecordFrom. As the benchmark, we will time how
713fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // long it takes to playback pictureRecordFrom into
714fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // pictureRecordTo.
71520bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    SkCanvas* tempCanvas = pictureRecordFrom.beginRecording(dim.fX, dim.fY,
71620bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
717fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(tempCanvas);
718fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.endRecording();
71920bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
72020bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
721fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas->ref();
722fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
723fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
724fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kNormal_benchModes:
725fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = new SkCanvas(device);
726fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
727fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                default:
728fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    SkASSERT(0);
72982a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
730a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            device->unref();
73182a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            SkAutoUnref canvasUnref(canvas);
73282a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com
7334c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doClip) {
73482a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performClip(canvas, dim.fX, dim.fY);
7354c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
736387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (doScale) {
73782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performScale(canvas, dim.fX, dim.fY);
738387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
7394c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doRotate) {
74082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performRotate(canvas, dim.fX, dim.fY);
7414c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
742508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
743af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // warm up caches if needed
744eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            if (repeatDraw > 1) {
74591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com#if SK_SUPPORT_GPU
746cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                // purge the GPU resources to reduce variance
747cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL != context) {
748cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    context->freeGpuResources();
74991ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                }
75091ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com#endif
75182a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
752fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (benchMode == kPictureRecord_benchModes) {
753fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.draw(canvas);
754fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
755fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(canvas);
756fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
757fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
758fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                if (kDeferredSilent_benchModes == benchMode) {
759fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
760fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else {
761fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    canvas->flush();
762fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                }
763cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
764cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL != context) {
765cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    context->flush();
766cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    SK_GL(*glContext, Finish());
767d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com                }
768cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
769eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            }
770af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
771af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // record timer values for each repeat, and their sum
7729a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com            TimerData timerData(perIterTimeformat, normalTimeFormat);
7734bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            for (int i = 0; i < repeatDraw; i++) {
774fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if ((benchMode == kRecord_benchModes
775fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                     || benchMode == kPictureRecord_benchModes)) {
776fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // This will clear the recorded commands so that they do not
777cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    // accumulate.
77820bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
77920bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
780fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
781fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
782cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timer->start();
78382a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
784fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (benchMode == kPictureRecord_benchModes) {
785fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.draw(canvas);
786fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
787fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(canvas);
788fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
789fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
790fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                if (kDeferredSilent_benchModes == benchMode) {
791fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
792fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else {
793fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    canvas->flush();
794fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                }
79591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com
79691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // stop the truncated timer after the last canvas call but
79791ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // don't wait for all the GL calls to complete
798cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timer->truncatedEnd();
799cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
800cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL != glContext) {
801cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    context->flush();
802cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    SK_GL(*glContext, Finish());
80325df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com                }
804cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
80591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // stop the inclusive and gpu timers once all the GL calls
80691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // have completed
807cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timer->end();
808af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
809cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timerData.appendTimes(timer, repeatDraw - 1 == i);
8102abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com
81125df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com            }
8124bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (repeatDraw > 1) {
8139a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                SkString result = timerData.getResult(logPerIter, printMin, repeatDraw, configName,
8149a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                                                      timerWall, truncatedTimerWall, timerCpu,
815cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                                                      truncatedTimerCpu,
816cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                                                      timerGpu && NULL != context);
8179a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                logger.logProgress(result);
8184bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
8194c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (outDir.size() > 0) {
820a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                saveFile(bench->getName(), configName, outDir.c_str(),
821a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                         device->accessBitmap(false));
822a543b604e425c00ca7957160e73220ca71f75e0bjvanverth@google.com                canvas->clear(SK_ColorWHITE);
8234c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
8244bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        }
825a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(SkString("\n"));
826bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
827cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
8289d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#if GR_CACHE_STATS
829cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    for (int i = 0; i <= GrContextFactory::kLastGLContextType; ++i) {
830cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        GrContextFactory::GLContextType ctxType = (GrContextFactory::GLContextType)i;
831cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        GrContext* context = gContextFactory.get(ctxType);
832cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        if (NULL != context) {
833cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDebugf("Cache Stats for %s context:\n", GrContextFactory::GLContextTypeName(ctxType));
834cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            context->printCacheStats();
835cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDebugf("\n");
836cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
837cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
8389d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#endif
839cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    // Destroy the GrContext before the inst tracking printing at main() exit occurs.
840cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    gContextFactory.destroyContexts();
841cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
8425c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
843cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        SkDELETE(timers[i]);
844cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
8459d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com
846bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    return 0;
847bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
8485987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
8497158e6acca1b1ecc321d4d514a31cba11b5ead60borenet@google.com#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
8505987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint main(int argc, char * const argv[]) {
8515987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com    return tool_main(argc, (char**) argv);
8525987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
8535987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
854