benchmain.cpp revision 9c55f801a35b0d6c39f007fae432bd13094f3c52
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
9971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
10971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "BenchTimer.h"
11971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
12cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
13971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrContext.h"
14cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#include "GrContextFactory.h"
15fe1b536bb7af523995549b64ad19de6685e11411robertphillips@google.com#include "gl/GrGLDefines.h"
16971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrRenderTarget.h"
17cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "SkGpuDevice.h"
1841809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.com#else
1941809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.comclass GrContext;
20cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
21971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
229a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com#include "SkBenchLogger.h"
23971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "SkBenchmark.h"
24bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkCanvas.h"
2582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com#include "SkDeferredCanvas.h"
2644b67b2ed16ecb6fe001b785498e20b13fa42d0cjunov@chromium.org#include "SkDevice.h"
27f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com#include "SkColorPriv.h"
283a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkGraphics.h"
29b398fe863860b072306b5297c8095c6d973aba06reed@android.com#include "SkImageEncoder.h"
306c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkNWayCanvas.h"
316c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkPicture.h"
32bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkString.h"
3341809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.com#include "SkTArray.h"
349a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com#include "TimerData.h"
3529348cb0612e19030d979156860946241e2ff4bdreed@android.com
36fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.orgenum benchModes {
37fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kNormal_benchModes,
38fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kDeferred_benchModes,
39fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    kDeferredSilent_benchModes,
40fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kRecord_benchModes,
41fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kPictureRecord_benchModes
42fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org};
43fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
44fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org///////////////////////////////////////////////////////////////////////////////
45fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
466c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic void erase(SkBitmap& bm) {
476c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
48dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com        bm.eraseColor(SK_ColorTRANSPARENT);
496c924ad46c89955e78e071c792ef00df9910b42freed@android.com    } else {
506c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm.eraseColor(SK_ColorWHITE);
516c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
526c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
536c924ad46c89955e78e071c792ef00df9910b42freed@android.com
54a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org#if 0
556c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic bool equal(const SkBitmap& bm1, const SkBitmap& bm2) {
566c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm1.width() != bm2.width() ||
576c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm1.height() != bm2.height() ||
586c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm1.config() != bm2.config()) {
596c924ad46c89955e78e071c792ef00df9910b42freed@android.com        return false;
606c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
61fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
626c924ad46c89955e78e071c792ef00df9910b42freed@android.com    size_t pixelBytes = bm1.width() * bm1.bytesPerPixel();
636c924ad46c89955e78e071c792ef00df9910b42freed@android.com    for (int y = 0; y < bm1.height(); y++) {
646c924ad46c89955e78e071c792ef00df9910b42freed@android.com        if (memcmp(bm1.getAddr(0, y), bm2.getAddr(0, y), pixelBytes)) {
656c924ad46c89955e78e071c792ef00df9910b42freed@android.com            return false;
666c924ad46c89955e78e071c792ef00df9910b42freed@android.com        }
676c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
686c924ad46c89955e78e071c792ef00df9910b42freed@android.com    return true;
696c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
70a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org#endif
716c924ad46c89955e78e071c792ef00df9910b42freed@android.com
72bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comclass Iter {
73bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.compublic:
74e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter(void* param) {
75bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        fBench = BenchRegistry::Head();
76e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com        fParam = param;
77bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
78fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
79bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* next() {
80bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        if (fBench) {
81bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            BenchRegistry::Factory f = fBench->factory();
82bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            fBench = fBench->next();
83e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            return f(fParam);
84bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
85bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        return NULL;
86bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
87d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
88bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comprivate:
89bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    const BenchRegistry* fBench;
90e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    void* fParam;
91bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com};
92bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
9330e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.comclass AutoPrePostDraw {
9430e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.compublic:
9530e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    AutoPrePostDraw(SkBenchmark* bench) : fBench(bench) {
9630e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        fBench->preDraw();
9730e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    }
9830e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    ~AutoPrePostDraw() {
9930e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        fBench->postDraw();
10030e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    }
10130e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.comprivate:
10230e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    SkBenchmark* fBench;
10330e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com};
10430e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
105bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comstatic void make_filename(const char name[], SkString* path) {
106bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    path->set(name);
107bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    for (int i = 0; name[i]; i++) {
108bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        switch (name[i]) {
109bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '/':
110bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '\\':
111bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ' ':
112bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ':':
113bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                path->writable_str()[i] = '-';
114bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
115bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            default:
116bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
117bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
118bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
119bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
120bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
1214c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void saveFile(const char name[], const char config[], const char dir[],
1224c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                     const SkBitmap& bm) {
1234c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkBitmap copy;
1244c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    if (!bm.copyTo(&copy, SkBitmap::kARGB_8888_Config)) {
1254c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        return;
1264c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
127fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
128f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
129f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        // turn alpha into gray-scale
130f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        size_t size = copy.getSize() >> 2;
131f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        SkPMColor* p = copy.getAddr32(0, 0);
132f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        for (size_t i = 0; i < size; i++) {
133f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            int c = (*p >> SK_A32_SHIFT) & 0xFF;
134f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c = 255 - c;
135f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c |= (c << 24) | (c << 16) | (c << 8);
136f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            *p++ = c | (SK_A32_MASK << SK_A32_SHIFT);
137f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        }
138f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    }
139fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1404c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkString str;
1414c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    make_filename(name, &str);
1424c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    str.appendf("_%s.png", config);
1434c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    str.prepend(dir);
1444c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    ::remove(str.c_str());
1454c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkImageEncoder::EncodeFile(str.c_str(), copy, SkImageEncoder::kPNG_Type,
1464c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                               100);
1474c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1484c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1494c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performClip(SkCanvas* canvas, int w, int h) {
1504c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkRect r;
151fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1524c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(10), SkIntToScalar(10),
1534c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
1544c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kIntersect_Op);
155fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1564c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
1574c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w-10), SkIntToScalar(h-10));
1584c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kXOR_Op);
1594c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1604c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1614c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performRotate(SkCanvas* canvas, int w, int h) {
1624c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
1634c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
164fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1654c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(x, y);
1664c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->rotate(SkIntToScalar(35));
1674c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(-x, -y);
1684c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1694c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
170387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.comstatic void performScale(SkCanvas* canvas, int w, int h) {
171387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
172387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
173fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
174387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(x, y);
175387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    // just enough so we can't take the sprite case
176387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
177387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(-x, -y);
178387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com}
179387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com
18029348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic bool parse_bool_arg(char * const* argv, char* const* stop, bool* var) {
18129348cb0612e19030d979156860946241e2ff4bdreed@android.com    if (argv < stop) {
18229348cb0612e19030d979156860946241e2ff4bdreed@android.com        *var = atoi(*argv) != 0;
18329348cb0612e19030d979156860946241e2ff4bdreed@android.com        return true;
18429348cb0612e19030d979156860946241e2ff4bdreed@android.com    }
18529348cb0612e19030d979156860946241e2ff4bdreed@android.com    return false;
18629348cb0612e19030d979156860946241e2ff4bdreed@android.com}
18729348cb0612e19030d979156860946241e2ff4bdreed@android.com
188a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgenum Backend {
189a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kRaster_Backend,
190a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kGPU_Backend,
191a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kPDF_Backend,
192a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org};
193a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
194a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgstatic SkDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
195cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                             Backend backend, GrContext* context) {
196a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkDevice* device = NULL;
197a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkBitmap bitmap;
198a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    bitmap.setConfig(config, size.fX, size.fY);
199fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
200a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    switch (backend) {
201a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kRaster_Backend:
202a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            bitmap.allocPixels();
203a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            erase(bitmap);
204cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            device = SkNEW_ARGS(SkDevice, (bitmap));
205a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
206cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
207cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        case kGPU_Backend: {
208cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrTextureDesc desc;
209cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fConfig = kSkia8888_GrPixelConfig;
210cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fFlags = kRenderTarget_GrTextureFlagBit;
211cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fWidth = size.fX;
212cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fHeight = size.fY;
213cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
214cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            if (!texture) {
215cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                return NULL;
216cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            }
217cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            device = SkNEW_ARGS(SkGpuDevice, (context, texture.get()));
218a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
219cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
220cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
221a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kPDF_Backend:
222a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        default:
223a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            SkASSERT(!"unsupported");
224a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    }
225a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    return device;
226a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org}
227a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
228cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
229cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comGrContextFactory gContextFactory;
230cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef GrContextFactory::GLContextType GLContextType;
231cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comstatic const GLContextType kDontCareGLCtxType = GrContextFactory::kNative_GLContextType;
232cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#else
233cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef int GLContextType;
234cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comstatic const GLContextType kDontCareGLCtxType = 0;
235cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
236cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com
2374bc1983e01d756ae9c91fd380758457f579d26eareed@android.comstatic const struct {
2384bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    SkBitmap::Config    fConfig;
2394bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    const char*         fName;
240a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend             fBackend;
241cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    GLContextType       fContextType;
2424bc1983e01d756ae9c91fd380758457f579d26eareed@android.com} gConfigs[] = {
243cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "8888",     kRaster_Backend, kDontCareGLCtxType },
244cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kRGB_565_Config,    "565",      kRaster_Backend, kDontCareGLCtxType },
245cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
246cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "GPU",      kGPU_Backend, GrContextFactory::kNative_GLContextType },
247d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
248cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "ANGLE",    kGPU_Backend, GrContextFactory::kANGLE_GLContextType },
249cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
250a0b63b86313694f695bf0387ee0ce31de3deabb3robertphillips@google.com#ifdef SK_DEBUG
251cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "Debug",    kGPU_Backend, GrContextFactory::kDebug_GLContextType },
252cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_DEBUG
253cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "NULLGPU",  kGPU_Backend, GrContextFactory::kNull_GLContextType },
254cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
2554bc1983e01d756ae9c91fd380758457f579d26eareed@android.com};
2564bc1983e01d756ae9c91fd380758457f579d26eareed@android.com
2574c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic int findConfig(const char config[]) {
2584c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
2594c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        if (!strcmp(config, gConfigs[i].fName)) {
2604c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            return i;
2614c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        }
2624c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
2634c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    return -1;
2644c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
2654c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
2661a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.comstatic bool skip_name(const SkTDArray<const char*> array, const char name[]) {
2671a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    if (0 == array.count()) {
2681a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        // no names, so don't skip anything
2691a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        return false;
2701a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    }
2711a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    for (int i = 0; i < array.count(); ++i) {
2721a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (strstr(name, array[i])) {
2731a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com            // found the name, so don't skip
2741a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com            return false;
2751a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        }
2761a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    }
2771a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    return true;
2781a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com}
2791a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com
28086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.comstatic void help() {
281161e1ba4c0a82e21c7d68808529699fd2394ad6cscroggo@google.com    SkDebugf("Usage: bench [-o outDir] [--repeat nr] [--logPerIter] "
2824cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                          "[--timers [wcgWC]*] [--rotate]\n"
2834cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--scale] [--clip] [--min] [--forceAA 1|0] [--forceFilter 1|0]\n"
2844cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--forceDither 1|0] [--forceBlend 1|0] [--strokeWidth width]\n"
285fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "    [--match name] [--mode normal|deferred|deferredSilent|record|picturerecord]\n"
2864cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com             "    [--config 8888|565|GPU|ANGLE|NULLGPU] [-Dfoo bar] [--logFile filename]\n"
28782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com             "    [-h|--help]");
28886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("\n\n");
28986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -o outDir : Image of each bench will be put in outDir.\n");
2904cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --repeat nr : Each bench repeats for nr times.\n");
291161e1ba4c0a82e21c7d68808529699fd2394ad6cscroggo@google.com    SkDebugf("    --logPerIter : "
292af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com             "Log each repeat timer instead of mean, default is disabled.\n");
2934cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --timers [wcgWC]* : "
29491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com             "Display wall, cpu, gpu, truncated wall or truncated cpu time for each bench.\n");
2954cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --rotate : Rotate before each bench runs.\n");
2964cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --scale : Scale before each bench runs.\n");
2974cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --clip : Clip before each bench runs.\n");
2984cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --min : Print the minimum times (instead of average).\n");
2994cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceAA 1|0 : "
30086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable anti-aliased, default is enabled.\n");
3014cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceFilter 1|0 : "
30286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable bitmap filtering, default is disabled.\n");
3034cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceDither 1|0 : "
30486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
3054cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --forceBlend 1|0 : "
30686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
3074cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --strokeWidth width : The width for path stroke.\n");
3084cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --match name : Only run bench whose name is matched.\n");
309fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org    SkDebugf("    --mode normal|deferred|deferredSilent|record|picturerecord :\n"
310fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "             Run in the corresponding mode\n"
311fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 normal, Use a normal canvas to draw to;\n"
312fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 deferred, Use a deferrred canvas when drawing;\n"
313fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org             "                 deferredSilent, deferred with silent playback;\n"
314fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 record, Benchmark the time to record to an SkPicture;\n"
315fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 picturerecord, Benchmark the time to do record from a \n"
316fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                                SkPicture to a SkPicture.\n");
3174cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --logFile filename : destination for writing log output, in addition to stdout.\n");
318cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
3194cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --config 8888|565|GPU|ANGLE|NULLGPU : "
32086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Run bench in corresponding config mode.\n");
321cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
3224cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com    SkDebugf("    --config 8888|565: "
323cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com             "Run bench in corresponding config mode.\n");
324cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
32586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -Dfoo bar : Add extra definition to bench.\n");
32686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -h|--help : Show this help message.\n");
32786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com}
32886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com
3295987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv);
3305987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv) {
3314e23068b374023d43c4c725138d523721d975892bsalomon@google.com#if SK_ENABLE_INST_COUNT
33265a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com    gPrintInstCount = true;
33365a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#endif
3343a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkAutoGraphics ag;
33565a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com
336e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    SkTDict<const char*> defineDict(1024);
3374bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int repeatDraw = 1;
338af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    bool logPerIter = false;
3394bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int forceAlpha = 0xFF;
3404bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    bool forceAA = true;
34129348cb0612e19030d979156860946241e2ff4bdreed@android.com    bool forceFilter = false;
3424e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com    SkTriState::State forceDither = SkTriState::kDefault;
343be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerWall = false;
34491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com    bool truncatedTimerWall = false;
345be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerCpu = true;
34691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com    bool truncatedTimerCpu = false;
347be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerGpu = true;
348387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    bool doScale = false;
3494c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doRotate = false;
3504c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doClip = false;
3512abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com    bool printMin = false;
352652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    bool hasStrokeWidth = false;
353652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    float strokeWidth;
3541a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    SkTDArray<const char*> fMatches;
355fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    benchModes benchMode = kNormal_benchModes;
356fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString perIterTimeformat("%.2f");
357fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString normalTimeFormat("%6.2f");
358fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
359b398fe863860b072306b5297c8095c6d973aba06reed@android.com    SkString outDir;
360387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    SkBitmap::Config outConfig = SkBitmap::kNo_Config;
361387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const char* configName = "";
362a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend backend = kRaster_Backend;  // for warning
36313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    SkTDArray<int> configs;
36413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    bool userConfig = false;
365fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
3669a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com    SkBenchLogger logger;
3679a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com
368b398fe863860b072306b5297c8095c6d973aba06reed@android.com    char* const* stop = argv + argc;
369b398fe863860b072306b5297c8095c6d973aba06reed@android.com    for (++argv; argv < stop; ++argv) {
370b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (strcmp(*argv, "-o") == 0) {
371b398fe863860b072306b5297c8095c6d973aba06reed@android.com            argv++;
372b398fe863860b072306b5297c8095c6d973aba06reed@android.com            if (argv < stop && **argv) {
373b398fe863860b072306b5297c8095c6d973aba06reed@android.com                outDir.set(*argv);
374b398fe863860b072306b5297c8095c6d973aba06reed@android.com                if (outDir.c_str()[outDir.size() - 1] != '/') {
375b398fe863860b072306b5297c8095c6d973aba06reed@android.com                    outDir.append("/");
376b398fe863860b072306b5297c8095c6d973aba06reed@android.com                }
377b398fe863860b072306b5297c8095c6d973aba06reed@android.com            }
3784cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--repeat") == 0) {
3794bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            argv++;
3804bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (argv < stop) {
3814bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                repeatDraw = atoi(*argv);
3824bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                if (repeatDraw < 1) {
3834bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                    repeatDraw = 1;
3844bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                }
3854bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            } else {
3864cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --repeat\n");
38786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
3884bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                return -1;
3894bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
3904cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--logPerIter") == 0) {
391161e1ba4c0a82e21c7d68808529699fd2394ad6cscroggo@google.com            logPerIter = true;
3924cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--timers") == 0) {
393be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            argv++;
394be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            if (argv < stop) {
395be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerWall = false;
39691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                truncatedTimerWall = false;
397be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerCpu = false;
39891ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                truncatedTimerCpu = false;
399be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerGpu = false;
400be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                for (char* t = *argv; *t; ++t) {
401be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    switch (*t) {
402be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'w': timerWall = true; break;
403be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'c': timerCpu = true; break;
40491ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    case 'W': truncatedTimerWall = true; break;
40591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                    case 'C': truncatedTimerCpu = true; break;
406be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'g': timerGpu = true; break;
407be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    }
408be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
409be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            } else {
4104cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --timers\n");
41186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
412be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                return -1;
413be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            }
4144cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--rotate")) {
4154c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doRotate = true;
4164cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--scale")) {
417387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            doScale = true;
4184cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--clip")) {
4194c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doClip = true;
4204cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (!strcmp(*argv, "--min")) {
4212abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com            printMin = true;
4224cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceAA") == 0) {
42329348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceAA)) {
4244cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceAA\n");
42586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
42629348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
42729348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
4284cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceFilter") == 0) {
42929348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceFilter)) {
4304cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceFilter\n");
43186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
43229348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
43329348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
4344cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceDither") == 0) {
4354e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            bool tmp;
4364e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            if (!parse_bool_arg(++argv, stop, &tmp)) {
4374cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceDither\n");
43886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
4394e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com                return -1;
4404e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            }
4414e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            forceDither = tmp ? SkTriState::kTrue : SkTriState::kFalse;
4424cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--forceBlend") == 0) {
44329348cb0612e19030d979156860946241e2ff4bdreed@android.com            bool wantAlpha = false;
44429348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &wantAlpha)) {
4454cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --forceBlend\n");
44686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
44729348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
44829348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
44929348cb0612e19030d979156860946241e2ff4bdreed@android.com            forceAlpha = wantAlpha ? 0x80 : 0xFF;
4504cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--mode") == 0) {
451fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            argv++;
452fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            if (argv < stop) {
453fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (strcmp(*argv, "normal") == 0) {
454fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kNormal_benchModes;
455fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "deferred") == 0) {
456fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kDeferred_benchModes;
457fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else if (strcmp(*argv, "deferredSilent") == 0) {
458fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    benchMode = kDeferredSilent_benchModes;
459fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "record") == 0) {
460fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kRecord_benchModes;
461fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "picturerecord") == 0) {
462fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kPictureRecord_benchModes;
463fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
4644cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                    logger.logError("bad arg for --mode\n");
465fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    help();
466fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    return -1;
467fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
468fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            } else {
4694cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --mode\n");
47082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                help();
47182a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                return -1;
47282a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
4734cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--strokeWidth") == 0) {
474652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            argv++;
475652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            if (argv < stop) {
476652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                const char *strokeWidthStr = *argv;
477652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                if (sscanf(strokeWidthStr, "%f", &strokeWidth) != 1) {
4784cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                  logger.logError("bad arg for --strokeWidth\n");
47986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                  help();
480652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                  return -1;
481652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                }
482652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                hasStrokeWidth = true;
483652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            } else {
4844cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --strokeWidth\n");
48586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
486652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                return -1;
487652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            }
4884cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--match") == 0) {
489387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
490387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
4911a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com                *fMatches.append() = *argv;
492387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
4934cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --match\n");
49486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
495387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
496387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
4974cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--config") == 0) {
498387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
499387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
500387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                int index = findConfig(*argv);
501387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                if (index >= 0) {
50213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    *configs.append() = index;
50313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    userConfig = true;
504387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                } else {
50529348cb0612e19030d979156860946241e2ff4bdreed@android.com                    SkString str;
50629348cb0612e19030d979156860946241e2ff4bdreed@android.com                    str.printf("unrecognized config %s\n", *argv);
507a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    logger.logError(str);
50886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                    help();
509387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                    return -1;
510387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                }
511387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
5124cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --config\n");
513a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                help();
514a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                return -1;
515a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            }
5164cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        } else if (strcmp(*argv, "--logFile") == 0) {
517a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            argv++;
518a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            if (argv < stop) {
519a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                if (!logger.SetLogFile(*argv)) {
520a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    SkString str;
521a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    str.printf("Could not open %s for writing.", *argv);
5229a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                    logger.logError(str);
523a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    return -1;
524a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                }
525a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            } else {
5264cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com                logger.logError("missing arg for --logFile\n");
52786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
528387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
5294c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
5300c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com        } else if (strlen(*argv) > 2 && strncmp(*argv, "-D", 2) == 0) {
531e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            argv++;
5320c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com            if (argv < stop) {
533e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                defineDict.set(argv[-1] + 2, *argv);
534e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            } else {
535a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("incomplete '-Dfoo bar' definition\n");
53686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
537e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                return -1;
538e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            }
53986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com        } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
54086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
54186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            return 0;
542387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else {
54329348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
54429348cb0612e19030d979156860946241e2ff4bdreed@android.com            str.printf("unrecognized arg %s\n", *argv);
545a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logError(str);
54686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
547387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            return -1;
548b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
549b398fe863860b072306b5297c8095c6d973aba06reed@android.com    }
550fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)
551fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            && !outDir.isEmpty()) {
5524cea9f41d192f0f6514f27cb3978a2363526a25bscroggo@google.com        logger.logError("'--mode record' and '--mode picturerecord' are not"
553fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                  " compatible with -o.\n");
554fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        return -1;
555fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
556fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) {
557fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        perIterTimeformat.set("%.4f");
558fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        normalTimeFormat.set("%6.4f");
559fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
56013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    if (!userConfig) {
56113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        // if no config is specified by user, we add them all.
56213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (unsigned int i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
56313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            *configs.append() = i;
56413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        }
56513eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    }
566a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
5673b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    // report our current settings
5683b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    {
5693b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com        SkString str;
570fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org        const char* deferredMode = benchMode == kDeferred_benchModes ? "yes" :
571fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org            (benchMode == kDeferredSilent_benchModes ? "silent" : "no");
572af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com        str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d "
573fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                   "deferred=%s logperiter=%d",
574fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                   forceAlpha, forceAA, forceFilter, deferredMode,
575fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                   logPerIter);
5762abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com        str.appendf(" rotate=%d scale=%d clip=%d min=%d",
5772abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                   doRotate, doScale, doClip, printMin);
578fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        str.appendf(" record=%d picturerecord=%d",
579fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kRecord_benchModes,
580fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kPictureRecord_benchModes);
581a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        const char * ditherName;
582a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        switch (forceDither) {
583a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kDefault: ditherName = "default"; break;
584a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kTrue: ditherName = "true"; break;
585a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kFalse: ditherName = "false"; break;
586a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            default: ditherName = "<invalid>"; break;
587a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
588a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.appendf(" dither=%s", ditherName);
589fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
590a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        if (hasStrokeWidth) {
591a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.appendf(" strokeWidth=%f", strokeWidth);
592a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        } else {
593a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.append(" strokeWidth=none");
594a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
595a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
596a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_SCALAR_IS_FLOAT)
597a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=float");
598a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_SCALAR_IS_FIXED)
599a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=fixed");
600a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
601a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
602a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_BUILD_FOR_WIN32)
603a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=WIN32");
604a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_MAC)
605a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=MAC");
606a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_ANDROID)
607a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=ANDROID");
608a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_UNIX)
609a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=UNIX");
610a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#else
611a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=other");
612a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
613a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
614a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_DEBUG)
615a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" DEBUG");
616a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
617a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append("\n");
618a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(str);
6193b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    }
620508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
621cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    SkTArray<BenchTimer*> timers(SK_ARRAY_COUNT(gConfigs));
6225c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
623cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
6246177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com        SkGLContextHelper* ctx = NULL;
625cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        if (kGPU_Backend == gConfigs[i].fBackend) {
626cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            ctx = gContextFactory.getGLContext(gConfigs[i].fContextType);
627cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
628cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        timers.push_back(SkNEW_ARGS(BenchTimer, (ctx)));
629cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#else
630cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        timers.push_back(SkNEW(BenchTimer));
631cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
632cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
63374913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com
634e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter iter(&defineDict);
635bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* bench;
636bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    while ((bench = iter.next()) != NULL) {
6377fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com        SkAutoTUnref<SkBenchmark> benchUnref(bench);
6387fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com
639b398fe863860b072306b5297c8095c6d973aba06reed@android.com        SkIPoint dim = bench->getSize();
640b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (dim.fX <= 0 || dim.fY <= 0) {
641b398fe863860b072306b5297c8095c6d973aba06reed@android.com            continue;
642b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
643fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
6444bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAlpha(forceAlpha);
6454bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAA(forceAA);
64629348cb0612e19030d979156860946241e2ff4bdreed@android.com        bench->setForceFilter(forceFilter);
6474e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com        bench->setDither(forceDither);
648652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        if (hasStrokeWidth) {
649652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            bench->setStrokeWidth(strokeWidth);
650652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        }
651fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
652387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        // only run benchmarks if their name contains matchStr
6531a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (skip_name(fMatches, bench->getName())) {
654387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            continue;
655387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        }
656fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
65729348cb0612e19030d979156860946241e2ff4bdreed@android.com        {
65829348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
659d34658a5f1b961e2852c2272ac8b47701a42e50dreed@google.com            str.printf("running bench [%d %d] %28s", dim.fX, dim.fY,
6600c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com                       bench->getName());
661a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logProgress(str);
66229348cb0612e19030d979156860946241e2ff4bdreed@android.com        }
663fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
66430e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        AutoPrePostDraw appd(bench);
66530e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
6669dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com        bool runOnce = false;
66713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (int x = 0; x < configs.count(); ++x) {
6689dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            if (!bench->isRendering() && runOnce) {
6699dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com                continue;
6709dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            }
6719dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com            runOnce = true;
6729dc2713fc4a75e7fbee2f985057fde680a07c7f0tomhudson@google.com
67313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            int configIndex = configs[x];
67413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com
67513eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            outConfig = gConfigs[configIndex].fConfig;
67613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            configName = gConfigs[configIndex].fName;
67713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            backend = gConfigs[configIndex].fBackend;
678cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrContext* context = NULL;
679cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            BenchTimer* timer = timers[configIndex];
680508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
681cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
6829c55f801a35b0d6c39f007fae432bd13094f3c52sugoi@google.com            SkGLContextHelper* glContext = NULL;
683cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            if (kGPU_Backend == backend) {
684cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                context = gContextFactory.get(gConfigs[configIndex].fContextType);
685cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL == context) {
686cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    continue;
687cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                }
688cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                glContext = gContextFactory.getGLContext(gConfigs[configIndex].fContextType);
6894bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
690cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
691cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDevice* device = make_device(outConfig, dim, backend, context);
692fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkCanvas* canvas = NULL;
693fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordFrom;
694fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordTo;
695fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            switch(benchMode) {
6964c5ea4480341f0f663b51e9d78b948bc0a785f4dskia.committer@gmail.com                case kDeferredSilent_benchModes:
697fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kDeferred_benchModes:
698fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = new SkDeferredCanvas(device);
699fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
700fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kRecord_benchModes:
70120bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
70220bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
703fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas->ref();
704fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
705fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kPictureRecord_benchModes: {
706fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // This sets up picture-to-picture recording.
707fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // The C++ drawing calls for the benchmark are recorded into
708fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // pictureRecordFrom. As the benchmark, we will time how
709fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // long it takes to playback pictureRecordFrom into
710fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // pictureRecordTo.
71120bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    SkCanvas* tempCanvas = pictureRecordFrom.beginRecording(dim.fX, dim.fY,
71220bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
713fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(tempCanvas);
714fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.endRecording();
71520bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
71620bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
717fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas->ref();
718fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
719fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
720fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kNormal_benchModes:
721fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = new SkCanvas(device);
722fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
723fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                default:
724fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    SkASSERT(0);
72582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
726a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            device->unref();
72782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            SkAutoUnref canvasUnref(canvas);
72882a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com
7294c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doClip) {
73082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performClip(canvas, dim.fX, dim.fY);
7314c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
732387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (doScale) {
73382a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performScale(canvas, dim.fX, dim.fY);
734387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
7354c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doRotate) {
73682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performRotate(canvas, dim.fX, dim.fY);
7374c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
738508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
739af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // warm up caches if needed
740eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            if (repeatDraw > 1) {
74191ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com#if SK_SUPPORT_GPU
742cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                // purge the GPU resources to reduce variance
743cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL != context) {
744cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    context->freeGpuResources();
74591ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                }
74691ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com#endif
74782a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
748fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (benchMode == kPictureRecord_benchModes) {
749fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.draw(canvas);
750fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
751fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(canvas);
752fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
753fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
754fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                if (kDeferredSilent_benchModes == benchMode) {
755fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
756fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else {
757fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    canvas->flush();
758fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                }
759cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
760cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL != context) {
761cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    context->flush();
762cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    SK_GL(*glContext, Finish());
763d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com                }
764cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
765eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            }
766af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
767af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // record timer values for each repeat, and their sum
7689a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com            TimerData timerData(perIterTimeformat, normalTimeFormat);
7694bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            for (int i = 0; i < repeatDraw; i++) {
770fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if ((benchMode == kRecord_benchModes
771fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                     || benchMode == kPictureRecord_benchModes)) {
772fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // This will clear the recorded commands so that they do not
773cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    // accumulate.
77420bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY,
77520bd04e365ca8f5cdb37068fedd696e783d1a775junov@chromium.org                        SkPicture::kUsePathBoundsForClip_RecordingFlag);
776fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
777fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
778cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timer->start();
77982a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
780fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (benchMode == kPictureRecord_benchModes) {
781fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.draw(canvas);
782fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
783fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(canvas);
784fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
785fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org
786fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                if (kDeferredSilent_benchModes == benchMode) {
787fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    static_cast<SkDeferredCanvas*>(canvas)->silentFlush();
788fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                } else {
789fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                    canvas->flush();
790fb10389403cf1cc771e103016207fde84c5f4825junov@chromium.org                }
79191ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com
79291ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // stop the truncated timer after the last canvas call but
79391ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // don't wait for all the GL calls to complete
794cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timer->truncatedEnd();
795cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
796cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL != glContext) {
797cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    context->flush();
798cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    SK_GL(*glContext, Finish());
79925df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com                }
800cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
80191ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // stop the inclusive and gpu timers once all the GL calls
80291ee3a11ed476f4f08e1e4ae183002c56349ec19robertphillips@google.com                // have completed
803cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timer->end();
804af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
805cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                timerData.appendTimes(timer, repeatDraw - 1 == i);
8062abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com
80725df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com            }
8084bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (repeatDraw > 1) {
8099a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                SkString result = timerData.getResult(logPerIter, printMin, repeatDraw, configName,
8109a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                                                      timerWall, truncatedTimerWall, timerCpu,
811cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                                                      truncatedTimerCpu,
812cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                                                      timerGpu && NULL != context);
8139a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com                logger.logProgress(result);
8144bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
8154c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (outDir.size() > 0) {
816a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                saveFile(bench->getName(), configName, outDir.c_str(),
817a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                         device->accessBitmap(false));
818a543b604e425c00ca7957160e73220ca71f75e0bjvanverth@google.com                canvas->clear(SK_ColorWHITE);
8194c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
8204bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        }
821a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(SkString("\n"));
822bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
823cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
8249d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#if GR_CACHE_STATS
825cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    for (int i = 0; i <= GrContextFactory::kLastGLContextType; ++i) {
826cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        GrContextFactory::GLContextType ctxType = (GrContextFactory::GLContextType)i;
827cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        GrContext* context = gContextFactory.get(ctxType);
828cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        if (NULL != context) {
829cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDebugf("Cache Stats for %s context:\n", GrContextFactory::GLContextTypeName(ctxType));
830cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            context->printCacheStats();
831cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkDebugf("\n");
832cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
833cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
8349d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com#endif
835cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    // Destroy the GrContext before the inst tracking printing at main() exit occurs.
836cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    gContextFactory.destroyContexts();
837cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
8385c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
839cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        SkDELETE(timers[i]);
840cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
8419d59420851893da677d89de84f8102fa65d6f7dcrobertphillips@google.com
842bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    return 0;
843bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
8445987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
8457158e6acca1b1ecc321d4d514a31cba11b5ead60borenet@google.com#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
8465987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint main(int argc, char * const argv[]) {
8475987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com    return tool_main(argc, (char**) argv);
8485987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
8495987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
850