aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/ResultsWriter.cpp33
-rw-r--r--bench/ResultsWriter.h26
-rw-r--r--bench/TimerData.cpp83
-rw-r--r--bench/TimerData.h4
-rw-r--r--gyp/bench.gyp1
-rw-r--r--gyp/tools.gyp1
-rw-r--r--tools/PictureBenchmark.cpp67
-rw-r--r--tools/PictureBenchmark.h8
-rw-r--r--tools/PictureResultsWriter.h232
-rw-r--r--tools/bench_pictures_main.cpp25
10 files changed, 410 insertions, 70 deletions
diff --git a/bench/ResultsWriter.cpp b/bench/ResultsWriter.cpp
new file mode 100644
index 0000000000..0bfcba8b1e
--- /dev/null
+++ b/bench/ResultsWriter.cpp
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Helper functions for result writing operations.
+ */
+
+#include "ResultsWriter.h"
+
+#ifdef SK_BUILD_JSON_WRITER
+
+Json::Value* SkFindNamedNode(Json::Value* root, const char name[]) {
+ Json::Value* search_results = NULL;
+ for(Json::Value::iterator iter = root->begin();
+ iter!= root->end(); ++iter) {
+ if(SkString(name).equals((*iter)["name"].asCString())) {
+ search_results = &(*iter);
+ break;
+ }
+ }
+
+ if(search_results != NULL) {
+ return search_results;
+ } else {
+ Json::Value* new_val = &(root->append(Json::Value()));
+ (*new_val)["name"] = name;
+ return new_val;
+ }
+}
+
+#endif // SK_BUILD_JSON_WRITER
diff --git a/bench/ResultsWriter.h b/bench/ResultsWriter.h
index a9eef802bd..c66593864f 100644
--- a/bench/ResultsWriter.h
+++ b/bench/ResultsWriter.h
@@ -101,26 +101,9 @@ private:
* },
* ...
*/
-class JSONResultsWriter : public ResultsWriter {
-private:
- Json::Value* find_named_node(Json::Value* root, const char name[]) {
- Json::Value* search_results = NULL;
- for(Json::Value::iterator iter = root->begin();
- iter!= root->end(); ++iter) {
- if(SkString(name).equals((*iter)["name"].asCString())) {
- search_results = &(*iter);
- break;
- }
- }
- if(search_results != NULL) {
- return search_results;
- } else {
- Json::Value* new_val = &(root->append(Json::Value()));
- (*new_val)["name"] = name;
- return new_val;
- }
- }
+Json::Value* SkFindNamedNode(Json::Value* root, const char name[]);
+class JSONResultsWriter : public ResultsWriter {
public:
explicit JSONResultsWriter(const char filename[])
: fFilename(filename)
@@ -138,12 +121,12 @@ public:
sk_name.appendS32(x);
sk_name.append("_");
sk_name.appendS32(y);
- Json::Value* bench_node = find_named_node(&fResults, sk_name.c_str());
+ Json::Value* bench_node = SkFindNamedNode(&fResults, sk_name.c_str());
fBench = &(*bench_node)["results"];
}
virtual void config(const char name[]) {
SkASSERT(NULL != fBench);
- fConfig = find_named_node(fBench, name);
+ fConfig = SkFindNamedNode(fBench, name);
}
virtual void timer(const char name[], double ms) {
SkASSERT(NULL != fConfig);
@@ -164,6 +147,7 @@ private:
};
#endif // SK_BUILD_JSON_WRITER
+
/**
* This ResultsWriter writes out to multiple ResultsWriters.
*/
diff --git a/bench/TimerData.cpp b/bench/TimerData.cpp
index a86f29394f..f72319e761 100644
--- a/bench/TimerData.cpp
+++ b/bench/TimerData.cpp
@@ -140,3 +140,86 @@ SkString TimerData::getResult(const char* doubleFormat,
}
return str;
}
+
+Json::Value TimerData::getJSON(uint32_t timerFlags,
+ Result result,
+ int itersPerTiming) {
+ SkASSERT(itersPerTiming >= 1);
+ Json::Value dataNode;
+ Json::Value wallNode, truncWall, cpuNode, truncCpu, gpuNode;
+ if (!fCurrTiming) {
+ return dataNode;
+ }
+
+ int numTimings = fCurrTiming;
+
+ double wallMin = std::numeric_limits<double>::max();
+ double truncWallMin = std::numeric_limits<double>::max();
+ double cpuMin = std::numeric_limits<double>::max();
+ double truncCpuMin = std::numeric_limits<double>::max();
+ double gpuMin = std::numeric_limits<double>::max();
+
+ double wallSum = 0;
+ double truncWallSum = 0;
+ double cpuSum = 0;
+ double truncCpuSum = 0;
+ double gpuSum = 0;
+
+ for (int i = 0; i < numTimings; ++i) {
+ if (kPerIter_Result == result) {
+ wallNode.append(fWallTimes[i] / itersPerTiming);
+ truncWall.append(fTruncatedWallTimes[i] / itersPerTiming);
+ cpuNode.append(fCpuTimes[i] / itersPerTiming);
+ truncCpu.append(fTruncatedCpuTimes[i] / itersPerTiming);
+ gpuNode.append(fGpuTimes[i] / itersPerTiming);
+ } else if (kMin_Result == result) {
+ wallMin = SkTMin(wallMin, fWallTimes[i]);
+ truncWallMin = SkTMin(truncWallMin, fTruncatedWallTimes[i]);
+ cpuMin = SkTMin(cpuMin, fCpuTimes[i]);
+ truncCpuMin = SkTMin(truncCpuMin, fTruncatedCpuTimes[i]);
+ gpuMin = SkTMin(gpuMin, fGpuTimes[i]);
+ } else {
+ SkASSERT(kAvg_Result == result);
+ wallSum += fWallTimes[i];
+ truncWallSum += fTruncatedWallTimes[i];
+ cpuSum += fCpuTimes[i];
+ truncCpuSum += fTruncatedCpuTimes[i];
+ }
+
+ // We always track the GPU sum because whether it is non-zero indicates if valid gpu times
+ // were recorded at all.
+ gpuSum += fGpuTimes[i];
+ }
+
+ if (kMin_Result == result) {
+ wallNode.append(wallMin / itersPerTiming);
+ truncWall.append(truncWallMin / itersPerTiming);
+ cpuNode.append(cpuMin / itersPerTiming);
+ truncCpu.append(truncCpuMin / itersPerTiming);
+ gpuNode.append(gpuMin / itersPerTiming);
+ } else if (kAvg_Result == result) {
+ int divisor = numTimings * itersPerTiming;
+ wallNode.append(wallSum / divisor);
+ truncWall.append(truncWallSum / divisor);
+ cpuNode.append(cpuSum / divisor);
+ truncCpu.append(truncCpuSum / divisor);
+ gpuNode.append(gpuSum / divisor);
+ }
+
+ if (timerFlags & kWall_Flag) {
+ dataNode["wall"] = wallNode;
+ }
+ if (timerFlags & kTruncatedWall_Flag) {
+ dataNode["truncWall"] = truncWall;
+ }
+ if (timerFlags & kCpu_Flag) {
+ dataNode["cpu"] = cpuNode;
+ }
+ if (timerFlags & kTruncatedCpu_Flag) {
+ dataNode["trucCpu"] = truncCpu;
+ }
+ if ((timerFlags & kGpu_Flag) && gpuSum > 0) {
+ dataNode["gpu"] = gpuNode;
+ }
+ return dataNode;
+}
diff --git a/bench/TimerData.h b/bench/TimerData.h
index ed0ee473c1..50539c7522 100644
--- a/bench/TimerData.h
+++ b/bench/TimerData.h
@@ -9,6 +9,7 @@
#ifndef TimerData_DEFINED
#define TimerData_DEFINED
+#include "SkJSONCPP.h"
#include "SkString.h"
#include "SkTemplates.h"
@@ -58,6 +59,9 @@ public:
const char* configName,
uint32_t timerFlags,
int itersPerTiming = 1);
+ Json::Value getJSON(uint32_t timerFlags,
+ Result result,
+ int itersPerTiming = 1);
private:
int fMaxNumTimings;
diff --git a/gyp/bench.gyp b/gyp/bench.gyp
index 553c0e72cd..651ee15652 100644
--- a/gyp/bench.gyp
+++ b/gyp/bench.gyp
@@ -15,6 +15,7 @@
'jsoncpp.gyp:jsoncpp',
],
'sources': [
+ '../bench/ResultsWriter.cpp',
'../bench/SkBenchLogger.cpp',
'../bench/SkBenchLogger.h',
'../bench/SkGMBench.cpp',
diff --git a/gyp/tools.gyp b/gyp/tools.gyp
index 63c2fbfb6e..4fc7505cd6 100644
--- a/gyp/tools.gyp
+++ b/gyp/tools.gyp
@@ -286,6 +286,7 @@
'target_name': 'bench_pictures',
'type': 'executable',
'sources': [
+ '../bench/ResultsWriter.cpp',
'../bench/SkBenchLogger.h',
'../bench/SkBenchLogger.cpp',
'../bench/TimerData.h',
diff --git a/tools/PictureBenchmark.cpp b/tools/PictureBenchmark.cpp
index 6c0325e2ee..f1d00035cc 100644
--- a/tools/PictureBenchmark.cpp
+++ b/tools/PictureBenchmark.cpp
@@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
-#include "SkBenchLogger.h"
#include "BenchTimer.h"
#include "PictureBenchmark.h"
#include "SkCanvas.h"
@@ -17,13 +16,13 @@ namespace sk_tools {
PictureBenchmark::PictureBenchmark()
: fRepeats(1)
-, fLogger(NULL)
, fRenderer(NULL)
, fTimerResult(TimerData::kAvg_Result)
, fTimerTypes(0)
, fTimeIndividualTiles(false)
, fPurgeDecodedTex(false)
, fPreprocess(false)
+, fWriter(NULL)
{}
PictureBenchmark::~PictureBenchmark() {
@@ -52,12 +51,6 @@ BenchTimer* PictureBenchmark::setupTimer(bool useGLTimer) {
return SkNEW_ARGS(BenchTimer, (NULL));
}
-void PictureBenchmark::logProgress(const char msg[]) {
- if (fLogger != NULL) {
- fLogger->logProgress(msg);
- }
-}
-
PictureRenderer* PictureBenchmark::setRenderer(sk_tools::PictureRenderer* renderer) {
SkRefCnt_SafeAssign(fRenderer, renderer);
return renderer;
@@ -137,10 +130,6 @@ void PictureBenchmark::run(SkPicture* pict) {
return;
}
- // Insert a newline so that each tile is reported on its own line (separate from the line
- // that describes the skp being run).
- this->logProgress("\n");
-
int x, y;
while (tiledRenderer->nextTile(x, y)) {
// There are two timers, which will behave slightly differently:
@@ -184,8 +173,8 @@ void PictureBenchmark::run(SkPicture* pict) {
SkAssertResult(longRunningTimerData.appendTimes(longRunningTimer.get()));
}
- SkString configName = tiledRenderer->getConfigName();
- configName.appendf(": tile [%i,%i] out of [%i,%i]", x, y, xTiles, yTiles);
+ fWriter->tileConfig(tiledRenderer->getConfigName());
+ fWriter->tileMeta(x, y, xTiles, yTiles);
// TODO(borenet): Turn off per-iteration tile time reporting for now.
// Avoiding logging the time for every iteration for each tile cuts
@@ -193,22 +182,23 @@ void PictureBenchmark::run(SkPicture* pict) {
// we're loading the bench data directly into a data store and are no
// longer generating SVG graphs.
#if 0
- SkString result = perTileTimerData.getResult(timeFormat.c_str(), fTimerResult,
- configName.c_str(), timerTypes);
- result.append("\n");
- this->logProgress(result.c_str());
+ fWriter->tileData(
+ &perTileTimerData,
+ timeFormat.c_str(),
+ fTimerResult,
+ timerTypes);
#endif
if (fPurgeDecodedTex) {
- configName.append(" <withPurging>");
+ fWriter->addTileFlag(PictureResultsWriter::kPurging);
}
- configName.append(" <averaged>");
- SkString longRunningResult = longRunningTimerData.getResult(
+ fWriter->addTileFlag(PictureResultsWriter::kAvg);
+ fWriter->tileData(
+ &longRunningTimerData,
tiledRenderer->getNormalTimeFormat().c_str(),
TimerData::kAvg_Result,
- configName.c_str(), timerTypes, numInnerLoops);
- longRunningResult.append("\n");
- this->logProgress(longRunningResult.c_str());
+ timerTypes,
+ numInnerLoops);
}
} else {
SkAutoTDelete<BenchTimer> longRunningTimer(this->setupTimer());
@@ -246,29 +236,26 @@ void PictureBenchmark::run(SkPicture* pict) {
SkAssertResult(longRunningTimerData.appendTimes(longRunningTimer.get()));
}
- SkString configName = fRenderer->getConfigName();
+ fWriter->tileConfig(fRenderer->getConfigName());
if (fPurgeDecodedTex) {
- configName.append(" <withPurging>");
+ fWriter->addTileFlag(PictureResultsWriter::kPurging);
}
// Beware - since the per-run-timer doesn't ever include a glFinish it can
// report a lower time then the long-running-timer
#if 0
- SkString result = perRunTimerData.getResult(timeFormat.c_str(),
- fTimerResult,
- configName.c_str(),
- timerTypes);
- result.append("\n");
-
- this->logProgress(result.c_str());
+ fWriter->tileData(
+ &perRunTimerData,
+ timeFormat.c_str(),
+ fTimerResult,
+ timerTypes);
#else
- SkString result = longRunningTimerData.getResult(timeFormat.c_str(),
- fTimerResult,
- configName.c_str(),
- timerTypes,
- numInnerLoops);
- result.append("\n");
- this->logProgress(result.c_str());
+ fWriter->tileData(
+ &longRunningTimerData,
+ timeFormat.c_str(),
+ fTimerResult,
+ timerTypes,
+ numInnerLoops);
#endif
}
diff --git a/tools/PictureBenchmark.h b/tools/PictureBenchmark.h
index e149f8c9e9..3ec3c6691c 100644
--- a/tools/PictureBenchmark.h
+++ b/tools/PictureBenchmark.h
@@ -11,6 +11,7 @@
#include "SkTypes.h"
#include "PictureRenderer.h"
#include "TimerData.h"
+#include "PictureResultsWriter.h"
class BenchTimer;
class SkBenchLogger;
@@ -27,7 +28,7 @@ public:
/**
* Draw the provided SkPicture fRepeats times while collecting timing data, and log the output
- * via fLogger.
+ * via fWriter.
*/
void run(SkPicture* pict);
@@ -55,11 +56,10 @@ public:
void setTimersToShow(bool wall, bool truncatedWall, bool cpu, bool truncatedCpu, bool gpu);
- void setLogger(SkBenchLogger* logger) { fLogger = logger; }
+ void setWriter(PictureResultsWriter* writer) { fWriter = writer; }
private:
int fRepeats;
- SkBenchLogger* fLogger;
PictureRenderer* fRenderer;
TimerData::Result fTimerResult;
uint32_t fTimerTypes; // bitfield of TimerData::TimerFlags values
@@ -67,7 +67,7 @@ private:
bool fPurgeDecodedTex;
bool fPreprocess;
- void logProgress(const char msg[]);
+ PictureResultsWriter* fWriter;
BenchTimer* setupTimer(bool useGLTimer = true);
};
diff --git a/tools/PictureResultsWriter.h b/tools/PictureResultsWriter.h
new file mode 100644
index 0000000000..0571e80d05
--- /dev/null
+++ b/tools/PictureResultsWriter.h
@@ -0,0 +1,232 @@
+/*
+ * Copyright 2014 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ *
+ * Classes for writing out bench results in various formats.
+ */
+#ifndef SkPictureResultsWriter_DEFINED
+#define SkPictureResultsWriter_DEFINED
+
+#include "ResultsWriter.h"
+#include "SkBenchLogger.h"
+#include "SkJSONCPP.h"
+#include "SkStream.h"
+#include "SkString.h"
+#include "SkTArray.h"
+
+/**
+ * Base class for writing picture bench results.
+ */
+class PictureResultsWriter : SkNoncopyable {
+public:
+ enum TileFlags {kPurging, kAvg};
+
+ PictureResultsWriter() {}
+ virtual ~PictureResultsWriter() {}
+
+ virtual void bench(const char name[], int32_t x, int32_t y) = 0;
+ virtual void tileConfig(SkString configName) = 0;
+ virtual void tileMeta(int x, int y, int tx, int ty) = 0;
+ virtual void addTileFlag(PictureResultsWriter::TileFlags flag) = 0;
+ virtual void tileData(
+ TimerData* data,
+ const char format[],
+ const TimerData::Result result,
+ uint32_t timerTypes,
+ int numInnerLoops = 1) = 0;
+ virtual void end() = 0;
+};
+
+/**
+ * This class allows bench data to be piped into multiple
+ * PictureResultWriter classes. It does not own any classes
+ * passed to it, so the owner is required to manage any classes
+ * passed to PictureResultsMultiWriter */
+class PictureResultsMultiWriter : public PictureResultsWriter {
+public:
+ PictureResultsMultiWriter()
+ : fWriters() {}
+ void add(PictureResultsWriter* newWriter) {
+ fWriters.push_back(newWriter);
+ }
+ virtual ~PictureResultsMultiWriter() {}
+ virtual void bench(const char name[], int32_t x, int32_t y) {
+ for(int i=0; i<fWriters.count(); ++i) {
+ fWriters[i]->bench(name, x, y);
+ }
+ }
+ virtual void tileConfig(SkString configName) {
+ for(int i=0; i<fWriters.count(); ++i) {
+ fWriters[i]->tileConfig(configName);
+ }
+ }
+ virtual void tileMeta(int x, int y, int tx, int ty) {
+ for(int i=0; i<fWriters.count(); ++i) {
+ fWriters[i]->tileMeta(x, y, tx, ty);
+ }
+ }
+ virtual void addTileFlag(PictureResultsWriter::TileFlags flag) {
+ for(int i=0; i<fWriters.count(); ++i) {
+ fWriters[i]->addTileFlag(flag);
+ }
+ }
+ virtual void tileData(
+ TimerData* data,
+ const char format[],
+ const TimerData::Result result,
+ uint32_t timerTypes,
+ int numInnerLoops = 1) {
+ for(int i=0; i<fWriters.count(); ++i) {
+ fWriters[i]->tileData(data, format, result, timerTypes,
+ numInnerLoops);
+ }
+ }
+ virtual void end() {
+ for(int i=0; i<fWriters.count(); ++i) {
+ fWriters[i]->end();
+ }
+ }
+private:
+ SkTArray<PictureResultsWriter*> fWriters;
+};
+
+/**
+ * Writes to SkBenchLogger to mimic original behavior
+ */
+class PictureResultsLoggerWriter : public PictureResultsWriter {
+private:
+ void logProgress(const char str[]) {
+ if(fLogger != NULL) {
+ fLogger->logProgress(str);
+ }
+ }
+public:
+ PictureResultsLoggerWriter(SkBenchLogger* log)
+ : fLogger(log), currentLine() {}
+ virtual void bench(const char name[], int32_t x, int32_t y) {
+ SkString result;
+ result.printf("running bench [%i %i] %s ", x, y, name);
+ this->logProgress(result.c_str());
+ }
+ virtual void tileConfig(SkString configName) {
+ currentLine = configName;
+ }
+ virtual void tileMeta(int x, int y, int tx, int ty) {
+ currentLine.appendf(": tile [%i,%i] out of [%i,%i]", x, y, tx, ty);
+ }
+ virtual void addTileFlag(PictureResultsWriter::TileFlags flag) {
+ if(flag == PictureResultsWriter::kPurging) {
+ currentLine.append(" <withPurging>");
+ } else if(flag == PictureResultsWriter::kAvg) {
+ currentLine.append(" <averaged>");
+ }
+ }
+ virtual void tileData(
+ TimerData* data,
+ const char format[],
+ const TimerData::Result result,
+ uint32_t timerTypes,
+ int numInnerLoops = 1) {
+ SkString results = data->getResult(format, result,
+ currentLine.c_str(), timerTypes, numInnerLoops);
+ results.append("\n");
+ this->logProgress(results.c_str());
+ }
+ virtual void end() {}
+private:
+ SkBenchLogger* fLogger;
+ SkString currentLine;
+};
+
+#ifdef SK_BUILD_JSON_WRITER
+/**
+ * This PictureResultsWriter collects data in a JSON node
+ *
+ * The format is something like
+ * {
+ * benches: [
+ * {
+ * name: "Name_of_test"
+ * tilesets: [
+ * {
+ * name: "Name of the configuration"
+ * tiles: [
+ * {
+ * flags: {
+ * purging: true //Flags for the current tile
+ * // are put here
+ * }
+ * data: {
+ * wsecs: [....] //Actual data ends up here
+ * }
+ * }
+ * ]
+ * }
+ * ]
+ * }
+ * ]
+ * }*/
+
+class PictureJSONResultsWriter : public PictureResultsWriter {
+public:
+ PictureJSONResultsWriter(const char filename[])
+ : fFilename(filename),
+ fRoot(),
+ fCurrentBench(NULL),
+ fCurrentTileSet(NULL),
+ fCurrentTile(NULL) {}
+
+ virtual void bench(const char name[], int32_t x, int32_t y) {
+ SkString sk_name(name);
+ sk_name.append("_");
+ sk_name.appendS32(x);
+ sk_name.append("_");
+ sk_name.appendS32(y);
+ Json::Value* bench_node = SkFindNamedNode(&fRoot["benches"], sk_name.c_str());
+ fCurrentBench = &(*bench_node)["tileSets"];
+ }
+ virtual void tileConfig(SkString configName) {
+ SkASSERT(fCurrentBench != NULL);
+ fCurrentTileSet = SkFindNamedNode(fCurrentBench, configName.c_str());
+ fCurrentTile = &(*fCurrentTileSet)["tiles"][0];
+ }
+ virtual void tileMeta(int x, int y, int tx, int ty) {
+ SkASSERT(fCurrentTileSet != NULL);
+ (*fCurrentTileSet)["tx"] = tx;
+ (*fCurrentTileSet)["ty"] = ty;
+ fCurrentTile = &(*fCurrentTileSet)["tiles"][x+tx*y];
+ }
+ virtual void addTileFlag(PictureResultsWriter::TileFlags flag) {
+ SkASSERT(fCurrentTile != NULL);
+ if(flag == PictureResultsWriter::kPurging) {
+ (*fCurrentTile)["flags"]["purging"] = true;
+ } else if(flag == PictureResultsWriter::kAvg) {
+ (*fCurrentTile)["flags"]["averaged"] = true;
+ }
+ }
+ virtual void tileData(
+ TimerData* data,
+ const char format[],
+ const TimerData::Result result,
+ uint32_t timerTypes,
+ int numInnerLoops = 1) {
+ SkASSERT(fCurrentTile != NULL);
+ (*fCurrentTile)["data"] = data->getJSON(timerTypes, result, numInnerLoops);
+ }
+ virtual void end() {
+ SkFILEWStream stream(fFilename.c_str());
+ stream.writeText(Json::FastWriter().write(fRoot).c_str());
+ stream.flush();
+ }
+private:
+ SkString fFilename;
+ Json::Value fRoot;
+ Json::Value *fCurrentBench;
+ Json::Value *fCurrentTileSet;
+ Json::Value *fCurrentTile;
+};
+#endif // SK_BUILD_JSON_WRITER
+
+#endif
diff --git a/tools/bench_pictures_main.cpp b/tools/bench_pictures_main.cpp
index 5ff519c8c5..b79dfedff2 100644
--- a/tools/bench_pictures_main.cpp
+++ b/tools/bench_pictures_main.cpp
@@ -12,6 +12,7 @@
#include "PictureRenderingFlags.h"
#include "SkBenchLogger.h"
#include "SkCommandLineFlags.h"
+#include "SkData.h"
#include "SkDiscardableMemoryPool.h"
#include "SkGraphics.h"
#include "SkImageDecoder.h"
@@ -20,8 +21,11 @@
#include "SkPicture.h"
#include "SkStream.h"
#include "picture_utils.h"
+#include "PictureResultsWriter.h"
SkBenchLogger gLogger;
+PictureResultsLoggerWriter gLogWriter(&gLogger);
+PictureResultsMultiWriter gWriter;
// Flags used by this file, in alphabetical order.
DEFINE_bool(countRAM, false, "Count the RAM used for bitmap pixels in each skp file");
@@ -35,6 +39,9 @@ DEFINE_string(filter, "",
"Specific flags are listed above.");
DEFINE_string(logFile, "", "Destination for writing log output, in addition to stdout.");
DEFINE_bool(logPerIter, false, "Log each repeat timer instead of mean.");
+#ifdef SK_BUILD_JSON_WRITER
+DEFINE_string(jsonLog, "", "Destination for writing JSON data.");
+#endif
DEFINE_bool(min, false, "Print the minimum times (instead of average).");
DECLARE_int32(multi);
DECLARE_string(readPath);
@@ -187,10 +194,7 @@ static bool run_single_benchmark(const SkString& inputPath,
SkString filename;
sk_tools::get_basename(&filename, inputPath);
- SkString result;
- result.printf("running bench [%i %i] %s ", picture->width(), picture->height(),
- filename.c_str());
- gLogger.logProgress(result);
+ gWriter.bench(filename.c_str(), picture->width(), picture->height());
benchmark.run(picture);
@@ -360,7 +364,7 @@ static void setup_benchmark(sk_tools::PictureBenchmark* benchmark) {
}
benchmark->setRenderer(renderer);
benchmark->setRepeats(FLAGS_repeat);
- benchmark->setLogger(&gLogger);
+ benchmark->setWriter(&gWriter);
}
static int process_input(const char* input,
@@ -417,6 +421,16 @@ int tool_main(int argc, char** argv) {
}
}
+#ifdef SK_BUILD_JSON_WRITER
+ SkAutoTDelete<PictureJSONResultsWriter> jsonWriter;
+ if (FLAGS_jsonLog.count() == 1) {
+ jsonWriter.reset(SkNEW(PictureJSONResultsWriter(FLAGS_jsonLog[0])));
+ gWriter.add(jsonWriter.get());
+ }
+
+#endif
+ gWriter.add(&gLogWriter);
+
#if SK_ENABLE_INST_COUNT
gPrintInstCount = true;
@@ -444,6 +458,7 @@ int tool_main(int argc, char** argv) {
(double) gTotalCacheHits / (gTotalCacheHits + gTotalCacheMisses));
}
#endif
+ gWriter.end();
return 0;
}