blob: a358ad4179d917eda54fb654d84a6647d3e9984c [file] [log] [blame]
keyar@chromium.org163b5672012-08-01 17:53:29 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
scroggo@google.com9a412522012-09-07 15:21:18 +00008#include "SkBenchLogger.h"
keyar@chromium.org163b5672012-08-01 17:53:29 +00009#include "BenchTimer.h"
10#include "PictureBenchmark.h"
11#include "SkCanvas.h"
12#include "SkPicture.h"
13#include "SkString.h"
14#include "picture_utils.h"
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +000015#include "TimerData.h"
keyar@chromium.org163b5672012-08-01 17:53:29 +000016
17namespace sk_tools {
18
scroggo@google.com5239c322012-09-11 19:15:32 +000019PictureBenchmark::PictureBenchmark()
20: fRepeats(1)
21, fLogger(NULL)
22, fRenderer(NULL)
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +000023, fLogPerIter(false)
24, fPrintMin(false)
25, fShowWallTime(false)
26, fShowTruncatedWallTime(false)
27, fShowCpuTime(true)
28, fShowTruncatedCpuTime(false)
29, fShowGpuTime(false)
scroggo@google.comcbcef702012-12-13 22:09:28 +000030, fTimeIndividualTiles(false)
scroggo@google.com5239c322012-09-11 19:15:32 +000031{}
32
33PictureBenchmark::~PictureBenchmark() {
34 SkSafeUnref(fRenderer);
35}
36
robertphillips@google.comf9d0c952013-02-07 16:21:22 +000037BenchTimer* PictureBenchmark::setupTimer(bool useGLTimer) {
keyar@chromium.org77a55222012-08-20 15:03:47 +000038#if SK_SUPPORT_GPU
robertphillips@google.comf9d0c952013-02-07 16:21:22 +000039 if (useGLTimer && fRenderer != NULL && fRenderer->isUsingGpuDevice()) {
scroggo@google.com5239c322012-09-11 19:15:32 +000040 return SkNEW_ARGS(BenchTimer, (fRenderer->getGLContext()));
keyar@chromium.org77a55222012-08-20 15:03:47 +000041 }
keyar@chromium.org77a55222012-08-20 15:03:47 +000042#endif
scroggo@google.comcbcef702012-12-13 22:09:28 +000043 return SkNEW_ARGS(BenchTimer, (NULL));
keyar@chromium.org77a55222012-08-20 15:03:47 +000044}
45
scroggo@google.com9a412522012-09-07 15:21:18 +000046void PictureBenchmark::logProgress(const char msg[]) {
47 if (fLogger != NULL) {
48 fLogger->logProgress(msg);
49 }
50}
51
scroggo@google.com5239c322012-09-11 19:15:32 +000052PictureRenderer* PictureBenchmark::setRenderer(sk_tools::PictureRenderer* renderer) {
53 SkRefCnt_SafeAssign(fRenderer, renderer);
54 return renderer;
55}
56
scroggo@google.com9a412522012-09-07 15:21:18 +000057void PictureBenchmark::run(SkPicture* pict) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +000058 SkASSERT(pict);
keyar@chromium.org78a35c52012-08-20 15:03:44 +000059 if (NULL == pict) {
keyar@chromium.org9d696c02012-08-07 17:11:33 +000060 return;
61 }
keyar@chromium.org163b5672012-08-01 17:53:29 +000062
scroggo@google.com5239c322012-09-11 19:15:32 +000063 SkASSERT(fRenderer != NULL);
64 if (NULL == fRenderer) {
scroggo@google.com9a412522012-09-07 15:21:18 +000065 return;
66 }
keyar@chromium.org163b5672012-08-01 17:53:29 +000067
scroggo@google.com5239c322012-09-11 19:15:32 +000068 fRenderer->init(pict);
69
70 // We throw this away to remove first time effects (such as paging in this program)
71 fRenderer->setup();
scroggo@google.com81f9d2e2012-09-20 14:54:21 +000072 fRenderer->render(NULL);
scroggo@google.com08085f82013-01-28 20:40:24 +000073 fRenderer->resetState(true);
keyar@chromium.org163b5672012-08-01 17:53:29 +000074
scroggo@google.com9a412522012-09-07 15:21:18 +000075 bool usingGpu = false;
keyar@chromium.orgf8a513f2012-08-20 15:03:52 +000076#if SK_SUPPORT_GPU
scroggo@google.com5239c322012-09-11 19:15:32 +000077 usingGpu = fRenderer->isUsingGpuDevice();
keyar@chromium.orgf8a513f2012-08-20 15:03:52 +000078#endif
keyar@chromium.org77a55222012-08-20 15:03:47 +000079
scroggo@google.comcbcef702012-12-13 22:09:28 +000080 if (fTimeIndividualTiles) {
81 TiledPictureRenderer* tiledRenderer = fRenderer->getTiledRenderer();
scroggo@google.com161e1ba2013-03-04 16:41:06 +000082 SkASSERT(tiledRenderer && tiledRenderer->supportsTimingIndividualTiles());
83 if (NULL == tiledRenderer || !tiledRenderer->supportsTimingIndividualTiles()) {
scroggo@google.comcbcef702012-12-13 22:09:28 +000084 return;
85 }
86 int xTiles, yTiles;
87 if (!tiledRenderer->tileDimensions(xTiles, yTiles)) {
88 return;
89 }
keyar@chromium.org163b5672012-08-01 17:53:29 +000090
scroggo@google.comcbcef702012-12-13 22:09:28 +000091 // Insert a newline so that each tile is reported on its own line (separate from the line
92 // that describes the skp being run).
93 this->logProgress("\n");
scroggo@google.com9a412522012-09-07 15:21:18 +000094
scroggo@google.comcbcef702012-12-13 22:09:28 +000095 int x, y;
96 while (tiledRenderer->nextTile(x, y)) {
scroggo@google.com08085f82013-01-28 20:40:24 +000097 // There are two timers, which will behave slightly differently:
98 // 1) longRunningTimer, along with perTileTimerData, will time how long it takes to draw
robertphillips@google.comfe1b5362013-02-07 19:45:46 +000099 // one tile fRepeats times, and take the average. As such, it will not respect thea
scroggo@google.com08085f82013-01-28 20:40:24 +0000100 // logPerIter or printMin options, since it does not know the time per iteration. It
101 // will also be unable to call flush() for each tile.
102 // The goal of this timer is to make up for a system timer that is not precise enough to
103 // measure the small amount of time it takes to draw one tile once.
104 //
105 // 2) perTileTimer, along with perTileTimerData, will record each run separately, and
106 // then take the average. As such, it supports logPerIter and printMin options.
robertphillips@google.com9b63c502013-02-07 20:20:27 +0000107 //
108 // Although "legal", having two gpu timers running at the same time
skia.committer@gmail.comee235f92013-02-08 07:16:45 +0000109 // seems to cause problems (i.e., INVALID_OPERATIONs) on several
110 // platforms. To work around this, we disable the gpu timer on the
robertphillips@google.com9b63c502013-02-07 20:20:27 +0000111 // long running timer.
borenet@google.comb15e6062013-02-11 18:42:43 +0000112 SkAutoTDelete<BenchTimer> longRunningTimer(this->setupTimer());
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +0000113 TimerData longRunningTimerData(tiledRenderer->getPerIterTimeFormat(),
114 tiledRenderer->getNormalTimeFormat());
borenet@google.comb15e6062013-02-11 18:42:43 +0000115 SkAutoTDelete<BenchTimer> perTileTimer(this->setupTimer(false));
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +0000116 TimerData perTileTimerData(tiledRenderer->getPerIterTimeFormat(),
117 tiledRenderer->getNormalTimeFormat());
scroggo@google.com08085f82013-01-28 20:40:24 +0000118 longRunningTimer->start();
scroggo@google.comcbcef702012-12-13 22:09:28 +0000119 for (int i = 0; i < fRepeats; ++i) {
scroggo@google.com08085f82013-01-28 20:40:24 +0000120 perTileTimer->start();
scroggo@google.comcbcef702012-12-13 22:09:28 +0000121 tiledRenderer->drawCurrentTile();
scroggo@google.com08085f82013-01-28 20:40:24 +0000122 perTileTimer->truncatedEnd();
123 tiledRenderer->resetState(false);
124 perTileTimer->end();
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +0000125 perTileTimerData.appendTimes(perTileTimer.get(), fRepeats - 1 == i);
scroggo@google.comcbcef702012-12-13 22:09:28 +0000126 }
scroggo@google.com08085f82013-01-28 20:40:24 +0000127 longRunningTimer->truncatedEnd();
128 tiledRenderer->resetState(true);
129 longRunningTimer->end();
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +0000130 longRunningTimerData.appendTimes(longRunningTimer.get(), true);
scroggo@google.com08085f82013-01-28 20:40:24 +0000131
scroggo@google.comcbcef702012-12-13 22:09:28 +0000132 SkString configName = tiledRenderer->getConfigName();
133 configName.appendf(": tile [%i,%i] out of [%i,%i]", x, y, xTiles, yTiles);
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +0000134 SkString result = perTileTimerData.getResult(fLogPerIter, fPrintMin, fRepeats,
135 configName.c_str(), fShowWallTime,
136 fShowTruncatedWallTime, fShowCpuTime,
137 fShowTruncatedCpuTime,
138 usingGpu && fShowGpuTime);
scroggo@google.comcbcef702012-12-13 22:09:28 +0000139 result.append("\n");
borenet@google.comb15e6062013-02-11 18:42:43 +0000140
141// TODO(borenet): Turn off per-iteration tile time reporting for now. Avoiding logging the time
142// for every iteration for each tile cuts down on data file size by a significant amount. Re-enable
143// this once we're loading the bench data directly into a data store and are no longer generating
144// SVG graphs.
145#if 0
scroggo@google.comcbcef702012-12-13 22:09:28 +0000146 this->logProgress(result.c_str());
borenet@google.comb15e6062013-02-11 18:42:43 +0000147#endif
scroggo@google.com08085f82013-01-28 20:40:24 +0000148
149 configName.append(" <averaged>");
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +0000150 SkString longRunningResult = longRunningTimerData.getResult(false, false, fRepeats,
151 configName.c_str(), fShowWallTime, fShowTruncatedWallTime,
152 fShowCpuTime, fShowTruncatedCpuTime, usingGpu && fShowGpuTime);
scroggo@google.com08085f82013-01-28 20:40:24 +0000153 longRunningResult.append("\n");
154 this->logProgress(longRunningResult.c_str());
scroggo@google.comcbcef702012-12-13 22:09:28 +0000155 }
156 } else {
scroggo@google.com08085f82013-01-28 20:40:24 +0000157 SkAutoTDelete<BenchTimer> timer(this->setupTimer());
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +0000158 TimerData timerData(fRenderer->getPerIterTimeFormat(), fRenderer->getNormalTimeFormat());
scroggo@google.comcbcef702012-12-13 22:09:28 +0000159 for (int i = 0; i < fRepeats; ++i) {
160 fRenderer->setup();
keyar@chromium.org163b5672012-08-01 17:53:29 +0000161
scroggo@google.comcbcef702012-12-13 22:09:28 +0000162 timer->start();
163 fRenderer->render(NULL);
164 timer->truncatedEnd();
165
166 // Finishes gl context
scroggo@google.com08085f82013-01-28 20:40:24 +0000167 fRenderer->resetState(true);
scroggo@google.comcbcef702012-12-13 22:09:28 +0000168 timer->end();
169
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +0000170 timerData.appendTimes(timer.get(), fRepeats - 1 == i);
scroggo@google.comcbcef702012-12-13 22:09:28 +0000171 }
172
173 SkString configName = fRenderer->getConfigName();
bsalomon@google.com68f2a0d2013-07-25 21:30:52 +0000174 SkString result = timerData.getResult(fLogPerIter, fPrintMin, fRepeats,
175 configName.c_str(), fShowWallTime,
176 fShowTruncatedWallTime, fShowCpuTime,
177 fShowTruncatedCpuTime, usingGpu && fShowGpuTime);
scroggo@google.comcbcef702012-12-13 22:09:28 +0000178 result.append("\n");
179 this->logProgress(result.c_str());
keyar@chromium.org163b5672012-08-01 17:53:29 +0000180 }
181
scroggo@google.com5239c322012-09-11 19:15:32 +0000182 fRenderer->end();
keyar@chromium.org163b5672012-08-01 17:53:29 +0000183}
184
185}