benchmain.cpp revision 330313a8a8343876ee596da39da06a5d69badd9c
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
9971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
10971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "BenchTimer.h"
11971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
12cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
13971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrContext.h"
14cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#include "GrContextFactory.h"
15fe1b536bb7af523995549b64ad19de6685e11411robertphillips@google.com#include "gl/GrGLDefines.h"
16971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrRenderTarget.h"
17cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "SkGpuDevice.h"
1841809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.com#else
1941809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.comclass GrContext;
20cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
21971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
229a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com#include "SkBenchLogger.h"
23971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "SkBenchmark.h"
24bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkCanvas.h"
25586db93c447b753364d50fadc5426de4fef9a759sglez@google.com#include "SkCommandLineFlags.h"
2682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com#include "SkDeferredCanvas.h"
2744b67b2ed16ecb6fe001b785498e20b13fa42d0cjunov@chromium.org#include "SkDevice.h"
28f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com#include "SkColorPriv.h"
293a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkGraphics.h"
30b398fe863860b072306b5297c8095c6d973aba06reed@android.com#include "SkImageEncoder.h"
316c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkNWayCanvas.h"
326c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkPicture.h"
33bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkString.h"
3441809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.com#include "SkTArray.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) {
49dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com        bm.eraseColor(SK_ColorTRANSPARENT);
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 {
190604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com    kNonRendering_Backend,
191a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kRaster_Backend,
192a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kGPU_Backend,
193a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kPDF_Backend,
194a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org};
195a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
1969b051a375ba6d6b61cea98f35834cd032aaa5347robertphillips@google.comstatic SkDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
1979b051a375ba6d6b61cea98f35834cd032aaa5347robertphillips@google.com                             Backend backend, int sampleCount, GrContext* context) {
1989b051a375ba6d6b61cea98f35834cd032aaa5347robertphillips@google.com    SkDevice* device = NULL;
199a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkBitmap bitmap;
200a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    bitmap.setConfig(config, size.fX, size.fY);
201fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
202a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    switch (backend) {
203a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kRaster_Backend:
204a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            bitmap.allocPixels();
205a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            erase(bitmap);
2069b051a375ba6d6b61cea98f35834cd032aaa5347robertphillips@google.com            device = SkNEW_ARGS(SkDevice, (bitmap));
207a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
208cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
209cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        case kGPU_Backend: {
210cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrTextureDesc desc;
211cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fConfig = kSkia8888_GrPixelConfig;
212cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fFlags = kRenderTarget_GrTextureFlagBit;
213cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fWidth = size.fX;
214cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fHeight = size.fY;
2158a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            desc.fSampleCnt = sampleCount;
216cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
217cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            if (!texture) {
218cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                return NULL;
219cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            }
220cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            device = SkNEW_ARGS(SkGpuDevice, (context, texture.get()));
221a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
222cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
223cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
224a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kPDF_Backend:
225a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        default:
226330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com            SkDEBUGFAIL("unsupported");
227a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    }
228a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    return device;
229a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org}
230a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
231cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
232cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comGrContextFactory gContextFactory;
233cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef GrContextFactory::GLContextType GLContextType;
234cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comstatic const GLContextType kDontCareGLCtxType = GrContextFactory::kNative_GLContextType;
235cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#else
236cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef int GLContextType;
237cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comstatic const GLContextType kDontCareGLCtxType = 0;
238cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
239cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com
2404bc1983e01d756ae9c91fd380758457f579d26eareed@android.comstatic const struct {
2414bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    SkBitmap::Config    fConfig;
2424bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    const char*         fName;
2438a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    int                 fSampleCnt;
244a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend             fBackend;
245cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    GLContextType       fContextType;
2468a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    bool                fRunByDefault;
2474bc1983e01d756ae9c91fd380758457f579d26eareed@android.com} gConfigs[] = {
2488a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    { SkBitmap::kNo_Config,         "NONRENDERING", 0, kNonRendering_Backend, kDontCareGLCtxType,                      true     },
2498a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "8888",         0, kRaster_Backend,       kDontCareGLCtxType,                      true     },
2508a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    { SkBitmap::kRGB_565_Config,    "565",          0, kRaster_Backend,       kDontCareGLCtxType,                      true     },
251cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
2528a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "GPU",          0, kGPU_Backend,          GrContextFactory::kNative_GLContextType, true     },
2538a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "MSAA4",        4, kGPU_Backend,          GrContextFactory::kNative_GLContextType, false    },
2548a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "MSAA16",      16, kGPU_Backend,          GrContextFactory::kNative_GLContextType, false    },
255d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
2568a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "ANGLE",        0, kGPU_Backend,          GrContextFactory::kANGLE_GLContextType,  true     },
257cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
258a0b63b86313694f695bf0387ee0ce31de3deabb3robertphillips@google.com#ifdef SK_DEBUG
2598a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "Debug",        0, kGPU_Backend,          GrContextFactory::kDebug_GLContextType,  GR_DEBUG },
260cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_DEBUG
2618a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "NULLGPU",      0, kGPU_Backend,          GrContextFactory::kNull_GLContextType,   true     },
262cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
2634bc1983e01d756ae9c91fd380758457f579d26eareed@android.com};
2644bc1983e01d756ae9c91fd380758457f579d26eareed@android.com
2654c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic int findConfig(const char config[]) {
2664c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
2674c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        if (!strcmp(config, gConfigs[i].fName)) {
2684c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            return i;
2694c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        }
2704c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
2714c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    return -1;
2724c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
2734c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
27486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.comstatic void help() {
2758a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    SkString configsStr;
2768a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    static const size_t kConfigCount = SK_ARRAY_COUNT(gConfigs);
2778a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    for (size_t i = 0; i < kConfigCount; ++i) {
2788a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com        configsStr.appendf("%s%s", gConfigs[i].fName, ((i == kConfigCount - 1) ? "" : "|"));
2798a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    }
2808a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com
281161e1ba4c0a82e21c7d68808529699fd2394ad6cscroggo@google.com    SkDebugf("Usage: bench [-o outDir] [--repeat nr] [--logPerIter] "
2824cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                          "[--timers [wcgWC]*] [--rotate]\n"
2834cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--scale] [--clip] [--min] [--forceAA 1|0] [--forceFilter 1|0]\n"
284c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             "    [--forceDither 1|0] [--forceBlend 1|0]"
285c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#if SK_SUPPORT_GPU
286c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             " [--gpuCacheSize <bytes> <count>]"
287c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#endif
288c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             "\n"
289c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             "    [--strokeWidth width] [--match name]\n"
290c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             "    [--mode normal|deferred|deferredSilent|record|picturerecord]\n"
2918a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com             "    [--config ");
2928a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    SkDebugf("%s]\n", configsStr.c_str());
2938a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    SkDebugf("    [-Dfoo bar] [--logFile filename] [-h|--help]");
29486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("\n\n");
29586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -o outDir : Image of each bench will be put in outDir.\n");
2964cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --repeat nr : Each bench repeats for nr times.\n");
297161e1ba4c0a82e21c7d68808529699fd2394ad6cscroggo@google.com    SkDebugf("    --logPerIter : "
298af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com             "Log each repeat timer instead of mean, default is disabled.\n");
2994cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --timers [wcgWC]* : "
30091ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com             "Display wall, cpu, gpu, truncated wall or truncated cpu time for each bench.\n");
3014cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --rotate : Rotate before each bench runs.\n");
3024cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --scale : Scale before each bench runs.\n");
3034cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --clip : Clip before each bench runs.\n");
3044cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --min : Print the minimum times (instead of average).\n");
3054cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceAA 1|0 : "
30686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable anti-aliased, default is enabled.\n");
3074cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceFilter 1|0 : "
30886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable bitmap filtering, default is disabled.\n");
3094cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceDither 1|0 : "
31086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
3114cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceBlend 1|0 : "
31286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
313c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#if SK_SUPPORT_GPU
314c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com    SkDebugf("    --gpuCacheSize <bytes> <count>: "
315c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com             "limits gpu cache to  bytes size or object count.\n");
316c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com    SkDebugf("      -1 for either value means use the default. 0 for either disables the cache.\n");
317c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#endif
3184cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --strokeWidth width : The width for path stroke.\n");
319512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com    SkDebugf("    --match [~][^]substring[$] [...] of test name to run.\n"
320512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com             "             Multiple matches may be separated by spaces.\n"
321512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com             "             ~ causes a matching test to always be skipped\n"
322512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com             "             ^ requires the start of the test to match\n"
323512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com             "             $ requires the end of the test to match\n"
324512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com             "             ^ and $ requires an exact match\n"
325512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com             "             If a test does not match any list entry,\n"
326512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com             "             it is skipped unless some list entry starts with ~\n");
327fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    SkDebugf("    --mode normal|deferred|deferredSilent|record|picturerecord :\n"
328fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "             Run in the corresponding mode\n"
329fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 normal, Use a normal canvas to draw to;\n"
330fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 deferred, Use a deferrred canvas when drawing;\n"
331fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "                 deferredSilent, deferred with silent playback;\n"
332fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 record, Benchmark the time to record to an SkPicture;\n"
333fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 picturerecord, Benchmark the time to do record from a \n"
334fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                                SkPicture to a SkPicture.\n");
3354cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --logFile filename : destination for writing log output, in addition to stdout.\n");
3368a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    SkDebugf("    --config %s:\n", configsStr.c_str());
3378a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    SkDebugf("             Run bench in corresponding config mode.\n");
33886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -Dfoo bar : Add extra definition to bench.\n");
33986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -h|--help : Show this help message.\n");
34086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com}
34186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com
3425987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv);
3435987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv) {
3444e23068b374023d43c4c725138d523721d975892bsalomon@google.com#if SK_ENABLE_INST_COUNT
34565a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com    gPrintInstCount = true;
34665a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#endif
3473a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkAutoGraphics ag;
34865a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com
349e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    SkTDict<const char*> defineDict(1024);
3504bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int repeatDraw = 1;
35155fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org
3524bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int forceAlpha = 0xFF;
3534bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    bool forceAA = true;
35429348cb0612e19030d979156860946241e2ff4bdreed@android.com    bool forceFilter = false;
3554e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com    SkTriState::State forceDither = SkTriState::kDefault;
35655fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org
35755fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org    static const uint32_t kDefaultTimerTypes = TimerData::kCpu_Flag | TimerData::kGpu_Flag;
35855fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org    static const TimerData::Result kDefaultTimerResult = TimerData::kAvg_Result;
35955fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org    uint32_t timerTypes = kDefaultTimerTypes;
36055fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org    TimerData::Result timerResult = kDefaultTimerResult;
36155fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org
362387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    bool doScale = false;
3634c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doRotate = false;
3644c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doClip = false;
365652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    bool hasStrokeWidth = false;
366c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com
367c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#if SK_SUPPORT_GPU
368c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com    struct {
369e3613cefe2bc8a947068bcd2a9907a00507ffb01bsalomon@google.com        int     fBytes;
370c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com        int     fCount;
371c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com    } gpuCacheSize = { -1, -1 }; // -1s mean use the default
372c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#endif
373c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com
374652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    float strokeWidth;
3751a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    SkTDArray<const char*> fMatches;
376fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    benchModes benchMode = kNormal_benchModes;
377fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString perIterTimeformat("%.2f");
378fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString normalTimeFormat("%6.2f");
379fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
380b398fe863860b072306b5297c8095c6d973aba06reed@android.com    SkString outDir;
381387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    SkBitmap::Config outConfig = SkBitmap::kNo_Config;
382387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const char* configName = "";
383a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend backend = kRaster_Backend;  // for warning
3848a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    int sampleCount = 0;
38513eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    SkTDArray<int> configs;
38613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    bool userConfig = false;
387fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3889a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com    SkBenchLogger logger;
3899a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com
390b398fe863860b072306b5297c8095c6d973aba06reed@android.com    char* const* stop = argv + argc;
391b398fe863860b072306b5297c8095c6d973aba06reed@android.com    for (++argv; argv < stop; ++argv) {
392b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (strcmp(*argv, "-o") == 0) {
393b398fe863860b072306b5297c8095c6d973aba06reed@android.com            argv++;
394b398fe863860b072306b5297c8095c6d973aba06reed@android.com            if (argv < stop && **argv) {
395b398fe863860b072306b5297c8095c6d973aba06reed@android.com                outDir.set(*argv);
396b398fe863860b072306b5297c8095c6d973aba06reed@android.com                if (outDir.c_str()[outDir.size() - 1] != '/') {
397b398fe863860b072306b5297c8095c6d973aba06reed@android.com                    outDir.append("/");
398b398fe863860b072306b5297c8095c6d973aba06reed@android.com                }
399b398fe863860b072306b5297c8095c6d973aba06reed@android.com            }
4004cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--repeat") == 0) {
4014bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            argv++;
4024bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (argv < stop) {
4034bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                repeatDraw = atoi(*argv);
4044bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                if (repeatDraw < 1) {
4054bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                    repeatDraw = 1;
4064bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                }
4074bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            } else {
4084cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --repeat\n");
40986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
4104bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                return -1;
4114bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
4124cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--logPerIter") == 0) {
41355fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org            timerResult = TimerData::kPerIter_Result;
4144cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--timers") == 0) {
415be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            argv++;
416be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            if (argv < stop) {
41755fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                timerTypes = 0;
418be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                for (char* t = *argv; *t; ++t) {
419be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    switch (*t) {
42055fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    case 'w': timerTypes |= TimerData::kWall_Flag; break;
42155fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    case 'c': timerTypes |= TimerData::kCpu_Flag; break;
42255fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    case 'W': timerTypes |= TimerData::kTruncatedWall_Flag; break;
42355fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    case 'C': timerTypes |= TimerData::kTruncatedCpu_Flag; break;
42455fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    case 'g': timerTypes |= TimerData::kGpu_Flag; break;
425be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    }
426be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
427be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            } else {
4284cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --timers\n");
42986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
430be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                return -1;
431be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            }
4324cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--rotate")) {
4334c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doRotate = true;
4344cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--scale")) {
435387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            doScale = true;
4364cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--clip")) {
4374c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doClip = true;
4384cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--min")) {
43955fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org            timerResult = TimerData::kMin_Result;
4404cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceAA") == 0) {
44129348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceAA)) {
4424cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceAA\n");
44386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
44429348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
44529348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
4464cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceFilter") == 0) {
44729348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceFilter)) {
4484cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceFilter\n");
44986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
45029348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
45129348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
4524cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceDither") == 0) {
4534e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            bool tmp;
4544e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            if (!parse_bool_arg(++argv, stop, &tmp)) {
4554cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceDither\n");
45686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
4574e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com                return -1;
4584e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            }
4594e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            forceDither = tmp ? SkTriState::kTrue : SkTriState::kFalse;
4604cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceBlend") == 0) {
46129348cb0612e19030d979156860946241e2ff4bdreed@android.com            bool wantAlpha = false;
46229348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &wantAlpha)) {
4634cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceBlend\n");
46486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
46529348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
46629348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
46729348cb0612e19030d979156860946241e2ff4bdreed@android.com            forceAlpha = wantAlpha ? 0x80 : 0xFF;
468c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#if SK_SUPPORT_GPU
469c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com        } else if (strcmp(*argv, "--gpuCacheSize") == 0) {
470c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            if (stop - argv > 2) {
471c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                gpuCacheSize.fBytes = atoi(*++argv);
472c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                gpuCacheSize.fCount = atoi(*++argv);
473c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            } else {
474c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                SkDebugf("missing arg for --gpuCacheSize\n");
475c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                help();
476c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                return -1;
477c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            }
478c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com#endif
4794cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--mode") == 0) {
480fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            argv++;
481fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            if (argv < stop) {
482fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (strcmp(*argv, "normal") == 0) {
483fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kNormal_benchModes;
484fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "deferred") == 0) {
485fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kDeferred_benchModes;
486fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else if (strcmp(*argv, "deferredSilent") == 0) {
487fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    benchMode = kDeferredSilent_benchModes;
488fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "record") == 0) {
489fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kRecord_benchModes;
490fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "picturerecord") == 0) {
491fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kPictureRecord_benchModes;
492fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
4934cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                    logger.logError("bad arg for --mode\n");
494fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    help();
495fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    return -1;
496fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
497fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            } else {
4984cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --mode\n");
49982a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                help();
50082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                return -1;
50182a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
5024cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--strokeWidth") == 0) {
503652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            argv++;
504652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            if (argv < stop) {
505652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                const char *strokeWidthStr = *argv;
506652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                if (sscanf(strokeWidthStr, "%f", &strokeWidth) != 1) {
5074cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                  logger.logError("bad arg for --strokeWidth\n");
50886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                  help();
509652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                  return -1;
510652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                }
511652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                hasStrokeWidth = true;
512652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            } else {
5134cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --strokeWidth\n");
51486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
515652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                return -1;
516652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            }
5174cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--match") == 0) {
518387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
519512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com            while (argv < stop && (*argv)[0] != '-') {
520512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com                *fMatches.append() = *argv++;
521512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com            }
522512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com            argv--;
523512c9b65fc9fd6d298892719aeda2a8bcd377ac5caryclark@google.com            if (!fMatches.count()) {
5244cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --match\n");
52586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
526387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
527387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
5284cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--config") == 0) {
529387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
530387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
531387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                int index = findConfig(*argv);
532387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                if (index >= 0) {
53313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    *configs.append() = index;
53413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    userConfig = true;
535387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                } else {
53629348cb0612e19030d979156860946241e2ff4bdreed@android.com                    SkString str;
53729348cb0612e19030d979156860946241e2ff4bdreed@android.com                    str.printf("unrecognized config %s\n", *argv);
538a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    logger.logError(str);
53986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                    help();
540387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                    return -1;
541387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                }
542387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
5434cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --config\n");
544a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                help();
545a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                return -1;
546a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            }
5474cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--logFile") == 0) {
548a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            argv++;
549a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            if (argv < stop) {
550a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                if (!logger.SetLogFile(*argv)) {
551a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    SkString str;
552a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    str.printf("Could not open %s for writing.", *argv);
5539a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                    logger.logError(str);
554a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    return -1;
555a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                }
556a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            } else {
5574cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --logFile\n");
55886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
559387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
5604c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
5610c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com        } else if (strlen(*argv) > 2 && strncmp(*argv, "-D", 2) == 0) {
562e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            argv++;
5630c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com            if (argv < stop) {
564e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                defineDict.set(argv[-1] + 2, *argv);
565e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            } else {
566a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("incomplete '-Dfoo bar' definition\n");
56786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
568e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                return -1;
569e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            }
57086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com        } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
57186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
57286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            return 0;
573387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else {
57429348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
57529348cb0612e19030d979156860946241e2ff4bdreed@android.com            str.printf("unrecognized arg %s\n", *argv);
576a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logError(str);
57786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
578387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            return -1;
579b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
580b398fe863860b072306b5297c8095c6d973aba06reed@android.com    }
581fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)
582fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            && !outDir.isEmpty()) {
5834cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        logger.logError("'--mode record' and '--mode picturerecord' are not"
584fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                  " compatible with -o.\n");
585fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        return -1;
586fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
587fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) {
588fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        perIterTimeformat.set("%.4f");
589fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        normalTimeFormat.set("%6.4f");
590fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
59113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    if (!userConfig) {
5928a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com        // if no config is specified by user, add the default configs
59313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (unsigned int i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
5948a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            if (gConfigs[i].fRunByDefault) {
5958a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                *configs.append() = i;
5968a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
59713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        }
59813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    }
599604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com    if (kNormal_benchModes != benchMode) {
600604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        // Non-rendering configs only run in normal mode
601604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        for (int i = 0; i < configs.count(); ++i) {
602604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            int configIdx = configs[i];
603604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            if (kNonRendering_Backend == gConfigs[configIdx].fBackend) {
604604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                configs.remove(i, 1);
605604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                --i;
606604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            }
607604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        }
608604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com    }
609a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
6108a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com#if SK_SUPPORT_GPU
6118a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    for (int i = 0; i < configs.count(); ++i) {
6128a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com        int configIdx = configs[i];
6138a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com
6148a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com        if (kGPU_Backend == gConfigs[configIdx].fBackend && gConfigs[configIdx].fSampleCnt > 0) {
6158a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            GrContext* context = gContextFactory.get(gConfigs[configIdx].fContextType);
6168a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            if (NULL == context) {
6178a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                SkString error;
6188a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                error.printf("Error creating GrContext for config %s. Config will be skipped.\n",
6198a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                             gConfigs[configIdx].fName);
6208a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                logger.logError(error.c_str());
6218a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                configs.remove(i);
6228a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                --i;
6238a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                continue;
6248a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
6258a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            if (gConfigs[configIdx].fSampleCnt > context->getMaxSampleCount()){
6268a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                SkString error;
6278a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                error.printf("Sample count (%d) for config %s is unsupported. "
6288a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                             "Config will be skipped.\n",
6298a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                             gConfigs[configIdx].fSampleCnt, gConfigs[configIdx].fName);
6308a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                logger.logError(error.c_str());
6318a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                configs.remove(i);
6328a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                --i;
6338a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                continue;
6348a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
6358a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com        }
6368a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    }
6378a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com#endif
6388a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com
6393b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    // report our current settings
6403b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    {
6413b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com        SkString str;
642fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        const char* deferredMode = benchMode == kDeferred_benchModes ? "yes" :
643fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org            (benchMode == kDeferredSilent_benchModes ? "silent" : "no");
644af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com        str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d "
645fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                   "deferred=%s logperiter=%d",
646fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                   forceAlpha, forceAA, forceFilter, deferredMode,
64755fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                   TimerData::kPerIter_Result == timerResult);
6482abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com        str.appendf(" rotate=%d scale=%d clip=%d min=%d",
64955fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                   doRotate, doScale, doClip, TimerData::kMin_Result == timerResult);
650fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        str.appendf(" record=%d picturerecord=%d",
651fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kRecord_benchModes,
652fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kPictureRecord_benchModes);
653a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        const char * ditherName;
654a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        switch (forceDither) {
655a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kDefault: ditherName = "default"; break;
656a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kTrue: ditherName = "true"; break;
657a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kFalse: ditherName = "false"; break;
658a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            default: ditherName = "<invalid>"; break;
659a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
660a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.appendf(" dither=%s", ditherName);
661fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
662a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        if (hasStrokeWidth) {
663a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.appendf(" strokeWidth=%f", strokeWidth);
664a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        } else {
665a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.append(" strokeWidth=none");
666a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
667a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
668a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_SCALAR_IS_FLOAT)
669a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=float");
670a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_SCALAR_IS_FIXED)
671a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=fixed");
672a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
673a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
674a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_BUILD_FOR_WIN32)
675a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=WIN32");
676a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_MAC)
677a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=MAC");
678a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_ANDROID)
679a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=ANDROID");
680a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_UNIX)
681a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=UNIX");
682a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#else
683a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=other");
684a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
685a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
686a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_DEBUG)
687a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" DEBUG");
688a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
689a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append("\n");
690a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(str);
6913b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    }
692508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
693cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    SkTArray<BenchTimer*> timers(SK_ARRAY_COUNT(gConfigs));
6945c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
695cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
696c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com        SkGLContextHelper* glCtx = NULL;
697cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        if (kGPU_Backend == gConfigs[i].fBackend) {
698c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            GrContext* context = gContextFactory.get(gConfigs[i].fContextType);
699c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            if (NULL != context) {
700c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                // Set the user specified cache limits if non-default.
701c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                size_t bytes;
702c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                int count;
703c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                context->getTextureCacheLimits(&count, &bytes);
704c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                if (-1 != gpuCacheSize.fBytes) {
705e3613cefe2bc8a947068bcd2a9907a00507ffb01bsalomon@google.com                    bytes = static_cast<size_t>(gpuCacheSize.fBytes);
706c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                }
707c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                if (-1 != gpuCacheSize.fCount) {
708c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                    count = gpuCacheSize.fCount;
709c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                }
710c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com                context->setTextureCacheLimits(count, bytes);
711c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            }
712c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com            glCtx = gContextFactory.getGLContext(gConfigs[i].fContextType);
713cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
714c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com        timers.push_back(SkNEW_ARGS(BenchTimer, (glCtx)));
715cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#else
716cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        timers.push_back(SkNEW(BenchTimer));
717cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
718cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
71974913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com
720e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter iter(&defineDict);
721bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* bench;
722bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    while ((bench = iter.next()) != NULL) {
7237fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com        SkAutoTUnref<SkBenchmark> benchUnref(bench);
7247fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com
725b398fe863860b072306b5297c8095c6d973aba06reed@android.com        SkIPoint dim = bench->getSize();
726b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (dim.fX <= 0 || dim.fY <= 0) {
727b398fe863860b072306b5297c8095c6d973aba06reed@android.com            continue;
728b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
729fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
7304bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAlpha(forceAlpha);
7314bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAA(forceAA);
73229348cb0612e19030d979156860946241e2ff4bdreed@android.com        bench->setForceFilter(forceFilter);
7334e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com        bench->setDither(forceDither);
734652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        if (hasStrokeWidth) {
735652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            bench->setStrokeWidth(strokeWidth);
736652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        }
737fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
738387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        // only run benchmarks if their name contains matchStr
739586db93c447b753364d50fadc5426de4fef9a759sglez@google.com        if (SkCommandLineFlags::ShouldSkip(fMatches, bench->getName())) {
740387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            continue;
741387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        }
742fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
743604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        bool loggedBenchStart = false;
744fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
74530e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        AutoPrePostDraw appd(bench);
74630e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
74713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (int x = 0; x < configs.count(); ++x) {
74813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            int configIndex = configs[x];
74913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com
7507495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org            bool setupFailed = false;
7517495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org
752604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            if (kNonRendering_Backend == gConfigs[configIndex].fBackend) {
753604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                if (bench->isRendering()) {
754604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                    continue;
755604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                }
756604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            } else {
757604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                if (!bench->isRendering()) {
758604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                    continue;
759604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                }
760604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            }
761604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com
76213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            outConfig = gConfigs[configIndex].fConfig;
76313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            configName = gConfigs[configIndex].fName;
76413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            backend = gConfigs[configIndex].fBackend;
7658a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            sampleCount = gConfigs[configIndex].fSampleCnt;
766cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrContext* context = NULL;
767cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            BenchTimer* timer = timers[configIndex];
768508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
769cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
7709c55f801a35b0d6c39f007fae432bd13094f3c52sugoi@google.com            SkGLContextHelper* glContext = NULL;
771cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            if (kGPU_Backend == backend) {
772cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                context = gContextFactory.get(gConfigs[configIndex].fContextType);
773cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL == context) {
774cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    continue;
775cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                }
776cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                glContext = gContextFactory.getGLContext(gConfigs[configIndex].fContextType);
7774bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
778cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
7799b051a375ba6d6b61cea98f35834cd032aaa5347robertphillips@google.com            SkDevice* device = NULL;
780fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkCanvas* canvas = NULL;
781fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordFrom;
782fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordTo;
783604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com
784604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            if (kNonRendering_Backend != backend) {
7858a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                device = make_device(outConfig, dim, backend, sampleCount, context);
7867495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                if (NULL == device) {
7877495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    SkString error;
7887495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    error.printf("Device creation failure for config %s. Will skip.\n", configName);
7897495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    logger.logError(error.c_str());
7907495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    setupFailed = true;
7917495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                } else {
7927495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    switch(benchMode) {
7937495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        case kDeferredSilent_benchModes:
7947495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        case kDeferred_benchModes:
795cb6222499625e78190a58e5a7df3ef8cc8e40f7acommit-bot@chromium.org                            canvas = SkDeferredCanvas::Create(device);
7967495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            break;
7977495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        case kRecord_benchModes:
7987495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
7997495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                                SkPicture::kUsePathBoundsForClip_RecordingFlag);
8007495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            canvas->ref();
8017495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            break;
8027495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        case kPictureRecord_benchModes: {
8037495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            // This sets up picture-to-picture recording.
8047495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            // The C++ drawing calls for the benchmark are recorded into
8057495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            // pictureRecordFrom. As the benchmark, we will time how
8067495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            // long it takes to playback pictureRecordFrom into
8077495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            // pictureRecordTo.
8087495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            SkCanvas* tempCanvas = pictureRecordFrom.beginRecording(dim.fX, dim.fY,
8097495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                                SkPicture::kUsePathBoundsForClip_RecordingFlag);
8107495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            bench->draw(tempCanvas);
8117495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            pictureRecordFrom.endRecording();
8127495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
8137495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                                SkPicture::kUsePathBoundsForClip_RecordingFlag);
8147495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            canvas->ref();
8157495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            break;
8167495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        }
8177495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        case kNormal_benchModes:
8187495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            canvas = new SkCanvas(device);
8197495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            break;
8207495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        default:
8217495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            SkASSERT(0);
822604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                    }
8237495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    device->unref();
8247495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    canvas->clear(SK_ColorWHITE);
825fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
82682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
82782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            SkAutoUnref canvasUnref(canvas);
8287495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org            if (!setupFailed) {
8297495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                if (NULL != canvas) {
8307495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (doClip) {
8317495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        performClip(canvas, dim.fX, dim.fY);
8327495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
8337495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (doScale) {
8347495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        performScale(canvas, dim.fX, dim.fY);
8357495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
8367495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (doRotate) {
8377495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        performRotate(canvas, dim.fX, dim.fY);
8387495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
839604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                }
840604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com
8417495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                if (!loggedBenchStart) {
8427495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    loggedBenchStart = true;
8437495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    SkString str;
8447495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    str.printf("running bench [%d %d] %28s", dim.fX, dim.fY, bench->getName());
8457495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    logger.logProgress(str);
8467495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                }
847508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
8487495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                // warm up caches if needed
8497495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                if (repeatDraw > 1 && NULL != canvas) {
85091ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com#if SK_SUPPORT_GPU
8517495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    // purge the GPU resources to reduce variance
8527495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (NULL != context) {
8537495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        context->freeGpuResources();
8547495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
85591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com#endif
8567495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    SkAutoCanvasRestore acr(canvas, true);
8577495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (benchMode == kPictureRecord_benchModes) {
8587495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        pictureRecordFrom.draw(canvas);
8597495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    } else {
8607495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        bench->draw(canvas);
8617495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
862fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
8637495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (kDeferredSilent_benchModes == benchMode) {
8647495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
8657495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    } else {
8667495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        canvas->flush();
8677495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
868cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
8697495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (NULL != context) {
8707495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        context->flush();
8717495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        SK_GL(*glContext, Finish());
8727495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
873cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
874fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
875fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
8767495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                // record timer values for each repeat, and their sum
87755fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                TimerData timerData(repeatDraw);
8787495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                for (int i = 0; i < repeatDraw; i++) {
8797495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) {
8807495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        // This will clear the recorded commands so that they do not
8817495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        // accumulate.
8827495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
8837495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                            SkPicture::kUsePathBoundsForClip_RecordingFlag);
8847495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
885fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
8867495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    timer->start(bench->getDurationScale());
8877495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (NULL != canvas) {
8887495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        canvas->save();
8897495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
8907495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (benchMode == kPictureRecord_benchModes) {
8917495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        pictureRecordFrom.draw(canvas);
8927495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    } else {
8937495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        bench->draw(canvas);
8947495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
89591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com
8967495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (kDeferredSilent_benchModes == benchMode) {
8977495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
8987495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    } else if (NULL != canvas) {
8997495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        canvas->flush();
9007495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
901604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com
9027495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (NULL != canvas) {
9037495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        canvas->restore();
9047495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
9057495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org
9067495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    // stop the truncated timer after the last canvas call but
9077495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    // don't wait for all the GL calls to complete
9087495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    timer->truncatedEnd();
909cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
9107495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    if (NULL != glContext) {
9117495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        context->flush();
9127495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                        SK_GL(*glContext, Finish());
9137495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    }
914cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
9157495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    // stop the inclusive and gpu timers once all the GL calls
9167495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    // have completed
9177495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    timer->end();
918af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
91955fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    SkAssertResult(timerData.appendTimes(timer));
9202abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com
9217495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                }
9227495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                if (repeatDraw > 1) {
92355fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    const char* timeFormat;
92455fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    if (TimerData::kPerIter_Result == timerResult) {
92555fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                        timeFormat = perIterTimeformat.c_str();
92655fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    } else {
92755fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                        timeFormat = normalTimeFormat.c_str();
92855fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    }
92955fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    uint32_t filteredTimerTypes = timerTypes;
93055fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    if (NULL == context) {
93155fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                        filteredTimerTypes &= ~TimerData::kGpu_Flag;
93255fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    }
93355fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                    SkString result = timerData.getResult(timeFormat,
93455fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                                        timerResult,
93555fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                                        configName,
93655fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org                                        filteredTimerTypes);
9377495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    logger.logProgress(result);
9387495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                }
9397495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                if (outDir.size() > 0 && kNonRendering_Backend != backend) {
9407495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                    saveFile(bench->getName(), configName, outDir.c_str(),
9417495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                             device->accessBitmap(false));
9427495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                }
94325df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com            }
94424ed8d721979d891b5fbdfd59dfdd0902778b912bensong@google.com        }
94524ed8d721979d891b5fbdfd59dfdd0902778b912bensong@google.com        if (loggedBenchStart) {
94624ed8d721979d891b5fbdfd59dfdd0902778b912bensong@google.com            logger.logProgress(SkString("\n"));
9474bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        }
948bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
949cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
9509d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#if GR_CACHE_STATS
951cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    for (int i = 0; i <= GrContextFactory::kLastGLContextType; ++i) {
952cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        GrContextFactory::GLContextType ctxType = (GrContextFactory::GLContextType)i;
953cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        GrContext* context = gContextFactory.get(ctxType);
954cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        if (NULL != context) {
955cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDebugf("Cache Stats for %s context:\n", GrContextFactory::GLContextTypeName(ctxType));
956cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            context->printCacheStats();
957cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDebugf("\n");
958cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
959cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
9609d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#endif
961cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    // Destroy the GrContext before the inst tracking printing at main() exit occurs.
962cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    gContextFactory.destroyContexts();
963cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
9645c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
965cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        SkDELETE(timers[i]);
966cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
9679d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com
968bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    return 0;
969bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
9705987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
9717158e6acca1b1ecc321d4d514a31cba11b5ead60borenet@google.com#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
9725987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint main(int argc, char * const argv[]) {
9735987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com    return tool_main(argc, (char**) argv);
9745987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
9755987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
976