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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 return true; | 163 return true; |
164 } | 164 } |
165 | 165 |
166 fBenchmark.reset(fBenchmarkStream->next()); | 166 fBenchmark.reset(fBenchmarkStream->next()); |
167 if (!fBenchmark) { | 167 if (!fBenchmark) { |
168 return false; | 168 return false; |
169 } | 169 } |
170 | 170 |
171 canvas->clear(0xffffffff); | 171 canvas->clear(0xffffffff); |
172 fBenchmark->preDraw(); | 172 fBenchmark->preDraw(); |
173 fBenchmark->perCanvasPreDraw(canvas); | |
174 fRecords.push_back(); | 173 fRecords.push_back(); |
175 return true; | 174 return true; |
176 } | 175 } |
177 | 176 |
| 177 inline void VisualBench::nextState(State nextState) { |
| 178 fState = nextState; |
| 179 } |
| 180 |
| 181 void VisualBench::perCanvasPreDraw(SkCanvas* canvas, State nextState) { |
| 182 fBenchmark->perCanvasPreDraw(canvas); |
| 183 fCurrentFrame = 0; |
| 184 this->nextState(nextState); |
| 185 } |
| 186 |
178 void VisualBench::preWarm(State nextState) { | 187 void VisualBench::preWarm(State nextState) { |
179 if (fCurrentFrame >= FLAGS_gpuFrameLag) { | 188 if (fCurrentFrame >= FLAGS_gpuFrameLag) { |
180 // we currently time across all frames to make sure we capture all GPU w
ork | 189 // we currently time across all frames to make sure we capture all GPU w
ork |
181 fState = nextState; | 190 this->nextState(nextState); |
182 fCurrentFrame = 0; | 191 fCurrentFrame = 0; |
183 fTimer.start(); | 192 fTimer.start(); |
184 } else { | 193 } else { |
185 fCurrentFrame++; | 194 fCurrentFrame++; |
186 } | 195 } |
187 } | 196 } |
188 | 197 |
189 void VisualBench::draw(SkCanvas* canvas) { | 198 void VisualBench::draw(SkCanvas* canvas) { |
190 if (!this->advanceRecordIfNecessary(canvas)) { | 199 if (!this->advanceRecordIfNecessary(canvas)) { |
191 this->closeWindow(); | 200 this->closeWindow(); |
192 return; | 201 return; |
193 } | 202 } |
194 this->renderFrame(canvas); | 203 this->renderFrame(canvas); |
195 switch (fState) { | 204 switch (fState) { |
| 205 case kPreWarmLoopsPerCanvasPreDraw_State: { |
| 206 this->perCanvasPreDraw(canvas, kPreWarmLoops_State); |
| 207 break; |
| 208 } |
196 case kPreWarmLoops_State: { | 209 case kPreWarmLoops_State: { |
197 this->preWarm(kTuneLoops_State); | 210 this->preWarm(kTuneLoops_State); |
198 break; | 211 break; |
199 } | 212 } |
200 case kTuneLoops_State: { | 213 case kTuneLoops_State: { |
201 if (1 << 30 == fLoops) { | 214 this->tuneLoops(); |
202 // We're about to wrap. Something's wrong with the bench. | 215 break; |
203 SkDebugf("InnerLoops wrapped\n"); | 216 } |
204 fLoops = 0; | 217 case kPreWarmTimingPerCanvasPreDraw_State: { |
205 } else { | 218 this->perCanvasPreDraw(canvas, kPreWarmTiming_State); |
206 fTimer.end(); | |
207 double elapsed = fTimer.fWall; | |
208 if (elapsed > FLAGS_loopMs) { | |
209 fState = kPreWarmTiming_State; | |
210 | |
211 // Scale back the number of loops | |
212 fLoops = (int)ceil(fLoops * FLAGS_loopMs / elapsed); | |
213 fFlushes = (int)ceil(FLAGS_flushMs / elapsed); | |
214 } else { | |
215 fState = kPreWarmLoops_State; | |
216 fLoops *= 2; | |
217 } | |
218 | |
219 fCurrentFrame = 0; | |
220 fTimer = WallTimer(); | |
221 this->resetContext(); | |
222 } | |
223 break; | 219 break; |
224 } | 220 } |
225 case kPreWarmTiming_State: { | 221 case kPreWarmTiming_State: { |
226 this->preWarm(kTiming_State); | 222 this->preWarm(kTiming_State); |
227 break; | 223 break; |
228 } | 224 } |
229 case kTiming_State: { | 225 case kTiming_State: { |
230 if (fCurrentFrame >= FLAGS_frames) { | 226 this->timing(canvas); |
231 fTimer.end(); | |
232 fRecords.back().fMeasurements.push_back( | |
233 fTimer.fWall / (FLAGS_frames * fLoops * fFlushes)); | |
234 if (fCurrentSample++ >= FLAGS_samples) { | |
235 fState = kPreWarmLoops_State; | |
236 this->printStats(); | |
237 fBenchmark->perCanvasPostDraw(canvas); | |
238 fBenchmark.reset(NULL); | |
239 fCurrentSample = 0; | |
240 fFlushes = 1; | |
241 fLoops = 1; | |
242 } else { | |
243 fState = kPreWarmTiming_State; | |
244 } | |
245 fTimer = WallTimer(); | |
246 this->resetContext(); | |
247 fCurrentFrame = 0; | |
248 } else { | |
249 fCurrentFrame++; | |
250 } | |
251 break; | 227 break; |
252 } | 228 } |
253 } | 229 } |
254 | 230 |
255 // Invalidate the window to force a redraw. Poor man's animation mechanism. | 231 // Invalidate the window to force a redraw. Poor man's animation mechanism. |
256 this->inval(NULL); | 232 this->inval(NULL); |
257 } | 233 } |
258 | 234 |
| 235 inline double VisualBench::elapsed() { |
| 236 fTimer.end(); |
| 237 return fTimer.fWall; |
| 238 } |
| 239 |
| 240 void VisualBench::resetTimingState() { |
| 241 fCurrentFrame = 0; |
| 242 fTimer = WallTimer(); |
| 243 this->resetContext(); |
| 244 } |
| 245 |
| 246 void VisualBench::scaleLoops(double elapsedMs) { |
| 247 // Scale back the number of loops |
| 248 fLoops = (int)ceil(fLoops * FLAGS_loopMs / elapsedMs); |
| 249 fFlushes = (int)ceil(FLAGS_flushMs / elapsedMs); |
| 250 } |
| 251 |
| 252 inline void VisualBench::tuneLoops() { |
| 253 if (1 << 30 == fLoops) { |
| 254 // We're about to wrap. Something's wrong with the bench. |
| 255 SkDebugf("InnerLoops wrapped\n"); |
| 256 fLoops = 0; |
| 257 } else { |
| 258 double elapsedMs = this->elapsed(); |
| 259 if (elapsedMs > FLAGS_loopMs) { |
| 260 this->scaleLoops(elapsedMs); |
| 261 this->nextState(kPreWarmTimingPerCanvasPreDraw_State); |
| 262 } else { |
| 263 fLoops *= 2; |
| 264 this->nextState(kPreWarmLoops_State); |
| 265 } |
| 266 this->resetTimingState(); |
| 267 } |
| 268 } |
| 269 |
| 270 void VisualBench::recordMeasurement() { |
| 271 double measurement = this->elapsed() / (FLAGS_frames * fLoops * fFlushes); |
| 272 fRecords.back().fMeasurements.push_back(measurement); |
| 273 } |
| 274 |
| 275 void VisualBench::postDraw(SkCanvas* canvas) { |
| 276 fBenchmark->perCanvasPostDraw(canvas); |
| 277 fBenchmark.reset(NULL); |
| 278 fCurrentSample = 0; |
| 279 fFlushes = 1; |
| 280 fLoops = 1; |
| 281 } |
| 282 |
| 283 inline void VisualBench::timing(SkCanvas* canvas) { |
| 284 if (fCurrentFrame >= FLAGS_frames) { |
| 285 this->recordMeasurement(); |
| 286 if (fCurrentSample++ >= FLAGS_samples) { |
| 287 this->printStats(); |
| 288 this->postDraw(canvas); |
| 289 this->nextState(kPreWarmLoopsPerCanvasPreDraw_State); |
| 290 } else { |
| 291 this->nextState(kPreWarmTimingPerCanvasPreDraw_State); |
| 292 } |
| 293 this->resetTimingState(); |
| 294 } else { |
| 295 fCurrentFrame++; |
| 296 } |
| 297 } |
| 298 |
259 void VisualBench::onSizeChange() { | 299 void VisualBench::onSizeChange() { |
260 this->setupRenderTarget(); | 300 this->setupRenderTarget(); |
261 } | 301 } |
262 | 302 |
263 bool VisualBench::onHandleChar(SkUnichar unichar) { | 303 bool VisualBench::onHandleChar(SkUnichar unichar) { |
264 return true; | 304 return true; |
265 } | 305 } |
266 | 306 |
267 // Externally declared entry points | 307 // Externally declared entry points |
268 void application_init() { | 308 void application_init() { |
269 SkGraphics::Init(); | 309 SkGraphics::Init(); |
270 SkEvent::Init(); | 310 SkEvent::Init(); |
271 } | 311 } |
272 | 312 |
273 void application_term() { | 313 void application_term() { |
274 SkEvent::Term(); | 314 SkEvent::Term(); |
275 SkGraphics::Term(); | 315 SkGraphics::Term(); |
276 } | 316 } |
277 | 317 |
278 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { | 318 SkOSWindow* create_sk_window(void* hwnd, int argc, char** argv) { |
279 return new VisualBench(hwnd, argc, argv); | 319 return new VisualBench(hwnd, argc, argv); |
280 } | 320 } |
281 | 321 |
OLD | NEW |