aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/SkBenchLogger.cpp30
-rw-r--r--bench/SkBenchLogger.h77
-rw-r--r--bench/TimerData.cpp108
-rw-r--r--bench/TimerData.h46
-rw-r--r--bench/benchmain.cpp149
-rw-r--r--gyp/bench.gypi5
-rw-r--r--gyp/tools.gyp25
-rw-r--r--tools/PictureBenchmark.cpp227
-rw-r--r--tools/PictureBenchmark.h64
-rw-r--r--tools/PictureRenderer.cpp73
-rw-r--r--tools/PictureRenderer.h67
-rw-r--r--tools/bench_pictures_main.cpp83
-rw-r--r--tools/picture_utils.cpp7
-rw-r--r--tools/picture_utils.h5
-rw-r--r--tools/render_pictures_main.cpp4
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);