180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2012 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkBenchLogger.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "BenchTimer.h"
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "PictureBenchmark.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkCanvas.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPicture.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkString.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "picture_utils.h"
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "TimerData.h"
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querunamespace sk_tools {
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruPictureBenchmark::PictureBenchmark()
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru: fRepeats(1)
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru, fLogger(NULL)
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru, fRenderer(NULL)
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru, fLogPerIter(false)
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru, fPrintMin(false)
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru, fShowWallTime(false)
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru, fShowTruncatedWallTime(false)
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru, fShowCpuTime(true)
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru, fShowTruncatedCpuTime(false)
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru, fShowGpuTime(false)
30363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger, fTimeIndividualTiles(false)
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru{}
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruPictureBenchmark::~PictureBenchmark() {
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkSafeUnref(fRenderer);
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruBenchTimer* PictureBenchmark::setupTimer() {
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if SK_SUPPORT_GPU
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fRenderer != NULL && fRenderer->isUsingGpuDevice()) {
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return SkNEW_ARGS(BenchTimer, (fRenderer->getGLContext()));
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
43363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    return SkNEW_ARGS(BenchTimer, (NULL));
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid PictureBenchmark::logProgress(const char msg[]) {
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (fLogger != NULL) {
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fLogger->logProgress(msg);
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruPictureRenderer* PictureBenchmark::setRenderer(sk_tools::PictureRenderer* renderer) {
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkRefCnt_SafeAssign(fRenderer, renderer);
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return renderer;
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid PictureBenchmark::run(SkPicture* pict) {
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(pict);
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == pict) {
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkASSERT(fRenderer != NULL);
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == fRenderer) {
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRenderer->init(pict);
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // We throw this away to remove first time effects (such as paging in this program)
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRenderer->setup();
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRenderer->render(NULL);
73d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    fRenderer->resetState(true);
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    bool usingGpu = false;
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#if SK_SUPPORT_GPU
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    usingGpu = fRenderer->isUsingGpuDevice();
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#endif
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
80363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    if (fTimeIndividualTiles) {
81363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        TiledPictureRenderer* tiledRenderer = fRenderer->getTiledRenderer();
82363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkASSERT(tiledRenderer);
83363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        if (NULL == tiledRenderer) {
84363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            return;
85363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        }
86363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        int xTiles, yTiles;
87363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        if (!tiledRenderer->tileDimensions(xTiles, yTiles)) {
88363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            return;
89363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        }
90363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
91363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        // Insert a newline so that each tile is reported on its own line (separate from the line
92363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        // that describes the skp being run).
93363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        this->logProgress("\n");
94363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
95363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        int x, y;
96363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        while (tiledRenderer->nextTile(x, y)) {
97d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            // There are two timers, which will behave slightly differently:
98d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            // 1) longRunningTimer, along with perTileTimerData, will time how long it takes to draw
99d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            // one tile fRepeats times, and take the average. As such, it will not respect the
100d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            // logPerIter or printMin options, since it does not know the time per iteration. It
101d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            // will also be unable to call flush() for each tile.
102d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            // The goal of this timer is to make up for a system timer that is not precise enough to
103d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            // measure the small amount of time it takes to draw one tile once.
104d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            //
105d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            // 2) perTileTimer, along with perTileTimerData, will record each run separately, and
106d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            // then take the average. As such, it supports logPerIter and printMin options.
107d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            SkAutoTDelete<BenchTimer> longRunningTimer(this->setupTimer());
108d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            TimerData longRunningTimerData(tiledRenderer->getPerIterTimeFormat(),
109d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                           tiledRenderer->getNormalTimeFormat());
110d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            SkAutoTDelete<BenchTimer> perTileTimer(this->setupTimer());
111d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            TimerData perTileTimerData(tiledRenderer->getPerIterTimeFormat(),
112d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                       tiledRenderer->getNormalTimeFormat());
113d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            longRunningTimer->start();
114363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            for (int i = 0; i < fRepeats; ++i) {
115d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                perTileTimer->start();
116363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                tiledRenderer->drawCurrentTile();
117d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                perTileTimer->truncatedEnd();
118d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                tiledRenderer->resetState(false);
119d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                perTileTimer->end();
120d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                perTileTimerData.appendTimes(perTileTimer.get(), fRepeats - 1 == i);
121363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            }
122d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            longRunningTimer->truncatedEnd();
123d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            tiledRenderer->resetState(true);
124d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            longRunningTimer->end();
125d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            longRunningTimerData.appendTimes(longRunningTimer.get(), true);
126d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
127363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            SkString configName = tiledRenderer->getConfigName();
128363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            configName.appendf(": tile [%i,%i] out of [%i,%i]", x, y, xTiles, yTiles);
129d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            SkString result = perTileTimerData.getResult(fLogPerIter, fPrintMin, fRepeats,
130d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                                         configName.c_str(), fShowWallTime,
131d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                                         fShowTruncatedWallTime, fShowCpuTime,
132d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                                         fShowTruncatedCpuTime,
133d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                                         usingGpu && fShowGpuTime);
134363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            result.append("\n");
135363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            this->logProgress(result.c_str());
136d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger
137d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            configName.append(" <averaged>");
138d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            SkString longRunningResult = longRunningTimerData.getResult(false, false, fRepeats,
139d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                    configName.c_str(), fShowWallTime, fShowTruncatedWallTime,
140d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                    fShowCpuTime, fShowTruncatedCpuTime, usingGpu && fShowGpuTime);
141d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            longRunningResult.append("\n");
142d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            this->logProgress(longRunningResult.c_str());
143363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        }
144363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    } else {
145d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        SkAutoTDelete<BenchTimer> timer(this->setupTimer());
146363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        TimerData timerData(fRenderer->getPerIterTimeFormat(), fRenderer->getNormalTimeFormat());
147363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        for (int i = 0; i < fRepeats; ++i) {
148363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            fRenderer->setup();
149363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
150363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            timer->start();
151363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            fRenderer->render(NULL);
152363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            timer->truncatedEnd();
153363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
154363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            // Finishes gl context
155d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            fRenderer->resetState(true);
156363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            timer->end();
157363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
158d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger            timerData.appendTimes(timer.get(), fRepeats - 1 == i);
159363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        }
160363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger
161363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkString configName = fRenderer->getConfigName();
162363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        SkString result = timerData.getResult(fLogPerIter, fPrintMin, fRepeats,
163363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                              configName.c_str(), fShowWallTime,
164363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                              fShowTruncatedWallTime, fShowCpuTime,
165363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                              fShowTruncatedCpuTime, usingGpu && fShowGpuTime);
166363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        result.append("\n");
167363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        this->logProgress(result.c_str());
16880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
16980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fRenderer->end();
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
174