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) SK_OVERRIDE { |
83 for(int i=0; i<fWriters.count(); ++i) { | 85 for(int i=0; i<fWriters.count(); ++i) { |
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) { |
| 184 fBuilderName = SkString(builderName); |
| 185 fBuildNumber = buildNumber; |
| 186 fTimestamp = timestamp; |
| 187 fGitHash = SkString(gitHash); |
| 188 fGitNumber = gitNumber; |
| 189 fBuilderData = SkMakeBuilderJSON(fBuilderName); |
| 190 } |
181 | 191 |
182 virtual void bench(const char name[], int32_t x, int32_t y) { | 192 virtual void bench(const char name[], int32_t x, int32_t y) SK_OVERRIDE { |
183 SkString sk_name(name); | 193 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 } | 194 } |
191 virtual void tileConfig(SkString configName) { | 195 virtual void logRenderer(sk_tools::PictureRenderer* pr) SK_OVERRIDE { |
192 SkASSERT(fCurrentBench != NULL); | 196 fParams = pr->getJSONConfig(); |
193 fCurrentTileSet = SkFindNamedNode(fCurrentBench, configName.c_str()); | 197 fConfigString = pr->getConfigName(); |
194 fCurrentTile = &(*fCurrentTileSet)["tiles"][0]; | |
195 } | 198 } |
196 virtual void tileMeta(int x, int y, int tx, int ty) { | 199 // Apparently tiles aren't used, so tileMeta is empty |
197 SkASSERT(fCurrentTileSet != NULL); | 200 virtual void tileMeta(int x, int y, int tx, int ty) SK_OVERRIDE {} |
198 (*fCurrentTileSet)["tx"] = tx; | 201 // Flags aren't used, so addTileFlag is empty |
199 (*fCurrentTileSet)["ty"] = ty; | 202 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( | 203 virtual void tileData( |
211 TimerData* data, | 204 TimerData* data, |
212 const char format[], | 205 const char format[], |
213 const TimerData::Result result, | 206 const TimerData::Result result, |
214 uint32_t timerTypes, | 207 uint32_t timerTypes, |
215 int numInnerLoops = 1) { | 208 int numInnerLoops = 1) SK_OVERRIDE { |
216 SkASSERT(fCurrentTile != NULL); | 209 Json::Value newData = data->getJSON(timerTypes, result, numInnerLoops); |
217 (*fCurrentTile)["data"] = data->getJSON(timerTypes, result, numInnerLoop
s); | 210 Json::Value combinedParams(fBuilderData); |
| 211 for(Json::ValueIterator iter = fParams.begin(); iter != fParams.end(); |
| 212 iter++) { |
| 213 combinedParams[iter.key().asString()]= *iter; |
| 214 } |
| 215 // For each set of timer data |
| 216 for(Json::ValueIterator iter = newData.begin(); iter != newData.end(); |
| 217 iter++) { |
| 218 Json::Value data; |
| 219 data["buildNumber"] = fBuildNumber; |
| 220 data["timestamp"] = fTimestamp; |
| 221 data["gitHash"] = fGitHash.c_str(); |
| 222 data["gitNumber"] = fGitNumber; |
| 223 data["isTrybot"] = fBuilderName.endsWith("Trybot"); |
| 224 |
| 225 data["params"] = combinedParams; |
| 226 data["params"]["benchName"] = fBenchName.c_str(); |
| 227 |
| 228 // Not including skpSize because that's deprecated? |
| 229 data["key"] = this->makeKey(iter.key().asString().c_str()).c_str(); |
| 230 // Get the data |
| 231 SkTArray<double> times; |
| 232 Json::Value val = *iter; |
| 233 for(Json::ValueIterator vals = val.begin(); vals != val.end(); |
| 234 vals++) { |
| 235 times.push_back((*vals).asDouble()); |
| 236 } |
| 237 qsort(static_cast<void*>(times.begin()), times.count(), |
| 238 sizeof(double), PictureJSONResultsWriter::CompareDoubles); |
| 239 data["value"] = times[static_cast<int>(times.count() * 0.25f)]; |
| 240 data["params"]["measurementType"] = iter.key().asString(); |
| 241 fStream.writeText(Json::FastWriter().write(data).c_str()); |
| 242 } |
218 } | 243 } |
219 virtual void end() { | 244 virtual void end() SK_OVERRIDE { |
220 SkFILEWStream stream(fFilename.c_str()); | 245 fStream.flush(); |
221 stream.writeText(Json::FastWriter().write(fRoot).c_str()); | |
222 stream.flush(); | |
223 } | 246 } |
224 private: | 247 private: |
225 SkString fFilename; | 248 static int CompareDoubles(const void* p1, const void* p2) { |
226 Json::Value fRoot; | 249 if(*static_cast<const double*>(p1) < *static_cast<const double*>(p2)) { |
227 Json::Value *fCurrentBench; | 250 return -1; |
228 Json::Value *fCurrentTileSet; | 251 } else if(*static_cast<const double*>(p1) == |
229 Json::Value *fCurrentTile; | 252 *static_cast<const double*>(p2)) { |
| 253 return 0; |
| 254 } else { |
| 255 return 1; |
| 256 } |
| 257 } |
| 258 SkString makeKey(const char measurementType[]) const { |
| 259 SkString tmp(fBuilderName); |
| 260 tmp.append("_"); |
| 261 tmp.append(fBenchName); |
| 262 tmp.append("_"); |
| 263 tmp.append(fConfigString); |
| 264 tmp.append("_"); |
| 265 tmp.append(measurementType); |
| 266 return tmp; |
| 267 } |
| 268 |
| 269 SkFILEWStream fStream; |
| 270 Json::Value fBuilderData; |
| 271 SkString fBenchName; |
| 272 Json::Value fParams; |
| 273 |
| 274 SkString fConfigString; |
| 275 SkString fBuilderName; |
| 276 int fBuildNumber; |
| 277 int fTimestamp; |
| 278 SkString fGitHash; |
| 279 int fGitNumber; |
230 }; | 280 }; |
231 | 281 |
232 #endif | 282 #endif |
OLD | NEW |