benchmain.cpp revision e9cd27d4a3c92393cc6c79d4d6f93d266411d95e
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
9cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
10971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrContext.h"
11cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#include "GrContextFactory.h"
12971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "GrRenderTarget.h"
13cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#include "SkGpuDevice.h"
14c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#include "gl/GrGLDefines.h"
1541809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.com#else
1641809934d77a486ac30e36baadc519cbb11c4c05bsalomon@google.comclass GrContext;
17cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
18971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com
19c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#include "BenchTimer.h"
209a4125283ad56cea3b986337cb669dde14bf0ed8scroggo@google.com#include "SkBenchLogger.h"
21971d0c8049c6bfc7a58f0b41f8f59f9ec9ca077bbsalomon@google.com#include "SkBenchmark.h"
2273672254a3e498081967d00d27b17ada443e2ab2robertphillips@google.com#include "SkBitmapDevice.h"
23bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkCanvas.h"
2478d0379dcc777b4bc4965cff0c2b3fc44ccaef56mtklein@google.com#include "SkColorPriv.h"
25586db93c447b753364d50fadc5426de4fef9a759sglez@google.com#include "SkCommandLineFlags.h"
2682a7bfcb2dbd4f8845a85fc8bddf2c1e59528582bsalomon@google.com#include "SkDeferredCanvas.h"
273a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com#include "SkGraphics.h"
28b398fe863860b072306b5297c8095c6d973aba06reed@android.com#include "SkImageEncoder.h"
29c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#include "SkOSFile.h"
306c924ad46c89955e78e071c792ef00df9910b42freed@android.com#include "SkPicture.h"
31bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com#include "SkString.h"
32fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
339ef1d21dc8edd167ebbf1ec35f25769f9f6b683bmtklein@google.com#include <limits>
349ef1d21dc8edd167ebbf1ec35f25769f9f6b683bmtklein@google.com
35c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comenum BenchMode {
36c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kNormal_BenchMode,
37c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kDeferred_BenchMode,
38c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kDeferredSilent_BenchMode,
39c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kRecord_BenchMode,
40c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    kPictureRecord_BenchMode
41c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com};
42dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comconst char* BenchMode_Name[] = {
43dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    "normal", "deferred", "deferredSilent", "record", "picturerecord"
44dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com};
45515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org
464e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.comstatic const char kDefaultsConfigStr[] = "defaults";
474e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com
48fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org///////////////////////////////////////////////////////////////////////////////
49fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
506c924ad46c89955e78e071c792ef00df9910b42freed@android.comstatic void erase(SkBitmap& bm) {
516c924ad46c89955e78e071c792ef00df9910b42freed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
52dbfac8a72393eaf01670aeb3244de0e18d8faf98junov@google.com        bm.eraseColor(SK_ColorTRANSPARENT);
536c924ad46c89955e78e071c792ef00df9910b42freed@android.com    } else {
546c924ad46c89955e78e071c792ef00df9910b42freed@android.com        bm.eraseColor(SK_ColorWHITE);
556c924ad46c89955e78e071c792ef00df9910b42freed@android.com    }
566c924ad46c89955e78e071c792ef00df9910b42freed@android.com}
576c924ad46c89955e78e071c792ef00df9910b42freed@android.com
58bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comclass Iter {
59bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.compublic:
60c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    Iter() : fBench(BenchRegistry::Head()) {}
61fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
62bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* next() {
63bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        if (fBench) {
64bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            BenchRegistry::Factory f = fBench->factory();
65bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            fBench = fBench->next();
66410e6e80f00a6c660675c80904807a041c7b7d2amtklein@google.com            return f();
67bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
68bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        return NULL;
69bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
70d1a416a97cac1769c1616cd3b092876dc6077e59bungeman@google.com
71bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comprivate:
72bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    const BenchRegistry* fBench;
73bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com};
74bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
7530e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.comclass AutoPrePostDraw {
7630e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.compublic:
7730e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    AutoPrePostDraw(SkBenchmark* bench) : fBench(bench) {
7830e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        fBench->preDraw();
7930e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    }
8030e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    ~AutoPrePostDraw() {
8130e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        fBench->postDraw();
8230e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    }
8330e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.comprivate:
8430e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com    SkBenchmark* fBench;
8530e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com};
8630e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
87bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.comstatic void make_filename(const char name[], SkString* path) {
88bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    path->set(name);
89bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    for (int i = 0; name[i]; i++) {
90bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        switch (name[i]) {
91bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '/':
92bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case '\\':
93bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ' ':
94bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            case ':':
95bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                path->writable_str()[i] = '-';
96bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
97bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com            default:
98bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com                break;
99bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com        }
100bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
101bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
102bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com
1034c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void saveFile(const char name[], const char config[], const char dir[],
1044c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com                     const SkBitmap& bm) {
1054c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkBitmap copy;
1064c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    if (!bm.copyTo(&copy, SkBitmap::kARGB_8888_Config)) {
1074c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com        return;
1084c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    }
109fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
110f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    if (bm.config() == SkBitmap::kA8_Config) {
111f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        // turn alpha into gray-scale
112f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        size_t size = copy.getSize() >> 2;
113f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        SkPMColor* p = copy.getAddr32(0, 0);
114f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        for (size_t i = 0; i < size; i++) {
115f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            int c = (*p >> SK_A32_SHIFT) & 0xFF;
116f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c = 255 - c;
117f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            c |= (c << 24) | (c << 16) | (c << 8);
118f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com            *p++ = c | (SK_A32_MASK << SK_A32_SHIFT);
119f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com        }
120f523e25da069e3e1af2cb73d37073a34f3bb9ea2reed@android.com    }
121fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
122c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkString filename;
123c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    make_filename(name, &filename);
124c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    filename.appendf("_%s.png", config);
125c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkString path = SkOSPath::SkPathJoin(dir, filename.c_str());
126c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    ::remove(path.c_str());
127c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkImageEncoder::EncodeFile(path.c_str(), copy, SkImageEncoder::kPNG_Type, 100);
1284c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1294c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1304c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performClip(SkCanvas* canvas, int w, int h) {
1314c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    SkRect r;
132fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1334c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(10), SkIntToScalar(10),
1344c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w*2/3), SkIntToScalar(h*2/3));
1354c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kIntersect_Op);
136fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1374c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    r.set(SkIntToScalar(w/3), SkIntToScalar(h/3),
1384c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com          SkIntToScalar(w-10), SkIntToScalar(h-10));
1394c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->clipRect(r, SkRegion::kXOR_Op);
1404c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1414c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
1424c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.comstatic void performRotate(SkCanvas* canvas, int w, int h) {
1434c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
1444c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
145fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
1464c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(x, y);
1474c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->rotate(SkIntToScalar(35));
1484c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com    canvas->translate(-x, -y);
1494c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com}
1504c7d3d6828b103ada10201608bd6e116d0ac7e61reed@android.com
151387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.comstatic void performScale(SkCanvas* canvas, int w, int h) {
152387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar x = SkIntToScalar(w) / 2;
153387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    const SkScalar y = SkIntToScalar(h) / 2;
154fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
155387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(x, y);
156387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    // just enough so we can't take the sprite case
157387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->scale(SK_Scalar1 * 99/100, SK_Scalar1 * 99/100);
158387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com    canvas->translate(-x, -y);
159387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com}
160387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com
161a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.orgenum Backend {
162604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com    kNonRendering_Backend,
163a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kRaster_Backend,
164a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kGPU_Backend,
165a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    kPDF_Backend,
166a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org};
167a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
1681f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.comstatic SkBaseDevice* make_device(SkBitmap::Config config, const SkIPoint& size,
1691f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com                                 Backend backend, int sampleCount, GrContext* context) {
1701f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com    SkBaseDevice* device = NULL;
171a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    SkBitmap bitmap;
172a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    bitmap.setConfig(config, size.fX, size.fY);
173fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
174a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    switch (backend) {
175a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kRaster_Backend:
176a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            bitmap.allocPixels();
177a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            erase(bitmap);
1781f2f338e23789f3eef168dcbd8171a28820ba6c1robertphillips@google.com            device = SkNEW_ARGS(SkBitmapDevice, (bitmap));
179a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
180cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
181cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        case kGPU_Backend: {
182cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrTextureDesc desc;
183cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fConfig = kSkia8888_GrPixelConfig;
184cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fFlags = kRenderTarget_GrTextureFlagBit;
185cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fWidth = size.fX;
186cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            desc.fHeight = size.fY;
1878a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            desc.fSampleCnt = sampleCount;
188cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            SkAutoTUnref<GrTexture> texture(context->createUncachedTexture(desc, NULL, 0));
189cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            if (!texture) {
190cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                return NULL;
191cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            }
192cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            device = SkNEW_ARGS(SkGpuDevice, (context, texture.get()));
193a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org            break;
194cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
195cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
196a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        case kPDF_Backend:
197a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org        default:
198330313a8a8343876ee596da39da06a5d69badd9cmtklein@google.com            SkDEBUGFAIL("unsupported");
199a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    }
200a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org    return device;
201a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org}
202a9015f897cd32f549349994e8163ead1db442088mike@reedtribe.org
203cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
204cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comGrContextFactory gContextFactory;
205cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef GrContextFactory::GLContextType GLContextType;
206c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kNative = GrContextFactory::kNative_GLContextType;
207c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#if SK_ANGLE
208c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kANGLE  = GrContextFactory::kANGLE_GLContextType;
209c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#else
210c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kANGLE  = kNative;
211c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#endif
212c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kDebug  = GrContextFactory::kDebug_GLContextType;
213c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kNull   = GrContextFactory::kNull_GLContextType;
214cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#else
215cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.comtypedef int GLContextType;
216c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const GLContextType kNative = 0, kANGLE = 0, kDebug = 0, kNull = 0;
217c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#endif
218c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
219c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#ifdef SK_DEBUG
220c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const bool kIsDebug = true;
221c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#else
222c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const bool kIsDebug = false;
223cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
224cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com
225c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comstatic const struct Config {
226c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkBitmap::Config    config;
227c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    const char*         name;
228c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    int                 sampleCount;
229c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    Backend             backend;
230c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    GLContextType       contextType;
231c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    bool                runByDefault;
2324bc1983e01d756ae9c91fd380758457f579d26eareed@android.com} gConfigs[] = {
233c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    { SkBitmap::kNo_Config,        "NONRENDERING", 0, kNonRendering_Backend, kNative, true},
234c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    { SkBitmap::kARGB_8888_Config, "8888",         0, kRaster_Backend,       kNative, true},
235c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    { SkBitmap::kRGB_565_Config,   "565",          0, kRaster_Backend,       kNative, true},
236cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
237c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    { SkBitmap::kARGB_8888_Config, "GPU",          0, kGPU_Backend,          kNative, true},
238c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    { SkBitmap::kARGB_8888_Config, "MSAA4",        4, kGPU_Backend,          kNative, false},
239c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    { SkBitmap::kARGB_8888_Config, "MSAA16",      16, kGPU_Backend,          kNative, false},
240d3b9fbbc48c13a1b2a664cf7e01374a44c201f51robertphillips@google.com#if SK_ANGLE
241c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    { SkBitmap::kARGB_8888_Config, "ANGLE",        0, kGPU_Backend,          kANGLE,  true},
242cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_ANGLE
243c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    { SkBitmap::kARGB_8888_Config, "Debug",        0, kGPU_Backend,          kDebug,  kIsDebug},
244c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    { SkBitmap::kARGB_8888_Config, "NULLGPU",      0, kGPU_Backend,          kNull,   true},
245cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif // SK_SUPPORT_GPU
2464bc1983e01d756ae9c91fd380758457f579d26eareed@android.com};
2474bc1983e01d756ae9c91fd380758457f579d26eareed@android.com
248c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(outDir, "", "If given, image of each bench will be put in outDir.");
249c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(timers, "cg", "Timers to display. "
250c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com              "Options: w(all) W(all, truncated) c(pu) C(pu, truncated) g(pu)");
251c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
252c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(rotate, false,  "Rotate canvas before bench run?");
253c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(scale,  false,  "Scale canvas before bench run?");
254c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(clip,   false,  "Clip canvas before bench run?");
255c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
256c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(forceAA,        true,     "Force anti-aliasing?");
257c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(forceFilter,    false,    "Force bitmap filtering?");
258c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(forceDither, "default", "Force dithering: true, false, or default?");
259c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_bool(forceBlend,     false,    "Force alpha blending?");
260c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
261c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_int32(gpuCacheBytes, -1, "GPU cache size limit in bytes.  0 to disable cache.");
262c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_int32(gpuCacheCount, -1, "GPU cache size limit in object count.  0 to disable cache.");
263c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
264c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(match, "",  "[~][^]substring[$] [...] of test name to run.\n"
265c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "Multiple matches may be separated by spaces.\n"
266c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "~ causes a matching test to always be skipped\n"
267c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "^ requires the start of the test to match\n"
268c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "$ requires the end of the test to match\n"
269c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "^ and $ requires an exact match\n"
270c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "If a test does not match any list entry,\n"
271c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                          "it is skipped unless some list entry starts with ~\n");
272c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(mode, "normal",
273c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "normal:         draw to a normal canvas;\n"
274c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "deferred:       draw to a deferred canvas;\n"
275c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "deferredSilent: deferred with silent playback;\n"
276c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "record:         draw to an SkPicture;\n"
277c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com             "picturerecord:  draw from an SkPicture to an SkPicture.\n");
2784e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.comDEFINE_string(config, kDefaultsConfigStr,
2794e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com              "Run configs given.  By default, runs the configs marked \"runByDefault\" in gConfigs.");
280c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(logFile, "", "Also write stdout here.");
281dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_int32(minMs, 20,  "Shortest time we'll allow a benchmark to run.");
282dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_int32(maxMs, 4000, "Longest time we'll allow a benchmark to run.");
283dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_double(error, 0.01,
284dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com              "Ratio of subsequent bench measurements must drop within 1±error to converge.");
285c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.comDEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per 1000 loops.");
286dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comDEFINE_bool2(verbose, v, false, "Print more.");
287111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.comDEFINE_string2(resourcePath, i, NULL, "directory for test resources.");
288dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com
289dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com// Has this bench converged?  First arguments are milliseconds / loop iteration,
290dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com// last is overall runtime in milliseconds.
291dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.comstatic bool HasConverged(double prevPerLoop, double currPerLoop, double currRaw) {
292dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    if (currRaw < FLAGS_minMs) {
293dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com        return false;
294dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    }
295dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    const double low = 1 - FLAGS_error, high = 1 + FLAGS_error;
296dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    const double ratio = currPerLoop / prevPerLoop;
297dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com    return low < ratio && ratio < high;
298dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com}
29986bb9b73a00d16eb13a6db13c5d2f775040caf13tomhudson@google.com
3005987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv);
3015987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint tool_main(int argc, char** argv) {
3024e23068b374023d43c4c725138d523721d975892bsalomon@google.com#if SK_ENABLE_INST_COUNT
30365a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com    gPrintInstCount = true;
30465a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com#endif
3053a859a00342ed078af683fd1901fd26c93dd40f0reed@android.com    SkAutoGraphics ag;
306c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkCommandLineFlags::Parse(argc, argv);
30765a87cc13d6babcf12844cca244ca7cc5258cadcbsalomon@google.com
308c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // First, parse some flags.
30955fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org
310c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkBenchLogger logger;
311c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    if (FLAGS_logFile.count()) {
312c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        logger.SetLogFile(FLAGS_logFile[0]);
313c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
31455fd612adfd08f5c64fb728bc37a2cb4ae224656commit-bot@chromium.org
315c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF;
316c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkTriState::State dither = SkTriState::kDefault;
317c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    for (size_t i = 0; i < 3; i++) {
318c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) {
319c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            dither = static_cast<SkTriState::State>(i);
320c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
321c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
322c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com
323c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    BenchMode benchMode = kNormal_BenchMode;
324c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) {
325c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (strcmp(FLAGS_mode[0], BenchMode_Name[i]) == 0) {
326c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            benchMode = static_cast<BenchMode>(i);
327c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
328c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
329c732f259fa9cb0045623f3e0e3f033c20f06be8cbsalomon@google.com
33013eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    SkTDArray<int> configs;
3314e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com    bool runDefaultConfigs = false;
332c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Try user-given configs first.
333c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    for (int i = 0; i < FLAGS_config.count(); i++) {
334e9cd27d4a3c92393cc6c79d4d6f93d266411d95erobertphillips@google.com        for (int j = 0; j < static_cast<int>(SK_ARRAY_COUNT(gConfigs)); ++j) {
335c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (0 == strcmp(FLAGS_config[i], gConfigs[j].name)) {
336c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                *configs.append() = j;
3374e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com            } else if (0 == strcmp(FLAGS_config[i], kDefaultsConfigStr)) {
3384e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com                runDefaultConfigs = true;
339e9d0060f4d7b5a07a220182d83aae3a140784c4breed@android.com            }
340b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
341b398fe863860b072306b5297c8095c6d973aba06reed@android.com    }
342c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // If there weren't any, fill in with defaults.
3434e061d3f1594e7cfa243d73e0eea0b649dead904borenet@google.com    if (runDefaultConfigs) {
344e9cd27d4a3c92393cc6c79d4d6f93d266411d95erobertphillips@google.com        for (int i = 0; i < static_cast<int>(SK_ARRAY_COUNT(gConfigs)); ++i) {
345c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (gConfigs[i].runByDefault) {
3468a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                *configs.append() = i;
3478a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
34813eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com        }
34913eaaaa75a16fa300fa212ec910107f77530ef2ctomhudson@google.com    }
350c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Filter out things we can't run.
351c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    if (kNormal_BenchMode != benchMode) {
352604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        // Non-rendering configs only run in normal mode
353604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        for (int i = 0; i < configs.count(); ++i) {
354c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const Config& config = gConfigs[configs[i]];
355c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (kNonRendering_Backend == config.backend) {
356604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                configs.remove(i, 1);
357604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                --i;
358604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            }
359604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com        }
360604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com    }
361111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    // Set the resource path.
362111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    if (!FLAGS_resourcePath.isEmpty()) {
363111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com        SkBenchmark::SetResourcePath(FLAGS_resourcePath[0]);
364111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com    }
365111fd11e11cbc296c97225ea16b7ff174a4bcdb5scroggo@google.com
3668a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com#if SK_SUPPORT_GPU
3678a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    for (int i = 0; i < configs.count(); ++i) {
368c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        const Config& config = gConfigs[configs[i]];
3698a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com
370c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (kGPU_Backend == config.backend) {
371c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            GrContext* context = gContextFactory.get(config.contextType);
3728a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            if (NULL == context) {
373dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                logger.logError(SkStringPrintf(
374dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                    "Error creating GrContext for config %s. Config will be skipped.\n",
375dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                    config.name));
3768a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                configs.remove(i);
3778a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                --i;
3788a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                continue;
3798a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
380c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (config.sampleCount > context->getMaxSampleCount()){
381dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                logger.logError(SkStringPrintf(
382dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                    "Sample count (%d) for config %s is unsupported. Config will be skipped.\n",
383dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                    config.sampleCount, config.name));
3848a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                configs.remove(i);
3858a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                --i;
3868a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com                continue;
3878a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com            }
3888a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com        }
3898a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com    }
3908a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com#endif
3918a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com
392c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // All flags should be parsed now.  Report our settings.
393c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    if (kIsDebug) {
394c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        logger.logError("bench was built in Debug mode, so we're going to hide the times."
395c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        "  It's for your own good!\n");
396c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
397c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    SkString str("skia bench:");
398c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.appendf(" mode=%s", FLAGS_mode[0]);
399c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.appendf(" alpha=0x%02X antialias=%d filter=%d dither=%s",
400c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                alpha, FLAGS_forceAA, FLAGS_forceFilter, SkTriState::Name[dither]);
401c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.appendf(" rotate=%d scale=%d clip=%d", FLAGS_rotate, FLAGS_scale, FLAGS_clip);
402c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
403c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#if defined(SK_SCALAR_IS_FIXED)
404c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.append(" scalar=fixed");
405c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#else
406c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.append(" scalar=float");
407a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
408a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
409a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_BUILD_FOR_WIN32)
410c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.append(" system=WIN32");
411a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_MAC)
412c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.append(" system=MAC");
413a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_ANDROID)
414c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.append(" system=ANDROID");
415a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#elif defined(SK_BUILD_FOR_UNIX)
416c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.append(" system=UNIX");
417a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#else
418c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.append(" system=other");
419a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
420a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com
421a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#if defined(SK_DEBUG)
422c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.append(" DEBUG");
423a5d48414249b7df5387ac572d178a1b6550880a5bungeman@google.com#endif
424c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    str.append("\n");
425c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    logger.logProgress(str);
426c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
427508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
428c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Set texture cache limits if non-default.
4295c90e291425b2788f47679266d9584845ceefc2ebsalomon@google.com    for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) {
430cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#if SK_SUPPORT_GPU
431c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        const Config& config = gConfigs[i];
432c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (kGPU_Backend != config.backend) {
433c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            continue;
434cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com        }
435c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        GrContext* context = gContextFactory.get(config.contextType);
436c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (NULL == context) {
437c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            continue;
438c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
439c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
440c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        size_t bytes;
441c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        int count;
442c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        context->getTextureCacheLimits(&count, &bytes);
443c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (-1 != FLAGS_gpuCacheBytes) {
444c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            bytes = static_cast<size_t>(FLAGS_gpuCacheBytes);
445c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
446c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (-1 != FLAGS_gpuCacheCount) {
447c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            count = FLAGS_gpuCacheCount;
448c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        }
449c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        context->setTextureCacheLimits(count, bytes);
450cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com#endif
451cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    }
45274913722bfe5e4b6810545891958e3d8e9c63791bsalomon@google.com
453c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Find the longest name of the benches we're going to run to make the output pretty.
454c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    Iter names;
455bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    SkBenchmark* bench;
456c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    int longestName = 0;
457c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    while ((bench = names.next()) != NULL) {
4587fbc6048b1cacbf11852e25b838edc8fe9433dcdbsalomon@google.com        SkAutoTUnref<SkBenchmark> benchUnref(bench);
459c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
460b398fe863860b072306b5297c8095c6d973aba06reed@android.com            continue;
461b398fe863860b072306b5297c8095c6d973aba06reed@android.com        }
462c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        const int length = strlen(bench->getName());
463c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        longestName = length > longestName ? length : longestName;
464c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    }
465fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
466c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    // Run each bench in each configuration it supports and we asked for.
467c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    Iter iter;
468c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com    while ((bench = iter.next()) != NULL) {
469c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        SkAutoTUnref<SkBenchmark> benchUnref(bench);
470c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
471387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com            continue;
472387359e3483056a7ae7e4cf50347b71b4e3b2d60reed@android.com        }
473fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
474c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setForceAlpha(alpha);
475c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setForceAA(FLAGS_forceAA);
476c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setForceFilter(FLAGS_forceFilter);
477c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bench->setDither(dither);
47830e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com        AutoPrePostDraw appd(bench);
47930e6d2c2054c15f1cb6c0637bee6756261291751bsalomon@google.com
480c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        bool loggedBenchName = false;
481c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        for (int i = 0; i < configs.count(); ++i) {
482c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const int configIndex = configs[i];
483c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const Config& config = gConfigs[configIndex];
4847495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org
485c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if ((kNonRendering_Backend == config.backend) == bench->isRendering()) {
486c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                continue;
487604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com            }
488604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com
489cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com            GrContext* context = NULL;
490cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
4919c55f801a35b0d6c39f007fae432bd13094f3c52sugoi@google.com            SkGLContextHelper* glContext = NULL;
492c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (kGPU_Backend == config.backend) {
493c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                context = gContextFactory.get(config.contextType);
494cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                if (NULL == context) {
495cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                    continue;
496cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com                }
497c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                glContext = gContextFactory.getGLContext(config.contextType);
4984bc1983e01d756ae9c91fd380758457f579d26eareed@android.com            }
499cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
500c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            SkAutoTUnref<SkBaseDevice> device;
501c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            SkAutoTUnref<SkCanvas> canvas;
502c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            SkPicture recordFrom, recordTo;
503c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const SkIPoint dim = bench->getSize();
504c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
505c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const SkPicture::RecordingFlags kRecordFlags =
506c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                SkPicture::kUsePathBoundsForClip_RecordingFlag;
507c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
508c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (kNonRendering_Backend != config.backend) {
509c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                device.reset(make_device(config.config,
510c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                                         dim,
511c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                                         config.backend,
512c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                                         config.sampleCount,
513c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                                         context));
514c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                if (!device.get()) {
515dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                    logger.logError(SkStringPrintf(
516dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                        "Device creation failure for config %s. Will skip.\n", config.name));
517c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    continue;
518604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com                }
519604a56ad4201cc66a85d7bf20efe201ec14b2c1fbsalomon@google.com
520c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                switch(benchMode) {
521c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kDeferredSilent_BenchMode:
522c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kDeferred_BenchMode:
523c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        canvas.reset(SkDeferredCanvas::Create(device.get()));
524c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
525c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kRecord_BenchMode:
526c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        canvas.reset(SkRef(recordTo.beginRecording(dim.fX, dim.fY, kRecordFlags)));
527c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
528c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kPictureRecord_BenchMode:
529c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        bench->draw(recordFrom.beginRecording(dim.fX, dim.fY, kRecordFlags));
530c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        recordFrom.endRecording();
531c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        canvas.reset(SkRef(recordTo.beginRecording(dim.fX, dim.fY, kRecordFlags)));
532c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
533c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    case kNormal_BenchMode:
534c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        canvas.reset(new SkCanvas(device.get()));
535c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        break;
536c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    default:
537c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                        SkASSERT(false);
5387495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                }
539c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
540508824bd4b944a77cefad527006e687e5cd927d2bsalomon@google.com
541c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (NULL != canvas) {
542c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                canvas->clear(SK_ColorWHITE);
543c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                if (FLAGS_clip)   {   performClip(canvas, dim.fX, dim.fY); }
544c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                if (FLAGS_scale)  {  performScale(canvas, dim.fX, dim.fY); }
545c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                if (FLAGS_rotate) { performRotate(canvas, dim.fX, dim.fY); }
546c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
547c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
548c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (!loggedBenchName) {
549c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                loggedBenchName = true;
550c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                SkString str;
551c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                str.printf("running bench [%3d %3d] %*s ",
552c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                           dim.fX, dim.fY, longestName, bench->getName());
553c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                logger.logProgress(str);
554c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
555fdd909ca000801aced49881558760170b5f1eb97keyar@chromium.org
556cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
557c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            SkGLContextHelper* contextHelper = NULL;
558c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (kGPU_Backend == config.backend) {
559c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                contextHelper = gContextFactory.getGLContext(config.contextType);
560c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
561c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            BenchTimer timer(contextHelper);
562c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#else
563c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            BenchTimer timer;
564cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
565af3d79a8c81f3f224a5eff53b0ca8615b884f922bensong@google.com
5669ef1d21dc8edd167ebbf1ec35f25769f9f6b683bmtklein@google.com            double previous = std::numeric_limits<double>::infinity();
567dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com            bool converged = false;
56870de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
56970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            // variables used to compute loopsPerFrame
57070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            double frameIntervalTime = 0.0f;
57170de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            int frameIntervalTotalLoops = 0;
57270de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
57370de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            bool frameIntervalComputed = false;
57470de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            int loopsPerFrame = 0;
57570de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            int loopsPerIter = 0;
576dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com            if (FLAGS_verbose) { SkDebugf("%s %s: ", bench->getName(), config.name); }
577c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            do {
57870de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                // Ramp up 1 -> 2 -> 4 -> 8 -> 16 -> ... -> ~1 billion.
57970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                loopsPerIter = (loopsPerIter == 0) ? 1 : loopsPerIter * 2;
58070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                if (loopsPerIter >= (1<<30) || timer.fWall > FLAGS_maxMs) {
581c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    // If you find it takes more than a billion loops to get up to 20ms of runtime,
582c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    // you've got a computer clocked at several THz or have a broken benchmark.  ;)
583c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    //     "1B ought to be enough for anybody."
584dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                    logger.logError(SkStringPrintf(
58570de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        "\nCan't get %s %s to converge in %dms (%d loops)",
58670de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                         bench->getName(), config.name, FLAGS_maxMs, loopsPerIter));
587c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    break;
588c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                }
589c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
590c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                if ((benchMode == kRecord_BenchMode || benchMode == kPictureRecord_BenchMode)) {
591c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    // Clear the recorded commands so that they do not accumulate.
592c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    canvas.reset(recordTo.beginRecording(dim.fX, dim.fY, kRecordFlags));
593c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                }
5942abed834789bb64c7da740df4c47efc142b7311arobertphillips@google.com
595c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                timer.start();
59670de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                // Inner loop that allows us to break the run into smaller
59770de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                // chunks (e.g. frames). This is especially useful for the GPU
59870de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                // as we can flush and/or swap buffers to keep the GPU from
59970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                // queuing up too much work.
60070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                for (int loopCount = loopsPerIter; loopCount > 0; ) {
6012887119a63e314704673b971e9bc9a3461313a2ccommit-bot@chromium.org                    // Save and restore around each call to draw() to guarantee a pristine canvas.
6022887119a63e314704673b971e9bc9a3461313a2ccommit-bot@chromium.org                    SkAutoCanvasRestore saveRestore(canvas, true/*also save*/);
6032887119a63e314704673b971e9bc9a3461313a2ccommit-bot@chromium.org
60470de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    if (frameIntervalComputed && loopCount > loopsPerFrame) {
60570de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        bench->setLoops(loopsPerFrame);
60670de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        loopCount -= loopsPerFrame;
60770de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    } else {
60870de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        bench->setLoops(loopCount);
60970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        loopCount = 0;
61070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
61170de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
61270de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    if (benchMode == kPictureRecord_BenchMode) {
61370de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        recordFrom.draw(canvas);
61470de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    } else {
61570de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        bench->draw(canvas);
61670de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
61770de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
61870de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    if (kDeferredSilent_BenchMode == benchMode) {
61970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        static_cast<SkDeferredCanvas*>(canvas.get())->silentFlush();
62070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    } else if (NULL != canvas) {
62170de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        canvas->flush();
62270de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
62370de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
62470de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com#if SK_SUPPORT_GPU
62570de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    // swap drawing buffers on each frame to prevent the GPU
62670de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    // from queuing up too much work
62770de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    if (NULL != glContext) {
62870de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        glContext->swapBuffers();
62970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
63070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com#endif
631c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                }
632c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
633c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
634c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
635c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                // Stop truncated timers before GL calls complete, and stop the full timers after.
636c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                timer.truncatedEnd();
637c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#if SK_SUPPORT_GPU
638c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                if (NULL != glContext) {
639c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    context->flush();
640c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    SK_GL(*glContext, Finish());
6418ad29cea429e5b6f5b37f647a0eacadd7c9cf86aborenet@google.com                }
642c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com#endif
643c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                timer.end();
64470de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com
645dcfed6cecfde7a6e4983c1caf7ffb417c891667fdjsollen@google.com                // setup the frame interval for subsequent iterations
646dcfed6cecfde7a6e4983c1caf7ffb417c891667fdjsollen@google.com                if (!frameIntervalComputed) {
64770de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    frameIntervalTime += timer.fWall;
64870de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    frameIntervalTotalLoops += loopsPerIter;
64970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    if (frameIntervalTime >= FLAGS_minMs) {
65070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        frameIntervalComputed = true;
65170de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        loopsPerFrame =
6524e1d4b3d23fb9ffb655b6cf2a17b35533b57869fdjsollen@google.com                          (int)(((double)frameIntervalTotalLoops / frameIntervalTime) * FLAGS_minMs);
65370de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        if (loopsPerFrame < 1) {
65470de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                            loopsPerFrame = 1;
65570de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                        }
65670de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com//                        SkDebugf("  %s has %d loops in %f ms (normalized to %d)\n",
65770de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com//                                 bench->getName(), frameIntervalTotalLoops,
65870de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com//                                 timer.fWall, loopsPerFrame);
65970de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                    }
66070de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                }
661dcfed6cecfde7a6e4983c1caf7ffb417c891667fdjsollen@google.com
66270de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com                const double current = timer.fWall / loopsPerIter;
663dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                if (FLAGS_verbose && current > previous) { SkDebugf("↑"); }
664dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                if (FLAGS_verbose) { SkDebugf("%.3g ", current); }
665dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                converged = HasConverged(previous, current, timer.fWall);
666dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com                previous = current;
667dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com            } while (!kIsDebug && !converged);
668dbd41c885768f9fec3bd9e216518f9ea1b181a96mtklein@google.com            if (FLAGS_verbose) { SkDebugf("\n"); }
669c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
670c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (FLAGS_outDir.count() && kNonRendering_Backend != config.backend) {
671c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                saveFile(bench->getName(),
672c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                         config.name,
673c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                         FLAGS_outDir[0],
674c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                         device->accessBitmap(false));
675c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
676c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
677c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            if (kIsDebug) {
678c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                // Let's not mislead ourselves by looking at Debug build bench times!
679c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                continue;
680c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            }
681c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
682c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            // Normalize to ms per 1000 iterations.
68370de4da331b70fed227de795a7464dd6f0f0a8d7djsollen@google.com            const double normalize = 1000.0 / loopsPerIter;
684c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            const struct { char shortName; const char* longName; double ms; } times[] = {
685c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'w', "msecs",  normalize * timer.fWall},
686c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'W', "Wmsecs", normalize * timer.fTruncatedWall},
687c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'c', "cmsecs", normalize * timer.fCpu},
688c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'C', "Cmsecs", normalize * timer.fTruncatedCpu},
689c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                {'g', "gmsecs", normalize * timer.fGpu},
690c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            };
691c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com
692c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            SkString result;
693c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            result.appendf("   %s:", config.name);
694c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) {
695c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms > 0) {
696c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    result.appendf(" %s = ", times[i].longName);
697c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com                    result.appendf(FLAGS_timeFormat[0], times[i].ms);
6987495f59d39f869deaba13ba5218e42dc3a7ddbaecommit-bot@chromium.org                }
69925df8884bb616f8acf1ddbfb15d800a215c5ac65reed@google.com            }
700c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            logger.logProgress(result);
70124ed8d721979d891b5fbdfd59dfdd0902778b912bensong@google.com        }
702c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com        if (loggedBenchName) {
703c289743864e2ab926a95e617a5cd1d29b26d1825mtklein@google.com            logger.logProgress("\n");
7044bc1983e01d756ae9c91fd380758457f579d26eareed@android.com        }
705bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    }
706cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#if SK_SUPPORT_GPU
707cb26535ff71fc323278892d6b90546b3b1c54649bsalomon@google.com    gContextFactory.destroyContexts();
708cf8fb1f6f03fc77f9927564f9ef9abeeeec508d2bsalomon@google.com#endif
709bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com    return 0;
710bd700c391dd45acd8ea1a40321789c9d92a14bb8reed@android.com}
7115987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com
7127158e6acca1b1ecc321d4d514a31cba11b5ead60borenet@google.com#if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL)
7135987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.comint main(int argc, char * const argv[]) {
7145987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com    return tool_main(argc, (char**) argv);
7155987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com}
7165987f58036574ccf23049b5fe71f29a441d0641dcaryclark@google.com#endif
717