2014-05-29 17:10:24 +00:00
|
|
|
/*
|
|
|
|
* 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(
|
2014-05-30 03:06:10 +00:00
|
|
|
TimerData* data,
|
|
|
|
const char format[],
|
2014-05-29 17:10:24 +00:00
|
|
|
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:
|
2014-05-30 03:06:10 +00:00
|
|
|
PictureResultsMultiWriter()
|
2014-05-29 17:10:24 +00:00
|
|
|
: 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(
|
2014-05-30 03:06:10 +00:00
|
|
|
TimerData* data,
|
|
|
|
const char format[],
|
2014-05-29 17:10:24 +00:00
|
|
|
const TimerData::Result result,
|
|
|
|
uint32_t timerTypes,
|
|
|
|
int numInnerLoops = 1) {
|
|
|
|
for(int i=0; i<fWriters.count(); ++i) {
|
2014-05-30 03:06:10 +00:00
|
|
|
fWriters[i]->tileData(data, format, result, timerTypes,
|
2014-05-29 17:10:24 +00:00
|
|
|
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
|
|
|
|
*/
|
2014-05-30 03:06:10 +00:00
|
|
|
class PictureResultsLoggerWriter : public PictureResultsWriter {
|
2014-05-29 17:10:24 +00:00
|
|
|
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(
|
2014-05-30 03:06:10 +00:00
|
|
|
TimerData* data,
|
|
|
|
const char format[],
|
2014-05-29 17:10:24 +00:00
|
|
|
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;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* 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),
|
2014-05-30 03:06:10 +00:00
|
|
|
fRoot(),
|
2014-05-29 17:10:24 +00:00
|
|
|
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(
|
2014-05-30 03:06:10 +00:00
|
|
|
TimerData* data,
|
|
|
|
const char format[],
|
2014-05-29 17:10:24 +00:00
|
|
|
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
|