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