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 | 7 |
8 #include <ctype.h> | 8 #include <ctype.h> |
9 | 9 |
| 10 #include "nanobench.h" |
| 11 |
10 #include "Benchmark.h" | 12 #include "Benchmark.h" |
11 #include "CrashHandler.h" | 13 #include "CrashHandler.h" |
12 #include "DecodingBench.h" | 14 #include "DecodingBench.h" |
13 #include "DecodingSubsetBench.h" | 15 #include "DecodingSubsetBench.h" |
14 #include "GMBench.h" | 16 #include "GMBench.h" |
15 #include "ProcStats.h" | 17 #include "ProcStats.h" |
16 #include "ResultsWriter.h" | 18 #include "ResultsWriter.h" |
17 #include "RecordingBench.h" | 19 #include "RecordingBench.h" |
18 #include "SKPBench.h" | 20 #include "SKPBench.h" |
19 #include "Stats.h" | 21 #include "Stats.h" |
20 #include "Timer.h" | 22 #include "Timer.h" |
21 | 23 |
22 #include "SkBBoxHierarchy.h" | 24 #include "SkBBoxHierarchy.h" |
23 #include "SkCanvas.h" | 25 #include "SkCanvas.h" |
24 #include "SkCommonFlags.h" | 26 #include "SkCommonFlags.h" |
25 #include "SkData.h" | 27 #include "SkData.h" |
26 #include "SkForceLinking.h" | 28 #include "SkForceLinking.h" |
27 #include "SkGraphics.h" | 29 #include "SkGraphics.h" |
28 #include "SkOSFile.h" | 30 #include "SkOSFile.h" |
29 #include "SkPictureRecorder.h" | 31 #include "SkPictureRecorder.h" |
30 #include "SkPictureUtils.h" | 32 #include "SkPictureUtils.h" |
31 #include "SkString.h" | 33 #include "SkString.h" |
32 #include "SkSurface.h" | 34 #include "SkSurface.h" |
33 #include "SkTaskGroup.h" | 35 #include "SkTaskGroup.h" |
34 | 36 |
| 37 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK |
| 38 #include "nanobenchAndroid.h" |
| 39 #endif |
| 40 |
35 #if SK_SUPPORT_GPU | 41 #if SK_SUPPORT_GPU |
36 #include "gl/GrGLDefines.h" | 42 #include "gl/GrGLDefines.h" |
37 #include "GrContextFactory.h" | 43 #include "GrContextFactory.h" |
38 SkAutoTDelete<GrContextFactory> gGrFactory; | 44 SkAutoTDelete<GrContextFactory> gGrFactory; |
39 #endif | 45 #endif |
40 | 46 |
41 __SK_FORCE_IMAGE_DECODER_LINKING; | 47 __SK_FORCE_IMAGE_DECODER_LINKING; |
42 | 48 |
43 static const int kAutoTuneLoops = 0; | 49 static const int kAutoTuneLoops = 0; |
44 | 50 |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
79 DEFINE_int32(flushEvery, 10, "Flush --outResultsFile every Nth run."); | 85 DEFINE_int32(flushEvery, 10, "Flush --outResultsFile every Nth run."); |
80 DEFINE_bool(resetGpuContext, true, "Reset the GrContext before running each test
."); | 86 DEFINE_bool(resetGpuContext, true, "Reset the GrContext before running each test
."); |
81 DEFINE_bool(gpuStats, false, "Print GPU stats after each gpu benchmark?"); | 87 DEFINE_bool(gpuStats, false, "Print GPU stats after each gpu benchmark?"); |
82 | 88 |
83 static SkString humanize(double ms) { | 89 static SkString humanize(double ms) { |
84 if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); | 90 if (FLAGS_verbose) return SkStringPrintf("%llu", (uint64_t)(ms*1e6)); |
85 return HumanizeMs(ms); | 91 return HumanizeMs(ms); |
86 } | 92 } |
87 #define HUMANIZE(ms) humanize(ms).c_str() | 93 #define HUMANIZE(ms) humanize(ms).c_str() |
88 | 94 |
89 static double time(int loops, Benchmark* bench, SkCanvas* canvas, SkGLContext* g
l) { | 95 bool Target::init(SkImageInfo info, Benchmark* bench) { |
| 96 if (Benchmark::kRaster_Backend == config.backend) { |
| 97 this->surface.reset(SkSurface::NewRaster(info)); |
| 98 if (!this->surface.get()) { |
| 99 return false; |
| 100 } |
| 101 } |
| 102 return true; |
| 103 } |
| 104 bool Target::capturePixels(SkBitmap* bmp) { |
| 105 if (!this->surface.get()) { |
| 106 return false; |
| 107 } |
| 108 SkCanvas* canvas = this->surface->getCanvas(); |
| 109 if (!canvas) { |
| 110 return false; |
| 111 } |
| 112 bmp->setInfo(canvas->imageInfo()); |
| 113 if (!canvas->readPixels(bmp, 0, 0)) { |
| 114 SkDebugf("Can't read canvas pixels.\n"); |
| 115 return false; |
| 116 } |
| 117 return true; |
| 118 } |
| 119 |
| 120 #if SK_SUPPORT_GPU |
| 121 struct GPUTarget : public Target { |
| 122 explicit GPUTarget(const Config& c) : Target(c), gl(NULL) { } |
| 123 SkGLContext* gl; |
| 124 |
| 125 void setup() override { |
| 126 this->gl->makeCurrent(); |
| 127 // Make sure we're done with whatever came before. |
| 128 SK_GL(*this->gl, Finish()); |
| 129 } |
| 130 void endTiming() override { |
| 131 if (this->gl) { |
| 132 SK_GL(*this->gl, Flush()); |
| 133 this->gl->swapBuffers(); |
| 134 } |
| 135 } |
| 136 void fence() override { |
| 137 SK_GL(*this->gl, Finish()); |
| 138 } |
| 139 |
| 140 bool needsFrameTiming() const override { return true; } |
| 141 bool init(SkImageInfo info, Benchmark* bench) override { |
| 142 uint32_t flags = this->config.useDFText ? SkSurfaceProps::kUseDistanceFi
eldFonts_Flag : 0; |
| 143 SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); |
| 144 this->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(this->con
fig.ctxType), |
| 145 SkSurface::kNo_Budgeted
, info, |
| 146 this->config.samples, &
props)); |
| 147 this->gl = gGrFactory->getGLContext(this->config.ctxType); |
| 148 if (!this->surface.get()) { |
| 149 return false; |
| 150 } |
| 151 return true; |
| 152 } |
| 153 void fillOptions(ResultsWriter* log) override { |
| 154 const GrGLubyte* version; |
| 155 SK_GL_RET(*this->gl, version, GetString(GR_GL_VERSION)); |
| 156 log->configOption("GL_VERSION", (const char*)(version)); |
| 157 |
| 158 SK_GL_RET(*this->gl, version, GetString(GR_GL_RENDERER)); |
| 159 log->configOption("GL_RENDERER", (const char*) version); |
| 160 |
| 161 SK_GL_RET(*this->gl, version, GetString(GR_GL_VENDOR)); |
| 162 log->configOption("GL_VENDOR", (const char*) version); |
| 163 |
| 164 SK_GL_RET(*this->gl, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION))
; |
| 165 log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version); |
| 166 } |
| 167 }; |
| 168 |
| 169 #endif |
| 170 |
| 171 static double time(int loops, Benchmark* bench, SkCanvas* canvas, Target* target
) { |
90 if (canvas) { | 172 if (canvas) { |
91 canvas->clear(SK_ColorWHITE); | 173 canvas->clear(SK_ColorWHITE); |
92 } | 174 } |
93 WallTimer timer; | 175 WallTimer timer; |
94 timer.start(); | 176 timer.start(); |
| 177 if (target) { |
| 178 canvas = target->beginTiming(canvas); |
| 179 } |
95 if (bench) { | 180 if (bench) { |
96 bench->draw(loops, canvas); | 181 bench->draw(loops, canvas); |
97 } | 182 } |
98 if (canvas) { | 183 if (canvas) { |
99 canvas->flush(); | 184 canvas->flush(); |
100 } | 185 } |
101 #if SK_SUPPORT_GPU | 186 if (target) { |
102 if (gl) { | 187 target->endTiming(); |
103 SK_GL(*gl, Flush()); | |
104 gl->swapBuffers(); | |
105 } | 188 } |
106 #endif | |
107 timer.end(); | 189 timer.end(); |
108 return timer.fWall; | 190 return timer.fWall; |
109 } | 191 } |
110 | 192 |
111 static double estimate_timer_overhead() { | 193 static double estimate_timer_overhead() { |
112 double overhead = 0; | 194 double overhead = 0; |
113 for (int i = 0; i < FLAGS_overheadLoops; i++) { | 195 for (int i = 0; i < FLAGS_overheadLoops; i++) { |
114 overhead += time(1, NULL, NULL, NULL); | 196 overhead += time(1, NULL, NULL, NULL); |
115 } | 197 } |
116 return overhead / FLAGS_overheadLoops; | 198 return overhead / FLAGS_overheadLoops; |
(...skipping 13 matching lines...) Expand all Loading... |
130 "There's probably something wrong with the bench.\n", loops); | 212 "There's probably something wrong with the bench.\n", loops); |
131 return 1; | 213 return 1; |
132 } | 214 } |
133 if (loops > FLAGS_maxLoops) { | 215 if (loops > FLAGS_maxLoops) { |
134 SkDebugf("WARNING: clamping loops from %d to FLAGS_maxLoops, %d.\n", loo
ps, FLAGS_maxLoops); | 216 SkDebugf("WARNING: clamping loops from %d to FLAGS_maxLoops, %d.\n", loo
ps, FLAGS_maxLoops); |
135 return FLAGS_maxLoops; | 217 return FLAGS_maxLoops; |
136 } | 218 } |
137 return loops; | 219 return loops; |
138 } | 220 } |
139 | 221 |
140 static bool write_canvas_png(SkCanvas* canvas, const SkString& filename) { | 222 static bool write_canvas_png(Target* target, const SkString& filename) { |
| 223 |
141 if (filename.isEmpty()) { | 224 if (filename.isEmpty()) { |
142 return false; | 225 return false; |
143 } | 226 } |
144 if (kUnknown_SkColorType == canvas->imageInfo().colorType()) { | 227 if (target->surface.get() && target->surface->getCanvas() && |
| 228 kUnknown_SkColorType == target->surface->getCanvas()->imageInfo().colorT
ype()) { |
145 return false; | 229 return false; |
146 } | 230 } |
| 231 |
147 SkBitmap bmp; | 232 SkBitmap bmp; |
148 bmp.setInfo(canvas->imageInfo()); | 233 |
149 if (!canvas->readPixels(&bmp, 0, 0)) { | 234 if (!target->capturePixels(&bmp)) { |
150 SkDebugf("Can't read canvas pixels.\n"); | |
151 return false; | 235 return false; |
152 } | 236 } |
| 237 |
153 SkString dir = SkOSPath::Dirname(filename.c_str()); | 238 SkString dir = SkOSPath::Dirname(filename.c_str()); |
154 if (!sk_mkdir(dir.c_str())) { | 239 if (!sk_mkdir(dir.c_str())) { |
155 SkDebugf("Can't make dir %s.\n", dir.c_str()); | 240 SkDebugf("Can't make dir %s.\n", dir.c_str()); |
156 return false; | 241 return false; |
157 } | 242 } |
158 SkFILEWStream stream(filename.c_str()); | 243 SkFILEWStream stream(filename.c_str()); |
159 if (!stream.isValid()) { | 244 if (!stream.isValid()) { |
160 SkDebugf("Can't write %s.\n", filename.c_str()); | 245 SkDebugf("Can't write %s.\n", filename.c_str()); |
161 return false; | 246 return false; |
162 } | 247 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 } else { | 293 } else { |
209 loops = detect_forever_loops(loops); | 294 loops = detect_forever_loops(loops); |
210 } | 295 } |
211 | 296 |
212 for (int i = 0; i < FLAGS_samples; i++) { | 297 for (int i = 0; i < FLAGS_samples; i++) { |
213 samples[i] = time(loops, bench, canvas, NULL) / loops; | 298 samples[i] = time(loops, bench, canvas, NULL) / loops; |
214 } | 299 } |
215 return loops; | 300 return loops; |
216 } | 301 } |
217 | 302 |
218 #if SK_SUPPORT_GPU | 303 static int gpu_bench(Target* target, |
219 static void setup_gl(SkGLContext* gl) { | |
220 gl->makeCurrent(); | |
221 // Make sure we're done with whatever came before. | |
222 SK_GL(*gl, Finish()); | |
223 } | |
224 | |
225 static int gpu_bench(SkGLContext* gl, | |
226 Benchmark* bench, | 304 Benchmark* bench, |
227 SkCanvas* canvas, | 305 SkCanvas* canvas, |
228 double* samples) { | 306 double* samples) { |
229 // First, figure out how many loops it'll take to get a frame up to FLAGS_gp
uMs. | 307 // First, figure out how many loops it'll take to get a frame up to FLAGS_gp
uMs. |
230 int loops = FLAGS_loops; | 308 int loops = FLAGS_loops; |
231 if (kAutoTuneLoops == loops) { | 309 if (kAutoTuneLoops == loops) { |
232 loops = 1; | 310 loops = 1; |
233 double elapsed = 0; | 311 double elapsed = 0; |
234 do { | 312 do { |
235 if (1<<30 == loops) { | 313 if (1<<30 == loops) { |
236 // We're about to wrap. Something's wrong with the bench. | 314 // We're about to wrap. Something's wrong with the bench. |
237 loops = 0; | 315 loops = 0; |
238 break; | 316 break; |
239 } | 317 } |
240 loops *= 2; | 318 loops *= 2; |
241 // If the GPU lets frames lag at all, we need to make sure we're tim
ing | 319 // If the GPU lets frames lag at all, we need to make sure we're tim
ing |
242 // _this_ round, not still timing last round. We force this by loop
ing | 320 // _this_ round, not still timing last round. We force this by loop
ing |
243 // more times than any reasonable GPU will allow frames to lag. | 321 // more times than any reasonable GPU will allow frames to lag. |
244 for (int i = 0; i < FLAGS_gpuFrameLag; i++) { | 322 for (int i = 0; i < FLAGS_gpuFrameLag; i++) { |
245 elapsed = time(loops, bench, canvas, gl); | 323 elapsed = time(loops, bench, canvas, target); |
246 } | 324 } |
247 } while (elapsed < FLAGS_gpuMs); | 325 } while (elapsed < FLAGS_gpuMs); |
248 | 326 |
249 // We've overshot at least a little. Scale back linearly. | 327 // We've overshot at least a little. Scale back linearly. |
250 loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); | 328 loops = (int)ceil(loops * FLAGS_gpuMs / elapsed); |
251 loops = clamp_loops(loops); | 329 loops = clamp_loops(loops); |
252 | 330 |
253 // Might as well make sure we're not still timing our calibration. | 331 // Make sure we're not still timing our calibration. |
254 SK_GL(*gl, Finish()); | 332 target->fence(); |
255 } else { | 333 } else { |
256 loops = detect_forever_loops(loops); | 334 loops = detect_forever_loops(loops); |
257 } | 335 } |
258 | 336 |
259 // Pretty much the same deal as the calibration: do some warmup to make | 337 // Pretty much the same deal as the calibration: do some warmup to make |
260 // sure we're timing steady-state pipelined frames. | 338 // sure we're timing steady-state pipelined frames. |
261 for (int i = 0; i < FLAGS_gpuFrameLag; i++) { | 339 for (int i = 0; i < FLAGS_gpuFrameLag; i++) { |
262 time(loops, bench, canvas, gl); | 340 time(loops, bench, canvas, target); |
263 } | 341 } |
264 | 342 |
265 // Now, actually do the timing! | 343 // Now, actually do the timing! |
266 for (int i = 0; i < FLAGS_samples; i++) { | 344 for (int i = 0; i < FLAGS_samples; i++) { |
267 samples[i] = time(loops, bench, canvas, gl) / loops; | 345 samples[i] = time(loops, bench, canvas, target) / loops; |
268 } | 346 } |
| 347 |
269 return loops; | 348 return loops; |
270 } | 349 } |
271 #endif | |
272 | 350 |
273 static SkString to_lower(const char* str) { | 351 static SkString to_lower(const char* str) { |
274 SkString lower(str); | 352 SkString lower(str); |
275 for (size_t i = 0; i < lower.size(); i++) { | 353 for (size_t i = 0; i < lower.size(); i++) { |
276 lower[i] = tolower(lower[i]); | 354 lower[i] = tolower(lower[i]); |
277 } | 355 } |
278 return lower; | 356 return lower; |
279 } | 357 } |
280 | 358 |
281 struct Config { | |
282 const char* name; | |
283 Benchmark::Backend backend; | |
284 SkColorType color; | |
285 SkAlphaType alpha; | |
286 int samples; | |
287 #if SK_SUPPORT_GPU | |
288 GrContextFactory::GLContextType ctxType; | |
289 bool useDFText; | |
290 #else | |
291 int bogusInt; | |
292 bool bogusBool; | |
293 #endif | |
294 }; | |
295 | |
296 struct Target { | |
297 explicit Target(const Config& c) : config(c) {} | |
298 const Config config; | |
299 SkAutoTDelete<SkSurface> surface; | |
300 #if SK_SUPPORT_GPU | |
301 SkGLContext* gl; | |
302 #endif | |
303 }; | |
304 | |
305 static bool is_cpu_config_allowed(const char* name) { | 359 static bool is_cpu_config_allowed(const char* name) { |
306 for (int i = 0; i < FLAGS_config.count(); i++) { | 360 for (int i = 0; i < FLAGS_config.count(); i++) { |
307 if (to_lower(FLAGS_config[i]).equals(name)) { | 361 if (to_lower(FLAGS_config[i]).equals(name)) { |
308 return true; | 362 return true; |
309 } | 363 } |
310 } | 364 } |
311 return false; | 365 return false; |
312 } | 366 } |
313 | 367 |
314 #if SK_SUPPORT_GPU | 368 #if SK_SUPPORT_GPU |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
366 GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4, false) | 420 GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4, false) |
367 GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16, false) | 421 GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16, false) |
368 GPU_CONFIG(gpudft, kNative_GLContextType, 0, true) | 422 GPU_CONFIG(gpudft, kNative_GLContextType, 0, true) |
369 GPU_CONFIG(debug, kDebug_GLContextType, 0, false) | 423 GPU_CONFIG(debug, kDebug_GLContextType, 0, false) |
370 GPU_CONFIG(nullgpu, kNull_GLContextType, 0, false) | 424 GPU_CONFIG(nullgpu, kNull_GLContextType, 0, false) |
371 #ifdef SK_ANGLE | 425 #ifdef SK_ANGLE |
372 GPU_CONFIG(angle, kANGLE_GLContextType, 0, false) | 426 GPU_CONFIG(angle, kANGLE_GLContextType, 0, false) |
373 #endif | 427 #endif |
374 } | 428 } |
375 #endif | 429 #endif |
| 430 |
| 431 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK |
| 432 if (is_cpu_config_allowed("hwui")) { |
| 433 Config config = { "hwui", Benchmark::kHWUI_Backend, kRGBA_8888_SkColorTy
pe, |
| 434 kPremul_SkAlphaType, 0, kBogusGLContextType, false }; |
| 435 configs->push(config); |
| 436 } |
| 437 #endif |
376 } | 438 } |
377 | 439 |
378 // If bench is enabled for config, returns a Target* for it, otherwise NULL. | 440 // If bench is enabled for config, returns a Target* for it, otherwise NULL. |
379 static Target* is_enabled(Benchmark* bench, const Config& config) { | 441 static Target* is_enabled(Benchmark* bench, const Config& config) { |
380 if (!bench->isSuitableFor(config.backend)) { | 442 if (!bench->isSuitableFor(config.backend)) { |
381 return NULL; | 443 return NULL; |
382 } | 444 } |
383 | 445 |
384 SkImageInfo info = SkImageInfo::Make(bench->getSize().fX, bench->getSize().f
Y, | 446 SkImageInfo info = SkImageInfo::Make(bench->getSize().fX, bench->getSize().f
Y, |
385 config.color, config.alpha); | 447 config.color, config.alpha); |
386 | 448 |
387 Target* target = new Target(config); | 449 Target* target = NULL; |
388 | 450 |
389 if (Benchmark::kRaster_Backend == config.backend) { | 451 switch (config.backend) { |
390 target->surface.reset(SkSurface::NewRaster(info)); | 452 #if SK_SUPPORT_GPU |
| 453 case Benchmark::kGPU_Backend: |
| 454 target = new GPUTarget(config); |
| 455 break; |
| 456 #endif |
| 457 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK |
| 458 case Benchmark::kHWUI_Backend: |
| 459 target = new HWUITarget(config, bench); |
| 460 break; |
| 461 #endif |
| 462 default: |
| 463 target = new Target(config); |
| 464 break; |
391 } | 465 } |
392 #if SK_SUPPORT_GPU | |
393 else if (Benchmark::kGPU_Backend == config.backend) { | |
394 uint32_t flags = config.useDFText ? SkSurfaceProps::kUseDistanceFieldFon
ts_Flag : 0; | |
395 SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType); | |
396 target->surface.reset(SkSurface::NewRenderTarget(gGrFactory->get(config.
ctxType), | |
397 SkSurface::kNo_Budgeted
, info, | |
398 config.samples, &props)
); | |
399 target->gl = gGrFactory->getGLContext(config.ctxType); | |
400 } | |
401 #endif | |
402 | 466 |
403 if (Benchmark::kNonRendering_Backend != config.backend && !target->surface.g
et()) { | 467 if (!target->init(info, bench)) { |
404 delete target; | 468 delete target; |
405 return NULL; | 469 return NULL; |
406 } | 470 } |
407 return target; | 471 return target; |
408 } | 472 } |
409 | 473 |
410 // Creates targets for a benchmark and a set of configs. | 474 // Creates targets for a benchmark and a set of configs. |
411 static void create_targets(SkTDArray<Target*>* targets, Benchmark* b, | 475 static void create_targets(SkTDArray<Target*>* targets, Benchmark* b, |
412 const SkTDArray<Config>& configs) { | 476 const SkTDArray<Config>& configs) { |
413 for (int i = 0; i < configs.count(); ++i) { | 477 for (int i = 0; i < configs.count(); ++i) { |
414 if (Target* t = is_enabled(b, configs[i])) { | 478 if (Target* t = is_enabled(b, configs[i])) { |
415 targets->push(t); | 479 targets->push(t); |
416 } | 480 } |
417 | 481 |
418 } | 482 } |
419 } | 483 } |
420 | 484 |
421 #if SK_SUPPORT_GPU | |
422 static void fill_gpu_options(ResultsWriter* log, SkGLContext* ctx) { | |
423 const GrGLubyte* version; | |
424 SK_GL_RET(*ctx, version, GetString(GR_GL_VERSION)); | |
425 log->configOption("GL_VERSION", (const char*)(version)); | |
426 | |
427 SK_GL_RET(*ctx, version, GetString(GR_GL_RENDERER)); | |
428 log->configOption("GL_RENDERER", (const char*) version); | |
429 | |
430 SK_GL_RET(*ctx, version, GetString(GR_GL_VENDOR)); | |
431 log->configOption("GL_VENDOR", (const char*) version); | |
432 | |
433 SK_GL_RET(*ctx, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION)); | |
434 log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version); | |
435 } | |
436 #endif | |
437 | 485 |
438 class BenchmarkStream { | 486 class BenchmarkStream { |
439 public: | 487 public: |
440 BenchmarkStream() : fBenches(BenchRegistry::Head()) | 488 BenchmarkStream() : fBenches(BenchRegistry::Head()) |
441 , fGMs(skiagm::GMRegistry::Head()) | 489 , fGMs(skiagm::GMRegistry::Head()) |
442 , fCurrentRecording(0) | 490 , fCurrentRecording(0) |
443 , fCurrentScale(0) | 491 , fCurrentScale(0) |
444 , fCurrentSKP(0) | 492 , fCurrentSKP(0) |
445 , fCurrentUseMPD(0) | 493 , fCurrentUseMPD(0) |
446 , fCurrentImage(0) | 494 , fCurrentImage(0) |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 } | 831 } |
784 | 832 |
785 SkTDArray<Target*> targets; | 833 SkTDArray<Target*> targets; |
786 create_targets(&targets, bench.get(), configs); | 834 create_targets(&targets, bench.get(), configs); |
787 | 835 |
788 if (!targets.isEmpty()) { | 836 if (!targets.isEmpty()) { |
789 log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSi
ze().fY); | 837 log->bench(bench->getUniqueName(), bench->getSize().fX, bench->getSi
ze().fY); |
790 bench->preDraw(); | 838 bench->preDraw(); |
791 } | 839 } |
792 for (int j = 0; j < targets.count(); j++) { | 840 for (int j = 0; j < targets.count(); j++) { |
| 841 // During HWUI output this canvas may be NULL. |
793 SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->
getCanvas() : NULL; | 842 SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->
getCanvas() : NULL; |
794 const char* config = targets[j]->config.name; | 843 const char* config = targets[j]->config.name; |
795 | 844 |
796 #if SK_SUPPORT_GPU | 845 targets[j]->setup(); |
797 if (Benchmark::kGPU_Backend == targets[j]->config.backend) { | |
798 setup_gl(targets[j]->gl); | |
799 } | |
800 #endif | |
801 | |
802 bench->perCanvasPreDraw(canvas); | 846 bench->perCanvasPreDraw(canvas); |
803 | 847 |
804 const int loops = | 848 const int loops = |
805 #if SK_SUPPORT_GPU | 849 targets[j]->needsFrameTiming() |
806 Benchmark::kGPU_Backend == targets[j]->config.backend | 850 ? gpu_bench(targets[j], bench.get(), canvas, samples.get()) |
807 ? gpu_bench(targets[j]->gl, bench.get(), canvas, samples.get()) | 851 : cpu_bench(overhead, bench.get(), canvas, samples.get()); |
808 : | |
809 #endif | |
810 cpu_bench( overhead, bench.get(), canvas, samples.get()); | |
811 | 852 |
812 bench->perCanvasPostDraw(canvas); | 853 bench->perCanvasPostDraw(canvas); |
813 | 854 |
814 if (canvas && !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { | 855 if (Benchmark::kNonRendering_Backend != targets[j]->config.backend &
& |
| 856 !FLAGS_writePath.isEmpty() && FLAGS_writePath[0]) { |
815 SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config
); | 857 SkString pngFilename = SkOSPath::Join(FLAGS_writePath[0], config
); |
816 pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniq
ueName()); | 858 pngFilename = SkOSPath::Join(pngFilename.c_str(), bench->getUniq
ueName()); |
817 pngFilename.append(".png"); | 859 pngFilename.append(".png"); |
818 write_canvas_png(canvas, pngFilename); | 860 write_canvas_png(targets[j], pngFilename); |
819 } | 861 } |
820 | 862 |
821 if (kFailedLoops == loops) { | 863 if (kFailedLoops == loops) { |
822 // Can't be timed. A warning note has already been printed. | 864 // Can't be timed. A warning note has already been printed. |
823 continue; | 865 continue; |
824 } | 866 } |
825 | 867 |
826 Stats stats(samples.get(), FLAGS_samples); | 868 Stats stats(samples.get(), FLAGS_samples); |
827 log->config(config); | 869 log->config(config); |
828 log->configOption("name", bench->getName()); | 870 log->configOption("name", bench->getName()); |
829 benchStream.fillCurrentOptions(log.get()); | 871 benchStream.fillCurrentOptions(log.get()); |
830 #if SK_SUPPORT_GPU | 872 targets[j]->fillOptions(log.get()); |
831 if (Benchmark::kGPU_Backend == targets[j]->config.backend) { | |
832 fill_gpu_options(log.get(), targets[j]->gl); | |
833 } | |
834 #endif | |
835 log->metric("min_ms", stats.min); | 873 log->metric("min_ms", stats.min); |
836 if (runs++ % FLAGS_flushEvery == 0) { | 874 if (runs++ % FLAGS_flushEvery == 0) { |
837 log->flush(); | 875 log->flush(); |
838 } | 876 } |
839 | 877 |
840 if (kAutoTuneLoops != FLAGS_loops) { | 878 if (kAutoTuneLoops != FLAGS_loops) { |
841 if (targets.count() == 1) { | 879 if (targets.count() == 1) { |
842 config = ""; // Only print the config if we run the same ben
ch on more than one. | 880 config = ""; // Only print the config if we run the same ben
ch on more than one. |
843 } | 881 } |
844 SkDebugf("%4dM\t%s\t%s\n" | 882 SkDebugf("%4dM\t%s\t%s\n" |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
896 | 934 |
897 return 0; | 935 return 0; |
898 } | 936 } |
899 | 937 |
900 #if !defined SK_BUILD_FOR_IOS | 938 #if !defined SK_BUILD_FOR_IOS |
901 int main(int argc, char** argv) { | 939 int main(int argc, char** argv) { |
902 SkCommandLineFlags::Parse(argc, argv); | 940 SkCommandLineFlags::Parse(argc, argv); |
903 return nanobench_main(); | 941 return nanobench_main(); |
904 } | 942 } |
905 #endif | 943 #endif |
OLD | NEW |