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