OLD | NEW |
---|---|
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) { |
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) { |
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) { |
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) { |
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); |
(...skipping 29 matching lines...) Expand all Loading... | |
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), currentLine() {} |
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) { |
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 } |
robertphillips
2014/06/24 20:49:52
OVERRIDE here ?
kelvinly
2014/06/24 22:25:19
Ah, sorry, didn't know that was a thing. Fixed
| |
115 virtual void tileConfig(SkString configName) { | 117 virtual void logRenderer(sk_tools::PictureRenderer* renderer) { |
robertphillips
2014/06/24 20:49:51
fCurrentLine ?
kelvinly
2014/06/24 22:25:19
Done.
| |
116 currentLine = configName; | 118 currentLine = 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) { |
119 currentLine.appendf(": tile [%i,%i] out of [%i,%i]", x, y, tx, ty); | 121 currentLine.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) { |
122 if(flag == PictureResultsWriter::kPurging) { | 124 if(flag == PictureResultsWriter::kPurging) { |
123 currentLine.append(" <withPurging>"); | 125 currentLine.append(" <withPurging>"); |
124 } else if(flag == PictureResultsWriter::kAvg) { | 126 } else if(flag == PictureResultsWriter::kAvg) { |
125 currentLine.append(" <averaged>"); | 127 currentLine.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) { |
134 SkString results = data->getResult(format, result, | 136 SkString results = data->getResult(format, result, |
135 currentLine.c_str(), timerTypes, numInnerLoops); | 137 currentLine.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; |
robertphillips
2014/06/24 20:49:52
fCurrentLine ?
kelvinly
2014/06/24 22:25:19
Done.
| |
142 SkString currentLine; | 144 SkString currentLine; |
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 * { |
(...skipping 13 matching lines...) Expand all Loading... | |
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) | |
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) { |
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 } |
robertphillips
2014/06/24 20:49:51
OVERRIDE here ?
kelvinly
2014/06/24 22:25:19
Done.
| |
191 virtual void tileConfig(SkString configName) { | 197 virtual void logRenderer(sk_tools::PictureRenderer* pr) { |
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 |
robertphillips
2014/06/24 20:49:51
OVERRIDE here ?
Don't need ';' here
kelvinly
2014/06/24 22:25:19
Done.
| |
197 SkASSERT(fCurrentTileSet != NULL); | 202 virtual void tileMeta(int x, int y, int tx, int ty) { ; } |
198 (*fCurrentTileSet)["tx"] = tx; | 203 // Flags aren't used, so addTileFlag is empty |
robertphillips
2014/06/24 20:49:52
Same here
kelvinly
2014/06/24 22:25:19
Done.
| |
199 (*fCurrentTileSet)["ty"] = ty; | 204 virtual void addTileFlag(PictureResultsWriter::TileFlags flag) { ; } |
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) { |
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? | |
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(); | |
236 vals++) { | |
237 times.push_back((*vals).asDouble()); | |
238 } | |
239 // Because there's no sort I'll just remove the smallest | |
240 // 25% of values | |
241 int numValues = times.count(); | |
242 double currentMin = 10000000.0f; | |
243 for(int i = 0; i < numValues; i++) { | |
244 if(times[i] < currentMin) { | |
245 currentMin = times[i]; | |
246 } | |
247 } | |
248 for(int i = 0; i < numValues*0.25f; i++) { | |
249 double localMin = currentMin; | |
250 for(int j = 0; j < numValues; j++) { | |
251 if(times[i] > currentMin && times[i] < localMin) { | |
252 localMin = times[i]; | |
253 } | |
254 } | |
255 currentMin = localMin; | |
256 } | |
257 data["value"] = currentMin; | |
258 data["params"]["measurementType"] = iter.key().asString(); | |
259 fStream.writeText(Json::FastWriter().write(data).c_str()); | |
260 } | |
218 } | 261 } |
219 virtual void end() { | 262 virtual void end() { |
220 SkFILEWStream stream(fFilename.c_str()); | 263 fStream.flush(); |
221 stream.writeText(Json::FastWriter().write(fRoot).c_str()); | |
222 stream.flush(); | |
223 } | 264 } |
224 private: | 265 private: |
225 SkString fFilename; | 266 SkString makeKey(const char measurementType[]) { |
226 Json::Value fRoot; | 267 SkString tmp(fBuilderName); |
227 Json::Value *fCurrentBench; | 268 tmp.append("_"); |
228 Json::Value *fCurrentTileSet; | 269 tmp.append(fBenchName); |
229 Json::Value *fCurrentTile; | 270 tmp.append("_"); |
271 tmp.append(fConfigString); | |
272 tmp.append("_"); | |
273 tmp.append(measurementType); | |
274 return tmp; | |
275 } | |
276 | |
277 SkFILEWStream fStream; | |
278 Json::Value fBuilderData; | |
279 SkString fBenchName; | |
280 Json::Value fParams; | |
281 | |
282 SkString fConfigString; | |
283 SkString fBuilderName; | |
284 int fBuildNumber; | |
285 int fTimestamp; | |
286 SkString fGitHash; | |
287 int fGitNumber; | |
230 }; | 288 }; |
231 | 289 |
232 #endif | 290 #endif |
OLD | NEW |