Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(685)

Side by Side Diff: tools/PictureResultsWriter.h

Issue 329993008: Make SKP bench JSON ouput better (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix stuff Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 * 6 *
7 * Classes for writing out bench results in various formats. 7 * Classes for writing out bench results in various formats.
8 */ 8 */
9 9
10 #ifndef SkPictureResultsWriter_DEFINED 10 #ifndef SkPictureResultsWriter_DEFINED
11 #define SkPictureResultsWriter_DEFINED 11 #define SkPictureResultsWriter_DEFINED
12 12
13
14 #include "PictureRenderer.h"
13 #include "BenchLogger.h" 15 #include "BenchLogger.h"
14 #include "ResultsWriter.h" 16 #include "ResultsWriter.h"
15 #include "SkJSONCPP.h" 17 #include "SkJSONCPP.h"
16 #include "SkStream.h" 18 #include "SkStream.h"
17 #include "SkString.h" 19 #include "SkString.h"
18 #include "SkTArray.h" 20 #include "SkTArray.h"
19 #include "TimerData.h" 21 #include "TimerData.h"
20 22
21 /** 23 /**
22 * Base class for writing picture bench results. 24 * Base class for writing picture bench results.
23 */ 25 */
24 class PictureResultsWriter : SkNoncopyable { 26 class PictureResultsWriter : SkNoncopyable {
25 public: 27 public:
26 enum TileFlags {kPurging, kAvg}; 28 enum TileFlags {kPurging, kAvg};
27 29
28 PictureResultsWriter() {} 30 PictureResultsWriter() {}
29 virtual ~PictureResultsWriter() {} 31 virtual ~PictureResultsWriter() {}
30 32
31 virtual void bench(const char name[], int32_t x, int32_t y) = 0; 33 virtual void bench(const char name[], int32_t x, int32_t y) = 0;
32 virtual void tileConfig(SkString configName) = 0; 34 virtual void logRenderer(sk_tools::PictureRenderer *pr) = 0;
33 virtual void tileMeta(int x, int y, int tx, int ty) = 0; 35 virtual void tileMeta(int x, int y, int tx, int ty) = 0;
34 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) = 0; 36 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) = 0;
35 virtual void tileData( 37 virtual void tileData(
36 TimerData* data, 38 TimerData* data,
37 const char format[], 39 const char format[],
38 const TimerData::Result result, 40 const TimerData::Result result,
39 uint32_t timerTypes, 41 uint32_t timerTypes,
40 int numInnerLoops = 1) = 0; 42 int numInnerLoops = 1) = 0;
41 virtual void end() = 0; 43 virtual void end() = 0;
42 }; 44 };
43 45
44 /** 46 /**
45 * This class allows bench data to be piped into multiple 47 * This class allows bench data to be piped into multiple
46 * PictureResultWriter classes. It does not own any classes 48 * PictureResultWriter classes. It does not own any classes
47 * passed to it, so the owner is required to manage any classes 49 * passed to it, so the owner is required to manage any classes
48 * passed to PictureResultsMultiWriter */ 50 * passed to PictureResultsMultiWriter */
49 class PictureResultsMultiWriter : public PictureResultsWriter { 51 class PictureResultsMultiWriter : public PictureResultsWriter {
50 public: 52 public:
51 PictureResultsMultiWriter() 53 PictureResultsMultiWriter()
52 : fWriters() {} 54 : fWriters() {}
53 void add(PictureResultsWriter* newWriter) { 55 void add(PictureResultsWriter* newWriter) {
54 fWriters.push_back(newWriter); 56 fWriters.push_back(newWriter);
55 } 57 }
56 virtual ~PictureResultsMultiWriter() {} 58 virtual ~PictureResultsMultiWriter() {}
57 virtual void bench(const char name[], int32_t x, int32_t y) { 59 virtual void bench(const char name[], int32_t x, int32_t y) SK_OVERRIDE {
58 for(int i=0; i<fWriters.count(); ++i) { 60 for(int i=0; i<fWriters.count(); ++i) {
59 fWriters[i]->bench(name, x, y); 61 fWriters[i]->bench(name, x, y);
60 } 62 }
61 } 63 }
62 virtual void tileConfig(SkString configName) { 64 virtual void logRenderer(sk_tools::PictureRenderer *pr) SK_OVERRIDE {
63 for(int i=0; i<fWriters.count(); ++i) { 65 for(int i=0; i<fWriters.count(); ++i) {
64 fWriters[i]->tileConfig(configName); 66 fWriters[i]->logRenderer(pr);
65 } 67 }
66 } 68 }
67 virtual void tileMeta(int x, int y, int tx, int ty) { 69 virtual void tileMeta(int x, int y, int tx, int ty) SK_OVERRIDE {
68 for(int i=0; i<fWriters.count(); ++i) { 70 for(int i=0; i<fWriters.count(); ++i) {
69 fWriters[i]->tileMeta(x, y, tx, ty); 71 fWriters[i]->tileMeta(x, y, tx, ty);
70 } 72 }
71 } 73 }
72 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) { 74 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) SK_OVERRIDE {
73 for(int i=0; i<fWriters.count(); ++i) { 75 for(int i=0; i<fWriters.count(); ++i) {
74 fWriters[i]->addTileFlag(flag); 76 fWriters[i]->addTileFlag(flag);
75 } 77 }
76 } 78 }
77 virtual void tileData( 79 virtual void tileData(
78 TimerData* data, 80 TimerData* data,
79 const char format[], 81 const char format[],
80 const TimerData::Result result, 82 const TimerData::Result result,
81 uint32_t timerTypes, 83 uint32_t timerTypes,
82 int numInnerLoops = 1) { 84 int numInnerLoops = 1) {
robertphillips 2014/06/26 16:17:33 This SK_OVERRIDE is misplaced!
kelvinly 2014/06/26 17:18:09 Haha, fixed. I'm confused why that didn't emit som
83 for(int i=0; i<fWriters.count(); ++i) { 85 for(int i=0; i<fWriters.count(); ++i) SK_OVERRIDE {
84 fWriters[i]->tileData(data, format, result, timerTypes, 86 fWriters[i]->tileData(data, format, result, timerTypes,
85 numInnerLoops); 87 numInnerLoops);
86 } 88 }
87 } 89 }
88 virtual void end() { 90 virtual void end() SK_OVERRIDE {
89 for(int i=0; i<fWriters.count(); ++i) { 91 for(int i=0; i<fWriters.count(); ++i) {
90 fWriters[i]->end(); 92 fWriters[i]->end();
91 } 93 }
92 } 94 }
93 private: 95 private:
94 SkTArray<PictureResultsWriter*> fWriters; 96 SkTArray<PictureResultsWriter*> fWriters;
95 }; 97 };
96 98
97 /** 99 /**
98 * Writes to BenchLogger to mimic original behavior 100 * Writes to BenchLogger to mimic original behavior
99 */ 101 */
100 class PictureResultsLoggerWriter : public PictureResultsWriter { 102 class PictureResultsLoggerWriter : public PictureResultsWriter {
101 private: 103 private:
102 void logProgress(const char str[]) { 104 void logProgress(const char str[]) {
103 if(fLogger != NULL) { 105 if(fLogger != NULL) {
104 fLogger->logProgress(str); 106 fLogger->logProgress(str);
105 } 107 }
106 } 108 }
107 public: 109 public:
108 PictureResultsLoggerWriter(BenchLogger* log) 110 PictureResultsLoggerWriter(BenchLogger* log)
109 : fLogger(log), currentLine() {} 111 : fLogger(log), fCurrentLine() {}
110 virtual void bench(const char name[], int32_t x, int32_t y) { 112 virtual void bench(const char name[], int32_t x, int32_t y) SK_OVERRIDE {
111 SkString result; 113 SkString result;
112 result.printf("running bench [%i %i] %s ", x, y, name); 114 result.printf("running bench [%i %i] %s ", x, y, name);
113 this->logProgress(result.c_str()); 115 this->logProgress(result.c_str());
114 } 116 }
115 virtual void tileConfig(SkString configName) { 117 virtual void logRenderer(sk_tools::PictureRenderer* renderer) SK_OVERRIDE {
116 currentLine = configName; 118 fCurrentLine = renderer->getConfigName();
117 } 119 }
118 virtual void tileMeta(int x, int y, int tx, int ty) { 120 virtual void tileMeta(int x, int y, int tx, int ty) SK_OVERRIDE {
119 currentLine.appendf(": tile [%i,%i] out of [%i,%i]", x, y, tx, ty); 121 fCurrentLine.appendf(": tile [%i,%i] out of [%i,%i]", x, y, tx, ty);
120 } 122 }
121 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) { 123 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) SK_OVERRIDE {
122 if(flag == PictureResultsWriter::kPurging) { 124 if(flag == PictureResultsWriter::kPurging) {
123 currentLine.append(" <withPurging>"); 125 fCurrentLine.append(" <withPurging>");
124 } else if(flag == PictureResultsWriter::kAvg) { 126 } else if(flag == PictureResultsWriter::kAvg) {
125 currentLine.append(" <averaged>"); 127 fCurrentLine.append(" <averaged>");
126 } 128 }
127 } 129 }
128 virtual void tileData( 130 virtual void tileData(
129 TimerData* data, 131 TimerData* data,
130 const char format[], 132 const char format[],
131 const TimerData::Result result, 133 const TimerData::Result result,
132 uint32_t timerTypes, 134 uint32_t timerTypes,
133 int numInnerLoops = 1) { 135 int numInnerLoops = 1) SK_OVERRIDE {
134 SkString results = data->getResult(format, result, 136 SkString results = data->getResult(format, result,
135 currentLine.c_str(), timerTypes, numInnerLoops); 137 fCurrentLine.c_str(), timerTypes, numInnerLoops);
136 results.append("\n"); 138 results.append("\n");
137 this->logProgress(results.c_str()); 139 this->logProgress(results.c_str());
138 } 140 }
139 virtual void end() {} 141 virtual void end() {}
140 private: 142 private:
141 BenchLogger* fLogger; 143 BenchLogger* fLogger;
142 SkString currentLine; 144 SkString fCurrentLine;
143 }; 145 };
144 146
145 /** 147 /**
146 * This PictureResultsWriter collects data in a JSON node 148 * This PictureResultsWriter collects data in a JSON node
147 * 149 *
148 * The format is something like 150 * The format is something like
149 * { 151 * {
150 * benches: [ 152 * benches: [
151 * { 153 * {
152 * name: "Name_of_test" 154 * name: "Name_of_test"
(...skipping 12 matching lines...) Expand all
165 * } 167 * }
166 * ] 168 * ]
167 * } 169 * }
168 * ] 170 * ]
169 * } 171 * }
170 * ] 172 * ]
171 * }*/ 173 * }*/
172 174
173 class PictureJSONResultsWriter : public PictureResultsWriter { 175 class PictureJSONResultsWriter : public PictureResultsWriter {
174 public: 176 public:
175 PictureJSONResultsWriter(const char filename[]) 177 PictureJSONResultsWriter(const char filename[],
176 : fFilename(filename), 178 const char builderName[],
177 fRoot(), 179 int buildNumber,
178 fCurrentBench(NULL), 180 int timestamp,
179 fCurrentTileSet(NULL), 181 const char gitHash[],
180 fCurrentTile(NULL) {} 182 int gitNumber)
183 : fStream(filename)
robertphillips 2014/06/26 16:17:33 Don't need to explicitly call default ctor here (f
kelvinly 2014/06/26 17:18:09 Done.
184 , fParams()
185 , fConfigString() {
186 fBuilderName = SkString(builderName);
187 fBuildNumber = buildNumber;
188 fTimestamp = timestamp;
189 fGitHash = SkString(gitHash);
190 fGitNumber = gitNumber;
191 fBuilderData = makeBuilderJSON(fBuilderName);
192 }
181 193
182 virtual void bench(const char name[], int32_t x, int32_t y) { 194 virtual void bench(const char name[], int32_t x, int32_t y) SK_OVERRIDE {
183 SkString sk_name(name); 195 fBenchName = SkString(name);
184 sk_name.append("_");
185 sk_name.appendS32(x);
186 sk_name.append("_");
187 sk_name.appendS32(y);
188 Json::Value* bench_node = SkFindNamedNode(&fRoot["benches"], sk_name.c_s tr());
189 fCurrentBench = &(*bench_node)["tileSets"];
190 } 196 }
191 virtual void tileConfig(SkString configName) { 197 virtual void logRenderer(sk_tools::PictureRenderer* pr) SK_OVERRIDE {
192 SkASSERT(fCurrentBench != NULL); 198 fParams = pr->getJSONConfig();
193 fCurrentTileSet = SkFindNamedNode(fCurrentBench, configName.c_str()); 199 fConfigString = pr->getConfigName();
194 fCurrentTile = &(*fCurrentTileSet)["tiles"][0];
195 } 200 }
196 virtual void tileMeta(int x, int y, int tx, int ty) { 201 // Apparently tiles aren't used, so tileMeta is empty
197 SkASSERT(fCurrentTileSet != NULL); 202 virtual void tileMeta(int x, int y, int tx, int ty) SK_OVERRIDE {}
198 (*fCurrentTileSet)["tx"] = tx; 203 // Flags aren't used, so addTileFlag is empty
199 (*fCurrentTileSet)["ty"] = ty; 204 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) SK_OVERRIDE { }
200 fCurrentTile = &(*fCurrentTileSet)["tiles"][x+tx*y];
201 }
202 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) {
203 SkASSERT(fCurrentTile != NULL);
204 if(flag == PictureResultsWriter::kPurging) {
205 (*fCurrentTile)["flags"]["purging"] = true;
206 } else if(flag == PictureResultsWriter::kAvg) {
207 (*fCurrentTile)["flags"]["averaged"] = true;
208 }
209 }
210 virtual void tileData( 205 virtual void tileData(
211 TimerData* data, 206 TimerData* data,
212 const char format[], 207 const char format[],
213 const TimerData::Result result, 208 const TimerData::Result result,
214 uint32_t timerTypes, 209 uint32_t timerTypes,
215 int numInnerLoops = 1) { 210 int numInnerLoops = 1) SK_OVERRIDE {
216 SkASSERT(fCurrentTile != NULL); 211 Json::Value newData = data->getJSON(timerTypes, result, numInnerLoops);
217 (*fCurrentTile)["data"] = data->getJSON(timerTypes, result, numInnerLoop s); 212 Json::Value combinedParams(fBuilderData);
213 for(Json::ValueIterator iter = fParams.begin(); iter != fParams.end();
214 iter++) {
215 combinedParams[iter.key().asString()]= *iter;
216 }
217 // For each set of timer data
218 for(Json::ValueIterator iter = newData.begin(); iter != newData.end();
219 iter++) {
220 Json::Value data;
221 data["buildNumber"] = fBuildNumber;
222 data["timestamp"] = fTimestamp;
223 data["gitHash"] = fGitHash.c_str();
224 data["gitNumber"] = fGitNumber;
225 data["isTrybot"] = fBuilderName.endsWith("Trybot");
226
227 data["params"] = combinedParams;
228 data["params"]["benchName"] = fBenchName.c_str();
229
230 // Not including skpSize because that's deprecated?
robertphillips 2014/06/26 16:17:33 this->makeKey ?
kelvinly 2014/06/26 17:18:09 Done.
231 data["key"] = makeKey(iter.key().asString().c_str()).c_str();
232 // Get the data
233 SkTArray<double> times;
234 Json::Value val = *iter;
235 for(Json::ValueIterator vals = val.begin(); vals != val.end();
robertphillips 2014/06/26 16:17:33 can this fit on the prior line ?
kelvinly 2014/06/26 17:18:09 ~4 characters too long
236 vals++) {
237 times.push_back((*vals).asDouble());
238 }
239 qsort(static_cast<void*>(times.begin()), times.count(),
robertphillips 2014/06/26 16:17:33 CompareDoubles ?
kelvinly 2014/06/26 17:18:09 Done.
240 sizeof(double), PictureJSONResultsWriter::compareDoubles);
241 data["value"] = times[static_cast<int>(times.count() * 0.25f)];
242 data["params"]["measurementType"] = iter.key().asString();
243 fStream.writeText(Json::FastWriter().write(data).c_str());
244 }
218 } 245 }
219 virtual void end() { 246 virtual void end() SK_OVERRIDE {
220 SkFILEWStream stream(fFilename.c_str()); 247 fStream.flush();
221 stream.writeText(Json::FastWriter().write(fRoot).c_str());
222 stream.flush();
223 } 248 }
224 private: 249 private:
225 SkString fFilename; 250 static int compareDoubles(const void* p1, const void* p2) {
226 Json::Value fRoot; 251 if(*static_cast<const double*>(p1) < *static_cast<const double*>(p2)) {
227 Json::Value *fCurrentBench; 252 return -1;
228 Json::Value *fCurrentTileSet; 253 } else if(*static_cast<const double*>(p1) ==
229 Json::Value *fCurrentTile; 254 *static_cast<const double*>(p2)) {
255 return 0;
256 } else {
257 return 1;
258 }
259 }
robertphillips 2014/06/26 16:17:33 make this const ?
kelvinly 2014/06/26 17:18:09 Done.
260 SkString makeKey(const char measurementType[]) {
261 SkString tmp(fBuilderName);
262 tmp.append("_");
263 tmp.append(fBenchName);
264 tmp.append("_");
265 tmp.append(fConfigString);
266 tmp.append("_");
267 tmp.append(measurementType);
268 return tmp;
269 }
270
robertphillips 2014/06/26 16:17:33 line up the variable names ?
kelvinly 2014/06/26 17:18:09 Done.
271 SkFILEWStream fStream;
272 Json::Value fBuilderData;
273 SkString fBenchName;
274 Json::Value fParams;
275
276 SkString fConfigString;
277 SkString fBuilderName;
278 int fBuildNumber;
279 int fTimestamp;
280 SkString fGitHash;
281 int fGitNumber;
230 }; 282 };
231 283
232 #endif 284 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698