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 |