diff options
-rw-r--r-- | bench/ResultsWriter.cpp | 33 | ||||
-rw-r--r-- | bench/ResultsWriter.h | 26 | ||||
-rw-r--r-- | bench/TimerData.cpp | 86 | ||||
-rw-r--r-- | bench/TimerData.h | 15 | ||||
-rw-r--r-- | gyp/bench.gyp | 1 | ||||
-rw-r--r-- | gyp/tools.gyp | 22 | ||||
-rw-r--r-- | tools/PictureBenchmark.cpp | 67 | ||||
-rw-r--r-- | tools/PictureBenchmark.h | 8 | ||||
-rw-r--r-- | tools/PictureResultsWriter.h | 232 | ||||
-rw-r--r-- | tools/bench_pictures_main.cpp | 25 |
10 files changed, 439 insertions, 76 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..ba682f0e24 100644 --- a/bench/TimerData.cpp +++ b/bench/TimerData.cpp @@ -5,7 +5,6 @@ * 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" @@ -140,3 +139,88 @@ SkString TimerData::getResult(const char* doubleFormat, } return str; } + +#ifdef SK_BUILD_JSON_WRITER +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; +} +#endif // SK_BUILD_JSON_WRITER diff --git a/bench/TimerData.h b/bench/TimerData.h index ed0ee473c1..8f6a7194ab 100644 --- a/bench/TimerData.h +++ b/bench/TimerData.h @@ -12,6 +12,16 @@ #include "SkString.h" #include "SkTemplates.h" +#ifdef SK_BUILD_FOR_WIN + #pragma warning(push) + #pragma warning(disable : 4530) +#endif + +#include "SkJSONCPP.h" + +#ifdef SK_BUILD_FOR_WIN + #pragma warning(pop) +#endif class BenchTimer; @@ -58,6 +68,11 @@ public: const char* configName, uint32_t timerFlags, int itersPerTiming = 1); +#ifdef SK_BUILD_JSON_WRITER + Json::Value getJSON(uint32_t timerFlags, + Result result, + int itersPerTiming = 1); +#endif // SK_BUILD_JSON_WRITER 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..cd184153d5 100644 --- a/gyp/tools.gyp +++ b/gyp/tools.gyp @@ -286,12 +286,12 @@ 'target_name': 'bench_pictures', 'type': 'executable', 'sources': [ + '../bench/ResultsWriter.cpp', + '../tools/PictureBenchmark.cpp', + '../tools/PictureResultsWriter.h', '../bench/SkBenchLogger.h', '../bench/SkBenchLogger.cpp', - '../bench/TimerData.h', - '../bench/TimerData.cpp', '../tools/bench_pictures_main.cpp', - '../tools/PictureBenchmark.cpp', ], 'include_dirs': [ '../src/core/', @@ -301,9 +301,11 @@ 'dependencies': [ 'bench.gyp:bench_timer', 'flags.gyp:flags', + 'jsoncpp.gyp:jsoncpp', 'skia_lib.gyp:skia_lib', 'tools.gyp:picture_utils', 'tools.gyp:picture_renderer', + 'tools.gyp:timer_data', ], }, { @@ -505,12 +507,11 @@ '../tools/bbh_shootout.cpp', # Bench code: - '../bench/TimerData.h', - '../bench/TimerData.cpp', ], 'dependencies': [ 'bench.gyp:bench_timer', 'flags.gyp:flags', + 'tools.gyp:timer_data', 'skia_lib.gyp:skia_lib', 'tools.gyp:picture_renderer', 'tools.gyp:picture_utils', @@ -549,6 +550,17 @@ 'skia_lib.gyp:skia_lib', ], }, + { + 'target_name': 'timer_data', + 'type': 'static_library', + 'sources': [ + '../bench/TimerData.cpp', + ], + 'dependencies': [ + 'skia_lib.gyp:skia_lib', + 'jsoncpp.gyp:jsoncpp' + ] + } ], 'conditions': [ ['skia_shared_lib', 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; } |