OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 */ | 7 */ |
8 | 8 |
9 #include "VisualBench.h" | 9 #include "VisualBench.h" |
10 | 10 |
(...skipping 18 matching lines...) Expand all Loading... |
29 | 29 |
30 DEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allow
s to lag."); | 30 DEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allow
s to lag."); |
31 DEFINE_int32(samples, 10, "Number of times to time each skp."); | 31 DEFINE_int32(samples, 10, "Number of times to time each skp."); |
32 DEFINE_int32(frames, 5, "Number of frames of each skp to render per sample."); | 32 DEFINE_int32(frames, 5, "Number of frames of each skp to render per sample."); |
33 DEFINE_double(flushMs, 20, "Target flush time in millseconds."); | 33 DEFINE_double(flushMs, 20, "Target flush time in millseconds."); |
34 DEFINE_double(loopMs, 5, "Target loop time in millseconds."); | 34 DEFINE_double(loopMs, 5, "Target loop time in millseconds."); |
35 DEFINE_int32(msaa, 0, "Number of msaa samples."); | 35 DEFINE_int32(msaa, 0, "Number of msaa samples."); |
36 DEFINE_bool2(fullscreen, f, true, "Run fullscreen."); | 36 DEFINE_bool2(fullscreen, f, true, "Run fullscreen."); |
37 DEFINE_bool2(verbose, v, false, "enable verbose output from the test driver."); | 37 DEFINE_bool2(verbose, v, false, "enable verbose output from the test driver."); |
38 DEFINE_string(key, "", ""); // dummy to enable gm tests that have platform-spec
ific names | 38 DEFINE_string(key, "", ""); // dummy to enable gm tests that have platform-spec
ific names |
| 39 DEFINE_string(outResultsFile, "", "If given, write results here as JSON."); |
| 40 DEFINE_string(properties, "", |
| 41 "Space-separated key/value pairs to add to JSON identifying this r
un."); |
39 | 42 |
40 static SkString humanize(double ms) { | 43 static SkString humanize(double ms) { |
41 if (FLAGS_verbose) { | 44 if (FLAGS_verbose) { |
42 return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); | 45 return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); |
43 } | 46 } |
44 return HumanizeMs(ms); | 47 return HumanizeMs(ms); |
45 } | 48 } |
46 | 49 |
47 #define HUMANIZE(time) humanize(time).c_str() | 50 #define HUMANIZE(time) humanize(time).c_str() |
48 | 51 |
49 VisualBench::VisualBench(void* hwnd, int argc, char** argv) | 52 VisualBench::VisualBench(void* hwnd, int argc, char** argv) |
50 : INHERITED(hwnd) | 53 : INHERITED(hwnd) |
51 , fCurrentSample(0) | 54 , fCurrentSample(0) |
52 , fCurrentFrame(0) | 55 , fCurrentFrame(0) |
53 , fFlushes(1) | 56 , fFlushes(1) |
54 , fLoops(1) | 57 , fLoops(1) |
55 , fState(kPreWarmLoops_State) | 58 , fState(kPreWarmLoops_State) |
56 , fBenchmark(NULL) { | 59 , fBenchmark(NULL) |
| 60 , fResults(SkNEW(ResultsWriter)) { |
57 SkCommandLineFlags::Parse(argc, argv); | 61 SkCommandLineFlags::Parse(argc, argv); |
58 | 62 |
59 this->setTitle(); | 63 this->setTitle(); |
60 this->setupBackend(); | 64 this->setupBackend(); |
61 | 65 |
62 fBenchmarkStream.reset(SkNEW(VisualBenchmarkStream)); | 66 fBenchmarkStream.reset(SkNEW(VisualBenchmarkStream)); |
63 | 67 |
64 // Print header | 68 // Print header |
65 SkDebugf("curr/maxrss\tloops\tflushes\tmin\tmedian\tmean\tmax\tstddev\tbench
\n"); | 69 SkDebugf("curr/maxrss\tloops\tflushes\tmin\tmedian\tmean\tmax\tstddev\tbench
\n"); |
| 70 |
| 71 // setup json logging if required |
| 72 if (!FLAGS_outResultsFile.isEmpty()) { |
| 73 fResults.reset(SkNEW(NanoJSONResultsWriter(FLAGS_outResultsFile[0]))); |
| 74 } |
| 75 |
| 76 if (1 == FLAGS_properties.count() % 2) { |
| 77 SkDebugf("ERROR: --properties must be passed with an even number of argu
ments.\n"); |
| 78 } else { |
| 79 for (int i = 1; i < FLAGS_properties.count(); i += 2) { |
| 80 fResults->property(FLAGS_properties[i - 1], FLAGS_properties[i]); |
| 81 } |
| 82 } |
66 } | 83 } |
67 | 84 |
68 VisualBench::~VisualBench() { | 85 VisualBench::~VisualBench() { |
69 INHERITED::detach(); | 86 INHERITED::detach(); |
70 } | 87 } |
71 | 88 |
72 void VisualBench::setTitle() { | 89 void VisualBench::setTitle() { |
73 SkString title("VisualBench"); | 90 SkString title("VisualBench"); |
74 INHERITED::setTitle(title.c_str()); | 91 INHERITED::setTitle(title.c_str()); |
75 } | 92 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 for (int flush = 0; flush < fFlushes; flush++) { | 146 for (int flush = 0; flush < fFlushes; flush++) { |
130 fBenchmark->draw(fLoops, canvas); | 147 fBenchmark->draw(fLoops, canvas); |
131 canvas->flush(); | 148 canvas->flush(); |
132 } | 149 } |
133 INHERITED::present(); | 150 INHERITED::present(); |
134 } | 151 } |
135 | 152 |
136 void VisualBench::printStats() { | 153 void VisualBench::printStats() { |
137 const SkTArray<double>& measurements = fRecords.back().fMeasurements; | 154 const SkTArray<double>& measurements = fRecords.back().fMeasurements; |
138 const char* shortName = fBenchmark->getUniqueName(); | 155 const char* shortName = fBenchmark->getUniqueName(); |
| 156 |
| 157 // update log |
| 158 // Note: We currently log only the minimum. It would be interesting to log
more information |
| 159 SkString configName; |
| 160 if (FLAGS_msaa > 0) { |
| 161 configName.appendf("msaa_%d", FLAGS_msaa); |
| 162 } else { |
| 163 configName.appendf("gpu"); |
| 164 } |
| 165 fResults->config(configName.c_str()); |
| 166 fResults->configOption("name", fBenchmark->getUniqueName()); |
| 167 SkASSERT(measurements.count()); |
| 168 Stats stats(measurements); |
| 169 fResults->metric("min_ms", stats.min); |
| 170 |
| 171 // Print output |
139 if (FLAGS_verbose) { | 172 if (FLAGS_verbose) { |
140 for (int i = 0; i < measurements.count(); i++) { | 173 for (int i = 0; i < measurements.count(); i++) { |
141 SkDebugf("%s ", HUMANIZE(measurements[i])); | 174 SkDebugf("%s ", HUMANIZE(measurements[i])); |
142 } | 175 } |
143 SkDebugf("%s\n", shortName); | 176 SkDebugf("%s\n", shortName); |
144 } else { | 177 } else { |
145 SkASSERT(measurements.count()); | |
146 Stats stats(measurements); | |
147 const double stdDevPercent = 100 * sqrt(stats.var) / stats.mean; | 178 const double stdDevPercent = 100 * sqrt(stats.var) / stats.mean; |
148 SkDebugf("%4d/%-4dMB\t%d\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\n", | 179 SkDebugf("%4d/%-4dMB\t%d\t%d\t%s\t%s\t%s\t%s\t%.0f%%\t%s\n", |
149 sk_tools::getCurrResidentSetSizeMB(), | 180 sk_tools::getCurrResidentSetSizeMB(), |
150 sk_tools::getMaxResidentSetSizeMB(), | 181 sk_tools::getMaxResidentSetSizeMB(), |
151 fLoops, | 182 fLoops, |
152 fFlushes, | 183 fFlushes, |
153 HUMANIZE(stats.min), | 184 HUMANIZE(stats.min), |
154 HUMANIZE(stats.median), | 185 HUMANIZE(stats.median), |
155 HUMANIZE(stats.mean), | 186 HUMANIZE(stats.mean), |
156 HUMANIZE(stats.max), | 187 HUMANIZE(stats.max), |
157 stdDevPercent, | 188 stdDevPercent, |
158 shortName); | 189 shortName); |
159 } | 190 } |
160 } | 191 } |
161 | 192 |
162 bool VisualBench::advanceRecordIfNecessary(SkCanvas* canvas) { | 193 bool VisualBench::advanceRecordIfNecessary(SkCanvas* canvas) { |
163 if (fBenchmark) { | 194 if (fBenchmark) { |
164 return true; | 195 return true; |
165 } | 196 } |
166 | 197 |
167 fBenchmark.reset(fBenchmarkStream->next()); | 198 fBenchmark.reset(fBenchmarkStream->next()); |
168 if (!fBenchmark) { | 199 if (!fBenchmark) { |
169 return false; | 200 return false; |
170 } | 201 } |
171 | 202 |
172 canvas->clear(0xffffffff); | 203 canvas->clear(0xffffffff); |
173 fBenchmark->preDraw(); | 204 fBenchmark->preDraw(); |
174 fRecords.push_back(); | 205 fRecords.push_back(); |
| 206 |
| 207 // Log bench name |
| 208 fResults->bench(fBenchmark->getUniqueName(), fBenchmark->getSize().fX, |
| 209 fBenchmark->getSize().fY); |
175 return true; | 210 return true; |
176 } | 211 } |
177 | 212 |
178 inline void VisualBench::nextState(State nextState) { | 213 inline void VisualBench::nextState(State nextState) { |
179 fState = nextState; | 214 fState = nextState; |
180 } | 215 } |
181 | 216 |
182 void VisualBench::perCanvasPreDraw(SkCanvas* canvas, State nextState) { | 217 void VisualBench::perCanvasPreDraw(SkCanvas* canvas, State nextState) { |
183 fBenchmark->perCanvasPreDraw(canvas); | 218 fBenchmark->perCanvasPreDraw(canvas); |
184 fCurrentFrame = 0; | 219 fCurrentFrame = 0; |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 348 |
314 void application_term() { | 349 void application_term() { |
315 SkEvent::Term(); | 350 SkEvent::Term(); |
316 SkGraphics::Term(); | 351 SkGraphics::Term(); |
317 } | 352 } |
318 | 353 |
319 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { | 354 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { |
320 return new VisualBench(hwnd, argc, argv); | 355 return new VisualBench(hwnd, argc, argv); |
321 } | 356 } |
322 | 357 |
OLD | NEW |