benchmain.cpp revision af3d79a8c81f3f224a5eff53b0ca8615b884f922
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
12971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrContext.h"
13971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrRenderTarget.h"
14971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
15971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "SkBenchmark.h"
16bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkCanvas.h"
1782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com#include "SkDeferredCanvas.h"
18f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com#include "SkColorPriv.h"
19971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "SkGpuDevice.h"
203a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkGraphics.h"
21b398fe863860b072306b5297c8095c6d973aba06reed@android.com#include "SkImageEncoder.h"
22d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
23d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#include "gl/SkANGLEGLContext.h"
24d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#endif
256bf38b59c9de1cd35cd091cf8766117f4e1f66a0tomhudson@google.com#include "gl/SkNativeGLContext.h"
266bf38b59c9de1cd35cd091cf8766117f4e1f66a0tomhudson@google.com#include "gl/SkNullGLContext.h"
270da3719050473344b6013fd7b614611984f20effrobertphillips@google.com#include "gl/SkDebugGLContext.h"
286c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkNWayCanvas.h"
296c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkPicture.h"
30bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkString.h"
31bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
3256c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
3329348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic void log_error(const char msg[]) { SkDebugf("%s", msg); }
3429348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic void log_progress(const char msg[]) { SkDebugf("%s", msg); }
3529348cb0612e19030d979156860946241e2ff4bdreed@android.com#else
3629348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic void log_error(const char msg[]) { fprintf(stderr, "%s", msg); }
3729348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic void log_progress(const char msg[]) { printf("%s", msg); }
3829348cb0612e19030d979156860946241e2ff4bdreed@android.com#endif
3929348cb0612e19030d979156860946241e2ff4bdreed@android.com
4029348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic void log_error(const SkString& str) { log_error(str.c_str()); }
4129348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic void log_progress(const SkString& str) { log_progress(str.c_str()); }
4229348cb0612e19030d979156860946241e2ff4bdreed@android.com
4329348cb0612e19030d979156860946241e2ff4bdreed@android.com///////////////////////////////////////////////////////////////////////////////
4429348cb0612e19030d979156860946241e2ff4bdreed@android.com
456c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic void erase(SkBitmap& bm) {
466c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
476c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm.eraseColor(0);
486c924ad46c89955e78e071c792ef00df9910b42freed@android.com    } else {
496c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm.eraseColor(SK_ColorWHITE);
506c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
516c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
526c924ad46c89955e78e071c792ef00df9910b42freed@android.com
53a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org#if 0
546c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic bool equal(const SkBitmap& bm1, const SkBitmap& bm2) {
556c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm1.width() != bm2.width() ||
566c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm1.height() != bm2.height() ||
576c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm1.config() != bm2.config()) {
586c924ad46c89955e78e071c792ef00df9910b42freed@android.com        return false;
596c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
606c924ad46c89955e78e071c792ef00df9910b42freed@android.com
616c924ad46c89955e78e071c792ef00df9910b42freed@android.com    size_t pixelBytes = bm1.width() * bm1.bytesPerPixel();
626c924ad46c89955e78e071c792ef00df9910b42freed@android.com    for (int y = 0; y < bm1.height(); y++) {
636c924ad46c89955e78e071c792ef00df9910b42freed@android.com        if (memcmp(bm1.getAddr(0, y), bm2.getAddr(0, y), pixelBytes)) {
646c924ad46c89955e78e071c792ef00df9910b42freed@android.com            return false;
656c924ad46c89955e78e071c792ef00df9910b42freed@android.com        }
666c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
676c924ad46c89955e78e071c792ef00df9910b42freed@android.com    return true;
686c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
69a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org#endif
706c924ad46c89955e78e071c792ef00df9910b42freed@android.com
71bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comclass Iter {
72bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.compublic:
73e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter(void* param) {
74bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        fBench = BenchRegistry::Head();
75e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com        fParam = param;
76bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
77bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
78bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* next() {
79bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        if (fBench) {
80bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            BenchRegistry::Factory f = fBench->factory();
81bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            fBench = fBench->next();
82e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            return f(fParam);
83bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
84bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        return NULL;
85bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
86d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
87bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comprivate:
88bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    const BenchRegistry* fBench;
89e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    void* fParam;
90bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com};
91bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
92bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comstatic void make_filename(const char name[], SkString* path) {
93bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    path->set(name);
94bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    for (int i = 0; name[i]; i++) {
95bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        switch (name[i]) {
96bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '/':
97bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '\\':
98bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ' ':
99bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ':':
100bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                path->writable_str()[i] = '-';
101bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
102bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            default:
103bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
104bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
105bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
106bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
107bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
1084c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void saveFile(const char name[], const char config[], const char dir[],
1094c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                     const SkBitmap& bm) {
1104c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkBitmap copy;
1114c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    if (!bm.copyTo(&copy, SkBitmap::kARGB_8888_Config)) {
1124c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        return;
1134c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
114f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com
115f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
116f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        // turn alpha into gray-scale
117f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        size_t size = copy.getSize() >> 2;
118f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        SkPMColor* p = copy.getAddr32(0, 0);
119f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        for (size_t i = 0; i < size; i++) {
120f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            int c = (*p >> SK_A32_SHIFT) & 0xFF;
121f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c = 255 - c;
122f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c |= (c << 24) | (c << 16) | (c << 8);
123f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            *p++ = c | (SK_A32_MASK << SK_A32_SHIFT);
124f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        }
125f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    }
126d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
1274c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkString str;
1284c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    make_filename(name, &str);
1294c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    str.appendf("_%s.png", config);
1304c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    str.prepend(dir);
1314c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    ::remove(str.c_str());
1324c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkImageEncoder::EncodeFile(str.c_str(), copy, SkImageEncoder::kPNG_Type,
1334c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                               100);
1344c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1354c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1364c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performClip(SkCanvas* canvas, int w, int h) {
1374c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkRect r;
1384c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1394c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(10), SkIntToScalar(10),
1404c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
1414c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kIntersect_Op);
142d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
1434c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
1444c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w-10), SkIntToScalar(h-10));
1454c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kXOR_Op);
1464c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1474c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1484c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performRotate(SkCanvas* canvas, int w, int h) {
1494c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
1504c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
1514c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1524c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(x, y);
1534c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->rotate(SkIntToScalar(35));
1544c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(-x, -y);
1554c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1564c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
157387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.comstatic void performScale(SkCanvas* canvas, int w, int h) {
158387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
159387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
160387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com
161387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(x, y);
162387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    // just enough so we can't take the sprite case
163387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
164387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(-x, -y);
165387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com}
166387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com
16729348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic bool parse_bool_arg(char * const* argv, char* const* stop, bool* var) {
16829348cb0612e19030d979156860946241e2ff4bdreed@android.com    if (argv < stop) {
16929348cb0612e19030d979156860946241e2ff4bdreed@android.com        *var = atoi(*argv) != 0;
17029348cb0612e19030d979156860946241e2ff4bdreed@android.com        return true;
17129348cb0612e19030d979156860946241e2ff4bdreed@android.com    }
17229348cb0612e19030d979156860946241e2ff4bdreed@android.com    return false;
17329348cb0612e19030d979156860946241e2ff4bdreed@android.com}
17429348cb0612e19030d979156860946241e2ff4bdreed@android.com
175a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgenum Backend {
176a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kRaster_Backend,
177a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kGPU_Backend,
178a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kPDF_Backend,
179a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org};
180a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
181508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comclass GLHelper {
182508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.compublic:
183508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GLHelper() {
184508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
185508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
186508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    bool init(SkGLContext* glCtx, int width, int height) {
187508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        GrContext* grCtx;
188508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        GrRenderTarget* rt;
189508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        if (glCtx->init(width, height)) {
190508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            GrPlatform3DContext ctx =
191508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                reinterpret_cast<GrPlatform3DContext>(glCtx->gl());
192508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            grCtx = GrContext::Create(kOpenGL_Shaders_GrEngine, ctx);
193508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            if (NULL != grCtx) {
194508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                GrPlatformRenderTargetDesc desc;
195508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                desc.fConfig = kSkia8888_PM_GrPixelConfig;
196508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                desc.fWidth = width;
197508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                desc.fHeight = height;
198508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                desc.fStencilBits = 8;
199508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                desc.fRenderTargetHandle = glCtx->getFBOID();
200508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                rt = grCtx->createPlatformRenderTarget(desc);
201508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                if (NULL == rt) {
202508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    grCtx->unref();
203508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    return false;
204508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                }
205508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            }
206508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        } else {
207508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            return false;
208508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        }
209508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        glCtx->ref();
210508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        fGLContext.reset(glCtx);
211508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        fGrContext.reset(grCtx);
212508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        fRenderTarget.reset(rt);
213508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return true;
214508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
215508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
2160da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    void cleanup() {
2170da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        fGLContext.reset(NULL);
2180da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        fGrContext.reset(NULL);
2190da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        fRenderTarget.reset(NULL);
2200da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    }
2210da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
222508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    bool isValid() {
223508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return NULL != fGLContext.get();
224508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
225508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
226508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkGLContext* glContext() {
227508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return fGLContext.get();
228508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
229508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
230508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GrRenderTarget* renderTarget() {
231508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return fRenderTarget.get();
232508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
233508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
234508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GrContext* grContext() {
235508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return fGrContext.get();
236508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
237508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comprivate:
238508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<SkGLContext> fGLContext;
239508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<GrContext> fGrContext;
240508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<GrRenderTarget> fRenderTarget;
241508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com};
242508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
243508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comstatic GLHelper gRealGLHelper;
244508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comstatic GLHelper gNullGLHelper;
2450da3719050473344b6013fd7b614611984f20effrobertphillips@google.comstatic GLHelper gDebugGLHelper;
246d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
247d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.comstatic GLHelper gANGLEGLHelper;
248d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#endif
249508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
250a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgstatic SkDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
251508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                             Backend backend, GLHelper* glHelper) {
252a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkDevice* device = NULL;
253a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkBitmap bitmap;
254a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    bitmap.setConfig(config, size.fX, size.fY);
255d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
256a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    switch (backend) {
257a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kRaster_Backend:
258a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            bitmap.allocPixels();
259a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            erase(bitmap);
260af951c9bc4cbb6e60b430194fe5127ebe99c53fbreed@google.com            device = new SkDevice(bitmap);
261a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
262a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kGPU_Backend:
263508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            device = new SkGpuDevice(glHelper->grContext(),
264508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                                     glHelper->renderTarget());
265a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
266a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kPDF_Backend:
267a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        default:
268a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            SkASSERT(!"unsupported");
269a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    }
270a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    return device;
271a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org}
272a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
2734bc1983e01d756ae9c91fd380758457f579d26eareed@android.comstatic const struct {
2744bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    SkBitmap::Config    fConfig;
2754bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    const char*         fName;
276a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend             fBackend;
277508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GLHelper*           fGLHelper;
2784bc1983e01d756ae9c91fd380758457f579d26eareed@android.com} gConfigs[] = {
279508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "8888",     kRaster_Backend, NULL },
280508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kRGB_565_Config,    "565",      kRaster_Backend, NULL },
281508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "GPU",      kGPU_Backend, &gRealGLHelper },
282d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
283d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    { SkBitmap::kARGB_8888_Config,  "ANGLE",    kGPU_Backend, &gANGLEGLHelper },
284d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#endif
285a0b63b86313694f695bf0387ee0ce31de3deabb3robertphillips@google.com#ifdef SK_DEBUG
286a0b63b86313694f695bf0387ee0ce31de3deabb3robertphillips@google.com    { SkBitmap::kARGB_8888_Config,  "Debug",    kGPU_Backend, &gDebugGLHelper },
287a0b63b86313694f695bf0387ee0ce31de3deabb3robertphillips@google.com#endif
288508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "NULLGPU",  kGPU_Backend, &gNullGLHelper },
2894bc1983e01d756ae9c91fd380758457f579d26eareed@android.com};
2904bc1983e01d756ae9c91fd380758457f579d26eareed@android.com
2914c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic int findConfig(const char config[]) {
2924c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
2934c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        if (!strcmp(config, gConfigs[i].fName)) {
2944c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            return i;
2954c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        }
2964c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
2974c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    return -1;
2984c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
2994c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
3008382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.comstatic void determine_gpu_context_size(SkTDict<const char*>& defineDict,
3018382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com                                       int* contextWidth,
3028382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com                                       int* contextHeight) {
3038382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    Iter iter(&defineDict);
3048382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    SkBenchmark* bench;
3058382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    while ((bench = iter.next()) != NULL) {
3068382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        SkIPoint dim = bench->getSize();
3078382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        if (*contextWidth < dim.fX) {
3088382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com            *contextWidth = dim.fX;
3098382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        }
3108382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        if (*contextHeight < dim.fY) {
3118382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com            *contextHeight = dim.fY;
3128382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        }
3138382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    }
3148382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com}
3158382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com
3161a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.comstatic bool skip_name(const SkTDArray<const char*> array, const char name[]) {
3171a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    if (0 == array.count()) {
3181a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        // no names, so don't skip anything
3191a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        return false;
3201a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    }
3211a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    for (int i = 0; i < array.count(); ++i) {
3221a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (strstr(name, array[i])) {
3231a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com            // found the name, so don't skip
3241a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com            return false;
3251a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        }
3261a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    }
3271a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    return true;
3281a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com}
3291a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com
33086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.comstatic void help() {
331af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    SkDebugf("Usage: bench [-o outDir] [-repeat nr] [-logPerIter 1|0] "
33286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                          "[-timers [wcg]*] [-rotate]\n"
33386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "    [-scale] [-clip] [-forceAA 1|0] [-forceFilter 1|0]\n"
33486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "    [-forceDither 1|0] [-forceBlend 1|0] [-strokeWidth width]\n"
33582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com             "    [-forceDeferred 1|0] [-match name]\n"
33682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com             "    [-config 8888|565|GPU|ANGLE|NULLGPU] [-Dfoo bar]\n"
33782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com             "    [-h|--help]");
33886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("\n\n");
33986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -o outDir : Image of each bench will be put in outDir.\n");
34086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -repeat nr : Each bench repeats for nr times.\n");
341af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    SkDebugf("    -logPerIter 1|0 : "
342af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com             "Log each repeat timer instead of mean, default is disabled.\n");
34386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -timers [wcg]* : "
34486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Display wall time, cpu time or gpu time for each bench.\n");
34586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -rotate : Rotate before each bench runs.\n");
34686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -scale : Scale before each bench runs.\n");
34786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -clip : Clip before each bench runs.\n");
34886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -forceAA 1|0 : "
34986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable anti-aliased, default is enabled.\n");
35086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -forceFilter 1|0 : "
35186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable bitmap filtering, default is disabled.\n");
35286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -forceDither 1|0 : "
35386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
35486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -forceBlend 1|0 : "
35586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
35682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com    SkDebugf("    -forceDeferred 1|0 : "
35782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com             "Enable/disable deferred canvas, default is disabled.\n");
35886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -strokeWidth width : The width for path stroke.\n");
35986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -match name : Only run bench whose name is matched.\n");
36086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -config 8888|565|GPU|ANGLE|NULLGPU : "
36186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Run bench in corresponding config mode.\n");
36286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -Dfoo bar : Add extra definition to bench.\n");
36386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -h|--help : Show this help message.\n");
36486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com}
36586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com
366bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comint main (int argc, char * const argv[]) {
3673a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkAutoGraphics ag;
368d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
369e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    SkTDict<const char*> defineDict(1024);
3704bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int repeatDraw = 1;
371af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    bool logPerIter = false;
3724bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int forceAlpha = 0xFF;
3734bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    bool forceAA = true;
37429348cb0612e19030d979156860946241e2ff4bdreed@android.com    bool forceFilter = false;
3754e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com    SkTriState::State forceDither = SkTriState::kDefault;
37682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com    bool forceDeferred = false;
377be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerWall = false;
378be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerCpu = true;
379be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerGpu = true;
380387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    bool doScale = false;
3814c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doRotate = false;
3824c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doClip = false;
383652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    bool hasStrokeWidth = false;
384652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    float strokeWidth;
3851a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    SkTDArray<const char*> fMatches;
386d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
387b398fe863860b072306b5297c8095c6d973aba06reed@android.com    SkString outDir;
388387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    SkBitmap::Config outConfig = SkBitmap::kNo_Config;
389cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com    GLHelper* glHelper = NULL;
390387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const char* configName = "";
391a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend backend = kRaster_Backend;  // for warning
39213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    SkTDArray<int> configs;
39313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    bool userConfig = false;
394d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
395b398fe863860b072306b5297c8095c6d973aba06reed@android.com    char* const* stop = argv + argc;
396b398fe863860b072306b5297c8095c6d973aba06reed@android.com    for (++argv; argv < stop; ++argv) {
397b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (strcmp(*argv, "-o") == 0) {
398b398fe863860b072306b5297c8095c6d973aba06reed@android.com            argv++;
399b398fe863860b072306b5297c8095c6d973aba06reed@android.com            if (argv < stop && **argv) {
400b398fe863860b072306b5297c8095c6d973aba06reed@android.com                outDir.set(*argv);
401b398fe863860b072306b5297c8095c6d973aba06reed@android.com                if (outDir.c_str()[outDir.size() - 1] != '/') {
402b398fe863860b072306b5297c8095c6d973aba06reed@android.com                    outDir.append("/");
403b398fe863860b072306b5297c8095c6d973aba06reed@android.com                }
404b398fe863860b072306b5297c8095c6d973aba06reed@android.com            }
4054bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        } else if (strcmp(*argv, "-repeat") == 0) {
4064bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            argv++;
4074bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (argv < stop) {
4084bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                repeatDraw = atoi(*argv);
4094bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                if (repeatDraw < 1) {
4104bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                    repeatDraw = 1;
4114bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                }
4124bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            } else {
41329348cb0612e19030d979156860946241e2ff4bdreed@android.com                log_error("missing arg for -repeat\n");
41486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
4154bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                return -1;
4164bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
417af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com        } else if (strcmp(*argv, "-logPerIter") == 0) {
418af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            if (!parse_bool_arg(++argv, stop, &logPerIter)) {
419af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                log_error("missing arg for -logPerIter\n");
420af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                help();
421af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                return -1;
422af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            }
423be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com        } else if (strcmp(*argv, "-timers") == 0) {
424be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            argv++;
425be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            if (argv < stop) {
426be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerWall = false;
427be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerCpu = false;
428be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerGpu = false;
429be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                for (char* t = *argv; *t; ++t) {
430be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    switch (*t) {
431be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'w': timerWall = true; break;
432be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'c': timerCpu = true; break;
433be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'g': timerGpu = true; break;
434be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    }
435be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
436be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            } else {
437be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                log_error("missing arg for -timers\n");
43886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
439be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                return -1;
440be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            }
4414c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        } else if (!strcmp(*argv, "-rotate")) {
4424c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doRotate = true;
443387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else if (!strcmp(*argv, "-scale")) {
444387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            doScale = true;
4454c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        } else if (!strcmp(*argv, "-clip")) {
4464c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doClip = true;
4474bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        } else if (strcmp(*argv, "-forceAA") == 0) {
44829348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceAA)) {
44929348cb0612e19030d979156860946241e2ff4bdreed@android.com                log_error("missing arg for -forceAA\n");
45086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
45129348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
45229348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
45329348cb0612e19030d979156860946241e2ff4bdreed@android.com        } else if (strcmp(*argv, "-forceFilter") == 0) {
45429348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceFilter)) {
45529348cb0612e19030d979156860946241e2ff4bdreed@android.com                log_error("missing arg for -forceFilter\n");
45686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
45729348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
45829348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
4594e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com        } else if (strcmp(*argv, "-forceDither") == 0) {
4604e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            bool tmp;
4614e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            if (!parse_bool_arg(++argv, stop, &tmp)) {
4624e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com                log_error("missing arg for -forceDither\n");
46386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
4644e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com                return -1;
4654e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            }
4664e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            forceDither = tmp ? SkTriState::kTrue : SkTriState::kFalse;
4674bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        } else if (strcmp(*argv, "-forceBlend") == 0) {
46829348cb0612e19030d979156860946241e2ff4bdreed@android.com            bool wantAlpha = false;
46929348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &wantAlpha)) {
47029348cb0612e19030d979156860946241e2ff4bdreed@android.com                log_error("missing arg for -forceBlend\n");
47186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
47229348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
47329348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
47429348cb0612e19030d979156860946241e2ff4bdreed@android.com            forceAlpha = wantAlpha ? 0x80 : 0xFF;
47582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com        } else if (strcmp(*argv, "-forceDeferred") == 0) {
47682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            if (!parse_bool_arg(++argv, stop, &forceDeferred)) {
47782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                log_error("missing arg for -forceDeferred\n");
47882a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                help();
47982a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                return -1;
48082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
481652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        } else if (strcmp(*argv, "-strokeWidth") == 0) {
482652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            argv++;
483652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            if (argv < stop) {
484652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                const char *strokeWidthStr = *argv;
485652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                if (sscanf(strokeWidthStr, "%f", &strokeWidth) != 1) {
486652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                  log_error("bad arg for -strokeWidth\n");
48786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                  help();
488652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                  return -1;
489652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                }
490652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                hasStrokeWidth = true;
491652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            } else {
492652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                log_error("missing arg for -strokeWidth\n");
49386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
494652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                return -1;
495652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            }
496387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else if (strcmp(*argv, "-match") == 0) {
497387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
498387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
4991a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com                *fMatches.append() = *argv;
500387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
50129348cb0612e19030d979156860946241e2ff4bdreed@android.com                log_error("missing arg for -match\n");
50286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
503387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
504387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
505387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else if (strcmp(*argv, "-config") == 0) {
506387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
507387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
508387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                int index = findConfig(*argv);
509387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                if (index >= 0) {
51013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    *configs.append() = index;
51113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    userConfig = true;
512387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                } else {
51329348cb0612e19030d979156860946241e2ff4bdreed@android.com                    SkString str;
51429348cb0612e19030d979156860946241e2ff4bdreed@android.com                    str.printf("unrecognized config %s\n", *argv);
51529348cb0612e19030d979156860946241e2ff4bdreed@android.com                    log_error(str);
51686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                    help();
517387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                    return -1;
518387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                }
519387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
52029348cb0612e19030d979156860946241e2ff4bdreed@android.com                log_error("missing arg for -config\n");
52186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
522387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
5234c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
5240c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com        } else if (strlen(*argv) > 2 && strncmp(*argv, "-D", 2) == 0) {
525e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            argv++;
5260c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com            if (argv < stop) {
527e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                defineDict.set(argv[-1] + 2, *argv);
528e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            } else {
529e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                log_error("incomplete '-Dfoo bar' definition\n");
53086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
531e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                return -1;
532e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            }
53386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com        } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
53486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
53586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            return 0;
536387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else {
53729348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
53829348cb0612e19030d979156860946241e2ff4bdreed@android.com            str.printf("unrecognized arg %s\n", *argv);
53929348cb0612e19030d979156860946241e2ff4bdreed@android.com            log_error(str);
54086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
541387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            return -1;
542b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
543b398fe863860b072306b5297c8095c6d973aba06reed@android.com    }
54413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    if (!userConfig) {
54513eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        // if no config is specified by user, we add them all.
54613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (unsigned int i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
54713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            *configs.append() = i;
54813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        }
54913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    }
550d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
5513b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    // report our current settings
5523b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    {
5533b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com        SkString str;
554af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com        str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d "
555af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                   "deferred=%d logperiter=%d",
556af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                   forceAlpha, forceAA, forceFilter, forceDeferred, logPerIter);
557a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.appendf(" rotate=%d scale=%d clip=%d",
558a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com                   doRotate, doScale, doClip);
559a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
560a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        const char * ditherName;
561a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        switch (forceDither) {
562a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kDefault: ditherName = "default"; break;
563a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kTrue: ditherName = "true"; break;
564a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kFalse: ditherName = "false"; break;
565a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            default: ditherName = "<invalid>"; break;
566a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
567a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.appendf(" dither=%s", ditherName);
568a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
569a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        if (hasStrokeWidth) {
570a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.appendf(" strokeWidth=%f", strokeWidth);
571a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        } else {
572a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.append(" strokeWidth=none");
573a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
574a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
575a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_SCALAR_IS_FLOAT)
576a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=float");
577a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_SCALAR_IS_FIXED)
578a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=fixed");
579a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
580a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
581a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_BUILD_FOR_WIN32)
582a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=WIN32");
583a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_MAC)
584a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=MAC");
585a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_ANDROID)
586a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=ANDROID");
587a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_UNIX)
588a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=UNIX");
589a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#else
590a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=other");
591a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
592a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
593a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_DEBUG)
594a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" DEBUG");
595a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
596a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append("\n");
5973b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com        log_progress(str);
5983b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    }
599508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
600a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com    //Don't do GL when fixed.
601a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if !defined(SK_SCALAR_IS_FIXED)
6028382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    int contextWidth = 1024;
6038382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    int contextHeight = 1024;
6048382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    determine_gpu_context_size(defineDict, &contextWidth, &contextHeight);
605508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<SkGLContext> realGLCtx(new SkNativeGLContext);
606508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<SkGLContext> nullGLCtx(new SkNullGLContext);
6070da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    SkAutoTUnref<SkGLContext> debugGLCtx(new SkDebugGLContext);
608d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
609d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    SkAutoTUnref<SkGLContext> angleGLCtx(new SkANGLEGLContext);
610d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#endif
611508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    gRealGLHelper.init(realGLCtx.get(), contextWidth, contextHeight);
612508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    gNullGLHelper.init(nullGLCtx.get(), contextWidth, contextHeight);
6130da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    gDebugGLHelper.init(debugGLCtx.get(), contextWidth, contextHeight);
614d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
615d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    gANGLEGLHelper.init(angleGLCtx.get(), contextWidth, contextHeight);
616d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#endif
617a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
61874913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com
619af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    BenchTimer timer = BenchTimer(gRealGLHelper.glContext());
620e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter iter(&defineDict);
621bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* bench;
622bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    while ((bench = iter.next()) != NULL) {
623b398fe863860b072306b5297c8095c6d973aba06reed@android.com        SkIPoint dim = bench->getSize();
624b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (dim.fX <= 0 || dim.fY <= 0) {
625b398fe863860b072306b5297c8095c6d973aba06reed@android.com            continue;
626b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
627b398fe863860b072306b5297c8095c6d973aba06reed@android.com
6284bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAlpha(forceAlpha);
6294bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAA(forceAA);
63029348cb0612e19030d979156860946241e2ff4bdreed@android.com        bench->setForceFilter(forceFilter);
6314e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com        bench->setDither(forceDither);
632652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        if (hasStrokeWidth) {
633652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            bench->setStrokeWidth(strokeWidth);
634652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        }
635d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
636387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        // only run benchmarks if their name contains matchStr
6371a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (skip_name(fMatches, bench->getName())) {
638387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            continue;
639387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        }
640d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
64129348cb0612e19030d979156860946241e2ff4bdreed@android.com        {
64229348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
643d34658a5f1b961e2852c2272ac8b47701a42e50dreed@google.com            str.printf("running bench [%d %d] %28s", dim.fX, dim.fY,
6440c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com                       bench->getName());
64529348cb0612e19030d979156860946241e2ff4bdreed@android.com            log_progress(str);
64629348cb0612e19030d979156860946241e2ff4bdreed@android.com        }
647d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
64813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (int x = 0; x < configs.count(); ++x) {
64913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            int configIndex = configs[x];
65013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com
65113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            outConfig = gConfigs[configIndex].fConfig;
65213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            configName = gConfigs[configIndex].fName;
65313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            backend = gConfigs[configIndex].fBackend;
65413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            glHelper = gConfigs[configIndex].fGLHelper;
655508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
656508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            if (kGPU_Backend == backend &&
657508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                (NULL == glHelper || !glHelper->isValid())) {
658a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                continue;
6594bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
660d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
661508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            SkDevice* device = make_device(outConfig, dim, backend, glHelper);
66282a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            SkCanvas* canvas;
66382a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            if (forceDeferred) {
66482a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                canvas = new SkDeferredCanvas(device);
66582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            } else {
66682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                canvas = new SkCanvas(device);
66782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
668a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            device->unref();
66982a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            SkAutoUnref canvasUnref(canvas);
67082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com
6714c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doClip) {
67282a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performClip(canvas, dim.fX, dim.fY);
6734c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
674387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (doScale) {
67582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performScale(canvas, dim.fX, dim.fY);
676387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
6774c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doRotate) {
67882a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performRotate(canvas, dim.fX, dim.fY);
6794c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
680508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
681af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // warm up caches if needed
682eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            if (repeatDraw > 1) {
68382a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
68482a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                bench->draw(canvas);
68582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                canvas->flush();
686508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                if (glHelper) {
687508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    glHelper->grContext()->flush();
688508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    SK_GL(*glHelper->glContext(), Finish());
689d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com                }
690eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            }
691af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
692af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // record timer values for each repeat, and their sum
693af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            SkString fWallStr(" msecs = ");
694af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            SkString fCpuStr(" cmsecs = ");
695af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            SkString fGpuStr(" gmsecs = ");
696af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            double fWallSum = 0.0;
697af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            double fCpuSum = 0.0;
698af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            double fGpuSum = 0.0;
6994bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            for (int i = 0; i < repeatDraw; i++) {
700af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                timer.start();
70182a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
70282a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                bench->draw(canvas);
70382a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                canvas->flush();
704508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                if (glHelper) {
705508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    glHelper->grContext()->flush();
70625df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com                }
707af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                timer.end();
708af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
709af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                if (i == repeatDraw - 1) {
710af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    // no comma after the last value
711af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    fWallStr.appendf("%.2f", timer.fWall);
712af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    fCpuStr.appendf("%.2f", timer.fCpu);
713af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    fGpuStr.appendf("%.2f", timer.fGpu);
714af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                } else {
715af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    fWallStr.appendf("%.2f,", timer.fWall);
716af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    fCpuStr.appendf("%.2f,", timer.fCpu);
717af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    fGpuStr.appendf("%.2f,", timer.fGpu);
718af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                }
719af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                fWallSum += timer.fWall;
720af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                fCpuSum += timer.fCpu;
721af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                fGpuSum += timer.fGpu;
72225df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com            }
723508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com           if (glHelper) {
724508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                SK_GL(*glHelper->glContext(), Finish());
725788e2474846fd2136ea7f05ca41f7e46c652d508bsalomon@google.com           }
726af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
7274bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (repeatDraw > 1) {
728af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                // output each repeat (no average) if logPerIter is set,
729af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                // otherwise output only the average
730af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                if (!logPerIter) {
731af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    fWallStr.printf(" msecs = %6.2f", fWallSum / repeatDraw);
732af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    fCpuStr.printf(" cmsecs = %6.2f", fCpuSum / repeatDraw);
733af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    fGpuStr.printf(" gmsecs = %6.2f", fGpuSum / repeatDraw);
734af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                }
73529348cb0612e19030d979156860946241e2ff4bdreed@android.com                SkString str;
736be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                str.printf("  %4s:", configName);
737be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                if (timerWall) {
738af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    str += fWallStr;
739be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
740be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                if (timerCpu) {
741af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    str += fCpuStr;
742be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
743af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                if (timerGpu && glHelper && fGpuSum > 0) {
744af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    str += fGpuStr;
745be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
74629348cb0612e19030d979156860946241e2ff4bdreed@android.com                log_progress(str);
7474bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
7484c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (outDir.size() > 0) {
749a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                saveFile(bench->getName(), configName, outDir.c_str(),
750a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                         device->accessBitmap(false));
7514c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
7524bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        }
75329348cb0612e19030d979156860946241e2ff4bdreed@android.com        log_progress("\n");
754bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
755971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
7560da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    // need to clean up here rather than post-main to allow leak detection to work
7570da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    gDebugGLHelper.cleanup();
7580da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
759bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    return 0;
760bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
761