| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * Copyright 2011 Google Inc. | 2  * Copyright 2011 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 "BenchTimer.h" | 8 #include "BenchTimer.h" | 
|  | 9 #include "ResultsWriter.h" | 
| 9 #include "SkBenchLogger.h" | 10 #include "SkBenchLogger.h" | 
| 10 #include "SkBenchmark.h" | 11 #include "SkBenchmark.h" | 
| 11 #include "SkBitmapDevice.h" | 12 #include "SkBitmapDevice.h" | 
| 12 #include "SkCanvas.h" | 13 #include "SkCanvas.h" | 
| 13 #include "SkColorPriv.h" | 14 #include "SkColorPriv.h" | 
| 14 #include "SkCommandLineFlags.h" | 15 #include "SkCommandLineFlags.h" | 
| 15 #include "SkDeferredCanvas.h" | 16 #include "SkDeferredCanvas.h" | 
| 16 #include "SkGraphics.h" | 17 #include "SkGraphics.h" | 
| 17 #include "SkImageEncoder.h" | 18 #include "SkImageEncoder.h" | 
| 18 #include "SkOSFile.h" | 19 #include "SkOSFile.h" | 
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 268 DEFINE_string(config, kDefaultsConfigStr, | 269 DEFINE_string(config, kDefaultsConfigStr, | 
| 269               "Run configs given.  By default, runs the configs marked \"runByDe
     fault\" in gConfigs."); | 270               "Run configs given.  By default, runs the configs marked \"runByDe
     fault\" in gConfigs."); | 
| 270 DEFINE_string(logFile, "", "Also write stdout here."); | 271 DEFINE_string(logFile, "", "Also write stdout here."); | 
| 271 DEFINE_int32(minMs, 20,  "Shortest time we'll allow a benchmark to run."); | 272 DEFINE_int32(minMs, 20,  "Shortest time we'll allow a benchmark to run."); | 
| 272 DEFINE_int32(maxMs, 4000, "Longest time we'll allow a benchmark to run."); | 273 DEFINE_int32(maxMs, 4000, "Longest time we'll allow a benchmark to run."); | 
| 273 DEFINE_double(error, 0.01, | 274 DEFINE_double(error, 0.01, | 
| 274               "Ratio of subsequent bench measurements must drop within 1±error t
     o converge."); | 275               "Ratio of subsequent bench measurements must drop within 1±error t
     o converge."); | 
| 275 DEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per
      1000 loops."); | 276 DEFINE_string(timeFormat, "%9.2f", "Format to print results, in milliseconds per
      1000 loops."); | 
| 276 DEFINE_bool2(verbose, v, false, "Print more."); | 277 DEFINE_bool2(verbose, v, false, "Print more."); | 
| 277 DEFINE_string2(resourcePath, i, NULL, "directory for test resources."); | 278 DEFINE_string2(resourcePath, i, NULL, "directory for test resources."); | 
|  | 279 DEFINE_string(outResultsFile, "", "If given, the results will be written to the 
     file in JSON format."); | 
| 278 | 280 | 
| 279 // Has this bench converged?  First arguments are milliseconds / loop iteration, | 281 // Has this bench converged?  First arguments are milliseconds / loop iteration, | 
| 280 // last is overall runtime in milliseconds. | 282 // last is overall runtime in milliseconds. | 
| 281 static bool HasConverged(double prevPerLoop, double currPerLoop, double currRaw)
      { | 283 static bool HasConverged(double prevPerLoop, double currPerLoop, double currRaw)
      { | 
| 282     if (currRaw < FLAGS_minMs) { | 284     if (currRaw < FLAGS_minMs) { | 
| 283         return false; | 285         return false; | 
| 284     } | 286     } | 
| 285     const double low = 1 - FLAGS_error, high = 1 + FLAGS_error; | 287     const double low = 1 - FLAGS_error, high = 1 + FLAGS_error; | 
| 286     const double ratio = currPerLoop / prevPerLoop; | 288     const double ratio = currPerLoop / prevPerLoop; | 
| 287     return low < ratio && ratio < high; | 289     return low < ratio && ratio < high; | 
| 288 } | 290 } | 
| 289 | 291 | 
| 290 int tool_main(int argc, char** argv); | 292 int tool_main(int argc, char** argv); | 
| 291 int tool_main(int argc, char** argv) { | 293 int tool_main(int argc, char** argv) { | 
| 292 #if SK_ENABLE_INST_COUNT | 294 #if SK_ENABLE_INST_COUNT | 
| 293     gPrintInstCount = true; | 295     gPrintInstCount = true; | 
| 294 #endif | 296 #endif | 
| 295     SkAutoGraphics ag; | 297     SkAutoGraphics ag; | 
| 296     SkCommandLineFlags::Parse(argc, argv); | 298     SkCommandLineFlags::Parse(argc, argv); | 
| 297 | 299 | 
| 298     // First, parse some flags. | 300     // First, parse some flags. | 
| 299 |  | 
| 300     SkBenchLogger logger; | 301     SkBenchLogger logger; | 
| 301     if (FLAGS_logFile.count()) { | 302     if (FLAGS_logFile.count()) { | 
| 302         logger.SetLogFile(FLAGS_logFile[0]); | 303         logger.SetLogFile(FLAGS_logFile[0]); | 
| 303     } | 304     } | 
| 304 | 305 | 
|  | 306     LoggerResultsWriter logWriter(logger, FLAGS_timeFormat[0]); | 
|  | 307     MultiResultsWriter writer; | 
|  | 308     writer.add(&logWriter); | 
|  | 309     SkAutoTDelete<JSONResultsWriter> jsonWriter; | 
|  | 310     if (FLAGS_outResultsFile.count()) { | 
|  | 311         jsonWriter.reset(SkNEW(JSONResultsWriter(FLAGS_outResultsFile[0]))); | 
|  | 312         writer.add(jsonWriter.get()); | 
|  | 313     } | 
|  | 314     // Instantiate after all the writers have been added to writer so that we | 
|  | 315     // call close() before their destructors are called on the way out. | 
|  | 316     CallEnd<MultiResultsWriter> ender(writer); | 
|  | 317 | 
| 305     const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF; | 318     const uint8_t alpha = FLAGS_forceBlend ? 0x80 : 0xFF; | 
| 306     SkTriState::State dither = SkTriState::kDefault; | 319     SkTriState::State dither = SkTriState::kDefault; | 
| 307     for (size_t i = 0; i < 3; i++) { | 320     for (size_t i = 0; i < 3; i++) { | 
| 308         if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) { | 321         if (strcmp(SkTriState::Name[i], FLAGS_forceDither[0]) == 0) { | 
| 309             dither = static_cast<SkTriState::State>(i); | 322             dither = static_cast<SkTriState::State>(i); | 
| 310         } | 323         } | 
| 311     } | 324     } | 
| 312 | 325 | 
| 313     BenchMode benchMode = kNormal_BenchMode; | 326     BenchMode benchMode = kNormal_BenchMode; | 
| 314     for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) { | 327     for (size_t i = 0; i < SK_ARRAY_COUNT(BenchMode_Name); i++) { | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 377             } | 390             } | 
| 378         } | 391         } | 
| 379     } | 392     } | 
| 380 #endif | 393 #endif | 
| 381 | 394 | 
| 382     // All flags should be parsed now.  Report our settings. | 395     // All flags should be parsed now.  Report our settings. | 
| 383     if (kIsDebug) { | 396     if (kIsDebug) { | 
| 384         logger.logError("bench was built in Debug mode, so we're going to hide t
     he times." | 397         logger.logError("bench was built in Debug mode, so we're going to hide t
     he times." | 
| 385                         "  It's for your own good!\n"); | 398                         "  It's for your own good!\n"); | 
| 386     } | 399     } | 
| 387     SkString str("skia bench:"); | 400     writer.option("mode", FLAGS_mode[0]); | 
| 388     str.appendf(" mode=%s", FLAGS_mode[0]); | 401     writer.option("alpha", SkStringPrintf("0x%02X", alpha).c_str()); | 
| 389     str.appendf(" alpha=0x%02X antialias=%d filter=%d dither=%s", | 402     writer.option("antialias", SkStringPrintf("%d", FLAGS_forceAA).c_str()); | 
| 390                 alpha, FLAGS_forceAA, FLAGS_forceFilter, SkTriState::Name[dither
     ]); | 403     writer.option("filter", SkStringPrintf("%d", FLAGS_forceFilter).c_str()); | 
| 391     str.appendf(" rotate=%d scale=%d clip=%d", FLAGS_rotate, FLAGS_scale, FLAGS_
     clip); | 404     writer.option("dither",  SkTriState::Name[dither]); | 
|  | 405 | 
|  | 406     writer.option("rotate", SkStringPrintf("%d", FLAGS_rotate).c_str()); | 
|  | 407     writer.option("scale", SkStringPrintf("%d", FLAGS_scale).c_str()); | 
|  | 408     writer.option("clip", SkStringPrintf("%d", FLAGS_clip).c_str()); | 
| 392 | 409 | 
| 393 #if defined(SK_SCALAR_IS_FIXED) | 410 #if defined(SK_SCALAR_IS_FIXED) | 
| 394     str.append(" scalar=fixed"); | 411     writer.option("scalar", "fixed"); | 
| 395 #else | 412 #else | 
| 396     str.append(" scalar=float"); | 413     writer.option("scalar", "float"); | 
| 397 #endif | 414 #endif | 
| 398 | 415 | 
| 399 #if defined(SK_BUILD_FOR_WIN32) | 416 #if defined(SK_BUILD_FOR_WIN32) | 
| 400     str.append(" system=WIN32"); | 417     writer.option("system", "WIN32"); | 
| 401 #elif defined(SK_BUILD_FOR_MAC) | 418 #elif defined(SK_BUILD_FOR_MAC) | 
| 402     str.append(" system=MAC"); | 419     writer.option("system", "MAC"); | 
| 403 #elif defined(SK_BUILD_FOR_ANDROID) | 420 #elif defined(SK_BUILD_FOR_ANDROID) | 
| 404     str.append(" system=ANDROID"); | 421     writer.option("system", "ANDROID"); | 
| 405 #elif defined(SK_BUILD_FOR_UNIX) | 422 #elif defined(SK_BUILD_FOR_UNIX) | 
| 406     str.append(" system=UNIX"); | 423     writer.option("system", "UNIX"); | 
| 407 #else | 424 #else | 
| 408     str.append(" system=other"); | 425     writer.option("system", "other"); | 
| 409 #endif | 426 #endif | 
| 410 | 427 | 
| 411 #if defined(SK_DEBUG) | 428 #if defined(SK_DEBUG) | 
| 412     str.append(" DEBUG"); | 429     writer.option("build", "DEBUG"); | 
|  | 430 #else | 
|  | 431     writer.option("build", "RELEASE"); | 
| 413 #endif | 432 #endif | 
| 414     str.append("\n"); |  | 
| 415     logger.logProgress(str); |  | 
| 416 |  | 
| 417 | 433 | 
| 418     // Set texture cache limits if non-default. | 434     // Set texture cache limits if non-default. | 
| 419     for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) { | 435     for (size_t i = 0; i < SK_ARRAY_COUNT(gConfigs); ++i) { | 
| 420 #if SK_SUPPORT_GPU | 436 #if SK_SUPPORT_GPU | 
| 421         const Config& config = gConfigs[i]; | 437         const Config& config = gConfigs[i]; | 
| 422         if (SkBenchmark::kGPU_Backend != config.backend) { | 438         if (SkBenchmark::kGPU_Backend != config.backend) { | 
| 423             continue; | 439             continue; | 
| 424         } | 440         } | 
| 425         GrContext* context = gContextFactory.get(config.contextType); | 441         GrContext* context = gContextFactory.get(config.contextType); | 
| 426         if (NULL == context) { | 442         if (NULL == context) { | 
| 427             continue; | 443             continue; | 
| 428         } | 444         } | 
| 429 | 445 | 
| 430         size_t bytes; | 446         size_t bytes; | 
| 431         int count; | 447         int count; | 
| 432         context->getTextureCacheLimits(&count, &bytes); | 448         context->getTextureCacheLimits(&count, &bytes); | 
| 433         if (-1 != FLAGS_gpuCacheBytes) { | 449         if (-1 != FLAGS_gpuCacheBytes) { | 
| 434             bytes = static_cast<size_t>(FLAGS_gpuCacheBytes); | 450             bytes = static_cast<size_t>(FLAGS_gpuCacheBytes); | 
| 435         } | 451         } | 
| 436         if (-1 != FLAGS_gpuCacheCount) { | 452         if (-1 != FLAGS_gpuCacheCount) { | 
| 437             count = FLAGS_gpuCacheCount; | 453             count = FLAGS_gpuCacheCount; | 
| 438         } | 454         } | 
| 439         context->setTextureCacheLimits(count, bytes); | 455         context->setTextureCacheLimits(count, bytes); | 
| 440 #endif | 456 #endif | 
| 441     } | 457     } | 
| 442 | 458 | 
| 443     // Find the longest name of the benches we're going to run to make the outpu
     t pretty. |  | 
| 444     Iter names; |  | 
| 445     SkBenchmark* bench; |  | 
| 446     size_t longestName = 0; |  | 
| 447     while ((bench = names.next()) != NULL) { |  | 
| 448         SkAutoTUnref<SkBenchmark> benchUnref(bench); |  | 
| 449         if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { |  | 
| 450             continue; |  | 
| 451         } |  | 
| 452         const size_t length = strlen(bench->getName()); |  | 
| 453         longestName = length > longestName ? length : longestName; |  | 
| 454     } |  | 
| 455 |  | 
| 456     // Run each bench in each configuration it supports and we asked for. | 459     // Run each bench in each configuration it supports and we asked for. | 
| 457     Iter iter; | 460     Iter iter; | 
|  | 461     SkBenchmark* bench; | 
| 458     while ((bench = iter.next()) != NULL) { | 462     while ((bench = iter.next()) != NULL) { | 
| 459         SkAutoTUnref<SkBenchmark> benchUnref(bench); | 463         SkAutoTUnref<SkBenchmark> benchUnref(bench); | 
| 460         if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { | 464         if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { | 
| 461             continue; | 465             continue; | 
| 462         } | 466         } | 
| 463 | 467 | 
| 464         bench->setForceAlpha(alpha); | 468         bench->setForceAlpha(alpha); | 
| 465         bench->setForceAA(FLAGS_forceAA); | 469         bench->setForceAA(FLAGS_forceAA); | 
| 466         bench->setForceFilter(FLAGS_forceFilter); | 470         bench->setForceFilter(FLAGS_forceFilter); | 
| 467         bench->setDither(dither); | 471         bench->setDither(dither); | 
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 530 | 534 | 
| 531             if (NULL != canvas) { | 535             if (NULL != canvas) { | 
| 532                 canvas->clear(SK_ColorWHITE); | 536                 canvas->clear(SK_ColorWHITE); | 
| 533                 if (FLAGS_clip)   {   performClip(canvas, dim.fX, dim.fY); } | 537                 if (FLAGS_clip)   {   performClip(canvas, dim.fX, dim.fY); } | 
| 534                 if (FLAGS_scale)  {  performScale(canvas, dim.fX, dim.fY); } | 538                 if (FLAGS_scale)  {  performScale(canvas, dim.fX, dim.fY); } | 
| 535                 if (FLAGS_rotate) { performRotate(canvas, dim.fX, dim.fY); } | 539                 if (FLAGS_rotate) { performRotate(canvas, dim.fX, dim.fY); } | 
| 536             } | 540             } | 
| 537 | 541 | 
| 538             if (!loggedBenchName) { | 542             if (!loggedBenchName) { | 
| 539                 loggedBenchName = true; | 543                 loggedBenchName = true; | 
| 540                 SkString str; | 544                 writer.bench(bench->getName(), dim.fX, dim.fY); | 
| 541                 str.printf("running bench [%3d %3d] %*s ", |  | 
| 542                            dim.fX, dim.fY, (int)longestName, bench->getName()); |  | 
| 543                 logger.logProgress(str); |  | 
| 544             } | 545             } | 
| 545 | 546 | 
| 546 #if SK_SUPPORT_GPU | 547 #if SK_SUPPORT_GPU | 
| 547             SkGLContextHelper* contextHelper = NULL; | 548             SkGLContextHelper* contextHelper = NULL; | 
| 548             if (SkBenchmark::kGPU_Backend == config.backend) { | 549             if (SkBenchmark::kGPU_Backend == config.backend) { | 
| 549                 contextHelper = gContextFactory.getGLContext(config.contextType)
     ; | 550                 contextHelper = gContextFactory.getGLContext(config.contextType)
     ; | 
| 550             } | 551             } | 
| 551             BenchTimer timer(contextHelper); | 552             BenchTimer timer(contextHelper); | 
| 552 #else | 553 #else | 
| 553             BenchTimer timer; | 554             BenchTimer timer; | 
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 672             // Normalize to ms per 1000 iterations. | 673             // Normalize to ms per 1000 iterations. | 
| 673             const double normalize = 1000.0 / loopsPerIter; | 674             const double normalize = 1000.0 / loopsPerIter; | 
| 674             const struct { char shortName; const char* longName; double ms; } ti
     mes[] = { | 675             const struct { char shortName; const char* longName; double ms; } ti
     mes[] = { | 
| 675                 {'w', "msecs",  normalize * timer.fWall}, | 676                 {'w', "msecs",  normalize * timer.fWall}, | 
| 676                 {'W', "Wmsecs", normalize * timer.fTruncatedWall}, | 677                 {'W', "Wmsecs", normalize * timer.fTruncatedWall}, | 
| 677                 {'c', "cmsecs", normalize * timer.fCpu}, | 678                 {'c', "cmsecs", normalize * timer.fCpu}, | 
| 678                 {'C', "Cmsecs", normalize * timer.fTruncatedCpu}, | 679                 {'C', "Cmsecs", normalize * timer.fTruncatedCpu}, | 
| 679                 {'g', "gmsecs", normalize * timer.fGpu}, | 680                 {'g', "gmsecs", normalize * timer.fGpu}, | 
| 680             }; | 681             }; | 
| 681 | 682 | 
| 682             SkString result; | 683             writer.config(config.name); | 
| 683             result.appendf("   %s:", config.name); |  | 
| 684             for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) { | 684             for (size_t i = 0; i < SK_ARRAY_COUNT(times); i++) { | 
| 685                 if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms >
      0) { | 685                 if (strchr(FLAGS_timers[0], times[i].shortName) && times[i].ms >
      0) { | 
| 686                     result.appendf(" %s = ", times[i].longName); | 686                     writer.timer(times[i].longName, times[i].ms); | 
| 687                     result.appendf(FLAGS_timeFormat[0], times[i].ms); |  | 
| 688                 } | 687                 } | 
| 689             } | 688             } | 
| 690             logger.logProgress(result); |  | 
| 691         } |  | 
| 692         if (loggedBenchName) { |  | 
| 693             logger.logProgress("\n"); |  | 
| 694         } | 689         } | 
| 695     } | 690     } | 
| 696 #if SK_SUPPORT_GPU | 691 #if SK_SUPPORT_GPU | 
| 697     gContextFactory.destroyContexts(); | 692     gContextFactory.destroyContexts(); | 
| 698 #endif | 693 #endif | 
| 699     return 0; | 694     return 0; | 
| 700 } | 695 } | 
| 701 | 696 | 
| 702 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 697 #if !defined(SK_BUILD_FOR_IOS) && !defined(SK_BUILD_FOR_NACL) | 
| 703 int main(int argc, char * const argv[]) { | 698 int main(int argc, char * const argv[]) { | 
| 704     return tool_main(argc, (char**) argv); | 699     return tool_main(argc, (char**) argv); | 
| 705 } | 700 } | 
| 706 #endif | 701 #endif | 
| OLD | NEW | 
|---|