aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--bench/ResultsWriter.h103
-rw-r--r--bench/nanobench.cpp49
2 files changed, 143 insertions, 9 deletions
diff --git a/bench/ResultsWriter.h b/bench/ResultsWriter.h
index 1ee3616ceb..dc45f192f5 100644
--- a/bench/ResultsWriter.h
+++ b/bench/ResultsWriter.h
@@ -26,6 +26,10 @@ class ResultsWriter : SkNoncopyable {
public:
virtual ~ResultsWriter() {};
+ // Records one key value pair that makes up a unique identifier for this run.
+ // All keys must be set before calling bench().
+ virtual void key(const char name[], const char value[]) = 0;
+
// Records one option set for this run. All options must be set before
// calling bench().
virtual void option(const char name[], const char value[]) = 0;
@@ -37,6 +41,9 @@ public:
// Records the specific configuration a bench is run under, such as "8888".
virtual void config(const char name[]) = 0;
+ // Records the options for a configuration, such as "GL_RENDERER".
+ virtual void configOption(const char name[], const char* value) = 0;
+
// Records a single test metric.
virtual void timer(const char name[], double ms) = 0;
@@ -55,6 +62,9 @@ public:
, fTimeFormat(timeFormat) {
fLogger.logProgress("skia bench:");
}
+ virtual void key(const char name[], const char value[]) {
+ // Don't log keys to keep microbench output unchanged.
+ }
virtual void option(const char name[], const char value[]) {
fLogger.logProgress(SkStringPrintf(" %s=%s", name, value));
}
@@ -65,6 +75,9 @@ public:
virtual void config(const char name[]) {
fLogger.logProgress(SkStringPrintf(" %s:", name));
}
+ virtual void configOption(const char name[], const char* value) {
+ // Don't log configOptions to keep microbench output unchanged.
+ }
virtual void timer(const char name[], double ms) {
fLogger.logProgress(SkStringPrintf(" %s = ", name));
fLogger.logProgress(SkStringPrintf(fTimeFormat, ms));
@@ -113,6 +126,8 @@ public:
, fBench(NULL)
, fConfig(NULL) {
}
+ virtual void key(const char name[], const char value[]) {
+ }
virtual void option(const char name[], const char value[]) {
fRoot["options"][name] = value;
}
@@ -129,7 +144,84 @@ public:
SkASSERT(NULL != fBench);
fConfig = SkFindNamedNode(fBench, name);
}
+ virtual void configOption(const char name[], const char* value) {
+ }
+ virtual void timer(const char name[], double ms) {
+ SkASSERT(NULL != fConfig);
+ (*fConfig)[name] = ms;
+ }
+ virtual void end() {
+ SkFILEWStream stream(fFilename.c_str());
+ stream.writeText(Json::FastWriter().write(fRoot).c_str());
+ stream.flush();
+ }
+private:
+
+ SkString fFilename;
+ Json::Value fRoot;
+ Json::Value& fResults;
+ Json::Value* fBench;
+ Json::Value* fConfig;
+};
+
+/**
+ NanoJSONResultsWriter writes the test results out in the following
+ format:
+
+ {
+ "key": {
+ "arch": "Arm7",
+ "gpu": "SGX540",
+ "os": "Android",
+ "model": "GalaxyNexus",
+ }
+ "options": {
+ "GL_Version": "3.1",
+ ...
+ },
+ "gitHash": "d1830323662ae8ae06908b97f15180fd25808894",
+ "results" : {
+ "Xfermode_Luminosity_640_480" : {
+ "8888" : {
+ "median_ms" : 143.188128906250,
+ "min_ms" : 143.835957031250,
+ ...
+ },
+ ...
+*/
+class NanoJSONResultsWriter : public ResultsWriter {
+public:
+ explicit NanoJSONResultsWriter(const char filename[], const char gitHash[])
+ : fFilename(filename)
+ , fRoot()
+ , fResults(fRoot["results"])
+ , fBench(NULL)
+ , fConfig(NULL) {
+ fRoot["gitHash"] = gitHash;
+ }
+ virtual void key(const char name[], const char value[]) {
+ fRoot["key"][name] = value;
+ }
+ virtual void option(const char name[], const char value[]) {
+ fRoot["options"][name] = value;
+ }
+ virtual void bench(const char name[], int32_t x, int32_t y) {
+ SkString id = SkStringPrintf( "%s_%d_%d", name, x, y);
+ fResults[id.c_str()] = Json::Value(Json::objectValue);
+ fBench = &fResults[id.c_str()];
+ }
+ virtual void config(const char name[]) {
+ SkASSERT(NULL != fBench);
+ fConfig = &(*fBench)[name];
+ }
+ virtual void configOption(const char name[], const char* value) {
+ (*fConfig)["options"][name] = value;
+ }
virtual void timer(const char name[], double ms) {
+ // Don't record if nan, or -nan.
+ if (sk_double_isnan(ms)) {
+ return;
+ }
SkASSERT(NULL != fConfig);
(*fConfig)[name] = ms;
}
@@ -147,6 +239,7 @@ private:
Json::Value* fConfig;
};
+
/**
* This ResultsWriter writes out to multiple ResultsWriters.
*/
@@ -157,6 +250,11 @@ public:
void add(ResultsWriter* writer) {
writers.push_back(writer);
}
+ virtual void key(const char name[], const char value[]) {
+ for (int i = 0; i < writers.count(); ++i) {
+ writers[i]->key(name, value);
+ }
+ }
virtual void option(const char name[], const char value[]) {
for (int i = 0; i < writers.count(); ++i) {
writers[i]->option(name, value);
@@ -172,6 +270,11 @@ public:
writers[i]->config(name);
}
}
+ virtual void configOption(const char name[], const char* value) {
+ for (int i = 0; i < writers.count(); ++i) {
+ writers[i]->configOption(name, value);
+ }
+ }
virtual void timer(const char name[], double ms) {
for (int i = 0; i < writers.count(); ++i) {
writers[i]->timer(name, ms);
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index 59e85ed9e6..5cd3e2fbf4 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -21,6 +21,7 @@
#include "SkSurface.h"
#if SK_SUPPORT_GPU
+ #include "gl/GrGLDefines.h"
#include "GrContextFactory.h"
GrContextFactory gGrFactory;
#endif
@@ -53,6 +54,8 @@ DEFINE_bool(resetGpuContext, true, "Reset the GrContext before running each benc
DEFINE_int32(maxCalibrationAttempts, 3,
"Try up to this many times to guess loops for a bench, or skip the bench.");
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.");
static SkString humanize(double ms) {
@@ -276,13 +279,25 @@ static void fill_static_options(ResultsWriter* log) {
#else
log->option("system", "other");
#endif
-#if defined(SK_DEBUG)
- log->option("build", "DEBUG");
-#else
- log->option("build", "RELEASE");
-#endif
}
+#if SK_SUPPORT_GPU
+static void fill_gpu_options(ResultsWriter* log, SkGLContextHelper* ctx) {
+ const GLubyte* version;
+ SK_GL_RET(*ctx, version, GetString(GR_GL_VERSION));
+ log->configOption("GL_VERSION", (const char*)(version));
+
+ SK_GL_RET(*ctx, version, GetString(GR_GL_RENDERER));
+ log->configOption("GL_RENDERER", (const char*) version);
+
+ SK_GL_RET(*ctx, version, GetString(GR_GL_VENDOR));
+ log->configOption("GL_VENDOR", (const char*) version);
+
+ SK_GL_RET(*ctx, version, GetString(GR_GL_SHADING_LANGUAGE_VERSION));
+ log->configOption("GL_SHADING_LANGUAGE_VERSION", (const char*) version);
+}
+#endif
+
int tool_main(int argc, char** argv);
int tool_main(int argc, char** argv) {
SetupCrashHandler();
@@ -295,12 +310,21 @@ int tool_main(int argc, char** argv) {
}
MultiResultsWriter log;
- SkAutoTDelete<JSONResultsWriter> json;
+ SkAutoTDelete<NanoJSONResultsWriter> json;
if (!FLAGS_outResultsFile.isEmpty()) {
- json.reset(SkNEW(JSONResultsWriter(FLAGS_outResultsFile[0])));
+ const char* gitHash = FLAGS_gitHash.isEmpty() ? "unknown-revision" : FLAGS_gitHash[0];
+ json.reset(SkNEW(NanoJSONResultsWriter(FLAGS_outResultsFile[0], gitHash)));
log.add(json.get());
}
CallEnd<MultiResultsWriter> ender(log);
+
+ if (1 == FLAGS_key.count() % 2) {
+ SkDebugf("ERROR: --key must be passed with an even number of arguments.\n");
+ return 1;
+ }
+ for (int i = 1; i < FLAGS_key.count(); i += 2) {
+ log.key(FLAGS_key[i-1], FLAGS_key[i]);
+ }
fill_static_options(&log);
const double overhead = estimate_timer_overhead();
@@ -323,12 +347,14 @@ int tool_main(int argc, char** argv) {
if (SkCommandLineFlags::ShouldSkip(FLAGS_match, bench->getName())) {
continue;
}
- log.bench(bench->getName(), bench->getSize().fX, bench->getSize().fY);
SkTDArray<Target*> targets;
create_targets(bench.get(), &targets);
- bench->preDraw();
+ if (!targets.isEmpty()) {
+ log.bench(bench->getName(), bench->getSize().fX, bench->getSize().fY);
+ bench->preDraw();
+ }
for (int j = 0; j < targets.count(); j++) {
SkCanvas* canvas = targets[j]->surface.get() ? targets[j]->surface->getCanvas() : NULL;
const char* config = targets[j]->config;
@@ -349,6 +375,11 @@ int tool_main(int argc, char** argv) {
Stats stats(samples.get(), FLAGS_samples);
log.config(config);
+#if SK_SUPPORT_GPU
+ if (Benchmark::kGPU_Backend == targets[j]->backend) {
+ fill_gpu_options(&log, targets[j]->gl);
+ }
+#endif
log.timer("min_ms", stats.min);
log.timer("median_ms", stats.median);
log.timer("mean_ms", stats.mean);