diff options
-rw-r--r-- | bench/SkBenchLogger.cpp | 30 | ||||
-rw-r--r-- | bench/SkBenchLogger.h | 77 | ||||
-rw-r--r-- | bench/TimerData.cpp | 108 | ||||
-rw-r--r-- | bench/TimerData.h | 46 | ||||
-rw-r--r-- | bench/benchmain.cpp | 149 | ||||
-rw-r--r-- | gyp/bench.gypi | 5 | ||||
-rw-r--r-- | gyp/tools.gyp | 25 | ||||
-rw-r--r-- | tools/PictureBenchmark.cpp | 227 | ||||
-rw-r--r-- | tools/PictureBenchmark.h | 64 | ||||
-rw-r--r-- | tools/PictureRenderer.cpp | 73 | ||||
-rw-r--r-- | tools/PictureRenderer.h | 67 | ||||
-rw-r--r-- | tools/bench_pictures_main.cpp | 83 | ||||
-rw-r--r-- | tools/picture_utils.cpp | 7 | ||||
-rw-r--r-- | tools/picture_utils.h | 5 | ||||
-rw-r--r-- | tools/render_pictures_main.cpp | 4 |
15 files changed, 509 insertions, 461 deletions
diff --git a/bench/SkBenchLogger.cpp b/bench/SkBenchLogger.cpp new file mode 100644 index 0000000000..7cda32772c --- /dev/null +++ b/bench/SkBenchLogger.cpp @@ -0,0 +1,30 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkBenchLogger.h" +#include "SkStream.h" + +SkBenchLogger::SkBenchLogger() +: fFileStream(NULL) {} + +SkBenchLogger::~SkBenchLogger() { + if (fFileStream) { + SkDELETE(fFileStream); + } +} + +bool SkBenchLogger::SetLogFile(const char *file) { + fFileStream = SkNEW_ARGS(SkFILEWStream, (file)); + return fFileStream->isValid(); +} + +void SkBenchLogger::fileWrite(const char msg[], size_t size) { + if (fFileStream && fFileStream->isValid()) { + fFileStream->write(msg, size); + } +} diff --git a/bench/SkBenchLogger.h b/bench/SkBenchLogger.h new file mode 100644 index 0000000000..5eed9d373c --- /dev/null +++ b/bench/SkBenchLogger.h @@ -0,0 +1,77 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkBenchLogger_DEFINED +#define SkBenchLogger_DEFINED + +#include "SkTypes.h" +#include "SkString.h" + +class SkFILEWStream; + +/** + * Class that allows logging to a file while simultaneously logging to stdout/stderr. + */ +class SkBenchLogger { +public: + SkBenchLogger(); + + /** + * Not virtual, since this class is not intended to be subclassed. + */ + ~SkBenchLogger(); + + /** + * Specify a file to write progress logs to. Unless this is called with a valid file path, + * SkBenchLogger will only write to stdout/stderr. + */ + bool SetLogFile(const char file[]); + + /** + * Log an error to stderr, taking a C style string as input. + */ + void logError(const char msg[]) { this->nativeLogError(msg); } + + /** + * Log an error to stderr, taking an SkString as input. + */ + void logError(const SkString& str) { this->nativeLogError(str.c_str()); } + + /** + * Log the progress of the bench tool to both stdout and the log file specified by SetLogFile, + * if any, taking a C style string as input. + */ + void logProgress(const char msg[]) { + this->nativeLogProgress(msg); + this->fileWrite(msg, strlen(msg)); + } + + /** + * Log the progress of the bench tool to both stdout and the log file specified by SetLogFile, + * if any, taking an SkString as input. + */ + void logProgress(const SkString& str) { + this->nativeLogProgress(str.c_str()); + this->fileWrite(str.c_str(), str.size()); + } + +private: +#ifdef SK_BUILD_FOR_ANDROID + void nativeLogError(const char msg[]) { SkDebugf("%s", msg); } + void nativeLogProgress(const char msg[]) { SkDebugf("%s", msg); } +#else + void nativeLogError(const char msg[]) { fprintf(stderr, "%s", msg); } + void nativeLogProgress(const char msg[]) { printf("%s", msg); } +#endif + + void fileWrite(const char msg[], size_t size); + + SkFILEWStream* fFileStream; +}; + +#endif // SkBenchLogger_DEFINED diff --git a/bench/TimerData.cpp b/bench/TimerData.cpp new file mode 100644 index 0000000000..3b4baacfcd --- /dev/null +++ b/bench/TimerData.cpp @@ -0,0 +1,108 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "TimerData.h" + +#include "BenchTimer.h" +#include <limits> + +using namespace std; + +TimerData::TimerData(const SkString& perIterTimeFormat, const SkString& normalTimeFormat) +: fWallStr(" msecs = ") +, fTruncatedWallStr(" Wmsecs = ") +, fCpuStr(" cmsecs = ") +, fTruncatedCpuStr(" Cmsecs = ") +, fGpuStr(" gmsecs = ") +, fWallSum(0.0) +, fWallMin(numeric_limits<double>::max()) +, fTruncatedWallSum(0.0) +, fTruncatedWallMin(numeric_limits<double>::max()) +, fCpuSum(0.0) +, fCpuMin(numeric_limits<double>::max()) +, fTruncatedCpuSum(0.0) +, fTruncatedCpuMin(numeric_limits<double>::max()) +, fGpuSum(0.0) +, fGpuMin(numeric_limits<double>::max()) +, fPerIterTimeFormat(perIterTimeFormat) +, fNormalTimeFormat(normalTimeFormat) +{} + +static double Min(double a, double b) { + return (a < b) ? a : b; +} + +void TimerData::appendTimes(BenchTimer* timer, bool last) { + SkASSERT(timer != NULL); + SkString formatString(fPerIterTimeFormat); + if (!last) { + formatString.append(","); + } + const char* format = formatString.c_str(); + fWallStr.appendf(format, timer->fWall); + fCpuStr.appendf(format, timer->fCpu); + fTruncatedWallStr.appendf(format, timer->fTruncatedWall); + fTruncatedCpuStr.appendf(format, timer->fTruncatedCpu); + fGpuStr.appendf(format, timer->fGpu); + + // Store the minimum values. We do not need to special case the first time since we initialized + // to max double. + fWallMin = Min(fWallMin, timer->fWall); + fCpuMin = Min(fCpuMin, timer->fCpu); + fTruncatedWallMin = Min(fTruncatedWallMin, timer->fTruncatedWall); + fTruncatedCpuMin = Min(fTruncatedCpuMin, timer->fTruncatedCpu); + fGpuMin = Min(fGpuMin, timer->fGpu); + + // Tally the sum of each timer type. + fWallSum += timer->fWall; + fCpuSum += timer->fCpu; + fTruncatedWallSum += timer->fTruncatedWall; + fTruncatedCpuSum += timer->fTruncatedCpu; + fGpuSum += timer->fGpu; + +} + +SkString TimerData::getResult(bool logPerIter, bool printMin, int repeatDraw, + const char *configName, bool showWallTime, bool showTruncatedWallTime, + bool showCpuTime, bool showTruncatedCpuTime, bool showGpuTime) { + // output each repeat (no average) if logPerIter is set, + // otherwise output only the average + if (!logPerIter) { + const char* format = fNormalTimeFormat.c_str(); + fWallStr.set(" msecs = "); + fWallStr.appendf(format, printMin ? fWallMin : fWallSum / repeatDraw); + fCpuStr.set(" cmsecs = "); + fCpuStr.appendf(format, printMin ? fCpuMin : fCpuSum / repeatDraw); + fTruncatedWallStr.set(" Wmsecs = "); + fTruncatedWallStr.appendf(format, + printMin ? fTruncatedWallMin : fTruncatedWallSum / repeatDraw); + fTruncatedCpuStr.set(" Cmsecs = "); + fTruncatedCpuStr.appendf(format, + printMin ? fTruncatedCpuMin : fTruncatedCpuSum / repeatDraw); + fGpuStr.set(" gmsecs = "); + fGpuStr.appendf(format, printMin ? fGpuMin : fGpuSum / repeatDraw); + } + SkString str; + str.printf(" %4s:", configName); + if (showWallTime) { + str += fWallStr; + } + if (showTruncatedWallTime) { + str += fTruncatedWallStr; + } + if (showCpuTime) { + str += fCpuStr; + } + if (showTruncatedCpuTime) { + str += fTruncatedCpuStr; + } + if (showGpuTime && fGpuSum > 0) { + str += fGpuStr; + } + return str; +} diff --git a/bench/TimerData.h b/bench/TimerData.h new file mode 100644 index 0000000000..d97a0632aa --- /dev/null +++ b/bench/TimerData.h @@ -0,0 +1,46 @@ + +/* + * Copyright 2012 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef TimerData_DEFINED +#define TimerData_DEFINED + +#include "SkString.h" + +class BenchTimer; + +class TimerData { +public: + TimerData(const SkString& perIterTimeFormat, const SkString& normalTimeFormat); + + /** + * Append the value from each timer in BenchTimer to our various strings, and update the + * minimum and sum times. + * @param BenchTimer Must not be null. + * @param last True if this is the last set of times to add. + */ + void appendTimes(BenchTimer*, bool last); + SkString getResult(bool logPerIter, bool printMin, int repeatDraw, const char* configName, + bool showWallTime, bool showTruncatedWallTime, bool showCpuTime, + bool showTruncatedCpuTime, bool showGpuTime); +private: + SkString fWallStr; + SkString fTruncatedWallStr; + SkString fCpuStr; + SkString fTruncatedCpuStr; + SkString fGpuStr; + double fWallSum, fWallMin; + double fTruncatedWallSum, fTruncatedWallMin; + double fCpuSum, fCpuMin; + double fTruncatedCpuSum, fTruncatedCpuMin; + double fGpuSum, fGpuMin; + + SkString fPerIterTimeFormat; + SkString fNormalTimeFormat; +}; + +#endif // TimerData_DEFINED diff --git a/bench/benchmain.cpp b/bench/benchmain.cpp index e6f6620b31..bf5adfb098 100644 --- a/bench/benchmain.cpp +++ b/bench/benchmain.cpp @@ -21,6 +21,7 @@ #include "SkGpuDevice.h" #endif // SK_SUPPORT_GPU +#include "SkBenchLogger.h" #include "SkBenchmark.h" #include "SkCanvas.h" #include "SkDeferredCanvas.h" @@ -30,56 +31,8 @@ #include "SkImageEncoder.h" #include "SkNWayCanvas.h" #include "SkPicture.h" -#include "SkStream.h" #include "SkString.h" - -template <typename T> const T& Min(const T& a, const T& b) { - return (a < b) ? a : b; -} - -class SkBenchLogger { -public: - SkBenchLogger() : fFileStream(NULL) {} - ~SkBenchLogger() { - if (fFileStream) - SkDELETE(fFileStream); - } - - bool SetLogFile(const char file[]) { - fFileStream = SkNEW_ARGS(SkFILEWStream, (file)); - return fFileStream->isValid(); - } - - void logError(const char msg[]) { nativeLogError(msg); } - void logError(const SkString& str) { nativeLogError(str.c_str()); } - - void logProgress(const char msg[]) { - nativeLogProgress(msg); - fileWrite(msg, strlen(msg)); - } - void logProgress(const SkString& str) { - nativeLogProgress(str.c_str()); - fileWrite(str.c_str(), str.size()); - } - -private: -#ifdef SK_BUILD_FOR_ANDROID - void nativeLogError(const char msg[]) { SkDebugf("%s", msg); } - void nativeLogProgress(const char msg[]) { SkDebugf("%s", msg); } -#else - void nativeLogError(const char msg[]) { fprintf(stderr, "%s", msg); } - void nativeLogProgress(const char msg[]) { printf("%s", msg); } -#endif - - void fileWrite(const char msg[], size_t size) { - if (fFileStream && fFileStream->isValid()) - fFileStream->write(msg, size); - } - SkFILEWStream* fFileStream; - -} logger; - -/////////////////////////////////////////////////////////////////////////////// +#include "TimerData.h" enum benchModes { kNormal_benchModes, @@ -400,7 +353,7 @@ static void help() { " [-scale] [-clip] [-min] [-forceAA 1|0] [-forceFilter 1|0]\n" " [-forceDither 1|0] [-forceBlend 1|0] [-strokeWidth width]\n" " [-match name] [-mode normal|deferred|record|picturerecord]\n" - " [-config 8888|565|GPU|ANGLE|NULLGPU] [-Dfoo bar]\n" + " [-config 8888|565|GPU|ANGLE|NULLGPU] [-Dfoo bar] [-logFile filename]\n" " [-h|--help]"); SkDebugf("\n\n"); SkDebugf(" -o outDir : Image of each bench will be put in outDir.\n"); @@ -429,7 +382,7 @@ static void help() { " record, Benchmark the time to record to an SkPicture;\n" " picturerecord, Benchmark the time to do record from a \n" " SkPicture to a SkPicture.\n"); - SkDebugf(" -logFile : destination for writing log output, in addition to stdout.\n"); + SkDebugf(" -logFile filename : destination for writing log output, in addition to stdout.\n"); #if SK_SUPPORT_GPU SkDebugf(" -config 8888|565|GPU|ANGLE|NULLGPU : " "Run bench in corresponding config mode.\n"); @@ -478,6 +431,8 @@ int main (int argc, char * const argv[]) { SkTDArray<int> configs; bool userConfig = false; + SkBenchLogger logger; + char* const* stop = argv + argc; for (++argv; argv < stop; ++argv) { if (strcmp(*argv, "-o") == 0) { @@ -634,6 +589,7 @@ int main (int argc, char * const argv[]) { if (!logger.SetLogFile(*argv)) { SkString str; str.printf("Could not open %s for writing.", *argv); + logger.logError(str); return -1; } } else { @@ -864,16 +820,7 @@ int main (int argc, char * const argv[]) { } // record timer values for each repeat, and their sum - SkString fWallStr(" msecs = "); - SkString fTruncatedWallStr(" Wmsecs = "); - SkString fCpuStr(" cmsecs = "); - SkString fTruncatedCpuStr(" Cmsecs = "); - SkString fGpuStr(" gmsecs = "); - double fWallSum = 0.0, fWallMin; - double fTruncatedWallSum = 0.0, fTruncatedWallMin; - double fCpuSum = 0.0, fCpuMin; - double fTruncatedCpuSum = 0.0, fTruncatedCpuMin; - double fGpuSum = 0.0, fGpuMin; + TimerData timerData(perIterTimeformat, normalTimeFormat); for (int i = 0; i < repeatDraw; i++) { if ((benchMode == kRecord_benchModes || benchMode == kPictureRecord_benchModes)) { @@ -904,84 +851,14 @@ int main (int argc, char * const argv[]) { // have completed timer.end(); - if (i == repeatDraw - 1) { - // no comma after the last value - fWallStr.appendf(perIterTimeformat.c_str(), timer.fWall); - fCpuStr.appendf(perIterTimeformat.c_str(), timer.fCpu); - fTruncatedWallStr.appendf(perIterTimeformat.c_str(), timer.fTruncatedWall); - fTruncatedCpuStr.appendf(perIterTimeformat.c_str(), timer.fTruncatedCpu); - fGpuStr.appendf(perIterTimeformat.c_str(), timer.fGpu); - } else { - fWallStr.appendf(perIterTimeformat.c_str(), timer.fWall); - fWallStr.appendf(","); - fCpuStr.appendf(perIterTimeformat.c_str(), timer.fCpu); - fCpuStr.appendf(","); - fTruncatedWallStr.appendf(perIterTimeformat.c_str(), timer.fTruncatedWall); - fTruncatedWallStr.appendf(","); - fTruncatedCpuStr.appendf(perIterTimeformat.c_str(), timer.fTruncatedCpu); - fTruncatedCpuStr.appendf(","); - fGpuStr.appendf(perIterTimeformat.c_str(), timer.fGpu); - fGpuStr.appendf(","); - } - - if (0 == i) { - fWallMin = timer.fWall; - fCpuMin = timer.fCpu; - fTruncatedWallMin = timer.fTruncatedWall; - fTruncatedCpuMin = timer.fTruncatedCpu; - fGpuMin = timer.fGpu; - } else { - fWallMin = Min(fWallMin, timer.fWall); - fCpuMin = Min(fCpuMin, timer.fCpu); - fTruncatedWallMin = Min(fTruncatedWallMin, timer.fTruncatedWall); - fTruncatedCpuMin = Min(fTruncatedCpuMin, timer.fTruncatedCpu); - fGpuMin = Min(fGpuMin, timer.fGpu); - } + timerData.appendTimes(&timer, repeatDraw - 1 == i); - fWallSum += timer.fWall; - fCpuSum += timer.fCpu; - fTruncatedWallSum += timer.fTruncatedWall; - fTruncatedCpuSum += timer.fTruncatedCpu; - fGpuSum += timer.fGpu; } if (repeatDraw > 1) { - // output each repeat (no average) if logPerIter is set, - // otherwise output only the average - if (!logPerIter) { - fWallStr.set(" msecs = "); - fWallStr.appendf(normalTimeFormat.c_str(), - printMin ? fWallMin : fWallSum / repeatDraw); - fCpuStr.set(" cmsecs = "); - fCpuStr.appendf(normalTimeFormat.c_str(), - printMin ? fCpuMin : fCpuSum / repeatDraw); - fTruncatedWallStr.set(" Wmsecs = "); - fTruncatedWallStr.appendf(normalTimeFormat.c_str(), - printMin ? fTruncatedWallMin : fTruncatedWallSum / repeatDraw); - fTruncatedCpuStr.set(" Cmsecs = "); - fTruncatedCpuStr.appendf(normalTimeFormat.c_str(), - printMin ? fTruncatedCpuMin : fTruncatedCpuSum / repeatDraw); - fGpuStr.set(" gmsecs = "); - fGpuStr.appendf(normalTimeFormat.c_str(), - printMin ? fGpuMin : fGpuSum / repeatDraw); - } - SkString str; - str.printf(" %4s:", configName); - if (timerWall) { - str += fWallStr; - } - if (truncatedTimerWall) { - str += fTruncatedWallStr; - } - if (timerCpu) { - str += fCpuStr; - } - if (truncatedTimerCpu) { - str += fTruncatedCpuStr; - } - if (timerGpu && glHelper && fGpuSum > 0) { - str += fGpuStr; - } - logger.logProgress(str); + SkString result = timerData.getResult(logPerIter, printMin, repeatDraw, configName, + timerWall, truncatedTimerWall, timerCpu, + truncatedTimerCpu, timerGpu && glHelper); + logger.logProgress(result); } if (outDir.size() > 0) { saveFile(bench->getName(), configName, outDir.c_str(), diff --git a/gyp/bench.gypi b/gyp/bench.gypi index 042ccde6b8..81a00edcb1 100644 --- a/gyp/bench.gypi +++ b/gyp/bench.gypi @@ -38,6 +38,11 @@ '../bench/TextBench.cpp', '../bench/VertBench.cpp', '../bench/WriterBench.cpp', + + '../bench/SkBenchLogger.h', + '../bench/SkBenchLogger.cpp', + '../bench/TimerData.h', + '../bench/TimerData.cpp', ], } diff --git a/gyp/tools.gyp b/gyp/tools.gyp index de40dc4de7..45d98c224e 100644 --- a/gyp/tools.gyp +++ b/gyp/tools.gyp @@ -85,7 +85,12 @@ 'target_name': 'bench_pictures', 'type': 'executable', 'sources': [ + '../bench/SkBenchLogger.h', + '../bench/SkBenchLogger.cpp', + '../bench/TimerData.h', + '../bench/TimerData.cpp', '../tools/bench_pictures_main.cpp', + '../tools/PictureBenchmark.cpp', ], 'include_dirs': [ '../bench', @@ -95,27 +100,9 @@ 'effects.gyp:effects', 'ports.gyp:ports', 'tools.gyp:picture_utils', - 'tools.gyp:picture_benchmark', - ], - }, - { - 'target_name': 'picture_benchmark', - 'type': 'static_library', - 'sources': [ - '../tools/PictureBenchmark.cpp', - ], - 'include_dirs': [ - '../bench', - ], - 'dependencies': [ - 'core.gyp:core', - 'tools.gyp:picture_utils', 'tools.gyp:picture_renderer', 'bench.gyp:bench_timer', - ], - 'export_dependent_settings': [ - 'tools.gyp:picture_renderer', - ] + ], }, { 'target_name': 'picture_renderer', diff --git a/tools/PictureBenchmark.cpp b/tools/PictureBenchmark.cpp index 29152f8d69..f63d087ccc 100644 --- a/tools/PictureBenchmark.cpp +++ b/tools/PictureBenchmark.cpp @@ -6,12 +6,14 @@ */ #include "SkTypes.h" +#include "SkBenchLogger.h" #include "BenchTimer.h" #include "PictureBenchmark.h" #include "SkCanvas.h" #include "SkPicture.h" #include "SkString.h" #include "picture_utils.h" +#include "TimerData.h" namespace sk_tools { @@ -29,224 +31,67 @@ BenchTimer* PictureBenchmark::setupTimer() { #endif } -void PipePictureBenchmark::run(SkPicture* pict) { - SkASSERT(pict); - if (NULL == pict) { - return; +void PictureBenchmark::logProgress(const char msg[]) { + if (fLogger != NULL) { + fLogger->logProgress(msg); } - - fRenderer.init(pict); - - // We throw this away to remove first time effects (such as paging in this - // program) - fRenderer.render(); - fRenderer.resetState(); - - BenchTimer* timer = this->setupTimer(); - double wall_time = 0, truncated_wall_time = 0; -#if SK_SUPPORT_GPU - double gpu_time = 0; -#endif - - for (int i = 0; i < fRepeats; ++i) { - timer->start(); - fRenderer.render(); - timer->end(); - fRenderer.resetState(); - - wall_time += timer->fWall; - truncated_wall_time += timer->fTruncatedWall; -#if SK_SUPPORT_GPU - if (fRenderer.isUsingGpuDevice()) { - gpu_time += timer->fGpu; - } -#endif - } - - SkString result; - result.printf("pipe: msecs = %6.2f", wall_time / fRepeats); -#if SK_SUPPORT_GPU - if (fRenderer.isUsingGpuDevice()) { - result.appendf(" gmsecs = %6.2f", gpu_time / fRepeats); - } -#endif - result.appendf("\n"); - sk_tools::print_msg(result.c_str()); - - fRenderer.end(); - SkDELETE(timer); } -void RecordPictureBenchmark::run(SkPicture* pict) { +void PictureBenchmark::run(SkPicture* pict) { SkASSERT(pict); if (NULL == pict) { return; } - BenchTimer* timer = setupTimer(); - double wall_time = 0, truncated_wall_time = 0; - - for (int i = 0; i < fRepeats + 1; ++i) { - SkPicture replayer; - - timer->start(); - SkCanvas* recorder = replayer.beginRecording(pict->width(), pict->height()); - pict->draw(recorder); - replayer.endRecording(); - timer->end(); - - // We want to ignore first time effects - if (i > 0) { - wall_time += timer->fWall; - truncated_wall_time += timer->fTruncatedWall; - } - } - - SkString result; - result.printf("record: msecs = %6.5f\n", wall_time / fRepeats); - sk_tools::print_msg(result.c_str()); - - SkDELETE(timer); -} - -void SimplePictureBenchmark::run(SkPicture* pict) { - SkASSERT(pict); - if (NULL == pict) { + PictureRenderer* renderer = this->getRenderer(); + SkASSERT(renderer != NULL); + if (NULL == renderer) { return; } - - fRenderer.init(pict); + renderer->init(pict); // We throw this away to remove first time effects (such as paging in this // program) - fRenderer.render(); - fRenderer.resetState(); - + renderer->setup(); + renderer->render(false); + renderer->resetState(); BenchTimer* timer = this->setupTimer(); - double wall_time = 0, truncated_wall_time = 0; + bool usingGpu = false; #if SK_SUPPORT_GPU - double gpu_time = 0; + usingGpu = renderer->isUsingGpuDevice(); #endif + TimerData timerData(renderer->getPerIterTimeFormat(), renderer->getNormalTimeFormat()); for (int i = 0; i < fRepeats; ++i) { - timer->start(); - fRenderer.render(); - timer->end(); - fRenderer.resetState(); - - wall_time += timer->fWall; - truncated_wall_time += timer->fTruncatedWall; -#if SK_SUPPORT_GPU - if (fRenderer.isUsingGpuDevice()) { - gpu_time += timer->fGpu; - } -#endif - } + renderer->setup(); - - SkString result; - result.printf("simple: msecs = %6.2f", wall_time / fRepeats); -#if SK_SUPPORT_GPU - if (fRenderer.isUsingGpuDevice()) { - result.appendf(" gmsecs = %6.2f", gpu_time / fRepeats); - } -#endif - result.appendf("\n"); - sk_tools::print_msg(result.c_str()); - - fRenderer.end(); - SkDELETE(timer); -} - -void TiledPictureBenchmark::run(SkPicture* pict) { - SkASSERT(pict); - if (NULL == pict) { - return; - } - - fRenderer.init(pict); - - // We throw this away to remove first time effects (such as paging in this - // program) - fRenderer.drawTiles(); - fRenderer.resetState(); - - BenchTimer* timer = setupTimer(); - double wall_time = 0, truncated_wall_time = 0; -#if SK_SUPPORT_GPU - double gpu_time = 0; -#endif - - for (int i = 0; i < fRepeats; ++i) { timer->start(); - fRenderer.drawTiles(); - timer->end(); - fRenderer.resetState(); + renderer->render(false); + timer->truncatedEnd(); - wall_time += timer->fWall; - truncated_wall_time += timer->fTruncatedWall; -#if SK_SUPPORT_GPU - if (fRenderer.isUsingGpuDevice()) { - gpu_time += timer->fGpu; - } -#endif - } - - SkString result; - if (fRenderer.isMultiThreaded()) { - result.printf("multithreaded using %s ", (fRenderer.isUsePipe() ? "pipe" : "picture")); - } - if (fRenderer.getTileMinPowerOf2Width() > 0) { - result.appendf("%i_pow2tiles_%iminx%i: msecs = %6.2f", fRenderer.numTiles(), - fRenderer.getTileMinPowerOf2Width(), fRenderer.getTileHeight(), - wall_time / fRepeats); - } else { - result.appendf("%i_tiles_%ix%i: msecs = %6.2f", fRenderer.numTiles(), - fRenderer.getTileWidth(), fRenderer.getTileHeight(), wall_time / fRepeats); - } -#if SK_SUPPORT_GPU - if (fRenderer.isUsingGpuDevice()) { - result.appendf(" gmsecs = %6.2f", gpu_time / fRepeats); - } -#endif - result.appendf("\n"); - sk_tools::print_msg(result.c_str()); - - fRenderer.end(); - SkDELETE(timer); -} - -void UnflattenPictureBenchmark::run(SkPicture* pict) { - SkASSERT(pict); - if (NULL == pict) { - return; - } - - BenchTimer* timer = setupTimer(); - double wall_time = 0, truncated_wall_time = 0; - - for (int i = 0; i < fRepeats + 1; ++i) { - SkPicture replayer; - SkCanvas* recorder = replayer.beginRecording(pict->width(), pict->height()); - - recorder->drawPicture(*pict); - - timer->start(); - replayer.endRecording(); + // Finishes gl context + renderer->resetState(); timer->end(); - // We want to ignore first time effects - if (i > 0) { - wall_time += timer->fWall; - truncated_wall_time += timer->fTruncatedWall; - } + timerData.appendTimes(timer, fRepeats - 1 == i); } - SkString result; - result.printf("unflatten: msecs = %6.4f\n", wall_time / fRepeats); - sk_tools::print_msg(result.c_str()); + // FIXME: Pass these options on the command line. + bool logPerIter = false; + bool printMin = false; + const char* configName = usingGpu ? "gpu" : "raster"; + bool showWallTime = true; + bool showTruncatedWallTime = false; + bool showCpuTime = false; + bool showTruncatedCpuTime = false; + SkString result = timerData.getResult(logPerIter, printMin, fRepeats, + configName, showWallTime, showTruncatedWallTime, + showCpuTime, showTruncatedCpuTime, usingGpu); + result.append("\n"); + this->logProgress(result.c_str()); + renderer->end(); SkDELETE(timer); } diff --git a/tools/PictureBenchmark.h b/tools/PictureBenchmark.h index 2a14ea2888..c3767e1cb3 100644 --- a/tools/PictureBenchmark.h +++ b/tools/PictureBenchmark.h @@ -12,6 +12,7 @@ #include "PictureRenderer.h" class BenchTimer; +class SkBenchLogger; class SkPicture; class SkString; @@ -19,16 +20,16 @@ namespace sk_tools { class PictureBenchmark : public SkRefCnt { public: - virtual void run(SkPicture* pict) = 0; + PictureBenchmark() + : fRepeats(1) + , fLogger(NULL) {} + + void run(SkPicture* pict); void setRepeats(int repeats) { fRepeats = repeats; } - int getRepeats() const { - return fRepeats; - } - void setDeviceType(PictureRenderer::SkDeviceTypes deviceType) { sk_tools::PictureRenderer* renderer = getRenderer(); @@ -37,54 +38,58 @@ public: } } - BenchTimer* setupTimer(); - -protected: - int fRepeats; + void setLogger(SkBenchLogger* logger) { fLogger = logger; } private: - typedef SkRefCnt INHERITED; + int fRepeats; + SkBenchLogger* fLogger; - virtual sk_tools::PictureRenderer* getRenderer() { - return NULL; - } + void logProgress(const char msg[]); + + virtual sk_tools::PictureRenderer* getRenderer() = 0; + + BenchTimer* setupTimer(); + + typedef SkRefCnt INHERITED; }; +// TODO: Use just one PictureBenchmark with different renderers. + class PipePictureBenchmark : public PictureBenchmark { -public: - virtual void run(SkPicture* pict) SK_OVERRIDE; private: PipePictureRenderer fRenderer; - typedef PictureBenchmark INHERITED; virtual sk_tools::PictureRenderer* getRenderer() SK_OVERRIDE { return &fRenderer; } + + typedef PictureBenchmark INHERITED; }; class RecordPictureBenchmark : public PictureBenchmark { -public: - virtual void run(SkPicture* pict) SK_OVERRIDE; private: + RecordPictureRenderer fRenderer; + + virtual sk_tools::PictureRenderer* getRenderer() SK_OVERRIDE { + return &fRenderer; + } + typedef PictureBenchmark INHERITED; }; class SimplePictureBenchmark : public PictureBenchmark { -public: - virtual void run(SkPicture* pict) SK_OVERRIDE; private: SimplePictureRenderer fRenderer; - typedef PictureBenchmark INHERITED; virtual sk_tools::PictureRenderer* getRenderer() SK_OVERRIDE { return &fRenderer; } + + typedef PictureBenchmark INHERITED; }; class TiledPictureBenchmark : public PictureBenchmark { public: - virtual void run(SkPicture* pict) SK_OVERRIDE; - void setTileWidth(int width) { fRenderer.setTileWidth(width); } @@ -135,17 +140,22 @@ public: private: TiledPictureRenderer fRenderer; - typedef PictureBenchmark INHERITED; virtual sk_tools::PictureRenderer* getRenderer() SK_OVERRIDE{ return &fRenderer; } + + typedef PictureBenchmark INHERITED; }; -class UnflattenPictureBenchmark : public PictureBenchmark { -public: - virtual void run(SkPicture* pict) SK_OVERRIDE; +class PlaybackCreationBenchmark : public PictureBenchmark { private: + PlaybackCreationRenderer fRenderer; + + virtual sk_tools::PictureRenderer* getRenderer() SK_OVERRIDE{ + return &fRenderer; + } + typedef PictureBenchmark INHERITED; }; diff --git a/tools/PictureRenderer.cpp b/tools/PictureRenderer.cpp index edbdce9ea7..e7e4b1ad1c 100644 --- a/tools/PictureRenderer.cpp +++ b/tools/PictureRenderer.cpp @@ -87,29 +87,13 @@ void PictureRenderer::resetState() { if (this->isUsingGpuDevice()) { SkGLContext* glContext = fGrContextFactory.getGLContext( GrContextFactory::kNative_GLContextType); - SK_GL(*glContext, Finish()); - } -#endif -} - -void PictureRenderer::finishDraw() { - SkASSERT(fCanvas.get() != NULL); - if (NULL == fCanvas.get()) { - return; - } - - fCanvas->flush(); - -#if SK_SUPPORT_GPU - if (this->isUsingGpuDevice()) { - SkGLContext* glContext = fGrContextFactory.getGLContext( - GrContextFactory::kNative_GLContextType); SkASSERT(glContext != NULL); if (NULL == glContext) { return; } + fGrContext->flush(); SK_GL(*glContext, Finish()); } #endif @@ -131,7 +115,14 @@ bool PictureRenderer::write(const SkString& path) const { return SkImageEncoder::EncodeFile(path.c_str(), bitmap, SkImageEncoder::kPNG_Type, 100); } -void PipePictureRenderer::render() { +void RecordPictureRenderer::render(bool doExtraWorkToDrawToBaseCanvas) { + SkPicture replayer; + SkCanvas* recorder = replayer.beginRecording(fPicture->width(), fPicture->height()); + fPicture->draw(recorder); + replayer.endRecording(); +} + +void PipePictureRenderer::render(bool doExtraWorkToDrawToBaseCanvas) { SkASSERT(fCanvas.get() != NULL); SkASSERT(fPicture != NULL); if (NULL == fCanvas.get() || NULL == fPicture) { @@ -143,10 +134,10 @@ void PipePictureRenderer::render() { SkCanvas* pipeCanvas = writer.startRecording(&pipeController); pipeCanvas->drawPicture(*fPicture); writer.endRecording(); - this->finishDraw(); + fCanvas->flush(); } -void SimplePictureRenderer::render() { +void SimplePictureRenderer::render(bool doExtraWorkToDrawToBaseCanvas) { SkASSERT(fCanvas.get() != NULL); SkASSERT(fPicture != NULL); if (NULL == fCanvas.get() || NULL == fPicture) { @@ -154,7 +145,7 @@ void SimplePictureRenderer::render() { } fCanvas->drawPicture(*fPicture); - this->finishDraw(); + fCanvas->flush(); } TiledPictureRenderer::TiledPictureRenderer() @@ -189,7 +180,7 @@ void TiledPictureRenderer::init(SkPicture* pict) { } } -void TiledPictureRenderer::render() { +void TiledPictureRenderer::render(bool doExtraWorkToDrawToBaseCanvas) { SkASSERT(fCanvas.get() != NULL); SkASSERT(fPicture != NULL); if (NULL == fCanvas.get() || NULL == fPicture) { @@ -197,8 +188,9 @@ void TiledPictureRenderer::render() { } this->drawTiles(); - this->copyTilesToCanvas(); - this->finishDraw(); + if (doExtraWorkToDrawToBaseCanvas) { + this->copyTilesToCanvas(); + } } void TiledPictureRenderer::end() { @@ -293,6 +285,7 @@ static void DrawTile(void* data) { SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024); TileData* tileData = static_cast<TileData*>(data); tileData->fController->playback(tileData->fCanvas); + tileData->fCanvas->flush(); } TileData::TileData(SkCanvas* canvas, ThreadSafePipeController* controller) @@ -314,6 +307,7 @@ static void DrawClonedTile(void* data) { SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024); CloneData* cloneData = static_cast<CloneData*>(data); cloneData->fCanvas->drawPicture(*cloneData->fClone); + cloneData->fCanvas->flush(); } CloneData::CloneData(SkCanvas* target, SkPicture* clone) @@ -367,30 +361,11 @@ void TiledPictureRenderer::drawTiles() { } else { for (int i = 0; i < fTiles.count(); ++i) { fTiles[i]->drawPicture(*(fPicture)); + fTiles[i]->flush(); } } } -void TiledPictureRenderer::finishDraw() { - for (int i = 0; i < fTiles.count(); ++i) { - fTiles[i]->flush(); - } - -#if SK_SUPPORT_GPU - if (this->isUsingGpuDevice()) { - SkGLContext* glContext = fGrContextFactory.getGLContext( - GrContextFactory::kNative_GLContextType); - - SkASSERT(glContext != NULL); - if (NULL == glContext) { - return; - } - - SK_GL(*glContext, Finish()); - } -#endif -} - void TiledPictureRenderer::copyTilesToCanvas() { for (int i = 0; i < fTiles.count(); ++i) { // Since SkPicture performs a save and restore when being drawn to a @@ -404,6 +379,16 @@ void TiledPictureRenderer::copyTilesToCanvas() { fCanvas->drawBitmap(source, -tile_x_start, -tile_y_start); } + fCanvas->flush(); +} + +void PlaybackCreationRenderer::setup() { + SkCanvas* recorder = fReplayer.beginRecording(fPicture->width(), fPicture->height()); + fPicture->draw(recorder); +} + +void PlaybackCreationRenderer::render(bool doExtraWorkToDrawToBaseCanvas) { + fReplayer.endRecording(); } } diff --git a/tools/PictureRenderer.h b/tools/PictureRenderer.h index c901903cfe..afcd7f08b0 100644 --- a/tools/PictureRenderer.h +++ b/tools/PictureRenderer.h @@ -8,9 +8,11 @@ #ifndef PictureRenderer_DEFINED #define PictureRenderer_DEFINED #include "SkMath.h" +#include "SkPicture.h" #include "SkTypes.h" #include "SkTDArray.h" #include "SkRefCnt.h" +#include "SkString.h" #if SK_SUPPORT_GPU #include "GrContextFactory.h" @@ -20,8 +22,6 @@ class SkBitmap; class SkCanvas; class SkGLContext; -class SkPicture; -class SkString; namespace sk_tools { @@ -35,7 +35,23 @@ public: }; virtual void init(SkPicture* pict); - virtual void render() = 0; + + /** + * Perform any setup that should done prior to each iteration of render() which should not be + * timed. + */ + virtual void setup() {} + + /** + * Perform work that is to be timed. Typically this is rendering, but is also used for recording + * and preparing picture for playback by the subclasses which do those. + * @param doExtraWorkToDrawToBaseCanvas Perform extra work to draw to fCanvas. Some subclasses + * will automatically draw to fCanvas, but in the tiled + * case, for example, true needs to be passed so that + * the tiles will be stitched together on fCanvas. + */ + virtual void render(bool doExtraWorkToDrawToBaseCanvas) = 0; + virtual void end(); void resetState(); @@ -47,6 +63,10 @@ public: return kBitmap_DeviceType == fDeviceType; } + virtual SkString getPerIterTimeFormat() { return SkString("%.2f"); } + + virtual SkString getNormalTimeFormat() { return SkString("%6.2f"); } + #if SK_SUPPORT_GPU bool isUsingGpuDevice() { return kGPU_DeviceType == fDeviceType; @@ -72,7 +92,6 @@ public: bool write(const SkString& path) const; protected: - virtual void finishDraw(); SkCanvas* setupCanvas(); SkCanvas* setupCanvas(int width, int height); @@ -89,9 +108,21 @@ private: typedef SkRefCnt INHERITED; }; +/** + * This class does not do any rendering, but its render function executes recording, which we want + * to time. + */ +class RecordPictureRenderer : public PictureRenderer { + virtual void render(bool doExtraWorkToDrawToBaseCanvas) SK_OVERRIDE; + + virtual SkString getPerIterTimeFormat() SK_OVERRIDE { return SkString("%.4f"); } + + virtual SkString getNormalTimeFormat() SK_OVERRIDE { return SkString("%6.4f"); } +}; + class PipePictureRenderer : public PictureRenderer { public: - virtual void render() SK_OVERRIDE; + virtual void render(bool doExtraWorkToDrawToBaseCanvas) SK_OVERRIDE; private: typedef PictureRenderer INHERITED; @@ -99,7 +130,7 @@ private: class SimplePictureRenderer : public PictureRenderer { public: - virtual void render () SK_OVERRIDE; + virtual void render(bool doExtraWorkToDrawToBaseCanvas) SK_OVERRIDE; private: typedef PictureRenderer INHERITED; @@ -110,7 +141,7 @@ public: TiledPictureRenderer(); virtual void init(SkPicture* pict) SK_OVERRIDE; - virtual void render() SK_OVERRIDE; + virtual void render(bool doExtraWorkToDrawToBaseCanvas) SK_OVERRIDE; virtual void end() SK_OVERRIDE; void drawTiles(); @@ -181,9 +212,6 @@ public: ~TiledPictureRenderer(); -protected: - virtual void finishDraw(); - private: bool fMultiThreaded; bool fUsePipe; @@ -209,6 +237,25 @@ private: typedef PictureRenderer INHERITED; }; +/** + * This class does not do any rendering, but its render function executes turning an SkPictureRecord + * into an SkPicturePlayback, which we want to time. + */ +class PlaybackCreationRenderer : public PictureRenderer { +public: + virtual void setup() SK_OVERRIDE; + + virtual void render(bool doExtraWorkToDrawToBaseCanvas) SK_OVERRIDE; + + virtual SkString getPerIterTimeFormat() SK_OVERRIDE { return SkString("%.4f"); } + + virtual SkString getNormalTimeFormat() SK_OVERRIDE { return SkString("%6.4f"); } + +private: + SkPicture fReplayer; + typedef PictureRenderer INHERITED; +}; + } #endif // PictureRenderer_DEFINED diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp index 084a971acd..b51eaa20d1 100644 --- a/tools/bench_pictures_main.cpp +++ b/tools/bench_pictures_main.cpp @@ -7,6 +7,7 @@ #include "BenchTimer.h" #include "PictureBenchmark.h" +#include "SkBenchLogger.h" #include "SkCanvas.h" #include "SkMath.h" #include "SkOSFile.h" @@ -22,9 +23,10 @@ static void usage(const char* argv0) { SkDebugf("\n" "Usage: \n" " %s <inputDir>...\n" +" [--logFile filename]\n" " [--repeat] \n" " [--mode pow2tile minWidth height[] (multi) | record | simple\n" -" | tile width[] height[] (multi) | unflatten]\n" +" | tile width[] height[] (multi) | playbackCreation]\n" " [--pipe]\n" " [--device bitmap" #if SK_SUPPORT_GPU @@ -35,10 +37,11 @@ static void usage(const char* argv0) { SkDebugf("\n\n"); SkDebugf( " inputDir: A list of directories and files to use as input. Files are\n" -" expected to have the .skp extension.\n\n"); +" expected to have the .skp extension.\n\n" +" --logFile filename : destination for writing log output, in addition to stdout.\n"); SkDebugf( " --mode pow2tile minWidht height[] (multi) | record | simple\n" -" | tile width[] height[] (multi) | unflatten:\n" +" | tile width[] height[] (multi) | playbackCreation:\n" " Run in the corresponding mode.\n" " Default is simple.\n"); SkDebugf( @@ -63,7 +66,7 @@ static void usage(const char* argv0) { " Append \"multi\" for multithreaded\n" " drawing.\n"); SkDebugf( -" unflatten, Benchmark picture unflattening.\n"); +" playbackCreation, Benchmark creation of the SkPicturePlayback.\n"); SkDebugf("\n"); SkDebugf( " --pipe: Benchmark SkGPipe rendering. Compatible with tiled, multithreaded rendering.\n"); @@ -86,13 +89,17 @@ static void usage(const char* argv0) { " Default is %i.\n", DEFAULT_REPEATS); } +SkBenchLogger gLogger; + static void run_single_benchmark(const SkString& inputPath, sk_tools::PictureBenchmark& benchmark) { SkFILEStream inputStream; inputStream.setPath(inputPath.c_str()); if (!inputStream.isValid()) { - SkDebugf("Could not open file %s\n", inputPath.c_str()); + SkString err; + err.printf("Could not open file %s\n", inputPath.c_str()); + gLogger.logError(err); return; } @@ -104,7 +111,7 @@ static void run_single_benchmark(const SkString& inputPath, SkString result; result.printf("running bench [%i %i] %s ", picture.width(), picture.height(), filename.c_str()); - sk_tools::print_msg(result.c_str()); + gLogger.logProgress(result); benchmark.run(&picture); } @@ -118,6 +125,14 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* sk_tools::PictureRenderer::SkDeviceTypes deviceType = sk_tools::PictureRenderer::kBitmap_DeviceType; + // Create a string to show our current settings. + // TODO: Make it prettier. Currently it just repeats the command line. + SkString commandLine("bench_pictures:"); + for (int i = 1; i < argc; i++) { + commandLine.appendf(" %s", *(argv+i)); + } + commandLine.append("\n"); + bool usePipe = false; bool multiThreaded = false; bool useTiles = false; @@ -132,23 +147,38 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* repeats = atoi(*argv); if (repeats < 1) { SkDELETE(benchmark); - SkDebugf("--repeat must be given a value > 0\n"); + gLogger.logError("--repeat must be given a value > 0\n"); exit(-1); } } else { SkDELETE(benchmark); - SkDebugf("Missing arg for --repeat\n"); + gLogger.logError("Missing arg for --repeat\n"); usage(argv0); exit(-1); } } else if (0 == strcmp(*argv, "--pipe")) { usePipe = true; + } else if (0 == strcmp(*argv, "--logFile")) { + argv++; + if (argv < stop) { + if (!gLogger.SetLogFile(*argv)) { + SkString str; + str.printf("Could not open %s for writing.", *argv); + gLogger.logError(str); + usage(argv0); + exit(-1); + } + } else { + gLogger.logError("Missing arg for --logFile\n"); + usage(argv0); + exit(-1); + } } else if (0 == strcmp(*argv, "--mode")) { SkDELETE(benchmark); ++argv; if (argv >= stop) { - SkDebugf("Missing mode for --mode\n"); + gLogger.logError("Missing mode for --mode\n"); usage(argv0); exit(-1); } @@ -167,7 +197,9 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* ++argv; if (argv >= stop) { - SkDebugf("Missing width for --mode %s\n", mode); + SkString err; + err.printf("Missing width for --mode %s\n", mode); + gLogger.logError(err); usage(argv0); exit(-1); } @@ -175,7 +207,7 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* widthString = *argv; ++argv; if (argv >= stop) { - SkDebugf("Missing height for --mode tile\n"); + gLogger.logError("Missing height for --mode tile\n"); usage(argv0); exit(-1); } @@ -187,17 +219,19 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* } else { --argv; } - } else if (0 == strcmp(*argv, "unflatten")) { - benchmark = SkNEW(sk_tools::UnflattenPictureBenchmark); + } else if (0 == strcmp(*argv, "playbackCreation")) { + benchmark = SkNEW(sk_tools::PlaybackCreationBenchmark); } else { - SkDebugf("%s is not a valid mode for --mode\n", *argv); + SkString err; + err.printf("%s is not a valid mode for --mode\n", *argv); + gLogger.logError(err); usage(argv0); exit(-1); } } else if (0 == strcmp(*argv, "--device")) { ++argv; if (argv >= stop) { - SkDebugf("Missing mode for --deivce\n"); + gLogger.logError("Missing mode for --deivce\n"); usage(argv0); exit(-1); } @@ -211,7 +245,9 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* } #endif else { - SkDebugf("%s is not a valid mode for --device\n", *argv); + SkString err; + err.printf("%s is not a valid mode for --device\n", *argv); + gLogger.logError(err); usage(argv0); exit(-1); } @@ -231,8 +267,10 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* int minWidth = atoi(widthString); if (!SkIsPow2(minWidth) || minWidth < 0) { SkDELETE(tileBenchmark); - SkDebugf("--mode %s must be given a width" + SkString err; + err.printf("--mode %s must be given a width" " value that is a power of two\n", mode); + gLogger.logError(err); exit(-1); } tileBenchmark->setTileMinPowerOf2Width(minWidth); @@ -240,14 +278,14 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* tileBenchmark->setTileWidthPercentage(atof(widthString)); if (!(tileBenchmark->getTileWidthPercentage() > 0)) { SkDELETE(tileBenchmark); - SkDebugf("--mode tile must be given a width percentage > 0\n"); + gLogger.logError("--mode tile must be given a width percentage > 0\n"); exit(-1); } } else { tileBenchmark->setTileWidth(atoi(widthString)); if (!(tileBenchmark->getTileWidth() > 0)) { SkDELETE(tileBenchmark); - SkDebugf("--mode tile must be given a width > 0\n"); + gLogger.logError("--mode tile must be given a width > 0\n"); exit(-1); } } @@ -256,14 +294,14 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* tileBenchmark->setTileHeightPercentage(atof(heightString)); if (!(tileBenchmark->getTileHeightPercentage() > 0)) { SkDELETE(tileBenchmark); - SkDebugf("--mode tile must be given a height percentage > 0\n"); + gLogger.logError("--mode tile must be given a height percentage > 0\n"); exit(-1); } } else { tileBenchmark->setTileHeight(atoi(heightString)); if (!(tileBenchmark->getTileHeight() > 0)) { SkDELETE(tileBenchmark); - SkDebugf("--mode tile must be given a height > 0\n"); + gLogger.logError("--mode tile must be given a height > 0\n"); exit(-1); } } @@ -286,6 +324,9 @@ static void parse_commandline(int argc, char* const argv[], SkTArray<SkString>* benchmark->setRepeats(repeats); benchmark->setDeviceType(deviceType); + benchmark->setLogger(&gLogger); + // Report current settings: + gLogger.logProgress(commandLine); } static void process_input(const SkString& input, sk_tools::PictureBenchmark& benchmark) { diff --git a/tools/picture_utils.cpp b/tools/picture_utils.cpp index fb5f37cbc3..b9bedbb504 100644 --- a/tools/picture_utils.cpp +++ b/tools/picture_utils.cpp @@ -85,13 +85,6 @@ namespace sk_tools { return skString.endsWith("%"); } - // This copies how bench does printing of test results. -#ifdef SK_BUILD_FOR_ANDROID - void print_msg(const char msg[]) { SkDebugf("%s", msg); } -#else - void print_msg(const char msg[]) { printf("%s", msg); } -#endif - void setup_bitmap(SkBitmap* bitmap, int width, int height) { bitmap->setConfig(SkBitmap::kARGB_8888_Config, width, height); bitmap->allocPixels(); diff --git a/tools/picture_utils.h b/tools/picture_utils.h index bbde7f2789..cca9431238 100644 --- a/tools/picture_utils.h +++ b/tools/picture_utils.h @@ -36,11 +36,6 @@ namespace sk_tools { // Returns true if the string ends with % bool is_percentage(const char* const string); - // Prints to STDOUT so that test results can be easily seperated from the - // error stream. Note, that this still prints to the same stream as SkDebugf - // on Andoid. - void print_msg(const char msg[]); - // Prepares the bitmap so that it can be written. // // Specifically, it configures the bitmap, allocates pixels and then diff --git a/tools/render_pictures_main.cpp b/tools/render_pictures_main.cpp index ec0969659e..186a214512 100644 --- a/tools/render_pictures_main.cpp +++ b/tools/render_pictures_main.cpp @@ -104,7 +104,9 @@ static void render_picture(const SkString& inputPath, const SkString& outputDir, renderer.init(&picture); - renderer.render(); + renderer.render(true); + + renderer.resetState(); write_output(outputDir, inputFilename, renderer); |