d3b65972aa
This silences a new warning in clang 5.0 Change-Id: Ieb5b75a6ffed60107c3fd16075d2ecfd515b55e8 Reviewed-on: https://skia-review.googlesource.com/10006 Commit-Queue: Brian Salomon <bsalomon@google.com> Reviewed-by: Mike Klein <mtklein@chromium.org>
154 lines
4.5 KiB
C++
154 lines
4.5 KiB
C++
/*
|
|
* Copyright 2013 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*
|
|
* Classes for writing out bench results in various formats.
|
|
*/
|
|
|
|
#ifndef SkResultsWriter_DEFINED
|
|
#define SkResultsWriter_DEFINED
|
|
|
|
#include "BenchLogger.h"
|
|
#include "SkJSONCPP.h"
|
|
#include "SkOSFile.h"
|
|
#include "SkOSPath.h"
|
|
#include "SkStream.h"
|
|
#include "SkString.h"
|
|
#include "SkTypes.h"
|
|
|
|
/**
|
|
* Base class for writing out the bench results.
|
|
*
|
|
* Default implementation does nothing.
|
|
*/
|
|
class ResultsWriter : SkNoncopyable {
|
|
public:
|
|
virtual ~ResultsWriter() {}
|
|
|
|
// Record one key value pair that makes up a unique key for this type of run, e.g.
|
|
// builder name, machine type, Debug/Release, etc.
|
|
virtual void key(const char name[], const char value[]) {}
|
|
|
|
// Record one key value pair that describes the run instance, e.g. git hash, build number.
|
|
virtual void property(const char name[], const char value[]) {}
|
|
|
|
// Denote the start of a specific benchmark. Once bench is called,
|
|
// then config and metric can be called multiple times to record runs.
|
|
virtual void bench(const char name[], int32_t x, int32_t y) {}
|
|
|
|
// Record the specific configuration a bench is run under, such as "8888".
|
|
virtual void config(const char name[]) {}
|
|
|
|
// Record the options for a configuration, such as "GL_RENDERER".
|
|
virtual void configOption(const char name[], const char* value) {}
|
|
|
|
// Record a single test metric.
|
|
virtual void metric(const char name[], double ms) {}
|
|
|
|
// Record a list of test metrics.
|
|
virtual void metrics(const char name[], const SkTArray<double>& array) {}
|
|
|
|
// Flush to storage now please.
|
|
virtual void flush() {}
|
|
};
|
|
|
|
/**
|
|
NanoJSONResultsWriter writes the test results out in the following
|
|
format:
|
|
|
|
{
|
|
"key": {
|
|
"arch": "Arm7",
|
|
"gpu": "SGX540",
|
|
"os": "Android",
|
|
"model": "GalaxyNexus",
|
|
}
|
|
"gitHash": "d1830323662ae8ae06908b97f15180fd25808894",
|
|
"build_number": "1234",
|
|
"results" : {
|
|
"Xfermode_Luminosity_640_480" : {
|
|
"8888" : {
|
|
"median_ms" : 143.188128906250,
|
|
"min_ms" : 143.835957031250,
|
|
...
|
|
},
|
|
...
|
|
*/
|
|
class NanoJSONResultsWriter : public ResultsWriter {
|
|
public:
|
|
explicit NanoJSONResultsWriter(const char filename[])
|
|
: fFilename(filename)
|
|
, fRoot()
|
|
, fResults(fRoot["results"])
|
|
, fBench(nullptr)
|
|
, fConfig(nullptr) {}
|
|
|
|
~NanoJSONResultsWriter() override {
|
|
this->flush();
|
|
}
|
|
|
|
// Added under "key".
|
|
void key(const char name[], const char value[]) override {
|
|
fRoot["key"][name] = value;
|
|
}
|
|
// Inserted directly into the root.
|
|
void property(const char name[], const char value[]) override {
|
|
fRoot[name] = value;
|
|
}
|
|
void bench(const char name[], int32_t x, int32_t y) override {
|
|
SkString id = SkStringPrintf( "%s_%d_%d", name, x, y);
|
|
fResults[id.c_str()] = Json::Value(Json::objectValue);
|
|
fBench = &fResults[id.c_str()];
|
|
}
|
|
void config(const char name[]) override {
|
|
SkASSERT(fBench);
|
|
fConfig = &(*fBench)[name];
|
|
}
|
|
void configOption(const char name[], const char* value) override {
|
|
(*fConfig)["options"][name] = value;
|
|
}
|
|
void metric(const char name[], double ms) override {
|
|
// Don't record if nan, or -nan.
|
|
if (sk_double_isnan(ms)) {
|
|
return;
|
|
}
|
|
SkASSERT(fConfig);
|
|
(*fConfig)[name] = ms;
|
|
}
|
|
void metrics(const char name[], const SkTArray<double>& array) override {
|
|
SkASSERT(fConfig);
|
|
Json::Value value = Json::Value(Json::arrayValue);
|
|
value.resize(array.count());
|
|
for (int i = 0; i < array.count(); i++) {
|
|
// Don't care about nan-ness.
|
|
value[i] = array[i];
|
|
}
|
|
(*fConfig)[name] = std::move(value);
|
|
}
|
|
|
|
// Flush to storage now please.
|
|
void flush() override {
|
|
SkString dirname = SkOSPath::Dirname(fFilename.c_str());
|
|
if (!sk_exists(dirname.c_str(), kWrite_SkFILE_Flag)) {
|
|
if (!sk_mkdir(dirname.c_str())) {
|
|
SkDebugf("Failed to create directory.");
|
|
}
|
|
}
|
|
SkFILEWStream stream(fFilename.c_str());
|
|
stream.writeText(Json::StyledWriter().write(fRoot).c_str());
|
|
stream.flush();
|
|
}
|
|
|
|
private:
|
|
SkString fFilename;
|
|
Json::Value fRoot;
|
|
Json::Value& fResults;
|
|
Json::Value* fBench;
|
|
Json::Value* fConfig;
|
|
};
|
|
|
|
|
|
#endif
|