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) 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 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) | |
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 |
OLD | NEW |