blob: 12c968a5075d42b4c2890b0c540b8b6f3a2f83d7 [file] [log] [blame]
commit-bot@chromium.orge3bb3bc2013-12-03 18:16:48 +00001/*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 *
7 * Classes for writing out bench results in various formats.
8 */
9#ifndef SkResultsWriter_DEFINED
10#define SkResultsWriter_DEFINED
11
12#include "SkBenchLogger.h"
13#include "SkJSONCPP.h"
14#include "SkStream.h"
15#include "SkString.h"
16#include "SkTArray.h"
17#include "SkTypes.h"
18
19
20/**
21 * Base class for writing out the bench results.
22 *
23 * TODO(jcgregorio) Add info if tests fail to converge?
24 */
25class ResultsWriter : SkNoncopyable {
26public:
27 virtual ~ResultsWriter() {};
28
29 // Records one option set for this run. All options must be set before
30 // calling bench().
31 virtual void option(const char name[], const char value[]) = 0;
32
33 // Denotes the start of a specific benchmark. Once bench is called,
34 // then config and timer can be called multiple times to record runs.
35 virtual void bench(const char name[], int32_t x, int32_t y) = 0;
36
37 // Records the specific configuration a bench is run under, such as "8888".
38 virtual void config(const char name[]) = 0;
39
40 // Records a single test metric.
41 virtual void timer(const char name[], double ms) = 0;
42
43 // Call when all results are finished.
44 virtual void end() = 0;
45};
46
47/**
48 * This ResultsWriter handles writing out the human readable format of the
49 * bench results.
50 */
51class LoggerResultsWriter : public ResultsWriter {
52public:
53 explicit LoggerResultsWriter(SkBenchLogger& logger, const char* timeFormat)
54 : fLogger(logger)
55 , fTimeFormat(timeFormat) {
56 fLogger.logProgress("skia bench:");
57 }
58 virtual void option(const char name[], const char value[]) {
59 fLogger.logProgress(SkStringPrintf(" %s=%s", name, value));
60 }
61 virtual void bench(const char name[], int32_t x, int32_t y) {
62 fLogger.logProgress(SkStringPrintf(
63 "\nrunning bench [%3d %3d] %40s", x, y, name));
64 }
65 virtual void config(const char name[]) {
66 fLogger.logProgress(SkStringPrintf(" %s:", name));
67 }
68 virtual void timer(const char name[], double ms) {
69 fLogger.logProgress(SkStringPrintf(" %s = ", name));
70 fLogger.logProgress(SkStringPrintf(fTimeFormat, ms));
71 }
72 virtual void end() {
73 fLogger.logProgress("\n");
74 }
75private:
76 SkBenchLogger& fLogger;
77 const char* fTimeFormat;
78};
79
commit-bot@chromium.org61744ec2014-05-16 13:15:41 +000080#ifdef SK_BUILD_JSON_WRITER
commit-bot@chromium.orge3bb3bc2013-12-03 18:16:48 +000081/**
82 * This ResultsWriter handles writing out the results in JSON.
83 *
84 * The output looks like:
85 *
86 * {
87 * "options" : {
88 * "alpha" : "0xFF",
89 * "scale" : "0",
90 * ...
91 * "system" : "UNIX"
92 * },
93 * "results" : {
94 * "Xfermode_Luminosity_640_480" : {
95 * "565" : {
96 * "cmsecs" : 143.188128906250,
97 * "msecs" : 143.835957031250
98 * },
99 * ...
100 */
101class JSONResultsWriter : public ResultsWriter {
102public:
103 explicit JSONResultsWriter(const char filename[])
104 : fFilename(filename)
105 , fRoot()
106 , fResults(fRoot["results"])
107 , fBench(NULL)
108 , fConfig(NULL) {
109 }
110 virtual void option(const char name[], const char value[]) {
111 fRoot["options"][name] = value;
112 }
113 virtual void bench(const char name[], int32_t x, int32_t y) {
114 fBench = &fResults[SkStringPrintf( "%s_%d_%d", name, x, y).c_str()];
115 }
116 virtual void config(const char name[]) {
117 SkASSERT(NULL != fBench);
118 fConfig = &(*fBench)[name];
119 }
120 virtual void timer(const char name[], double ms) {
121 SkASSERT(NULL != fConfig);
122 (*fConfig)[name] = ms;
123 }
124 virtual void end() {
125 SkFILEWStream stream(fFilename.c_str());
126 stream.writeText(fRoot.toStyledString().c_str());
127 stream.flush();
128 }
129private:
130 SkString fFilename;
131 Json::Value fRoot;
132 Json::Value& fResults;
133 Json::Value* fBench;
134 Json::Value* fConfig;
135};
136
commit-bot@chromium.org61744ec2014-05-16 13:15:41 +0000137#endif // SK_BUILD_JSON_WRITER
commit-bot@chromium.orge3bb3bc2013-12-03 18:16:48 +0000138/**
139 * This ResultsWriter writes out to multiple ResultsWriters.
140 */
141class MultiResultsWriter : public ResultsWriter {
142public:
143 MultiResultsWriter() : writers() {
144 };
145 void add(ResultsWriter* writer) {
146 writers.push_back(writer);
147 }
148 virtual void option(const char name[], const char value[]) {
149 for (int i = 0; i < writers.count(); ++i) {
150 writers[i]->option(name, value);
151 }
152 }
153 virtual void bench(const char name[], int32_t x, int32_t y) {
154 for (int i = 0; i < writers.count(); ++i) {
155 writers[i]->bench(name, x, y);
156 }
157 }
158 virtual void config(const char name[]) {
159 for (int i = 0; i < writers.count(); ++i) {
160 writers[i]->config(name);
161 }
162 }
163 virtual void timer(const char name[], double ms) {
164 for (int i = 0; i < writers.count(); ++i) {
165 writers[i]->timer(name, ms);
166 }
167 }
168 virtual void end() {
169 for (int i = 0; i < writers.count(); ++i) {
170 writers[i]->end();
171 }
172 }
173private:
174 SkTArray<ResultsWriter *> writers;
175};
176
177/**
178 * Calls the end() method of T on destruction.
179 */
180template <typename T> class CallEnd : SkNoncopyable {
181public:
182 CallEnd(T& obj) : fObj(obj) {}
183 ~CallEnd() { fObj.end(); }
184private:
185 T& fObj;
186};
187
188#endif