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 "Benchmark.h" | 10 #include "Benchmark.h" |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
146 samples[i] = time(loops, bench, canvas, NULL) / loops; | 146 samples[i] = time(loops, bench, canvas, NULL) / loops; |
147 } | 147 } |
148 return loops; | 148 return loops; |
149 } | 149 } |
150 | 150 |
151 #if SK_SUPPORT_GPU | 151 #if SK_SUPPORT_GPU |
152 static int gpu_bench(SkGLContextHelper* gl, | 152 static int gpu_bench(SkGLContextHelper* gl, |
153 Benchmark* bench, | 153 Benchmark* bench, |
154 SkCanvas* canvas, | 154 SkCanvas* canvas, |
155 double* samples) { | 155 double* samples) { |
156 gl->makeCurrent(); | |
156 // Make sure we're done with whatever came before. | 157 // Make sure we're done with whatever came before. |
157 SK_GL(*gl, Finish()); | 158 SK_GL(*gl, Finish()); |
158 | 159 |
159 // First, figure out how many loops it'll take to get a frame up to FLAGS_gp uMs. | 160 // First, figure out how many loops it'll take to get a frame up to FLAGS_gp uMs. |
160 int loops = 1; | 161 int loops = 1; |
161 if (!FLAGS_runOnce) { | 162 if (!FLAGS_runOnce) { |
162 double elapsed = 0; | 163 double elapsed = 0; |
163 do { | 164 do { |
164 loops *= 2; | 165 loops *= 2; |
165 // If the GPU lets frames lag at all, we need to make sure we're tim ing | 166 // If the GPU lets frames lag at all, we need to make sure we're tim ing |
(...skipping 27 matching lines...) Expand all Loading... | |
193 #endif | 194 #endif |
194 | 195 |
195 static SkString to_lower(const char* str) { | 196 static SkString to_lower(const char* str) { |
196 SkString lower(str); | 197 SkString lower(str); |
197 for (size_t i = 0; i < lower.size(); i++) { | 198 for (size_t i = 0; i < lower.size(); i++) { |
198 lower[i] = tolower(lower[i]); | 199 lower[i] = tolower(lower[i]); |
199 } | 200 } |
200 return lower; | 201 return lower; |
201 } | 202 } |
202 | 203 |
204 struct Config { | |
205 const char* name; | |
206 Benchmark::Backend backend; | |
207 SkColorType color; | |
208 SkAlphaType alpha; | |
209 int samples; | |
210 #if SK_SUPPORT_GPU | |
211 GrContextFactory::GLContextType ctxType; | |
212 #endif | |
213 }; | |
214 | |
203 struct Target { | 215 struct Target { |
204 const char* config; | 216 explicit Target(const Config& c) : config(c) {} |
205 Benchmark::Backend backend; | 217 const Config config; |
mtklein
2014/07/22 18:16:17
No copy if you hold this as const Config& config.
bsalomon
2014/07/22 18:40:01
I know but the copy seems harmless and less prone
| |
206 SkAutoTDelete<SkSurface> surface; | 218 SkAutoTDelete<SkSurface> surface; |
207 #if SK_SUPPORT_GPU | 219 #if SK_SUPPORT_GPU |
208 SkGLContextHelper* gl; | 220 SkGLContextHelper* gl; |
209 #endif | 221 #endif |
210 }; | 222 }; |
211 | 223 |
212 // If bench is enabled for backend/config, returns a Target* for them, otherwise NULL. | 224 static bool is_cpu_config_allowed(const char* name) { |
213 static Target* is_enabled(Benchmark* bench, Benchmark::Backend backend, const ch ar* config) { | 225 for (int i = 0; i < FLAGS_config.count(); i++) { |
214 if (!bench->isSuitableFor(backend)) { | 226 if (to_lower(FLAGS_config[i]).equals(name)) { |
227 return true; | |
228 } | |
229 } | |
230 return false; | |
231 } | |
232 | |
233 #if SK_SUPPORT_GPU | |
234 static bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextT ype ctxType, | |
235 int sampleCnt) { | |
236 if (!is_cpu_config_allowed(name)) { | |
237 return false; | |
238 } | |
239 if (const GrContext* ctx = gGrFactory.get(ctxType)) { | |
240 return sampleCnt <= ctx->getMaxSampleCount(); | |
241 } | |
242 return false; | |
243 } | |
244 #endif | |
245 | |
246 // Append all configs that are enabled and supported. | |
247 static void create_configs(SkTDArray<Config>* configs) { | |
248 #define CPU_CONFIG(name, backend, color, alpha) \ | |
249 if (is_cpu_config_allowed(#name)) { \ | |
250 Config config = { #name, Benchmark::backend, color, alpha, 0 }; \ | |
251 configs->push(config); \ | |
252 } | |
253 | |
254 if (FLAGS_cpu) { | |
255 CPU_CONFIG(nonrendering, kNonRendering_Backend, kUnknown_SkColorType, kU npremul_SkAlphaType) | |
256 CPU_CONFIG(8888, kRaster_Backend, kN32_SkColorType, kPremul_SkAlphaType) | |
257 CPU_CONFIG(565, kRaster_Backend, kRGB_565_SkColorType, kOpaque_SkAlphaTy pe) | |
258 } | |
259 | |
260 #if SK_SUPPORT_GPU | |
261 #define GPU_CONFIG(name, ctxType, samples) \ | |
262 if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, samples)) { \ | |
263 Config config = { \ | |
264 #name, \ | |
265 Benchmark::kGPU_Backend, \ | |
266 kN32_SkColorType, \ | |
267 kPremul_SkAlphaType, \ | |
268 samples, \ | |
269 GrContextFactory::ctxType }; \ | |
270 configs->push(config); \ | |
271 } | |
272 | |
273 if (FLAGS_gpu) { | |
274 GPU_CONFIG(gpu, kNative_GLContextType, 0) | |
275 GPU_CONFIG(msaa4, kNative_GLContextType, 4) | |
276 GPU_CONFIG(msaa16, kNative_GLContextType, 16) | |
277 GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4) | |
278 GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16) | |
279 GPU_CONFIG(debug, kDebug_GLContextType, 0) | |
280 GPU_CONFIG(nullgpu, kNull_GLContextType, 0) | |
281 } | |
282 #endif | |
283 } | |
284 | |
285 // If bench is enabled for config, returns a Target* for it, otherwise NULL. | |
286 static Target* is_enabled(Benchmark* bench, const Config& config) { | |
287 if (!bench->isSuitableFor(config.backend)) { | |
215 return NULL; | 288 return NULL; |
216 } | 289 } |
217 | 290 |
218 for (int i = 0; i < FLAGS_config.count(); i++) { | 291 SkImageInfo info; |
219 if (to_lower(FLAGS_config[i]).equals(config)) { | 292 info.fAlphaType = config.alpha; |
220 Target* target = new Target; | 293 info.fColorType = config.color; |
221 target->config = config; | 294 info.fWidth = bench->getSize().fX; |
222 target->backend = backend; | 295 info.fHeight = bench->getSize().fY; |
223 return target; | 296 |
224 } | 297 Target* target = new Target(config); |
298 | |
299 if (Benchmark::kRaster_Backend == config.backend) { | |
300 target->surface.reset(SkSurface::NewRaster(info)); | |
225 } | 301 } |
226 return NULL; | 302 #if SK_SUPPORT_GPU |
303 else if (Benchmark::kGPU_Backend == config.backend) { | |
304 target->surface.reset(SkSurface::NewRenderTarget(gGrFactory.get(config.c txType), info, | |
305 config.samples)); | |
306 target->gl = gGrFactory.getGLContext(config.ctxType); | |
307 } | |
308 #endif | |
309 | |
310 if (Benchmark::kNonRendering_Backend != config.backend && !target->surface.g et()) { | |
311 delete target; | |
312 return NULL; | |
313 } | |
314 return target; | |
227 } | 315 } |
228 | 316 |
229 // Append all targets that are suitable for bench. | 317 // Creates targets for a benchmark and a set of configs. |
230 static void create_targets(Benchmark* bench, SkTDArray<Target*>* targets) { | 318 static void create_targets(SkTDArray<Target*>* targets, Benchmark* b, |
231 const int w = bench->getSize().fX, | 319 const SkTDArray<Config>& configs) { |
232 h = bench->getSize().fY; | 320 for (int i = 0; i < configs.count(); ++i) { |
233 const SkImageInfo _8888 = { w, h, kN32_SkColorType, kPremul_SkAlphaType }, | 321 if (Target* t = is_enabled(b, configs[i])) { |
234 _565 = { w, h, kRGB_565_SkColorType, kOpaque_SkAlphaType }; | 322 targets->push(t); |
235 | |
236 #define CPU_TARGET(config, backend, code) \ | |
237 if (Target* t = is_enabled(bench, Benchmark::backend, #config)) { \ | |
238 t->surface.reset(code); \ | |
239 targets->push(t); \ | |
240 } | 323 } |
241 if (FLAGS_cpu) { | 324 |
242 CPU_TARGET(nonrendering, kNonRendering_Backend, NULL) | |
243 CPU_TARGET(8888, kRaster_Backend, SkSurface::NewRaster(_8888)) | |
244 CPU_TARGET(565, kRaster_Backend, SkSurface::NewRaster(_565)) | |
245 } | 325 } |
246 | |
247 #if SK_SUPPORT_GPU | |
248 | |
249 #define GPU_TARGET(config, ctxType, info, samples) \ | |
250 if (Target* t = is_enabled(bench, Benchmark::kGPU_Backend, #config)) { \ | |
251 t->surface.reset(SkSurface::NewRenderTarget(gGrFactory.get(ctxType), info, samples)); \ | |
252 t->gl = gGrFactory.getGLContext(ctxType); \ | |
253 targets->push(t); \ | |
254 } | |
255 if (FLAGS_gpu) { | |
256 GPU_TARGET(gpu, GrContextFactory::kNative_GLContextType, _8888, 0) | |
257 GPU_TARGET(msaa4, GrContextFactory::kNative_GLContextType, _8888, 4) | |
258 GPU_TARGET(msaa16, GrContextFactory::kNative_GLContextType, _8888, 16) | |
259 GPU_TARGET(nvprmsaa4, GrContextFactory::kNVPR_GLContextType, _8888, 4) | |
260 GPU_TARGET(nvprmsaa16, GrContextFactory::kNVPR_GLContextType, _8888, 16) | |
261 GPU_TARGET(debug, GrContextFactory::kDebug_GLContextType, _8888, 0) | |
262 GPU_TARGET(nullgpu, GrContextFactory::kNull_GLContextType, _8888, 0) | |
263 #if SK_ANGLE | |
264 GPU_TARGET(angle, GrContextFactory::kANGLE_GLContextType, _8888, 0) | |
265 #endif | |
266 } | |
267 #endif | |
268 } | 326 } |
269 | 327 |
270 static void fill_static_options(ResultsWriter* log) { | 328 static void fill_static_options(ResultsWriter* log) { |
271 #if defined(SK_BUILD_FOR_WIN32) | 329 #if defined(SK_BUILD_FOR_WIN32) |
272 log->option("system", "WIN32"); | 330 log->option("system", "WIN32"); |
273 #elif defined(SK_BUILD_FOR_MAC) | 331 #elif defined(SK_BUILD_FOR_MAC) |
274 log->option("system", "MAC"); | 332 log->option("system", "MAC"); |
275 #elif defined(SK_BUILD_FOR_ANDROID) | 333 #elif defined(SK_BUILD_FOR_ANDROID) |
276 log->option("system", "ANDROID"); | 334 log->option("system", "ANDROID"); |
277 #elif defined(SK_BUILD_FOR_UNIX) | 335 #elif defined(SK_BUILD_FOR_UNIX) |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
335 if (FLAGS_runOnce) { | 393 if (FLAGS_runOnce) { |
336 SkDebugf("--runOnce is true; times would only be misleading so we won't print them.\n"); | 394 SkDebugf("--runOnce is true; times would only be misleading so we won't print them.\n"); |
337 } else if (FLAGS_verbose) { | 395 } else if (FLAGS_verbose) { |
338 // No header. | 396 // No header. |
339 } else if (FLAGS_quiet) { | 397 } else if (FLAGS_quiet) { |
340 SkDebugf("median\tbench\tconfig\n"); | 398 SkDebugf("median\tbench\tconfig\n"); |
341 } else { | 399 } else { |
342 SkDebugf("loops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\ n"); | 400 SkDebugf("loops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\ n"); |
343 } | 401 } |
344 | 402 |
403 SkTDArray<Config> configs; | |
404 create_configs(&configs); | |
405 | |
345 for (const BenchRegistry* r = BenchRegistry::Head(); r != NULL; r = r->next( )) { | 406 for (const BenchRegistry* r = BenchRegistry::Head(); r != NULL; r = r->next( )) { |
346 SkAutoTDelete<Benchmark> bench(r->factory()(NULL)); | 407 SkAutoTDelete<Benchmark> bench(r->factory()(NULL)); |
347 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { | 408 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { |
348 continue; | 409 continue; |
349 } | 410 } |
350 | 411 |
351 SkTDArray<Target*> targets; | 412 SkTDArray<Target*> targets; |
352 create_targets(bench.get(), &targets); | 413 create_targets(&targets, bench.get(), configs); |
353 | 414 |
354 if (!targets.isEmpty()) { | 415 if (!targets.isEmpty()) { |
355 log.bench(bench->getName(), bench->getSize().fX, bench->getSize().fY ); | 416 log.bench(bench->getName(), bench->getSize().fX, bench->getSize().fY ); |
356 bench->preDraw(); | 417 bench->preDraw(); |
357 } | 418 } |
358 for (int j = 0; j < targets.count(); j++) { | 419 for (int j = 0; j < targets.count(); j++) { |
359 SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface-> getCanvas() : NULL; | 420 SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface-> getCanvas() : NULL; |
360 const char* config = targets[j]->config; | 421 const char* config = targets[j]->config.name; |
361 | 422 |
362 const int loops = | 423 const int loops = |
363 #if SK_SUPPORT_GPU | 424 #if SK_SUPPORT_GPU |
364 Benchmark::kGPU_Backend == targets[j]->backend | 425 Benchmark::kGPU_Backend == targets[j]->config.backend |
365 ? gpu_bench(targets[j]->gl, bench.get(), canvas, samples.get()) | 426 ? gpu_bench(targets[j]->gl, bench.get(), canvas, samples.get()) |
366 : | 427 : |
367 #endif | 428 #endif |
368 cpu_bench( overhead, bench.get(), canvas, samples.get()); | 429 cpu_bench( overhead, bench.get(), canvas, samples.get()); |
369 | 430 |
370 if (loops == 0) { | 431 if (loops == 0) { |
371 SkDebugf("Unable to time %s\t%s (overhead %s)\n", | 432 SkDebugf("Unable to time %s\t%s (overhead %s)\n", |
372 bench->getName(), config, HUMANIZE(overhead)); | 433 bench->getName(), config, HUMANIZE(overhead)); |
373 continue; | 434 continue; |
374 } | 435 } |
375 | 436 |
376 Stats stats(samples.get(), FLAGS_samples); | 437 Stats stats(samples.get(), FLAGS_samples); |
377 log.config(config); | 438 log.config(config); |
378 #if SK_SUPPORT_GPU | 439 #if SK_SUPPORT_GPU |
379 if (Benchmark::kGPU_Backend == targets[j]->backend) { | 440 if (Benchmark::kGPU_Backend == targets[j]->config.backend) { |
380 fill_gpu_options(&log, targets[j]->gl); | 441 fill_gpu_options(&log, targets[j]->gl); |
381 } | 442 } |
382 #endif | 443 #endif |
383 log.timer("min_ms", stats.min); | 444 log.timer("min_ms", stats.min); |
384 log.timer("median_ms", stats.median); | 445 log.timer("median_ms", stats.median); |
385 log.timer("mean_ms", stats.mean); | 446 log.timer("mean_ms", stats.mean); |
386 log.timer("max_ms", stats.max); | 447 log.timer("max_ms", stats.max); |
387 log.timer("stddev_ms", sqrt(stats.var)); | 448 log.timer("stddev_ms", sqrt(stats.var)); |
388 | 449 |
389 if (FLAGS_runOnce) { | 450 if (FLAGS_runOnce) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
426 } | 487 } |
427 | 488 |
428 return 0; | 489 return 0; |
429 } | 490 } |
430 | 491 |
431 #if !defined SK_BUILD_FOR_IOS | 492 #if !defined SK_BUILD_FOR_IOS |
432 int main(int argc, char * const argv[]) { | 493 int main(int argc, char * const argv[]) { |
433 return tool_main(argc, (char**) argv); | 494 return tool_main(argc, (char**) argv); |
434 } | 495 } |
435 #endif | 496 #endif |
OLD | NEW |