benchmain.cpp revision 5987f58036574ccf23049b5fe71f29a441d0641d
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"
14971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrRenderTarget.h"
15cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_ANGLE
16cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "gl/SkANGLEGLContext.h"
17cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
18cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "gl/SkNativeGLContext.h"
19cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "gl/SkNullGLContext.h"
20cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "gl/SkDebugGLContext.h"
21cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "SkGpuDevice.h"
22cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
23971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
249a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com#include "SkBenchLogger.h"
25971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "SkBenchmark.h"
26bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkCanvas.h"
2782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com#include "SkDeferredCanvas.h"
2844b67b2ed16ecb6fe001b785498e20b13fa42d0cjunov@chromium.org#include "SkDevice.h"
29f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com#include "SkColorPriv.h"
303a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkGraphics.h"
31b398fe863860b072306b5297c8095c6d973aba06reed@android.com#include "SkImageEncoder.h"
326c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkNWayCanvas.h"
336c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkPicture.h"
34bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkString.h"
359a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com#include "TimerData.h"
3629348cb0612e19030d979156860946241e2ff4bdreed@android.com
37fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.orgenum benchModes {
38fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kNormal_benchModes,
39fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kDeferred_benchModes,
40fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    kDeferredSilent_benchModes,
41fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kRecord_benchModes,
42fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kPictureRecord_benchModes
43fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org};
44fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
45fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org///////////////////////////////////////////////////////////////////////////////
46fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
476c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic void erase(SkBitmap& bm) {
486c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
496c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm.eraseColor(0);
506c924ad46c89955e78e071c792ef00df9910b42freed@android.com    } else {
516c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm.eraseColor(SK_ColorWHITE);
526c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
536c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
546c924ad46c89955e78e071c792ef00df9910b42freed@android.com
55a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org#if 0
566c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic bool equal(const SkBitmap& bm1, const SkBitmap& bm2) {
576c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm1.width() != bm2.width() ||
586c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm1.height() != bm2.height() ||
596c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm1.config() != bm2.config()) {
606c924ad46c89955e78e071c792ef00df9910b42freed@android.com        return false;
616c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
62fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
636c924ad46c89955e78e071c792ef00df9910b42freed@android.com    size_t pixelBytes = bm1.width() * bm1.bytesPerPixel();
646c924ad46c89955e78e071c792ef00df9910b42freed@android.com    for (int y = 0; y < bm1.height(); y++) {
656c924ad46c89955e78e071c792ef00df9910b42freed@android.com        if (memcmp(bm1.getAddr(0, y), bm2.getAddr(0, y), pixelBytes)) {
666c924ad46c89955e78e071c792ef00df9910b42freed@android.com            return false;
676c924ad46c89955e78e071c792ef00df9910b42freed@android.com        }
686c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
696c924ad46c89955e78e071c792ef00df9910b42freed@android.com    return true;
706c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
71a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org#endif
726c924ad46c89955e78e071c792ef00df9910b42freed@android.com
73bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comclass Iter {
74bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.compublic:
75e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter(void* param) {
76bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        fBench = BenchRegistry::Head();
77e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com        fParam = param;
78bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
79fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
80bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* next() {
81bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        if (fBench) {
82bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            BenchRegistry::Factory f = fBench->factory();
83bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            fBench = fBench->next();
84e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            return f(fParam);
85bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
86bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        return NULL;
87bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
88d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
89bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comprivate:
90bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    const BenchRegistry* fBench;
91e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    void* fParam;
92bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com};
93bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
9430e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.comclass AutoPrePostDraw {
9530e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.compublic:
9630e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    AutoPrePostDraw(SkBenchmark* bench) : fBench(bench) {
9730e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        fBench->preDraw();
9830e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    }
9930e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    ~AutoPrePostDraw() {
10030e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        fBench->postDraw();
10130e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    }
10230e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.comprivate:
10330e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    SkBenchmark* fBench;
10430e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com};
10530e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
106bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comstatic void make_filename(const char name[], SkString* path) {
107bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    path->set(name);
108bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    for (int i = 0; name[i]; i++) {
109bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        switch (name[i]) {
110bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '/':
111bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '\\':
112bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ' ':
113bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ':':
114bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                path->writable_str()[i] = '-';
115bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
116bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            default:
117bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
118bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
119bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
120bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
121bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
1224c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void saveFile(const char name[], const char config[], const char dir[],
1234c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                     const SkBitmap& bm) {
1244c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkBitmap copy;
1254c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    if (!bm.copyTo(&copy, SkBitmap::kARGB_8888_Config)) {
1264c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        return;
1274c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
128fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
129f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
130f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        // turn alpha into gray-scale
131f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        size_t size = copy.getSize() >> 2;
132f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        SkPMColor* p = copy.getAddr32(0, 0);
133f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        for (size_t i = 0; i < size; i++) {
134f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            int c = (*p >> SK_A32_SHIFT) & 0xFF;
135f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c = 255 - c;
136f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c |= (c << 24) | (c << 16) | (c << 8);
137f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            *p++ = c | (SK_A32_MASK << SK_A32_SHIFT);
138f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        }
139f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    }
140fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1414c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkString str;
1424c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    make_filename(name, &str);
1434c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    str.appendf("_%s.png", config);
1444c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    str.prepend(dir);
1454c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    ::remove(str.c_str());
1464c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkImageEncoder::EncodeFile(str.c_str(), copy, SkImageEncoder::kPNG_Type,
1474c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                               100);
1484c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1494c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1504c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performClip(SkCanvas* canvas, int w, int h) {
1514c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkRect r;
152fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1534c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(10), SkIntToScalar(10),
1544c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
1554c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kIntersect_Op);
156fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1574c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
1584c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w-10), SkIntToScalar(h-10));
1594c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kXOR_Op);
1604c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1614c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1624c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performRotate(SkCanvas* canvas, int w, int h) {
1634c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
1644c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
165fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1664c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(x, y);
1674c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->rotate(SkIntToScalar(35));
1684c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(-x, -y);
1694c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1704c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
171387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.comstatic void performScale(SkCanvas* canvas, int w, int h) {
172387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
173387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
174fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
175387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(x, y);
176387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    // just enough so we can't take the sprite case
177387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
178387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(-x, -y);
179387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com}
180387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com
18129348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic bool parse_bool_arg(char * const* argv, char* const* stop, bool* var) {
18229348cb0612e19030d979156860946241e2ff4bdreed@android.com    if (argv < stop) {
18329348cb0612e19030d979156860946241e2ff4bdreed@android.com        *var = atoi(*argv) != 0;
18429348cb0612e19030d979156860946241e2ff4bdreed@android.com        return true;
18529348cb0612e19030d979156860946241e2ff4bdreed@android.com    }
18629348cb0612e19030d979156860946241e2ff4bdreed@android.com    return false;
18729348cb0612e19030d979156860946241e2ff4bdreed@android.com}
18829348cb0612e19030d979156860946241e2ff4bdreed@android.com
189a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgenum Backend {
190a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kRaster_Backend,
191a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kGPU_Backend,
192a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kPDF_Backend,
193a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org};
194a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
195cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
196508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comclass GLHelper {
197508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.compublic:
198508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GLHelper() {
199508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
200508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
201508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    bool init(SkGLContext* glCtx, int width, int height) {
202508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        GrContext* grCtx;
2038afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        if (!glCtx->init(width, height)) {
204508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            return false;
205508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        }
2068afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        GrPlatform3DContext ctx =
2078afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            reinterpret_cast<GrPlatform3DContext>(glCtx->gl());
2088afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        grCtx = GrContext::Create(kOpenGL_Shaders_GrEngine, ctx);
2098afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        if (NULL != grCtx) {
2108afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            GrPlatformRenderTargetDesc desc;
2118afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            desc.fConfig = kSkia8888_PM_GrPixelConfig;
2128afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            desc.fWidth = width;
2138afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            desc.fHeight = height;
2148afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            desc.fStencilBits = 8;
2158afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            desc.fRenderTargetHandle = glCtx->getFBOID();
2168afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            GrRenderTarget* rt = grCtx->createPlatformRenderTarget(desc);
2178afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            if (NULL == rt) {
2188afae61a57f87e4a50578effce6c428031499301tomhudson@google.com                grCtx->unref();
2198afae61a57f87e4a50578effce6c428031499301tomhudson@google.com                return false;
2208afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            }
2218afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            glCtx->ref();
2228afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            fGLContext.reset(glCtx);
2238afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            fGrContext.reset(grCtx);
2248afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            fRenderTarget.reset(rt);
2258afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        }
226508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return true;
227508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
228508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
2290da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    void cleanup() {
2300da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        fGLContext.reset(NULL);
2310da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        fGrContext.reset(NULL);
2320da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        fRenderTarget.reset(NULL);
2330da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    }
2340da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
235508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    bool isValid() {
236508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return NULL != fGLContext.get();
237508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
238508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
239508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkGLContext* glContext() {
240508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return fGLContext.get();
241508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
242508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
243508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GrRenderTarget* renderTarget() {
244508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return fRenderTarget.get();
245508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
246508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
247508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GrContext* grContext() {
248508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return fGrContext.get();
249508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
250508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comprivate:
251508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<SkGLContext> fGLContext;
252508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<GrContext> fGrContext;
253508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<GrRenderTarget> fRenderTarget;
254508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com};
255508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
256508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comstatic GLHelper gRealGLHelper;
257508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comstatic GLHelper gNullGLHelper;
2580da3719050473344b6013fd7b614611984f20effrobertphillips@google.comstatic GLHelper gDebugGLHelper;
259d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
260d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.comstatic GLHelper gANGLEGLHelper;
261cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
262cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else  // !SK_SUPPORT_GPU
263cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comclass GLHelper;
264cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comclass SkGLContext;
265cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // !SK_SUPPORT_GPU
266a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgstatic SkDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
267508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                             Backend backend, GLHelper* glHelper) {
268a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkDevice* device = NULL;
269a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkBitmap bitmap;
270a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    bitmap.setConfig(config, size.fX, size.fY);
271fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
272a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    switch (backend) {
273a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kRaster_Backend:
274a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            bitmap.allocPixels();
275a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            erase(bitmap);
276af951c9bc4cbb6e60b430194fe5127ebe99c53fbreed@google.com            device = new SkDevice(bitmap);
277a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
278cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
279a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kGPU_Backend:
280508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            device = new SkGpuDevice(glHelper->grContext(),
281508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                                     glHelper->renderTarget());
282a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
283cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
284a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kPDF_Backend:
285a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        default:
286a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            SkASSERT(!"unsupported");
287a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    }
288a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    return device;
289a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org}
290a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
2914bc1983e01d756ae9c91fd380758457f579d26eareed@android.comstatic const struct {
2924bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    SkBitmap::Config    fConfig;
2934bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    const char*         fName;
294a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend             fBackend;
295508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GLHelper*           fGLHelper;
2964bc1983e01d756ae9c91fd380758457f579d26eareed@android.com} gConfigs[] = {
297508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "8888",     kRaster_Backend, NULL },
298508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kRGB_565_Config,    "565",      kRaster_Backend, NULL },
299cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
300508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "GPU",      kGPU_Backend, &gRealGLHelper },
301d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
302d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    { SkBitmap::kARGB_8888_Config,  "ANGLE",    kGPU_Backend, &gANGLEGLHelper },
303cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
304a0b63b86313694f695bf0387ee0ce31de3deabb3robertphillips@google.com#ifdef SK_DEBUG
305a0b63b86313694f695bf0387ee0ce31de3deabb3robertphillips@google.com    { SkBitmap::kARGB_8888_Config,  "Debug",    kGPU_Backend, &gDebugGLHelper },
306cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_DEBUG
307508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "NULLGPU",  kGPU_Backend, &gNullGLHelper },
308cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
3094bc1983e01d756ae9c91fd380758457f579d26eareed@android.com};
3104bc1983e01d756ae9c91fd380758457f579d26eareed@android.com
3114c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic int findConfig(const char config[]) {
3124c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
3134c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        if (!strcmp(config, gConfigs[i].fName)) {
3144c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            return i;
3154c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        }
3164c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
3174c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    return -1;
3184c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
3194c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
3208382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.comstatic void determine_gpu_context_size(SkTDict<const char*>& defineDict,
3218382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com                                       int* contextWidth,
3228382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com                                       int* contextHeight) {
3238382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    Iter iter(&defineDict);
3248382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    SkBenchmark* bench;
3258382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    while ((bench = iter.next()) != NULL) {
3268382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        SkIPoint dim = bench->getSize();
3278382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        if (*contextWidth < dim.fX) {
3288382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com            *contextWidth = dim.fX;
3298382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        }
3308382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        if (*contextHeight < dim.fY) {
3318382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com            *contextHeight = dim.fY;
3328382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        }
3337fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com        bench->unref();
3348382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    }
3358382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com}
3368382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com
3371a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.comstatic bool skip_name(const SkTDArray<const char*> array, const char name[]) {
3381a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    if (0 == array.count()) {
3391a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        // no names, so don't skip anything
3401a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        return false;
3411a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    }
3421a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    for (int i = 0; i < array.count(); ++i) {
3431a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (strstr(name, array[i])) {
3441a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com            // found the name, so don't skip
3451a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com            return false;
3461a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        }
3471a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    }
3481a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    return true;
3491a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com}
3501a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com
35186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.comstatic void help() {
3524cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("Usage: bench [-o outDir] [--repeat nr] [--logPerIter 1|0] "
3534cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                          "[--timers [wcgWC]*] [--rotate]\n"
3544cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--scale] [--clip] [--min] [--forceAA 1|0] [--forceFilter 1|0]\n"
3554cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--forceDither 1|0] [--forceBlend 1|0] [--strokeWidth width]\n"
356fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "    [--match name] [--mode normal|deferred|deferredSilent|record|picturerecord]\n"
3574cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--config 8888|565|GPU|ANGLE|NULLGPU] [-Dfoo bar] [--logFile filename]\n"
35882a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com             "    [-h|--help]");
35986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("\n\n");
36086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -o outDir : Image of each bench will be put in outDir.\n");
3614cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --repeat nr : Each bench repeats for nr times.\n");
3624cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --logPerIter 1|0 : "
363af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com             "Log each repeat timer instead of mean, default is disabled.\n");
3644cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --timers [wcgWC]* : "
36591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com             "Display wall, cpu, gpu, truncated wall or truncated cpu time for each bench.\n");
3664cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --rotate : Rotate before each bench runs.\n");
3674cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --scale : Scale before each bench runs.\n");
3684cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --clip : Clip before each bench runs.\n");
3694cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --min : Print the minimum times (instead of average).\n");
3704cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceAA 1|0 : "
37186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable anti-aliased, default is enabled.\n");
3724cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceFilter 1|0 : "
37386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable bitmap filtering, default is disabled.\n");
3744cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceDither 1|0 : "
37586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
3764cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceBlend 1|0 : "
37786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
3784cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --strokeWidth width : The width for path stroke.\n");
3794cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --match name : Only run bench whose name is matched.\n");
380fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    SkDebugf("    --mode normal|deferred|deferredSilent|record|picturerecord :\n"
381fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "             Run in the corresponding mode\n"
382fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 normal, Use a normal canvas to draw to;\n"
383fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 deferred, Use a deferrred canvas when drawing;\n"
384fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "                 deferredSilent, deferred with silent playback;\n"
385fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 record, Benchmark the time to record to an SkPicture;\n"
386fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 picturerecord, Benchmark the time to do record from a \n"
387fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                                SkPicture to a SkPicture.\n");
3884cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --logFile filename : destination for writing log output, in addition to stdout.\n");
389cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
3904cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --config 8888|565|GPU|ANGLE|NULLGPU : "
39186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Run bench in corresponding config mode.\n");
392cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
3934cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --config 8888|565: "
394cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com             "Run bench in corresponding config mode.\n");
395cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
39686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -Dfoo bar : Add extra definition to bench.\n");
39786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -h|--help : Show this help message.\n");
39886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com}
39986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com
4005987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv);
4015987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv) {
40265a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#ifdef SK_ENABLE_INST_COUNT
40365a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com    gPrintInstCount = true;
40465a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#endif
4053a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkAutoGraphics ag;
40665a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com
407e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    SkTDict<const char*> defineDict(1024);
4084bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int repeatDraw = 1;
409af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    bool logPerIter = false;
4104bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int forceAlpha = 0xFF;
4114bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    bool forceAA = true;
41229348cb0612e19030d979156860946241e2ff4bdreed@android.com    bool forceFilter = false;
4134e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com    SkTriState::State forceDither = SkTriState::kDefault;
414be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerWall = false;
41591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com    bool truncatedTimerWall = false;
416be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerCpu = true;
41791ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com    bool truncatedTimerCpu = false;
418be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerGpu = true;
419387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    bool doScale = false;
4204c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doRotate = false;
4214c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doClip = false;
4222abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com    bool printMin = false;
423652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    bool hasStrokeWidth = false;
424652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    float strokeWidth;
4251a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    SkTDArray<const char*> fMatches;
426fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    benchModes benchMode = kNormal_benchModes;
427fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString perIterTimeformat("%.2f");
428fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString normalTimeFormat("%6.2f");
429fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
430b398fe863860b072306b5297c8095c6d973aba06reed@android.com    SkString outDir;
431387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    SkBitmap::Config outConfig = SkBitmap::kNo_Config;
432cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com    GLHelper* glHelper = NULL;
433387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const char* configName = "";
434a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend backend = kRaster_Backend;  // for warning
43513eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    SkTDArray<int> configs;
43613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    bool userConfig = false;
437fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
4389a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com    SkBenchLogger logger;
4399a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com
440b398fe863860b072306b5297c8095c6d973aba06reed@android.com    char* const* stop = argv + argc;
441b398fe863860b072306b5297c8095c6d973aba06reed@android.com    for (++argv; argv < stop; ++argv) {
442b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (strcmp(*argv, "-o") == 0) {
443b398fe863860b072306b5297c8095c6d973aba06reed@android.com            argv++;
444b398fe863860b072306b5297c8095c6d973aba06reed@android.com            if (argv < stop && **argv) {
445b398fe863860b072306b5297c8095c6d973aba06reed@android.com                outDir.set(*argv);
446b398fe863860b072306b5297c8095c6d973aba06reed@android.com                if (outDir.c_str()[outDir.size() - 1] != '/') {
447b398fe863860b072306b5297c8095c6d973aba06reed@android.com                    outDir.append("/");
448b398fe863860b072306b5297c8095c6d973aba06reed@android.com                }
449b398fe863860b072306b5297c8095c6d973aba06reed@android.com            }
4504cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--repeat") == 0) {
4514bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            argv++;
4524bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (argv < stop) {
4534bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                repeatDraw = atoi(*argv);
4544bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                if (repeatDraw < 1) {
4554bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                    repeatDraw = 1;
4564bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                }
4574bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            } else {
4584cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --repeat\n");
45986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
4604bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                return -1;
4614bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
4624cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--logPerIter") == 0) {
463af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            if (!parse_bool_arg(++argv, stop, &logPerIter)) {
4644cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --logPerIter\n");
465af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                help();
466af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                return -1;
467af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            }
4684cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--timers") == 0) {
469be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            argv++;
470be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            if (argv < stop) {
471be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerWall = false;
47291ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                truncatedTimerWall = false;
473be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerCpu = false;
47491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                truncatedTimerCpu = false;
475be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerGpu = false;
476be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                for (char* t = *argv; *t; ++t) {
477be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    switch (*t) {
478be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'w': timerWall = true; break;
479be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'c': timerCpu = true; break;
48091ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    case 'W': truncatedTimerWall = true; break;
48191ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    case 'C': truncatedTimerCpu = true; break;
482be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'g': timerGpu = true; break;
483be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    }
484be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
485be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            } else {
4864cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --timers\n");
48786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
488be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                return -1;
489be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            }
4904cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--rotate")) {
4914c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doRotate = true;
4924cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--scale")) {
493387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            doScale = true;
4944cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--clip")) {
4954c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doClip = true;
4964cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--min")) {
4972abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com            printMin = true;
4984cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceAA") == 0) {
49929348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceAA)) {
5004cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceAA\n");
50186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
50229348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
50329348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
5044cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceFilter") == 0) {
50529348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceFilter)) {
5064cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceFilter\n");
50786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
50829348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
50929348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
5104cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceDither") == 0) {
5114e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            bool tmp;
5124e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            if (!parse_bool_arg(++argv, stop, &tmp)) {
5134cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceDither\n");
51486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
5154e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com                return -1;
5164e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            }
5174e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            forceDither = tmp ? SkTriState::kTrue : SkTriState::kFalse;
5184cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceBlend") == 0) {
51929348cb0612e19030d979156860946241e2ff4bdreed@android.com            bool wantAlpha = false;
52029348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &wantAlpha)) {
5214cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceBlend\n");
52286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
52329348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
52429348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
52529348cb0612e19030d979156860946241e2ff4bdreed@android.com            forceAlpha = wantAlpha ? 0x80 : 0xFF;
5264cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--mode") == 0) {
527fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            argv++;
528fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            if (argv < stop) {
529fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (strcmp(*argv, "normal") == 0) {
530fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kNormal_benchModes;
531fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "deferred") == 0) {
532fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kDeferred_benchModes;
533fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else if (strcmp(*argv, "deferredSilent") == 0) {
534fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    benchMode = kDeferredSilent_benchModes;
535fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "record") == 0) {
536fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kRecord_benchModes;
537fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "picturerecord") == 0) {
538fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kPictureRecord_benchModes;
539fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
5404cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                    logger.logError("bad arg for --mode\n");
541fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    help();
542fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    return -1;
543fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
544fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            } else {
5454cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --mode\n");
54682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                help();
54782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                return -1;
54882a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
5494cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--strokeWidth") == 0) {
550652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            argv++;
551652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            if (argv < stop) {
552652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                const char *strokeWidthStr = *argv;
553652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                if (sscanf(strokeWidthStr, "%f", &strokeWidth) != 1) {
5544cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                  logger.logError("bad arg for --strokeWidth\n");
55586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                  help();
556652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                  return -1;
557652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                }
558652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                hasStrokeWidth = true;
559652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            } else {
5604cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --strokeWidth\n");
56186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
562652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                return -1;
563652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            }
5644cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--match") == 0) {
565387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
566387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
5671a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com                *fMatches.append() = *argv;
568387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
5694cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --match\n");
57086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
571387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
572387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
5734cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--config") == 0) {
574387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
575387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
576387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                int index = findConfig(*argv);
577387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                if (index >= 0) {
57813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    *configs.append() = index;
57913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    userConfig = true;
580387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                } else {
58129348cb0612e19030d979156860946241e2ff4bdreed@android.com                    SkString str;
58229348cb0612e19030d979156860946241e2ff4bdreed@android.com                    str.printf("unrecognized config %s\n", *argv);
583a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    logger.logError(str);
58486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                    help();
585387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                    return -1;
586387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                }
587387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
5884cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --config\n");
589a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                help();
590a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                return -1;
591a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            }
5924cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--logFile") == 0) {
593a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            argv++;
594a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            if (argv < stop) {
595a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                if (!logger.SetLogFile(*argv)) {
596a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    SkString str;
597a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    str.printf("Could not open %s for writing.", *argv);
5989a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                    logger.logError(str);
599a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    return -1;
600a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                }
601a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            } else {
6024cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --logFile\n");
60386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
604387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
6054c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
6060c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com        } else if (strlen(*argv) > 2 && strncmp(*argv, "-D", 2) == 0) {
607e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            argv++;
6080c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com            if (argv < stop) {
609e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                defineDict.set(argv[-1] + 2, *argv);
610e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            } else {
611a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("incomplete '-Dfoo bar' definition\n");
61286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
613e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                return -1;
614e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            }
61586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com        } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
61686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
61786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            return 0;
618387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else {
61929348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
62029348cb0612e19030d979156860946241e2ff4bdreed@android.com            str.printf("unrecognized arg %s\n", *argv);
621a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logError(str);
62286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
623387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            return -1;
624b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
625b398fe863860b072306b5297c8095c6d973aba06reed@android.com    }
626fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)
627fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            && !outDir.isEmpty()) {
6284cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        logger.logError("'--mode record' and '--mode picturerecord' are not"
629fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                  " compatible with -o.\n");
630fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        return -1;
631fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
632fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) {
633fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        perIterTimeformat.set("%.4f");
634fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        normalTimeFormat.set("%6.4f");
635fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
63613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    if (!userConfig) {
63713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        // if no config is specified by user, we add them all.
63813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (unsigned int i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
63913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            *configs.append() = i;
64013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        }
64113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    }
642a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
6433b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    // report our current settings
6443b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    {
6453b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com        SkString str;
646fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        const char* deferredMode = benchMode == kDeferred_benchModes ? "yes" :
647fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org            (benchMode == kDeferredSilent_benchModes ? "silent" : "no");
648af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com        str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d "
649fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                   "deferred=%s logperiter=%d",
650fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                   forceAlpha, forceAA, forceFilter, deferredMode,
651fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                   logPerIter);
6522abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com        str.appendf(" rotate=%d scale=%d clip=%d min=%d",
6532abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                   doRotate, doScale, doClip, printMin);
654fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        str.appendf(" record=%d picturerecord=%d",
655fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kRecord_benchModes,
656fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kPictureRecord_benchModes);
657a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        const char * ditherName;
658a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        switch (forceDither) {
659a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kDefault: ditherName = "default"; break;
660a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kTrue: ditherName = "true"; break;
661a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kFalse: ditherName = "false"; break;
662a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            default: ditherName = "<invalid>"; break;
663a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
664a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.appendf(" dither=%s", ditherName);
665fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
666a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        if (hasStrokeWidth) {
667a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.appendf(" strokeWidth=%f", strokeWidth);
668a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        } else {
669a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.append(" strokeWidth=none");
670a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
671a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
672a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_SCALAR_IS_FLOAT)
673a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=float");
674a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_SCALAR_IS_FIXED)
675a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=fixed");
676a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
677a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
678a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_BUILD_FOR_WIN32)
679a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=WIN32");
680a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_MAC)
681a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=MAC");
682a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_ANDROID)
683a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=ANDROID");
684a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_UNIX)
685a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=UNIX");
686a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#else
687a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=other");
688a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
689a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
690a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_DEBUG)
691a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" DEBUG");
692a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
693a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append("\n");
694a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(str);
6953b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    }
696508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
697cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    SkGLContext* timerCtx = NULL;
698a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com    //Don't do GL when fixed.
699cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if !defined(SK_SCALAR_IS_FIXED) && SK_SUPPORT_GPU
7008382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    int contextWidth = 1024;
7018382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    int contextHeight = 1024;
7028382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    determine_gpu_context_size(defineDict, &contextWidth, &contextHeight);
703508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<SkGLContext> realGLCtx(new SkNativeGLContext);
704508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<SkGLContext> nullGLCtx(new SkNullGLContext);
7050da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    SkAutoTUnref<SkGLContext> debugGLCtx(new SkDebugGLContext);
706508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    gRealGLHelper.init(realGLCtx.get(), contextWidth, contextHeight);
707508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    gNullGLHelper.init(nullGLCtx.get(), contextWidth, contextHeight);
7080da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    gDebugGLHelper.init(debugGLCtx.get(), contextWidth, contextHeight);
709d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
710cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    SkAutoTUnref<SkGLContext> angleGLCtx(new SkANGLEGLContext);
711d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    gANGLEGLHelper.init(angleGLCtx.get(), contextWidth, contextHeight);
712cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
713cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    timerCtx = gRealGLHelper.glContext();
714cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // !defined(SK_SCALAR_IS_FIXED) && SK_SUPPORT_GPU
71574913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com
716cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    BenchTimer timer = BenchTimer(timerCtx);
717e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter iter(&defineDict);
718bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* bench;
719bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    while ((bench = iter.next()) != NULL) {
7207fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com        SkAutoTUnref<SkBenchmark> benchUnref(bench);
7217fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com
722b398fe863860b072306b5297c8095c6d973aba06reed@android.com        SkIPoint dim = bench->getSize();
723b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (dim.fX <= 0 || dim.fY <= 0) {
724b398fe863860b072306b5297c8095c6d973aba06reed@android.com            continue;
725b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
726fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
7274bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAlpha(forceAlpha);
7284bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAA(forceAA);
72929348cb0612e19030d979156860946241e2ff4bdreed@android.com        bench->setForceFilter(forceFilter);
7304e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com        bench->setDither(forceDither);
731652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        if (hasStrokeWidth) {
732652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            bench->setStrokeWidth(strokeWidth);
733652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        }
734fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
735387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        // only run benchmarks if their name contains matchStr
7361a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (skip_name(fMatches, bench->getName())) {
737387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            continue;
738387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        }
739fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
74029348cb0612e19030d979156860946241e2ff4bdreed@android.com        {
74129348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
742d34658a5f1b961e2852c2272ac8b47701a42e50dreed@google.com            str.printf("running bench [%d %d] %28s", dim.fX, dim.fY,
7430c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com                       bench->getName());
744a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logProgress(str);
74529348cb0612e19030d979156860946241e2ff4bdreed@android.com        }
746fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
74730e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        AutoPrePostDraw appd(bench);
74830e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
7499dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com        bool runOnce = false;
75013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (int x = 0; x < configs.count(); ++x) {
7519dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            if (!bench->isRendering() && runOnce) {
7529dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com                continue;
7539dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            }
7549dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            runOnce = true;
7559dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com
75613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            int configIndex = configs[x];
75713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com
75813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            outConfig = gConfigs[configIndex].fConfig;
75913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            configName = gConfigs[configIndex].fName;
76013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            backend = gConfigs[configIndex].fBackend;
76113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            glHelper = gConfigs[configIndex].fGLHelper;
762508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
763cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
764508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            if (kGPU_Backend == backend &&
765508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                (NULL == glHelper || !glHelper->isValid())) {
766a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                continue;
7674bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
768cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
769508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            SkDevice* device = make_device(outConfig, dim, backend, glHelper);
770fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkCanvas* canvas = NULL;
771fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordFrom;
772fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordTo;
773fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            switch(benchMode) {
7744c5ea4480341f0f663b51e9d78b948bc0a785f4dskia.committer@gmail.com                case kDeferredSilent_benchModes:
775fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kDeferred_benchModes:
776fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = new SkDeferredCanvas(device);
777fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
778fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kRecord_benchModes:
779fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY);
780fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas->ref();
781fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
782fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kPictureRecord_benchModes: {
783fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // This sets up picture-to-picture recording.
784fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // The C++ drawing calls for the benchmark are recorded into
785fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // pictureRecordFrom. As the benchmark, we will time how
786fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // long it takes to playback pictureRecordFrom into
787fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // pictureRecordTo.
788fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    SkCanvas* tempCanvas = pictureRecordFrom.beginRecording(dim.fX, dim.fY);
789fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(tempCanvas);
790fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.endRecording();
791fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY);
792fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas->ref();
793fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
794fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
795fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kNormal_benchModes:
796fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = new SkCanvas(device);
797fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
798fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                default:
799fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    SkASSERT(0);
80082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
801a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            device->unref();
80282a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            SkAutoUnref canvasUnref(canvas);
80382a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com
8044c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doClip) {
80582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performClip(canvas, dim.fX, dim.fY);
8064c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
807387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (doScale) {
80882a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performScale(canvas, dim.fX, dim.fY);
809387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
8104c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doRotate) {
81182a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performRotate(canvas, dim.fX, dim.fY);
8124c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
813508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
814af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // warm up caches if needed
815eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            if (repeatDraw > 1) {
81691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com#if SK_SUPPORT_GPU
81791ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                if (glHelper) {
81891ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    // purge the GPU resources to reduce variance
81991ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    glHelper->grContext()->freeGpuResources();
82091ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                }
82191ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com#endif
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                }
834cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
835508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                if (glHelper) {
836508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    glHelper->grContext()->flush();
837508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    SK_GL(*glHelper->glContext(), Finish());
838d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com                }
839cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
840eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            }
841af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
842af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // record timer values for each repeat, and their sum
8439a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com            TimerData timerData(perIterTimeformat, normalTimeFormat);
8444bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            for (int i = 0; i < repeatDraw; i++) {
845fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if ((benchMode == kRecord_benchModes
846fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                     || benchMode == kPictureRecord_benchModes)) {
847fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // This will clear the recorded commands so that they do not
848fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // acculmulate.
849fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY);
850fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
851fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
852af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                timer.start();
85382a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
854fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (benchMode == kPictureRecord_benchModes) {
855fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.draw(canvas);
856fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
857fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(canvas);
858fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
859fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
860fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                if (kDeferredSilent_benchModes == benchMode) {
861fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
862fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else {
863fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    canvas->flush();
864fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                }
86591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com
86691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // stop the truncated timer after the last canvas call but
86791ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // don't wait for all the GL calls to complete
86891ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                timer.truncatedEnd();
869cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
870508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                if (glHelper) {
871508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    glHelper->grContext()->flush();
87291ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    SK_GL(*glHelper->glContext(), Finish());
87325df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com                }
874cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
87591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // stop the inclusive and gpu timers once all the GL calls
87691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // have completed
877af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                timer.end();
878af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
8799a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                timerData.appendTimes(&timer, repeatDraw - 1 == i);
8802abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com
88125df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com            }
8824bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (repeatDraw > 1) {
8839a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                SkString result = timerData.getResult(logPerIter, printMin, repeatDraw, configName,
8849a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                                                      timerWall, truncatedTimerWall, timerCpu,
8859a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                                                      truncatedTimerCpu, timerGpu && glHelper);
8869a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                logger.logProgress(result);
8874bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
8884c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (outDir.size() > 0) {
889a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                saveFile(bench->getName(), configName, outDir.c_str(),
890a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                         device->accessBitmap(false));
8914c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
8924bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        }
893a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(SkString("\n"));
894bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
895cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
8969d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#if GR_CACHE_STATS
8979d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com    gRealGLHelper.grContext()->printCacheStats();
8989d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#endif
8999d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com
9000da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    // need to clean up here rather than post-main to allow leak detection to work
9019d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com    gRealGLHelper.cleanup();
9020da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    gDebugGLHelper.cleanup();
9039d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com    gNullGLHelper.cleanup();
9049d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#if SK_ANGLE
9059d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com    gANGLEGLHelper.cleanup();
9069d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#endif // SK_ANGLE
907cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
9089d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com
909bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    return 0;
910bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
9115987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
9125987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#if !defined SK_BUILD_FOR_IOS
9135987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint main(int argc, char * const argv[]) {
9145987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com    return tool_main(argc, (char**) argv);
9155987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
9165987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
9175987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
918