| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 57               "Loop until timer overhead is at most this fraction of our measurm
     ents."); | 57               "Loop until timer overhead is at most this fraction of our measurm
     ents."); | 
| 58 DEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); | 58 DEFINE_double(gpuMs, 5, "Target bench time in millseconds for GPU."); | 
| 59 DEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allow
     s to lag."); | 59 DEFINE_int32(gpuFrameLag, 5, "Overestimate of maximum number of frames GPU allow
     s to lag."); | 
| 60 DEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling
      back to " | 60 DEFINE_bool(gpuCompressAlphaMasks, false, "Compress masks generated from falling
      back to " | 
| 61                                           "software path rendering."); | 61                                           "software path rendering."); | 
| 62 | 62 | 
| 63 DEFINE_string(outResultsFile, "", "If given, write results here as JSON."); | 63 DEFINE_string(outResultsFile, "", "If given, write results here as JSON."); | 
| 64 DEFINE_int32(maxCalibrationAttempts, 3, | 64 DEFINE_int32(maxCalibrationAttempts, 3, | 
| 65              "Try up to this many times to guess loops for a bench, or skip the 
     bench."); | 65              "Try up to this many times to guess loops for a bench, or skip the 
     bench."); | 
| 66 DEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this."); | 66 DEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this."); | 
|  | 67 DEFINE_string(properties, "", | 
|  | 68               "Space-separated key/value pairs to add to JSON identifying this n
     anobench run."); | 
| 67 DEFINE_string(key, "", | 69 DEFINE_string(key, "", | 
| 68               "Space-separated key/value pairs to add to JSON identifying this b
     ench config."); | 70               "Space-separated key/value pairs to add to JSON identifying this b
     ench config."); | 
| 69 DEFINE_string(options, "", |  | 
| 70               "Space-separated option/value pairs to add to JSON, logging extra 
     info."); |  | 
| 71 DEFINE_string(gitHash, "", "Git hash to add to JSON."); |  | 
| 72 | 71 | 
| 73 DEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs."); | 72 DEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs."); | 
| 74 DEFINE_string(scales, "1.0", "Space-separated scales for SKPs."); | 73 DEFINE_string(scales, "1.0", "Space-separated scales for SKPs."); | 
| 75 | 74 | 
| 76 static SkString humanize(double ms) { | 75 static SkString humanize(double ms) { | 
| 77     if (ms > 1e+3) return SkStringPrintf("%.3gs",  ms/1e3); | 76     if (ms > 1e+3) return SkStringPrintf("%.3gs",  ms/1e3); | 
| 78     if (ms < 1e-3) return SkStringPrintf("%.3gns", ms*1e6); | 77     if (ms < 1e-3) return SkStringPrintf("%.3gns", ms*1e6); | 
| 79 #ifdef SK_BUILD_FOR_WIN | 78 #ifdef SK_BUILD_FOR_WIN | 
| 80     if (ms < 1)    return SkStringPrintf("%.3gus", ms*1e3); | 79     if (ms < 1)    return SkStringPrintf("%.3gus", ms*1e3); | 
| 81 #else | 80 #else | 
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 385 static void create_targets(SkTDArray<Target*>* targets, Benchmark* b, | 384 static void create_targets(SkTDArray<Target*>* targets, Benchmark* b, | 
| 386                            const SkTDArray<Config>& configs) { | 385                            const SkTDArray<Config>& configs) { | 
| 387     for (int i = 0; i < configs.count(); ++i) { | 386     for (int i = 0; i < configs.count(); ++i) { | 
| 388         if (Target* t = is_enabled(b, configs[i])) { | 387         if (Target* t = is_enabled(b, configs[i])) { | 
| 389             targets->push(t); | 388             targets->push(t); | 
| 390         } | 389         } | 
| 391 | 390 | 
| 392     } | 391     } | 
| 393 } | 392 } | 
| 394 | 393 | 
| 395 static void fill_static_options(ResultsWriter* log) { |  | 
| 396 #if defined(SK_BUILD_FOR_WIN32) |  | 
| 397     log->option("system", "WIN32"); |  | 
| 398 #elif defined(SK_BUILD_FOR_MAC) |  | 
| 399     log->option("system", "MAC"); |  | 
| 400 #elif defined(SK_BUILD_FOR_ANDROID) |  | 
| 401     log->option("system", "ANDROID"); |  | 
| 402 #elif defined(SK_BUILD_FOR_UNIX) |  | 
| 403     log->option("system", "UNIX"); |  | 
| 404 #else |  | 
| 405     log->option("system", "other"); |  | 
| 406 #endif |  | 
| 407 } |  | 
| 408 |  | 
| 409 #if SK_SUPPORT_GPU | 394 #if SK_SUPPORT_GPU | 
| 410 static void fill_gpu_options(ResultsWriter* log, SkGLContextHelper* ctx) { | 395 static void fill_gpu_options(ResultsWriter* log, SkGLContextHelper* ctx) { | 
| 411     const GrGLubyte* version; | 396     const GrGLubyte* version; | 
| 412     SK_GL_RET(*ctx, version, GetString(GR_GL_VERSION)); | 397     SK_GL_RET(*ctx, version, GetString(GR_GL_VERSION)); | 
| 413     log->configOption("GL_VERSION", (const char*)(version)); | 398     log->configOption("GL_VERSION", (const char*)(version)); | 
| 414 | 399 | 
| 415     SK_GL_RET(*ctx, version, GetString(GR_GL_RENDERER)); | 400     SK_GL_RET(*ctx, version, GetString(GR_GL_RENDERER)); | 
| 416     log->configOption("GL_RENDERER", (const char*) version); | 401     log->configOption("GL_RENDERER", (const char*) version); | 
| 417 | 402 | 
| 418     SK_GL_RET(*ctx, version, GetString(GR_GL_VENDOR)); | 403     SK_GL_RET(*ctx, version, GetString(GR_GL_VENDOR)); | 
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 546     } | 531     } | 
| 547 | 532 | 
| 548     if (!FLAGS_writePath.isEmpty()) { | 533     if (!FLAGS_writePath.isEmpty()) { | 
| 549         SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); | 534         SkDebugf("Writing files to %s.\n", FLAGS_writePath[0]); | 
| 550         if (!sk_mkdir(FLAGS_writePath[0])) { | 535         if (!sk_mkdir(FLAGS_writePath[0])) { | 
| 551             SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_wri
     tePath[0]); | 536             SkDebugf("Could not create %s. Files won't be written.\n", FLAGS_wri
     tePath[0]); | 
| 552             FLAGS_writePath.set(0, NULL); | 537             FLAGS_writePath.set(0, NULL); | 
| 553         } | 538         } | 
| 554     } | 539     } | 
| 555 | 540 | 
| 556     MultiResultsWriter log; | 541     SkAutoTDelete<ResultsWriter> log(SkNEW(ResultsWriter)); | 
| 557     SkAutoTDelete<NanoJSONResultsWriter> json; |  | 
| 558     if (!FLAGS_outResultsFile.isEmpty()) { | 542     if (!FLAGS_outResultsFile.isEmpty()) { | 
| 559         const char* gitHash = FLAGS_gitHash.isEmpty() ? "unknown-revision" : FLA
     GS_gitHash[0]; | 543         log.reset(SkNEW(NanoJSONResultsWriter(FLAGS_outResultsFile[0]))); | 
| 560         json.reset(SkNEW(NanoJSONResultsWriter(FLAGS_outResultsFile[0], gitHash)
     )); |  | 
| 561         log.add(json.get()); |  | 
| 562     } | 544     } | 
| 563     CallEnd<MultiResultsWriter> ender(log); | 545 | 
|  | 546     if (1 == FLAGS_properties.count() % 2) { | 
|  | 547         SkDebugf("ERROR: --properties must be passed with an even number of argu
     ments.\n"); | 
|  | 548         return 1; | 
|  | 549     } | 
|  | 550     for (int i = 1; i < FLAGS_properties.count(); i += 2) { | 
|  | 551         log->property(FLAGS_properties[i-1], FLAGS_properties[i]); | 
|  | 552     } | 
| 564 | 553 | 
| 565     if (1 == FLAGS_key.count() % 2) { | 554     if (1 == FLAGS_key.count() % 2) { | 
| 566         SkDebugf("ERROR: --key must be passed with an even number of arguments.\
     n"); | 555         SkDebugf("ERROR: --key must be passed with an even number of arguments.\
     n"); | 
| 567         return 1; | 556         return 1; | 
| 568     } | 557     } | 
| 569     for (int i = 1; i < FLAGS_key.count(); i += 2) { | 558     for (int i = 1; i < FLAGS_key.count(); i += 2) { | 
| 570         log.key(FLAGS_key[i-1], FLAGS_key[i]); | 559         log->key(FLAGS_key[i-1], FLAGS_key[i]); | 
| 571     } |  | 
| 572 |  | 
| 573     fill_static_options(&log); |  | 
| 574     if (1 == FLAGS_options.count() % 2) { |  | 
| 575         SkDebugf("ERROR: --options must be passed with an even number of argumen
     ts.\n"); |  | 
| 576         return 1; |  | 
| 577     } |  | 
| 578     for (int i = 1; i < FLAGS_options.count(); i += 2) { |  | 
| 579         log.option(FLAGS_options[i-1], FLAGS_options[i]); |  | 
| 580     } | 560     } | 
| 581 | 561 | 
| 582     const double overhead = estimate_timer_overhead(); | 562     const double overhead = estimate_timer_overhead(); | 
| 583     SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead)); | 563     SkDebugf("Timer overhead: %s\n", HUMANIZE(overhead)); | 
| 584 | 564 | 
| 585     SkAutoTMalloc<double> samples(FLAGS_samples); | 565     SkAutoTMalloc<double> samples(FLAGS_samples); | 
| 586 | 566 | 
| 587     if (kAutoTuneLoops != FLAGS_loops) { | 567     if (kAutoTuneLoops != FLAGS_loops) { | 
| 588         SkDebugf("Fixed number of loops; times would only be misleading so we wo
     n't print them.\n"); | 568         SkDebugf("Fixed number of loops; times would only be misleading so we wo
     n't print them.\n"); | 
| 589     } else if (FLAGS_verbose) { | 569     } else if (FLAGS_verbose) { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 601     while (Benchmark* b = benchStream.next()) { | 581     while (Benchmark* b = benchStream.next()) { | 
| 602         SkAutoTDelete<Benchmark> bench(b); | 582         SkAutoTDelete<Benchmark> bench(b); | 
| 603         if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { | 583         if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { | 
| 604             continue; | 584             continue; | 
| 605         } | 585         } | 
| 606 | 586 | 
| 607         SkTDArray<Target*> targets; | 587         SkTDArray<Target*> targets; | 
| 608         create_targets(&targets, bench.get(), configs); | 588         create_targets(&targets, bench.get(), configs); | 
| 609 | 589 | 
| 610         if (!targets.isEmpty()) { | 590         if (!targets.isEmpty()) { | 
| 611             log.bench(bench->getName(), bench->getSize().fX, bench->getSize().fY
     ); | 591             log->bench(bench->getName(), bench->getSize().fX, bench->getSize().f
     Y); | 
| 612             bench->preDraw(); | 592             bench->preDraw(); | 
| 613         } | 593         } | 
| 614         for (int j = 0; j < targets.count(); j++) { | 594         for (int j = 0; j < targets.count(); j++) { | 
| 615             SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->
     getCanvas() : NULL; | 595             SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->
     getCanvas() : NULL; | 
| 616             const char* config = targets[j]->config.name; | 596             const char* config = targets[j]->config.name; | 
| 617 | 597 | 
| 618 #ifdef SK_DEBUG | 598 #ifdef SK_DEBUG | 
| 619             // skia:2797  Some SKPs SkASSERT in debug mode.  Skip them for now. | 599             // skia:2797  Some SKPs SkASSERT in debug mode.  Skip them for now. | 
| 620             if (0 == strcmp("565", config) && SkStrContains(bench->getName(), ".
     skp")) { | 600             if (0 == strcmp("565", config) && SkStrContains(bench->getName(), ".
     skp")) { | 
| 621                 SkDebugf("Skipping 565 %s.  See skia:2797\n", bench->getName()); | 601                 SkDebugf("Skipping 565 %s.  See skia:2797\n", bench->getName()); | 
| (...skipping 15 matching lines...) Expand all  Loading... | 
| 637                 pngFilename.append(".png"); | 617                 pngFilename.append(".png"); | 
| 638                 write_canvas_png(canvas, pngFilename); | 618                 write_canvas_png(canvas, pngFilename); | 
| 639             } | 619             } | 
| 640 | 620 | 
| 641             if (kFailedLoops == loops) { | 621             if (kFailedLoops == loops) { | 
| 642                 // Can't be timed.  A warning note has already been printed. | 622                 // Can't be timed.  A warning note has already been printed. | 
| 643                 continue; | 623                 continue; | 
| 644             } | 624             } | 
| 645 | 625 | 
| 646             Stats stats(samples.get(), FLAGS_samples); | 626             Stats stats(samples.get(), FLAGS_samples); | 
| 647             log.config(config); | 627             log->config(config); | 
| 648             benchStream.fillCurrentOptions(&log); | 628             benchStream.fillCurrentOptions(log.get()); | 
| 649 #if SK_SUPPORT_GPU | 629 #if SK_SUPPORT_GPU | 
| 650             if (Benchmark::kGPU_Backend == targets[j]->config.backend) { | 630             if (Benchmark::kGPU_Backend == targets[j]->config.backend) { | 
| 651                 fill_gpu_options(&log, targets[j]->gl); | 631                 fill_gpu_options(log.get(), targets[j]->gl); | 
| 652             } | 632             } | 
| 653 #endif | 633 #endif | 
| 654             log.timer("min_ms",    stats.min); | 634             log->timer("min_ms",    stats.min); | 
| 655             log.timer("median_ms", stats.median); | 635             log->timer("median_ms", stats.median); | 
| 656             log.timer("mean_ms",   stats.mean); | 636             log->timer("mean_ms",   stats.mean); | 
| 657             log.timer("max_ms",    stats.max); | 637             log->timer("max_ms",    stats.max); | 
| 658             log.timer("stddev_ms", sqrt(stats.var)); | 638             log->timer("stddev_ms", sqrt(stats.var)); | 
| 659 | 639 | 
| 660             if (kAutoTuneLoops != FLAGS_loops) { | 640             if (kAutoTuneLoops != FLAGS_loops) { | 
| 661                 if (targets.count() == 1) { | 641                 if (targets.count() == 1) { | 
| 662                     config = ""; // Only print the config if we run the same ben
     ch on more than one. | 642                     config = ""; // Only print the config if we run the same ben
     ch on more than one. | 
| 663                 } | 643                 } | 
| 664                 SkDebugf("%s\t%s\n", bench->getName(), config); | 644                 SkDebugf("%s\t%s\n", bench->getName(), config); | 
| 665             } else if (FLAGS_verbose) { | 645             } else if (FLAGS_verbose) { | 
| 666                 for (int i = 0; i < FLAGS_samples; i++) { | 646                 for (int i = 0; i < FLAGS_samples; i++) { | 
| 667                     SkDebugf("%s  ", HUMANIZE(samples[i])); | 647                     SkDebugf("%s  ", HUMANIZE(samples[i])); | 
| 668                 } | 648                 } | 
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 702 | 682 | 
| 703     return 0; | 683     return 0; | 
| 704 } | 684 } | 
| 705 | 685 | 
| 706 #if !defined SK_BUILD_FOR_IOS | 686 #if !defined SK_BUILD_FOR_IOS | 
| 707 int main(int argc, char** argv) { | 687 int main(int argc, char** argv) { | 
| 708     SkCommandLineFlags::Parse(argc, argv); | 688     SkCommandLineFlags::Parse(argc, argv); | 
| 709     return nanobench_main(); | 689     return nanobench_main(); | 
| 710 } | 690 } | 
| 711 #endif | 691 #endif | 
| OLD | NEW | 
|---|