Index: bench/nanobench.cpp |
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp |
index 742a6ed11d65d7450c07d5c22aa83a96a3845903..62db6ca52146feaf3f86bb56ffe690108312fed1 100644 |
--- a/bench/nanobench.cpp |
+++ b/bench/nanobench.cpp |
@@ -11,9 +11,11 @@ |
#include "CrashHandler.h" |
#include "GMBench.h" |
#include "ResultsWriter.h" |
+#include "SKPBench.h" |
#include "Stats.h" |
#include "Timer.h" |
+#include "SkOSFile.h" |
#include "SkCanvas.h" |
#include "SkCommonFlags.h" |
#include "SkForceLinking.h" |
@@ -49,6 +51,9 @@ DEFINE_int32(maxLoops, 1000000, "Never run a bench more times than this."); |
DEFINE_string(key, "", "Space-separated key/value pairs to add to JSON."); |
DEFINE_string(gitHash, "", "Git hash to add to JSON."); |
+DEFINE_string(clip, "0,0,1000,1000", "Clip for SKPs."); |
+DEFINE_string(scales, "1.0,1.1", "Scales for SKPs."); |
bsalomon
2014/08/01 13:23:24
Maybe the default should just be 1.0?
mtklein
2014/08/01 13:55:34
Done.
Oddly, having a single value by default mak
|
+ |
static SkString humanize(double ms) { |
if (ms > 1e+3) return SkStringPrintf("%.3gs", ms/1e3); |
if (ms < 1e-3) return SkStringPrintf("%.3gns", ms*1e6); |
@@ -357,28 +362,106 @@ static void fill_gpu_options(ResultsWriter* log, SkGLContextHelper* ctx) { |
class BenchmarkStream { |
public: |
- BenchmarkStream() : fBenches(BenchRegistry::Head()) , fGMs(skiagm::GMRegistry::Head()) {} |
+ BenchmarkStream() : fBenches(BenchRegistry::Head()) |
+ , fGMs(skiagm::GMRegistry::Head()) |
+ , fCurrentScale(0) |
+ , fCurrentSKP(0) { |
+ if (!FLAGS_skps.isEmpty()) { |
+ SkOSFile::Iter it(FLAGS_skps[0], ".skp"); |
+ SkString path; |
+ while (it.next(&path)) { |
+ fSKPs.push_back() = SkOSPath::Join(FLAGS_skps[0], path.c_str()); |
+ } |
+ } |
+ |
+ if (4 != sscanf(FLAGS_clip[0], "%d,%d,%d,%d", |
+ &fClip.fLeft, &fClip.fTop, &fClip.fRight, &fClip.fBottom)) { |
+ SkDebugf("Can't parse %s from --clip as an SkIRect.\n", FLAGS_clip[0]); |
+ exit(1); |
+ } |
+ |
+ SkTArray<SkString> scales; |
+ SkStrSplit(FLAGS_scales[0], ",", &scales); |
+ for (int i = 0; i < scales.count(); i++) { |
+ if (1 != sscanf(scales[i].c_str(), "%f", &fScales.push_back())) { |
+ SkDebugf("Can't parse %s from --scales as an SkScalar.\n", scales[i].c_str()); |
+ exit(1); |
+ } |
+ } |
+ } |
- Benchmark* next(const char** sourceType) { |
+ Benchmark* next() { |
if (fBenches) { |
Benchmark* bench = fBenches->factory()(NULL); |
fBenches = fBenches->next(); |
- *sourceType = "bench"; |
+ fSourceType = "bench"; |
return bench; |
} |
+ |
while (fGMs) { |
SkAutoTDelete<skiagm::GM> gm(fGMs->factory()(NULL)); |
fGMs = fGMs->next(); |
if (gm->getFlags() & skiagm::GM::kAsBench_Flag) { |
- *sourceType = "gm"; |
+ fSourceType = "gm"; |
return SkNEW_ARGS(GMBench, (gm.detach())); |
} |
} |
+ |
+ while (fCurrentScale < fScales.count()) { |
+ while (fCurrentSKP < fSKPs.count()) { |
+ const SkString& path = fSKPs[fCurrentSKP++]; |
+ |
+ // Not strictly necessary, as it will be checked again later, |
+ // but helps to avoid a lot of pointless work if we're going to skip it. |
+ if (SkCommandLineFlags::ShouldSkip(FLAGS_match, path.c_str())) { |
+ continue; |
+ } |
+ |
+ SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path.c_str())); |
+ if (stream.get() == NULL) { |
+ SkDebugf("Could not read %s.\n", path.c_str()); |
+ exit(1); |
+ } |
+ |
+ SkAutoTUnref<SkPicture> pic(SkPicture::CreateFromStream(stream.get())); |
+ if (pic.get() == NULL) { |
+ SkDebugf("Could not read %s as an SkPicture.\n", path.c_str()); |
+ exit(1); |
+ } |
+ |
+ SkString name = SkOSPath::Basename(path.c_str()); |
+ |
+ fSourceType = "skp"; |
+ return SkNEW_ARGS(SKPBench, |
+ (name.c_str(), pic.get(), fClip, fScales[fCurrentScale])); |
+ } |
+ fCurrentSKP = 0; |
+ fCurrentScale++; |
+ } |
+ |
return NULL; |
} |
+ |
+ void fillCurrentOptions(ResultsWriter* log) const { |
+ log->configOption("source_type", fSourceType); |
+ if (0 == strcmp(fSourceType, "skp")) { |
+ log->configOption("clip", |
+ SkStringPrintf("%d %d %d %d", fClip.fLeft, fClip.fTop, |
+ fClip.fRight, fClip.fBottom).c_str()); |
+ log->configOption("scale", SkStringPrintf("%.2g", fScales[fCurrentScale]).c_str()); |
+ } |
+ } |
+ |
private: |
const BenchRegistry* fBenches; |
const skiagm::GMRegistry* fGMs; |
+ SkIRect fClip; |
+ SkTArray<SkScalar> fScales; |
+ SkTArray<SkString> fSKPs; |
+ |
+ const char* fSourceType; |
+ int fCurrentScale; |
+ int fCurrentSKP; |
}; |
int nanobench_main(); |
@@ -427,9 +510,8 @@ int nanobench_main() { |
SkTDArray<Config> configs; |
create_configs(&configs); |
- BenchmarkStream benches; |
- const char* sourceType; |
- while (Benchmark* b = benches.next(&sourceType)) { |
+ BenchmarkStream benchStream; |
+ while (Benchmark* b = benchStream.next()) { |
SkAutoTDelete<Benchmark> bench(b); |
if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) { |
continue; |
@@ -446,6 +528,18 @@ int nanobench_main() { |
SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->getCanvas() : NULL; |
const char* config = targets[j]->config.name; |
+#if SK_DEBUG |
+ // FIXME: Some SKPs SkASSERT in debug mode. Skip them for now until we can fix things. |
bsalomon
2014/08/01 13:23:24
Should prolly file a bug and stick a link to it he
mtklein
2014/08/01 13:55:34
Done.
|
+ if (0 == strcmp("565", config) |
+ && ( SkStrStartsWith(bench->getName(), "desk_carsvg.skp") |
+ || SkStrStartsWith(bench->getName(), "desk_forecastio.skp") |
+ || SkStrStartsWith(bench->getName(), "tabl_cnet.skp") |
+ || SkStrStartsWith(bench->getName(), "tabl_googlecalendar.skp"))) { |
+ SkDebugf("Skipping 565 %s. It'd assert.\n", bench->getName()); |
+ continue; |
+ } |
+#endif |
+ |
const int loops = |
#if SK_SUPPORT_GPU |
Benchmark::kGPU_Backend == targets[j]->config.backend |
@@ -462,7 +556,7 @@ int nanobench_main() { |
Stats stats(samples.get(), FLAGS_samples); |
log.config(config); |
- log.configOption("source_type", sourceType); |
+ benchStream.fillCurrentOptions(&log); |
#if SK_SUPPORT_GPU |
if (Benchmark::kGPU_Backend == targets[j]->config.backend) { |
fill_gpu_options(&log, targets[j]->gl); |