benchmain.cpp revision fbfcd5602128ec010c82cb733c9cdc0a3254f9f3
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */
8971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
9971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
10971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "BenchTimer.h"
11971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
12cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
13971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrContext.h"
14971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrRenderTarget.h"
15cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_ANGLE
16cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "gl/SkANGLEGLContext.h"
17cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
18cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "gl/SkNativeGLContext.h"
19cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "gl/SkNullGLContext.h"
20cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "gl/SkDebugGLContext.h"
21cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "SkGpuDevice.h"
22cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
23971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
24971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "SkBenchmark.h"
25bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkCanvas.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"
33a2b32b80818adebfc028334e0095cb3218825188borenet@google.com#include "SkStream.h"
34bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkString.h"
35bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
362abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.comtemplate <typename T> const T& Min(const T& a, const T& b) {
372abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com    return (a < b) ? a : b;
382abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com}
392abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com
40a2b32b80818adebfc028334e0095cb3218825188borenet@google.comclass SkBenchLogger {
41a2b32b80818adebfc028334e0095cb3218825188borenet@google.compublic:
42a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    SkBenchLogger() : fFileStream(NULL) {}
43a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    ~SkBenchLogger() {
44a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        if (fFileStream)
45a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            SkDELETE(fFileStream);
46a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    }
47a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
48a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    bool SetLogFile(const char file[]) {
49a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        fFileStream = SkNEW_ARGS(SkFILEWStream, (file));
50a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        return fFileStream->isValid();
51a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    }
52a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
53a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    void logError(const char msg[]) { nativeLogError(msg); }
54a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    void logError(const SkString& str) { nativeLogError(str.c_str()); }
55a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
56a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    void logProgress(const char msg[]) {
57a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        nativeLogProgress(msg);
58a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        fileWrite(msg, strlen(msg));
59a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    }
60a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    void logProgress(const SkString& str) {
61a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        nativeLogProgress(str.c_str());
62a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        fileWrite(str.c_str(), str.size());
63a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    }
64a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
65a2b32b80818adebfc028334e0095cb3218825188borenet@google.comprivate:
6656c69773aea56c6c6bd47bc7e7970dd081205184djsollen@google.com#ifdef SK_BUILD_FOR_ANDROID
67a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    void nativeLogError(const char msg[]) { SkDebugf("%s", msg); }
68a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    void nativeLogProgress(const char msg[]) { SkDebugf("%s", msg); }
6929348cb0612e19030d979156860946241e2ff4bdreed@android.com#else
70a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    void nativeLogError(const char msg[]) { fprintf(stderr, "%s", msg); }
71a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    void nativeLogProgress(const char msg[]) { printf("%s", msg); }
7229348cb0612e19030d979156860946241e2ff4bdreed@android.com#endif
7329348cb0612e19030d979156860946241e2ff4bdreed@android.com
74a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    void fileWrite(const char msg[], size_t size) {
75a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        if (fFileStream && fFileStream->isValid())
76a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            fFileStream->write(msg, size);
77a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    }
78a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    SkFILEWStream* fFileStream;
79a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
80a2b32b80818adebfc028334e0095cb3218825188borenet@google.com} logger;
8129348cb0612e19030d979156860946241e2ff4bdreed@android.com
8229348cb0612e19030d979156860946241e2ff4bdreed@android.com///////////////////////////////////////////////////////////////////////////////
8329348cb0612e19030d979156860946241e2ff4bdreed@android.com
84fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.orgenum benchModes {
85fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kNormal_benchModes,
86fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kDeferred_benchModes,
87fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kRecord_benchModes,
88fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    kPictureRecord_benchModes
89fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org};
90fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
91fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org///////////////////////////////////////////////////////////////////////////////
92fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
936c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic void erase(SkBitmap& bm) {
946c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
956c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm.eraseColor(0);
966c924ad46c89955e78e071c792ef00df9910b42freed@android.com    } else {
976c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm.eraseColor(SK_ColorWHITE);
986c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
996c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
1006c924ad46c89955e78e071c792ef00df9910b42freed@android.com
101a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org#if 0
1026c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic bool equal(const SkBitmap& bm1, const SkBitmap& bm2) {
1036c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm1.width() != bm2.width() ||
1046c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm1.height() != bm2.height() ||
1056c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm1.config() != bm2.config()) {
1066c924ad46c89955e78e071c792ef00df9910b42freed@android.com        return false;
1076c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
108fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1096c924ad46c89955e78e071c792ef00df9910b42freed@android.com    size_t pixelBytes = bm1.width() * bm1.bytesPerPixel();
1106c924ad46c89955e78e071c792ef00df9910b42freed@android.com    for (int y = 0; y < bm1.height(); y++) {
1116c924ad46c89955e78e071c792ef00df9910b42freed@android.com        if (memcmp(bm1.getAddr(0, y), bm2.getAddr(0, y), pixelBytes)) {
1126c924ad46c89955e78e071c792ef00df9910b42freed@android.com            return false;
1136c924ad46c89955e78e071c792ef00df9910b42freed@android.com        }
1146c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
1156c924ad46c89955e78e071c792ef00df9910b42freed@android.com    return true;
1166c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
117a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org#endif
1186c924ad46c89955e78e071c792ef00df9910b42freed@android.com
119bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comclass Iter {
120bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.compublic:
121e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter(void* param) {
122bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        fBench = BenchRegistry::Head();
123e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com        fParam = param;
124bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
125fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
126bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* next() {
127bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        if (fBench) {
128bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            BenchRegistry::Factory f = fBench->factory();
129bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            fBench = fBench->next();
130e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            return f(fParam);
131bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
132bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        return NULL;
133bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
134d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
135bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comprivate:
136bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    const BenchRegistry* fBench;
137e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    void* fParam;
138bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com};
139bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
14030e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.comclass AutoPrePostDraw {
14130e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.compublic:
14230e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    AutoPrePostDraw(SkBenchmark* bench) : fBench(bench) {
14330e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        fBench->preDraw();
14430e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    }
14530e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    ~AutoPrePostDraw() {
14630e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        fBench->postDraw();
14730e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    }
14830e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.comprivate:
14930e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    SkBenchmark* fBench;
15030e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com};
15130e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
152bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comstatic void make_filename(const char name[], SkString* path) {
153bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    path->set(name);
154bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    for (int i = 0; name[i]; i++) {
155bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        switch (name[i]) {
156bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '/':
157bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '\\':
158bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ' ':
159bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ':':
160bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                path->writable_str()[i] = '-';
161bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
162bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            default:
163bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
164bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
165bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
166bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
167bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
1684c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void saveFile(const char name[], const char config[], const char dir[],
1694c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                     const SkBitmap& bm) {
1704c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkBitmap copy;
1714c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    if (!bm.copyTo(&copy, SkBitmap::kARGB_8888_Config)) {
1724c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        return;
1734c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
174fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
175f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
176f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        // turn alpha into gray-scale
177f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        size_t size = copy.getSize() >> 2;
178f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        SkPMColor* p = copy.getAddr32(0, 0);
179f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        for (size_t i = 0; i < size; i++) {
180f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            int c = (*p >> SK_A32_SHIFT) & 0xFF;
181f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c = 255 - c;
182f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c |= (c << 24) | (c << 16) | (c << 8);
183f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            *p++ = c | (SK_A32_MASK << SK_A32_SHIFT);
184f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        }
185f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    }
186fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1874c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkString str;
1884c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    make_filename(name, &str);
1894c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    str.appendf("_%s.png", config);
1904c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    str.prepend(dir);
1914c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    ::remove(str.c_str());
1924c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkImageEncoder::EncodeFile(str.c_str(), copy, SkImageEncoder::kPNG_Type,
1934c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                               100);
1944c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1954c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1964c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performClip(SkCanvas* canvas, int w, int h) {
1974c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkRect r;
198fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1994c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(10), SkIntToScalar(10),
2004c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
2014c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kIntersect_Op);
202fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
2034c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
2044c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w-10), SkIntToScalar(h-10));
2054c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kXOR_Op);
2064c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
2074c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
2084c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performRotate(SkCanvas* canvas, int w, int h) {
2094c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
2104c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
211fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
2124c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(x, y);
2134c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->rotate(SkIntToScalar(35));
2144c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(-x, -y);
2154c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
2164c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
217387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.comstatic void performScale(SkCanvas* canvas, int w, int h) {
218387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
219387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
220fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
221387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(x, y);
222387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    // just enough so we can't take the sprite case
223387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
224387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(-x, -y);
225387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com}
226387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com
22729348cb0612e19030d979156860946241e2ff4bdreed@android.comstatic bool parse_bool_arg(char * const* argv, char* const* stop, bool* var) {
22829348cb0612e19030d979156860946241e2ff4bdreed@android.com    if (argv < stop) {
22929348cb0612e19030d979156860946241e2ff4bdreed@android.com        *var = atoi(*argv) != 0;
23029348cb0612e19030d979156860946241e2ff4bdreed@android.com        return true;
23129348cb0612e19030d979156860946241e2ff4bdreed@android.com    }
23229348cb0612e19030d979156860946241e2ff4bdreed@android.com    return false;
23329348cb0612e19030d979156860946241e2ff4bdreed@android.com}
23429348cb0612e19030d979156860946241e2ff4bdreed@android.com
235a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgenum Backend {
236a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kRaster_Backend,
237a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kGPU_Backend,
238a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kPDF_Backend,
239a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org};
240a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
241cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
242508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comclass GLHelper {
243508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.compublic:
244508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GLHelper() {
245508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
246508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
247508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    bool init(SkGLContext* glCtx, int width, int height) {
248508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        GrContext* grCtx;
2498afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        if (!glCtx->init(width, height)) {
250508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            return false;
251508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        }
2528afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        GrPlatform3DContext ctx =
2538afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            reinterpret_cast<GrPlatform3DContext>(glCtx->gl());
2548afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        grCtx = GrContext::Create(kOpenGL_Shaders_GrEngine, ctx);
2558afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        if (NULL != grCtx) {
2568afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            GrPlatformRenderTargetDesc desc;
2578afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            desc.fConfig = kSkia8888_PM_GrPixelConfig;
2588afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            desc.fWidth = width;
2598afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            desc.fHeight = height;
2608afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            desc.fStencilBits = 8;
2618afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            desc.fRenderTargetHandle = glCtx->getFBOID();
2628afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            GrRenderTarget* rt = grCtx->createPlatformRenderTarget(desc);
2638afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            if (NULL == rt) {
2648afae61a57f87e4a50578effce6c428031499301tomhudson@google.com                grCtx->unref();
2658afae61a57f87e4a50578effce6c428031499301tomhudson@google.com                return false;
2668afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            }
2678afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            glCtx->ref();
2688afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            fGLContext.reset(glCtx);
2698afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            fGrContext.reset(grCtx);
2708afae61a57f87e4a50578effce6c428031499301tomhudson@google.com            fRenderTarget.reset(rt);
2718afae61a57f87e4a50578effce6c428031499301tomhudson@google.com        }
272508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return true;
273508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
274508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
2750da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    void cleanup() {
2760da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        fGLContext.reset(NULL);
2770da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        fGrContext.reset(NULL);
2780da3719050473344b6013fd7b614611984f20effrobertphillips@google.com        fRenderTarget.reset(NULL);
2790da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    }
2800da3719050473344b6013fd7b614611984f20effrobertphillips@google.com
281508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    bool isValid() {
282508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return NULL != fGLContext.get();
283508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
284508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
285508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkGLContext* glContext() {
286508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return fGLContext.get();
287508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
288508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
289508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GrRenderTarget* renderTarget() {
290508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return fRenderTarget.get();
291508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
292508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
293508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GrContext* grContext() {
294508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com        return fGrContext.get();
295508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    }
296508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comprivate:
297508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<SkGLContext> fGLContext;
298508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<GrContext> fGrContext;
299508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<GrRenderTarget> fRenderTarget;
300508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com};
301508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
302508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comstatic GLHelper gRealGLHelper;
303508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.comstatic GLHelper gNullGLHelper;
3040da3719050473344b6013fd7b614611984f20effrobertphillips@google.comstatic GLHelper gDebugGLHelper;
305d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
306d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.comstatic GLHelper gANGLEGLHelper;
307cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
308cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else  // !SK_SUPPORT_GPU
309cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comclass GLHelper;
310cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.comclass SkGLContext;
311cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // !SK_SUPPORT_GPU
312a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgstatic SkDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
313508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                             Backend backend, GLHelper* glHelper) {
314a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkDevice* device = NULL;
315a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkBitmap bitmap;
316a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    bitmap.setConfig(config, size.fX, size.fY);
317fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
318a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    switch (backend) {
319a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kRaster_Backend:
320a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            bitmap.allocPixels();
321a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            erase(bitmap);
322af951c9bc4cbb6e60b430194fe5127ebe99c53fbreed@google.com            device = new SkDevice(bitmap);
323a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
324cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
325a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kGPU_Backend:
326508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            device = new SkGpuDevice(glHelper->grContext(),
327508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                                     glHelper->renderTarget());
328a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
329cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
330a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kPDF_Backend:
331a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        default:
332a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            SkASSERT(!"unsupported");
333a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    }
334a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    return device;
335a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org}
336a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
3374bc1983e01d756ae9c91fd380758457f579d26eareed@android.comstatic const struct {
3384bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    SkBitmap::Config    fConfig;
3394bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    const char*         fName;
340a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend             fBackend;
341508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    GLHelper*           fGLHelper;
3424bc1983e01d756ae9c91fd380758457f579d26eareed@android.com} gConfigs[] = {
343508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "8888",     kRaster_Backend, NULL },
344508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kRGB_565_Config,    "565",      kRaster_Backend, NULL },
345cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
346508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "GPU",      kGPU_Backend, &gRealGLHelper },
347d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
348d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    { SkBitmap::kARGB_8888_Config,  "ANGLE",    kGPU_Backend, &gANGLEGLHelper },
349cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
350a0b63b86313694f695bf0387ee0ce31de3deabb3robertphillips@google.com#ifdef SK_DEBUG
351a0b63b86313694f695bf0387ee0ce31de3deabb3robertphillips@google.com    { SkBitmap::kARGB_8888_Config,  "Debug",    kGPU_Backend, &gDebugGLHelper },
352cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_DEBUG
353508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    { SkBitmap::kARGB_8888_Config,  "NULLGPU",  kGPU_Backend, &gNullGLHelper },
354cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
3554bc1983e01d756ae9c91fd380758457f579d26eareed@android.com};
3564bc1983e01d756ae9c91fd380758457f579d26eareed@android.com
3574c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic int findConfig(const char config[]) {
3584c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); i++) {
3594c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        if (!strcmp(config, gConfigs[i].fName)) {
3604c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            return i;
3614c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        }
3624c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
3634c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    return -1;
3644c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
3654c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
3668382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.comstatic void determine_gpu_context_size(SkTDict<const char*>& defineDict,
3678382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com                                       int* contextWidth,
3688382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com                                       int* contextHeight) {
3698382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    Iter iter(&defineDict);
3708382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    SkBenchmark* bench;
3718382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    while ((bench = iter.next()) != NULL) {
3728382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        SkIPoint dim = bench->getSize();
3738382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        if (*contextWidth < dim.fX) {
3748382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com            *contextWidth = dim.fX;
3758382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        }
3768382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        if (*contextHeight < dim.fY) {
3778382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com            *contextHeight = dim.fY;
3788382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com        }
3797fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com        bench->unref();
3808382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    }
3818382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com}
3828382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com
3831a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.comstatic bool skip_name(const SkTDArray<const char*> array, const char name[]) {
3841a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    if (0 == array.count()) {
3851a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        // no names, so don't skip anything
3861a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        return false;
3871a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    }
3881a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    for (int i = 0; i < array.count(); ++i) {
3891a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (strstr(name, array[i])) {
3901a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com            // found the name, so don't skip
3911a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com            return false;
3921a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        }
3931a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    }
3941a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    return true;
3951a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com}
3961a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com
39786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.comstatic void help() {
398af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    SkDebugf("Usage: bench [-o outDir] [-repeat nr] [-logPerIter 1|0] "
39986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                          "[-timers [wcg]*] [-rotate]\n"
4002abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com             "    [-scale] [-clip] [-min] [-forceAA 1|0] [-forceFilter 1|0]\n"
40186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "    [-forceDither 1|0] [-forceBlend 1|0] [-strokeWidth width]\n"
402fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "    [-match name] [-mode normal|deferred|record|picturerecord]\n"
40382a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com             "    [-config 8888|565|GPU|ANGLE|NULLGPU] [-Dfoo bar]\n"
40482a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com             "    [-h|--help]");
40586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("\n\n");
40686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -o outDir : Image of each bench will be put in outDir.\n");
40786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -repeat nr : Each bench repeats for nr times.\n");
408af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    SkDebugf("    -logPerIter 1|0 : "
409af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com             "Log each repeat timer instead of mean, default is disabled.\n");
41086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -timers [wcg]* : "
41186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Display wall time, cpu time or gpu time for each bench.\n");
41286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -rotate : Rotate before each bench runs.\n");
41386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -scale : Scale before each bench runs.\n");
41486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -clip : Clip before each bench runs.\n");
4152abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com    SkDebugf("    -min : Print the minimum times (instead of average).\n");
41686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -forceAA 1|0 : "
41786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable anti-aliased, default is enabled.\n");
41886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -forceFilter 1|0 : "
41986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable bitmap filtering, default is disabled.\n");
42086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -forceDither 1|0 : "
42186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
42286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -forceBlend 1|0 : "
42386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Enable/disable dithering, default is disabled.\n");
42486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -strokeWidth width : The width for path stroke.\n");
42586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -match name : Only run bench whose name is matched.\n");
426fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkDebugf("    -mode normal|deferred|record|picturerecord : Run in the corresponding mode\n"
427fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 normal, Use a normal canvas to draw to;\n"
428fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 deferred, Use a deferrred canvas when drawing;\n"
429fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 record, Benchmark the time to record to an SkPicture;\n"
430fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                 picturerecord, Benchmark the time to do record from a \n"
431fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org             "                                SkPicture to a SkPicture.\n");
432a2b32b80818adebfc028334e0095cb3218825188borenet@google.com    SkDebugf("    -logFile : destination for writing log output, in addition to stdout.\n");
433cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
43486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -config 8888|565|GPU|ANGLE|NULLGPU : "
43586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com             "Run bench in corresponding config mode.\n");
436cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#else
437cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    SkDebugf("    -config 8888|565: "
438cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com             "Run bench in corresponding config mode.\n");
439cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
44086bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -Dfoo bar : Add extra definition to bench.\n");
44186bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com    SkDebugf("    -h|--help : Show this help message.\n");
44286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com}
44386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com
444bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comint main (int argc, char * const argv[]) {
44565a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#ifdef SK_ENABLE_INST_COUNT
44665a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com    gPrintInstCount = true;
44765a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#endif
4483a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkAutoGraphics ag;
44965a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com
450e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    SkTDict<const char*> defineDict(1024);
4514bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int repeatDraw = 1;
452af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com    bool logPerIter = false;
4534bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    int forceAlpha = 0xFF;
4544bc1983e01d756ae9c91fd380758457f579d26eareed@android.com    bool forceAA = true;
45529348cb0612e19030d979156860946241e2ff4bdreed@android.com    bool forceFilter = false;
4564e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com    SkTriState::State forceDither = SkTriState::kDefault;
457be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerWall = false;
458be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerCpu = true;
459be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com    bool timerGpu = true;
460387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    bool doScale = false;
4614c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doRotate = false;
4624c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    bool doClip = false;
4632abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com    bool printMin = false;
464652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    bool hasStrokeWidth = false;
465652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org    float strokeWidth;
4661a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com    SkTDArray<const char*> fMatches;
467fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    benchModes benchMode = kNormal_benchModes;
468fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString perIterTimeformat("%.2f");
469fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    SkString normalTimeFormat("%6.2f");
470fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
471b398fe863860b072306b5297c8095c6d973aba06reed@android.com    SkString outDir;
472387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    SkBitmap::Config outConfig = SkBitmap::kNo_Config;
473cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com    GLHelper* glHelper = NULL;
474387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const char* configName = "";
475a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    Backend backend = kRaster_Backend;  // for warning
47613eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    SkTDArray<int> configs;
47713eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    bool userConfig = false;
478fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
479b398fe863860b072306b5297c8095c6d973aba06reed@android.com    char* const* stop = argv + argc;
480b398fe863860b072306b5297c8095c6d973aba06reed@android.com    for (++argv; argv < stop; ++argv) {
481b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (strcmp(*argv, "-o") == 0) {
482b398fe863860b072306b5297c8095c6d973aba06reed@android.com            argv++;
483b398fe863860b072306b5297c8095c6d973aba06reed@android.com            if (argv < stop && **argv) {
484b398fe863860b072306b5297c8095c6d973aba06reed@android.com                outDir.set(*argv);
485b398fe863860b072306b5297c8095c6d973aba06reed@android.com                if (outDir.c_str()[outDir.size() - 1] != '/') {
486b398fe863860b072306b5297c8095c6d973aba06reed@android.com                    outDir.append("/");
487b398fe863860b072306b5297c8095c6d973aba06reed@android.com                }
488b398fe863860b072306b5297c8095c6d973aba06reed@android.com            }
4894bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        } else if (strcmp(*argv, "-repeat") == 0) {
4904bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            argv++;
4914bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (argv < stop) {
4924bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                repeatDraw = atoi(*argv);
4934bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                if (repeatDraw < 1) {
4944bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                    repeatDraw = 1;
4954bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                }
4964bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            } else {
497a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -repeat\n");
49886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
4994bc1983e01d756ae9c91fd380758457f579d26eareed@android.com                return -1;
5004bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
501af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com        } else if (strcmp(*argv, "-logPerIter") == 0) {
502af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            if (!parse_bool_arg(++argv, stop, &logPerIter)) {
503a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -logPerIter\n");
504af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                help();
505af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                return -1;
506af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            }
507be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com        } else if (strcmp(*argv, "-timers") == 0) {
508be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            argv++;
509be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            if (argv < stop) {
510be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerWall = false;
511be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerCpu = false;
512be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                timerGpu = false;
513be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                for (char* t = *argv; *t; ++t) {
514be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    switch (*t) {
515be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'w': timerWall = true; break;
516be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'c': timerCpu = true; break;
517be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    case 'g': timerGpu = true; break;
518be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                    }
519be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
520be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            } else {
521a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -timers\n");
52286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
523be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                return -1;
524be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com            }
5254c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        } else if (!strcmp(*argv, "-rotate")) {
5264c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doRotate = true;
527387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else if (!strcmp(*argv, "-scale")) {
528387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            doScale = true;
5294c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        } else if (!strcmp(*argv, "-clip")) {
5304c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            doClip = true;
5312abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com        } else if (!strcmp(*argv, "-min")) {
5322abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com            printMin = true;
5334bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        } else if (strcmp(*argv, "-forceAA") == 0) {
53429348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceAA)) {
535a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -forceAA\n");
53686bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
53729348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
53829348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
53929348cb0612e19030d979156860946241e2ff4bdreed@android.com        } else if (strcmp(*argv, "-forceFilter") == 0) {
54029348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &forceFilter)) {
541a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -forceFilter\n");
54286bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
54329348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
54429348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
5454e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com        } else if (strcmp(*argv, "-forceDither") == 0) {
5464e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            bool tmp;
5474e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            if (!parse_bool_arg(++argv, stop, &tmp)) {
548a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -forceDither\n");
54986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
5504e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com                return -1;
5514e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            }
5524e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com            forceDither = tmp ? SkTriState::kTrue : SkTriState::kFalse;
5534bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        } else if (strcmp(*argv, "-forceBlend") == 0) {
55429348cb0612e19030d979156860946241e2ff4bdreed@android.com            bool wantAlpha = false;
55529348cb0612e19030d979156860946241e2ff4bdreed@android.com            if (!parse_bool_arg(++argv, stop, &wantAlpha)) {
556a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -forceBlend\n");
55786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
55829348cb0612e19030d979156860946241e2ff4bdreed@android.com                return -1;
55929348cb0612e19030d979156860946241e2ff4bdreed@android.com            }
56029348cb0612e19030d979156860946241e2ff4bdreed@android.com            forceAlpha = wantAlpha ? 0x80 : 0xFF;
561fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        } else if (strcmp(*argv, "-mode") == 0) {
562fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            argv++;
563fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            if (argv < stop) {
564fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (strcmp(*argv, "normal") == 0) {
565fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kNormal_benchModes;
566fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "deferred") == 0) {
567fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kDeferred_benchModes;
568fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "record") == 0) {
569fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kRecord_benchModes;
570fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else if (strcmp(*argv, "picturerecord") == 0) {
571fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode = kPictureRecord_benchModes;
572fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
573a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    logger.logError("bad arg for -mode\n");
574fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    help();
575fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    return -1;
576fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
577fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            } else {
578a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -mode\n");
57982a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                help();
58082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                return -1;
58182a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
582652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        } else if (strcmp(*argv, "-strokeWidth") == 0) {
583652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            argv++;
584652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            if (argv < stop) {
585652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                const char *strokeWidthStr = *argv;
586652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                if (sscanf(strokeWidthStr, "%f", &strokeWidth) != 1) {
587a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                  logger.logError("bad arg for -strokeWidth\n");
58886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                  help();
589652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                  return -1;
590652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                }
591652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                hasStrokeWidth = true;
592652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            } else {
593a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -strokeWidth\n");
59486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
595652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org                return -1;
596652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            }
597387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else if (strcmp(*argv, "-match") == 0) {
598387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
599387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
6001a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com                *fMatches.append() = *argv;
601387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
602a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -match\n");
60386bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
604387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
605387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
606387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else if (strcmp(*argv, "-config") == 0) {
607387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            argv++;
608387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (argv < stop) {
609387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                int index = findConfig(*argv);
610387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                if (index >= 0) {
61113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    *configs.append() = index;
61213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com                    userConfig = true;
613387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                } else {
61429348cb0612e19030d979156860946241e2ff4bdreed@android.com                    SkString str;
61529348cb0612e19030d979156860946241e2ff4bdreed@android.com                    str.printf("unrecognized config %s\n", *argv);
616a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    logger.logError(str);
61786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                    help();
618387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                    return -1;
619387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                }
620387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            } else {
621a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -config\n");
622a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                help();
623a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                return -1;
624a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            }
625a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        } else if (strcmp(*argv, "-logFile") == 0) {
626a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            argv++;
627a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            if (argv < stop) {
628a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                if (!logger.SetLogFile(*argv)) {
629a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    SkString str;
630a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    str.printf("Could not open %s for writing.", *argv);
631a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                    return -1;
632a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                }
633a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            } else {
634a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("missing arg for -logFile\n");
63586bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
636387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com                return -1;
6374c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
6380c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com        } else if (strlen(*argv) > 2 && strncmp(*argv, "-D", 2) == 0) {
639e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            argv++;
6400c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com            if (argv < stop) {
641e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                defineDict.set(argv[-1] + 2, *argv);
642e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            } else {
643a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logError("incomplete '-Dfoo bar' definition\n");
64486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com                help();
645e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com                return -1;
646e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            }
64786bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com        } else if (strcmp(*argv, "--help") == 0 || strcmp(*argv, "-h") == 0) {
64886bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
64986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            return 0;
650387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        } else {
65129348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
65229348cb0612e19030d979156860946241e2ff4bdreed@android.com            str.printf("unrecognized arg %s\n", *argv);
653a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logError(str);
65486bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com            help();
655387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            return -1;
656b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
657b398fe863860b072306b5297c8095c6d973aba06reed@android.com    }
658fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)
659fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            && !outDir.isEmpty()) {
660a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logError("'-mode record' and '-mode picturerecord' are not"
661fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                  " compatible with -o.\n");
662fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        return -1;
663fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
664fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) {
665fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        perIterTimeformat.set("%.4f");
666fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        normalTimeFormat.set("%6.4f");
667fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org    }
66813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    if (!userConfig) {
66913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        // if no config is specified by user, we add them all.
67013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (unsigned int i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
67113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            *configs.append() = i;
67213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        }
67313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    }
674a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
6753b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    // report our current settings
6763b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    {
6773b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com        SkString str;
678af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com        str.printf("skia bench: alpha=0x%02X antialias=%d filter=%d "
679af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                   "deferred=%d logperiter=%d",
680fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                   forceAlpha, forceAA, forceFilter, benchMode == kDeferred_benchModes,
681fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                   logPerIter);
6822abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com        str.appendf(" rotate=%d scale=%d clip=%d min=%d",
6832abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                   doRotate, doScale, doClip, printMin);
684fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org        str.appendf(" record=%d picturerecord=%d",
685fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kRecord_benchModes,
686fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    benchMode == kPictureRecord_benchModes);
687a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        const char * ditherName;
688a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        switch (forceDither) {
689a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kDefault: ditherName = "default"; break;
690a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kTrue: ditherName = "true"; break;
691a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            case SkTriState::kFalse: ditherName = "false"; break;
692a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            default: ditherName = "<invalid>"; break;
693a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
694a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.appendf(" dither=%s", ditherName);
695fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
696a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        if (hasStrokeWidth) {
697a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.appendf(" strokeWidth=%f", strokeWidth);
698a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        } else {
699a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com            str.append(" strokeWidth=none");
700a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        }
701a2b32b80818adebfc028334e0095cb3218825188borenet@google.com
702a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_SCALAR_IS_FLOAT)
703a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=float");
704a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_SCALAR_IS_FIXED)
705a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" scalar=fixed");
706a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
707a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
708a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_BUILD_FOR_WIN32)
709a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=WIN32");
710a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_MAC)
711a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=MAC");
712a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_ANDROID)
713a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=ANDROID");
714a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_UNIX)
715a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=UNIX");
716a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#else
717a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" system=other");
718a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
719a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
720a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_DEBUG)
721a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append(" DEBUG");
722a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
723a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com        str.append("\n");
724a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(str);
7253b14dc18511fdc2612791d07707e4385182d3ca7reed@google.com    }
726508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
727cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    SkGLContext* timerCtx = NULL;
728a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com    //Don't do GL when fixed.
729cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if !defined(SK_SCALAR_IS_FIXED) && SK_SUPPORT_GPU
7308382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    int contextWidth = 1024;
7318382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    int contextHeight = 1024;
7328382394bf260af223d5217ff8c45961f149bf1cftomhudson@google.com    determine_gpu_context_size(defineDict, &contextWidth, &contextHeight);
733508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<SkGLContext> realGLCtx(new SkNativeGLContext);
734508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    SkAutoTUnref<SkGLContext> nullGLCtx(new SkNullGLContext);
7350da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    SkAutoTUnref<SkGLContext> debugGLCtx(new SkDebugGLContext);
736508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    gRealGLHelper.init(realGLCtx.get(), contextWidth, contextHeight);
737508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com    gNullGLHelper.init(nullGLCtx.get(), contextWidth, contextHeight);
7380da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    gDebugGLHelper.init(debugGLCtx.get(), contextWidth, contextHeight);
739d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
740cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    SkAutoTUnref<SkGLContext> angleGLCtx(new SkANGLEGLContext);
741d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com    gANGLEGLHelper.init(angleGLCtx.get(), contextWidth, contextHeight);
742cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
743cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    timerCtx = gRealGLHelper.glContext();
744cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // !defined(SK_SCALAR_IS_FIXED) && SK_SUPPORT_GPU
74574913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com
746cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com    BenchTimer timer = BenchTimer(timerCtx);
747e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com    Iter iter(&defineDict);
748bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* bench;
749bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    while ((bench = iter.next()) != NULL) {
7507fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com        SkAutoTUnref<SkBenchmark> benchUnref(bench);
7517fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com
752b398fe863860b072306b5297c8095c6d973aba06reed@android.com        SkIPoint dim = bench->getSize();
753b398fe863860b072306b5297c8095c6d973aba06reed@android.com        if (dim.fX <= 0 || dim.fY <= 0) {
754b398fe863860b072306b5297c8095c6d973aba06reed@android.com            continue;
755b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
756fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
7574bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAlpha(forceAlpha);
7584bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        bench->setForceAA(forceAA);
75929348cb0612e19030d979156860946241e2ff4bdreed@android.com        bench->setForceFilter(forceFilter);
7604e635f9eb218b15f656a02e71c60d4f787fe9306reed@android.com        bench->setDither(forceDither);
761652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        if (hasStrokeWidth) {
762652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org            bench->setStrokeWidth(strokeWidth);
763652807bbc8c57e5fa9622126b51fd369f5c67935agl@chromium.org        }
764fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
765387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        // only run benchmarks if their name contains matchStr
7661a7eabc8dc9d0f9f4c7651959fa30f493215c1bareed@google.com        if (skip_name(fMatches, bench->getName())) {
767387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            continue;
768387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        }
769fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
77029348cb0612e19030d979156860946241e2ff4bdreed@android.com        {
77129348cb0612e19030d979156860946241e2ff4bdreed@android.com            SkString str;
772d34658a5f1b961e2852c2272ac8b47701a42e50dreed@google.com            str.printf("running bench [%d %d] %28s", dim.fX, dim.fY,
7730c9da393d9974877f53e8785082f40e1d1c4c833reed@android.com                       bench->getName());
774a2b32b80818adebfc028334e0095cb3218825188borenet@google.com            logger.logProgress(str);
77529348cb0612e19030d979156860946241e2ff4bdreed@android.com        }
776fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
77730e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        AutoPrePostDraw appd(bench);
77830e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
77913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        for (int x = 0; x < configs.count(); ++x) {
78013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            int configIndex = configs[x];
78113eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com
78213eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            outConfig = gConfigs[configIndex].fConfig;
78313eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            configName = gConfigs[configIndex].fName;
78413eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            backend = gConfigs[configIndex].fBackend;
78513eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com            glHelper = gConfigs[configIndex].fGLHelper;
786508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
787cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
788508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            if (kGPU_Backend == backend &&
789508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                (NULL == glHelper || !glHelper->isValid())) {
790a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                continue;
7914bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
792cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
793508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com            SkDevice* device = make_device(outConfig, dim, backend, glHelper);
794fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkCanvas* canvas = NULL;
795fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordFrom;
796fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            SkPicture pictureRecordTo;
797fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org            switch(benchMode) {
798fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kDeferred_benchModes:
799fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = new SkDeferredCanvas(device);
800fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
801fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kRecord_benchModes:
802fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY);
803fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas->ref();
804fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
805fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kPictureRecord_benchModes: {
806fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // This sets up picture-to-picture recording.
807fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // The C++ drawing calls for the benchmark are recorded into
808fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // pictureRecordFrom. As the benchmark, we will time how
809fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // long it takes to playback pictureRecordFrom into
810fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // pictureRecordTo.
811fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    SkCanvas* tempCanvas = pictureRecordFrom.beginRecording(dim.fX, dim.fY);
812fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(tempCanvas);
813fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.endRecording();
814fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY);
815fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas->ref();
816fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
817fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
818fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                case kNormal_benchModes:
819fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = new SkCanvas(device);
820fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    break;
821fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                default:
822fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    SkASSERT(0);
82382a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            }
824a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            device->unref();
82582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com            SkAutoUnref canvasUnref(canvas);
82682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com
8274c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doClip) {
82882a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performClip(canvas, dim.fX, dim.fY);
8294c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
830387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            if (doScale) {
83182a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performScale(canvas, dim.fX, dim.fY);
832387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            }
8334c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (doRotate) {
83482a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                performRotate(canvas, dim.fX, dim.fY);
8354c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
836508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
837af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // warm up caches if needed
838eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            if (repeatDraw > 1) {
83982a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
840fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (benchMode == kPictureRecord_benchModes) {
841fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.draw(canvas);
842fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
843fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(canvas);
844fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
84582a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                canvas->flush();
846cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
847508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                if (glHelper) {
848508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    glHelper->grContext()->flush();
849508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    SK_GL(*glHelper->glContext(), Finish());
850d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com                }
851cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
852eca48360678f1f62089d48ed1b5b885f0a134005reed@android.com            }
853af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
854af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            // record timer values for each repeat, and their sum
855af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            SkString fWallStr(" msecs = ");
856af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            SkString fCpuStr(" cmsecs = ");
857af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com            SkString fGpuStr(" gmsecs = ");
8582abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com            double fWallSum = 0.0, fWallMin;
8592abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com            double fCpuSum = 0.0, fCpuMin;
8602abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com            double fGpuSum = 0.0, fGpuMin;
8614bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            for (int i = 0; i < repeatDraw; i++) {
862fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if ((benchMode == kRecord_benchModes
863fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                     || benchMode == kPictureRecord_benchModes)) {
864fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // This will clear the recorded commands so that they do not
865fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    // acculmulate.
866fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    canvas = pictureRecordTo.beginRecording(dim.fX, dim.fY);
867fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
868fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
869af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                timer.start();
87082a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                SkAutoCanvasRestore acr(canvas, true);
871fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                if (benchMode == kPictureRecord_benchModes) {
872fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    pictureRecordFrom.draw(canvas);
873fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                } else {
874fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    bench->draw(canvas);
875fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                }
87682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com                canvas->flush();
877cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
878508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                if (glHelper) {
879508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                    glHelper->grContext()->flush();
88025df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com                }
881cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
882af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                timer.end();
883af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
884af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                if (i == repeatDraw - 1) {
885af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    // no comma after the last value
886fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fWallStr.appendf(perIterTimeformat.c_str(), timer.fWall);
887fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fCpuStr.appendf(perIterTimeformat.c_str(), timer.fCpu);
888fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fGpuStr.appendf(perIterTimeformat.c_str(), timer.fGpu);
889af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                } else {
890fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fWallStr.appendf(perIterTimeformat.c_str(), timer.fWall);
891fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fWallStr.appendf(",");
892fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fCpuStr.appendf(perIterTimeformat.c_str(), timer.fCpu);
893fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fCpuStr.appendf(",");
894fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fGpuStr.appendf(perIterTimeformat.c_str(), timer.fGpu);
895fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fGpuStr.appendf(",");
896af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                }
8972abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com
8982abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                if (0 == i) {
8992abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                    fWallMin = timer.fWall;
9002abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                    fCpuMin  = timer.fCpu;
9012abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                    fGpuMin  = timer.fGpu;
9022abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                } else {
9032abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                    fWallMin = Min(fWallMin, timer.fWall);
9042abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                    fCpuMin  = Min(fCpuMin,  timer.fCpu);
9052abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                    fGpuMin  = Min(fGpuMin,  timer.fGpu);
9062abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                }
9072abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com
908af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                fWallSum += timer.fWall;
909af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                fCpuSum += timer.fCpu;
910af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                fGpuSum += timer.fGpu;
91125df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com            }
912cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
913508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com           if (glHelper) {
914508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com                SK_GL(*glHelper->glContext(), Finish());
915788e2474846fd2136ea7f05ca41f7e46c652d508bsalomon@google.com           }
916cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
9174bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            if (repeatDraw > 1) {
918af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                // output each repeat (no average) if logPerIter is set,
919af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                // otherwise output only the average
920af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                if (!logPerIter) {
921fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fWallStr.set(" msecs = ");
9222abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                    fWallStr.appendf(normalTimeFormat.c_str(),
9232abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                        printMin ? fWallMin : fWallSum / repeatDraw);
924fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fCpuStr.set(" cmsecs = ");
9252abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                    fCpuStr.appendf(normalTimeFormat.c_str(),
9262abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                        printMin ? fCpuMin : fCpuSum / repeatDraw);
927fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org                    fGpuStr.set(" gmsecs = ");
9282abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                    fGpuStr.appendf(normalTimeFormat.c_str(),
9292abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com                        printMin ? fGpuMin : fGpuSum / repeatDraw);
930af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                }
93129348cb0612e19030d979156860946241e2ff4bdreed@android.com                SkString str;
932be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                str.printf("  %4s:", configName);
933be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                if (timerWall) {
934af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    str += fWallStr;
935be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
936be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                if (timerCpu) {
937af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    str += fCpuStr;
938be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
939af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                if (timerGpu && glHelper && fGpuSum > 0) {
940af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com                    str += fGpuStr;
941be9ad4e5fc6126a1273a7dccf1a85db72e763df3bungeman@google.com                }
942a2b32b80818adebfc028334e0095cb3218825188borenet@google.com                logger.logProgress(str);
9434bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
9444c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            if (outDir.size() > 0) {
945a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                saveFile(bench->getName(), configName, outDir.c_str(),
946a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org                         device->accessBitmap(false));
9474c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com            }
9484bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        }
949a2b32b80818adebfc028334e0095cb3218825188borenet@google.com        logger.logProgress(SkString("\n"));
950bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
951cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
9520da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    // need to clean up here rather than post-main to allow leak detection to work
9530da3719050473344b6013fd7b614611984f20effrobertphillips@google.com    gDebugGLHelper.cleanup();
954cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
955bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    return 0;
956bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
957