Chromium Code Reviews| 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 |