| Index: tools/PictureResultsWriter.h | 
| diff --git a/tools/PictureResultsWriter.h b/tools/PictureResultsWriter.h | 
| new file mode 100644 | 
| index 0000000000000000000000000000000000000000..0571e80d056031a00398e4db0e18d7a88d57f15f | 
| --- /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 | 
|  |