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 const Config* config; |
|
mtklein
2014/07/22 17:44:19
// unowned
or perhaps this?
struct Target {
ex
bsalomon
2014/07/22 18:10:14
Done, but makes a copy of config (seems harmless).
| |
| 205 Benchmark::Backend backend; | |
| 206 SkAutoTDelete<SkSurface> surface; | 217 SkAutoTDelete<SkSurface> surface; |
| 207 #if SK_SUPPORT_GPU | 218 #if SK_SUPPORT_GPU |
| 208 SkGLContextHelper* gl; | 219 SkGLContextHelper* gl; |
| 209 #endif | 220 #endif |
| 210 }; | 221 }; |
| 211 | 222 |
| 212 // If bench is enabled for backend/config, returns a Target* for them, otherwise NULL. | 223 static bool is_cpu_config_allowed(const char* name) { |
| 213 static Target* is_enabled(Benchmark* bench, Benchmark::Backend backend, const ch ar* config) { | |
| 214 if (!bench->isSuitableFor(backend)) { | |
| 215 return NULL; | |
| 216 } | |
| 217 | |
| 218 for (int i = 0; i < FLAGS_config.count(); i++) { | 224 for (int i = 0; i < FLAGS_config.count(); i++) { |
| 219 if (to_lower(FLAGS_config[i]).equals(config)) { | 225 if (to_lower(FLAGS_config[i]).equals(name)) { |
| 220 Target* target = new Target; | 226 return true; |
| 221 target->config = config; | |
| 222 target->backend = backend; | |
| 223 return target; | |
| 224 } | 227 } |
| 225 } | 228 } |
| 226 return NULL; | 229 return false; |
| 227 } | 230 } |
| 228 | 231 |
| 229 // Append all targets that are suitable for bench. | 232 #if SK_SUPPORT_GPU |
| 230 static void create_targets(Benchmark* bench, SkTDArray<Target*>* targets) { | 233 static bool is_gpu_config_allowed(const char* name, GrContextFactory::GLContextT ype ctxType, |
| 231 const int w = bench->getSize().fX, | 234 int sampleCnt) { |
|
mtklein
2014/07/22 17:44:19
funky alignment here
bsalomon
2014/07/22 18:10:14
Done.
| |
| 232 h = bench->getSize().fY; | 235 if (!is_cpu_config_allowed(name)) { |
| 233 const SkImageInfo _8888 = { w, h, kN32_SkColorType, kPremul_SkAlphaType }, | 236 return false; |
| 234 _565 = { w, h, kRGB_565_SkColorType, kOpaque_SkAlphaType }; | 237 } |
| 238 if (const GrContext* ctx = gGrFactory.get(ctxType)) { | |
| 239 return sampleCnt <= ctx->getMaxSampleCount(); | |
| 240 } | |
| 241 return false; | |
| 242 } | |
| 243 #endif | |
| 235 | 244 |
| 236 #define CPU_TARGET(config, backend, code) \ | 245 // Append all configs that are enabled and supported. |
| 237 if (Target* t = is_enabled(bench, Benchmark::backend, #config)) { \ | 246 static void create_configs(SkTDArray<Config>* configs) { |
| 238 t->surface.reset(code); \ | 247 #define CPU_CONFIG(name, backend, color, alpha) \ |
| 239 targets->push(t); \ | 248 if (is_cpu_config_allowed(#name)) { \ |
| 249 Config config = { #name, Benchmark::backend, color, alpha, 0 }; \ | |
| 250 configs->push(config); \ | |
| 240 } | 251 } |
| 252 | |
| 241 if (FLAGS_cpu) { | 253 if (FLAGS_cpu) { |
| 242 CPU_TARGET(nonrendering, kNonRendering_Backend, NULL) | 254 CPU_CONFIG(nonrendering, kNonRendering_Backend, kUnknown_SkColorType, kU npremul_SkAlphaType) |
| 243 CPU_TARGET(8888, kRaster_Backend, SkSurface::NewRaster(_8888)) | 255 CPU_CONFIG(8888, kRaster_Backend, kN32_SkColorType, kPremul_SkAlphaType) |
| 244 CPU_TARGET(565, kRaster_Backend, SkSurface::NewRaster(_565)) | 256 CPU_CONFIG(565, kRaster_Backend, kRGB_565_SkColorType, kOpaque_SkAlphaTy pe) |
| 245 } | 257 } |
| 246 | 258 |
| 247 #if SK_SUPPORT_GPU | 259 #if SK_SUPPORT_GPU |
| 248 | 260 #define GPU_CONFIG(name, ctxType, samples) \ |
| 249 #define GPU_TARGET(config, ctxType, info, samples) \ | 261 if (is_gpu_config_allowed(#name, GrContextFactory::ctxType, samples)) { \ |
| 250 if (Target* t = is_enabled(bench, Benchmark::kGPU_Backend, #config)) { \ | 262 Config config = { \ |
| 251 t->surface.reset(SkSurface::NewRenderTarget(gGrFactory.get(ctxType), info, samples)); \ | 263 #name, \ |
| 252 t->gl = gGrFactory.getGLContext(ctxType); \ | 264 Benchmark::kGPU_Backend, \ |
| 253 targets->push(t); \ | 265 kN32_SkColorType, \ |
| 266 kPremul_SkAlphaType, \ | |
| 267 samples, \ | |
| 268 GrContextFactory::ctxType }; \ | |
| 269 configs->push(config); \ | |
| 254 } | 270 } |
| 271 | |
| 255 if (FLAGS_gpu) { | 272 if (FLAGS_gpu) { |
| 256 GPU_TARGET(gpu, GrContextFactory::kNative_GLContextType, _8888, 0) | 273 GPU_CONFIG(gpu, kNative_GLContextType, 0) |
| 257 GPU_TARGET(msaa4, GrContextFactory::kNative_GLContextType, _8888, 4) | 274 GPU_CONFIG(msaa4, kNative_GLContextType, 4) |
| 258 GPU_TARGET(msaa16, GrContextFactory::kNative_GLContextType, _8888, 16) | 275 GPU_CONFIG(msaa16, kNative_GLContextType, 16) |
| 259 GPU_TARGET(nvprmsaa4, GrContextFactory::kNVPR_GLContextType, _8888, 4) | 276 GPU_CONFIG(nvprmsaa4, kNVPR_GLContextType, 4) |
| 260 GPU_TARGET(nvprmsaa16, GrContextFactory::kNVPR_GLContextType, _8888, 16) | 277 GPU_CONFIG(nvprmsaa16, kNVPR_GLContextType, 16) |
| 261 GPU_TARGET(debug, GrContextFactory::kDebug_GLContextType, _8888, 0) | 278 GPU_CONFIG(debug, kDebug_GLContextType, 0) |
| 262 GPU_TARGET(nullgpu, GrContextFactory::kNull_GLContextType, _8888, 0) | 279 GPU_CONFIG(nullgpu, kNull_GLContextType, 0) |
| 263 #if SK_ANGLE | |
| 264 GPU_TARGET(angle, GrContextFactory::kANGLE_GLContextType, _8888, 0) | |
| 265 #endif | |
| 266 } | 280 } |
| 267 #endif | 281 #endif |
| 268 } | 282 } |
| 269 | 283 |
| 284 // If bench is enabled for backend/config, returns a Target* for them, otherwise NULL. | |
|
mtklein
2014/07/22 17:44:19
... is enabled for config, returns a Target* for i
bsalomon
2014/07/22 18:10:14
Done.
| |
| 285 static Target* is_enabled(Benchmark* bench, const Config* config) { | |
|
mtklein
2014/07/22 17:44:19
const Config& ?
bsalomon
2014/07/22 18:10:14
Done.
| |
| 286 if (!bench->isSuitableFor(config->backend)) { | |
| 287 return NULL; | |
| 288 } | |
| 289 | |
| 290 const int w = bench->getSize().fX, | |
| 291 h = bench->getSize().fY; | |
| 292 | |
| 293 SkImageInfo info; | |
| 294 info.fAlphaType = config->alpha; | |
| 295 info.fColorType = config->color; | |
| 296 info.fWidth = w; | |
|
mtklein
2014/07/22 17:44:19
just inline bench->getSize().fX and bench->getSize
bsalomon
2014/07/22 18:10:14
Done.
| |
| 297 info.fHeight = h; | |
| 298 | |
| 299 Target* target = new Target; | |
| 300 target->config = config; | |
| 301 | |
| 302 SkAutoTUnref<SkSurface> surface; | |
|
mtklein
2014/07/22 17:44:19
Why go through the extra pointer?
if (Benchmark::
bsalomon
2014/07/22 18:10:14
Done.
| |
| 303 if (Benchmark::kRaster_Backend == config->backend) { | |
| 304 surface.reset(SkSurface::NewRaster(info)); | |
| 305 } | |
| 306 #if SK_SUPPORT_GPU | |
| 307 else if (Benchmark::kGPU_Backend == config->backend) { | |
| 308 surface.reset(SkSurface::NewRenderTarget(gGrFactory.get(config->ctxType) , info, | |
| 309 config->samples)); | |
| 310 target->gl = gGrFactory.getGLContext(config->ctxType); | |
| 311 } | |
| 312 #endif | |
| 313 | |
| 314 if (Benchmark::kNonRendering_Backend != config->backend && !surface) { | |
| 315 delete target; | |
| 316 return NULL; | |
| 317 } | |
| 318 | |
| 319 target->surface.reset(SkSafeRef(surface.get())); | |
| 320 return target; | |
| 321 } | |
| 322 | |
| 323 // Creates targets for a benchmark and a set of configs. | |
| 324 static void create_targets(SkTDArray<Target*>* targets, Benchmark* b, | |
| 325 const SkTDArray<Config>& configs) { | |
| 326 for (int i = 0; i < configs.count(); ++i) { | |
| 327 if (Target* t = is_enabled(b, &configs[i])) { | |
| 328 targets->push(t); | |
| 329 } | |
| 330 | |
| 331 } | |
| 332 } | |
| 333 | |
| 270 static void fill_static_options(ResultsWriter* log) { | 334 static void fill_static_options(ResultsWriter* log) { |
| 271 #if defined(SK_BUILD_FOR_WIN32) | 335 #if defined(SK_BUILD_FOR_WIN32) |
| 272 log->option("system", "WIN32"); | 336 log->option("system", "WIN32"); |
| 273 #elif defined(SK_BUILD_FOR_MAC) | 337 #elif defined(SK_BUILD_FOR_MAC) |
| 274 log->option("system", "MAC"); | 338 log->option("system", "MAC"); |
| 275 #elif defined(SK_BUILD_FOR_ANDROID) | 339 #elif defined(SK_BUILD_FOR_ANDROID) |
| 276 log->option("system", "ANDROID"); | 340 log->option("system", "ANDROID"); |
| 277 #elif defined(SK_BUILD_FOR_UNIX) | 341 #elif defined(SK_BUILD_FOR_UNIX) |
| 278 log->option("system", "UNIX"); | 342 log->option("system", "UNIX"); |
| 279 #else | 343 #else |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 335 if (FLAGS_runOnce) { | 399 if (FLAGS_runOnce) { |
| 336 SkDebugf("--runOnce is true; times would only be misleading so we won't print them.\n"); | 400 SkDebugf("--runOnce is true; times would only be misleading so we won't print them.\n"); |
| 337 } else if (FLAGS_verbose) { | 401 } else if (FLAGS_verbose) { |
| 338 // No header. | 402 // No header. |
| 339 } else if (FLAGS_quiet) { | 403 } else if (FLAGS_quiet) { |
| 340 SkDebugf("median\tbench\tconfig\n"); | 404 SkDebugf("median\tbench\tconfig\n"); |
| 341 } else { | 405 } else { |
| 342 SkDebugf("loops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\ n"); | 406 SkDebugf("loops\tmin\tmedian\tmean\tmax\tstddev\tsamples\tconfig\tbench\ n"); |
| 343 } | 407 } |
| 344 | 408 |
| 409 SkTDArray<Config> configs; | |
| 410 create_configs(&configs); | |
| 411 | |
| 345 for (const BenchRegistry* r = BenchRegistry::Head(); r != NULL; r = r->next( )) { | 412 for (const BenchRegistry* r = BenchRegistry::Head(); r != NULL; r = r->next( )) { |
| 346 SkAutoTDelete<Benchmark> bench(r->factory()(NULL)); | 413 SkAutoTDelete<Benchmark> bench(r->factory()(NULL)); |
| 347 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { | 414 if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { |
| 348 continue; | 415 continue; |
| 349 } | 416 } |
| 350 | 417 |
| 351 SkTDArray<Target*> targets; | 418 SkTDArray<Target*> targets; |
| 352 create_targets(bench.get(), &targets); | 419 create_targets(&targets, bench.get(), configs); |
| 353 | 420 |
| 354 if (!targets.isEmpty()) { | 421 if (!targets.isEmpty()) { |
| 355 log.bench(bench->getName(), bench->getSize().fX, bench->getSize().fY ); | 422 log.bench(bench->getName(), bench->getSize().fX, bench->getSize().fY ); |
| 356 bench->preDraw(); | 423 bench->preDraw(); |
| 357 } | 424 } |
| 358 for (int j = 0; j < targets.count(); j++) { | 425 for (int j = 0; j < targets.count(); j++) { |
| 359 SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface-> getCanvas() : NULL; | 426 SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface-> getCanvas() : NULL; |
| 360 const char* config = targets[j]->config; | 427 const char* config = targets[j]->config->name; |
| 361 | 428 |
| 362 const int loops = | 429 const int loops = |
| 363 #if SK_SUPPORT_GPU | 430 #if SK_SUPPORT_GPU |
| 364 Benchmark::kGPU_Backend == targets[j]->backend | 431 Benchmark::kGPU_Backend == targets[j]->config->backend |
| 365 ? gpu_bench(targets[j]->gl, bench.get(), canvas, samples.get()) | 432 ? gpu_bench(targets[j]->gl, bench.get(), canvas, samples.get()) |
| 366 : | 433 : |
| 367 #endif | 434 #endif |
| 368 cpu_bench( overhead, bench.get(), canvas, samples.get()); | 435 cpu_bench( overhead, bench.get(), canvas, samples.get()); |
| 369 | 436 |
| 370 if (loops == 0) { | 437 if (loops == 0) { |
| 371 SkDebugf("Unable to time %s\t%s (overhead %s)\n", | 438 SkDebugf("Unable to time %s\t%s (overhead %s)\n", |
| 372 bench->getName(), config, HUMANIZE(overhead)); | 439 bench->getName(), config, HUMANIZE(overhead)); |
| 373 continue; | 440 continue; |
| 374 } | 441 } |
| 375 | 442 |
| 376 Stats stats(samples.get(), FLAGS_samples); | 443 Stats stats(samples.get(), FLAGS_samples); |
| 377 log.config(config); | 444 log.config(config); |
| 378 #if SK_SUPPORT_GPU | 445 #if SK_SUPPORT_GPU |
| 379 if (Benchmark::kGPU_Backend == targets[j]->backend) { | 446 if (Benchmark::kGPU_Backend == targets[j]->config->backend) { |
| 380 fill_gpu_options(&log, targets[j]->gl); | 447 fill_gpu_options(&log, targets[j]->gl); |
| 381 } | 448 } |
| 382 #endif | 449 #endif |
| 383 log.timer("min_ms", stats.min); | 450 log.timer("min_ms", stats.min); |
| 384 log.timer("median_ms", stats.median); | 451 log.timer("median_ms", stats.median); |
| 385 log.timer("mean_ms", stats.mean); | 452 log.timer("mean_ms", stats.mean); |
| 386 log.timer("max_ms", stats.max); | 453 log.timer("max_ms", stats.max); |
| 387 log.timer("stddev_ms", sqrt(stats.var)); | 454 log.timer("stddev_ms", sqrt(stats.var)); |
| 388 | 455 |
| 389 if (FLAGS_runOnce) { | 456 if (FLAGS_runOnce) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 426 } | 493 } |
| 427 | 494 |
| 428 return 0; | 495 return 0; |
| 429 } | 496 } |
| 430 | 497 |
| 431 #if !defined SK_BUILD_FOR_IOS | 498 #if !defined SK_BUILD_FOR_IOS |
| 432 int main(int argc, char * const argv[]) { | 499 int main(int argc, char * const argv[]) { |
| 433 return tool_main(argc, (char**) argv); | 500 return tool_main(argc, (char**) argv); |
| 434 } | 501 } |
| 435 #endif | 502 #endif |
| OLD | NEW |