Upload picture byte size and op count metrics for SKP recording.
[platform/upstream/libSkiaSharp.git] / bench / ResultsWriter.h
1 /*
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
10 #ifndef SkResultsWriter_DEFINED
11 #define SkResultsWriter_DEFINED
12
13 #include "BenchLogger.h"
14 #include "SkJSONCPP.h"
15 #include "SkStream.h"
16 #include "SkString.h"
17 #include "SkTArray.h"
18 #include "SkTypes.h"
19
20 /**
21  * Base class for writing out the bench results.
22  *
23  * Default implementation does nothing.
24  */
25 class ResultsWriter : SkNoncopyable {
26 public:
27     virtual ~ResultsWriter() {}
28
29     // Record one key value pair that makes up a unique key for this type of run, e.g.
30     // builder name, machine type, Debug/Release, etc.
31     virtual void key(const char name[], const char value[]) {}
32
33     // Record one key value pair that describes the run instance, e.g. git hash, build number.
34     virtual void property(const char name[], const char value[]) {}
35
36     // Denote the start of a specific benchmark. Once bench is called,
37     // then config and metric can be called multiple times to record runs.
38     virtual void bench(const char name[], int32_t x, int32_t y) {}
39
40     // Record the specific configuration a bench is run under, such as "8888".
41     virtual void config(const char name[]) {}
42
43     // Record the options for a configuration, such as "GL_RENDERER".
44     virtual void configOption(const char name[], const char* value) {}
45
46     // Record a single test metric.
47     virtual void metric(const char name[], double ms) {}
48
49     // Flush to storage now please.
50     virtual void flush() {}
51 };
52
53 /**
54  NanoJSONResultsWriter writes the test results out in the following
55  format:
56
57  {
58     "key": {
59       "arch": "Arm7",
60       "gpu": "SGX540",
61       "os": "Android",
62       "model": "GalaxyNexus",
63     }
64     "gitHash": "d1830323662ae8ae06908b97f15180fd25808894",
65     "build_number": "1234",
66     "results" : {
67         "Xfermode_Luminosity_640_480" : {
68            "8888" : {
69                  "median_ms" : 143.188128906250,
70                  "min_ms" : 143.835957031250,
71                  ...
72               },
73           ...
74 */
75 class NanoJSONResultsWriter : public ResultsWriter {
76 public:
77     explicit NanoJSONResultsWriter(const char filename[])
78         : fFilename(filename)
79         , fRoot()
80         , fResults(fRoot["results"])
81         , fBench(NULL)
82         , fConfig(NULL) {}
83
84     ~NanoJSONResultsWriter() {
85         this->flush();
86     }
87
88     // Added under "key".
89     virtual void key(const char name[], const char value[]) {
90         fRoot["key"][name] = value;
91     }
92     // Inserted directly into the root.
93     virtual void property(const char name[], const char value[]) {
94         fRoot[name] = value;
95     }
96     virtual void bench(const char name[], int32_t x, int32_t y) {
97         SkString id = SkStringPrintf( "%s_%d_%d", name, x, y);
98         fResults[id.c_str()] = Json::Value(Json::objectValue);
99         fBench = &fResults[id.c_str()];
100     }
101     virtual void config(const char name[]) {
102         SkASSERT(fBench);
103         fConfig = &(*fBench)[name];
104     }
105     virtual void configOption(const char name[], const char* value) {
106         (*fConfig)["options"][name] = value;
107     }
108     virtual void metric(const char name[], double ms) {
109         // Don't record if nan, or -nan.
110         if (sk_double_isnan(ms)) {
111             return;
112         }
113         SkASSERT(fConfig);
114         (*fConfig)[name] = ms;
115     }
116
117     // Flush to storage now please.
118     virtual void flush() {
119         SkFILEWStream stream(fFilename.c_str());
120         stream.writeText(Json::StyledWriter().write(fRoot).c_str());
121         stream.flush();
122     }
123
124 private:
125     SkString fFilename;
126     Json::Value fRoot;
127     Json::Value& fResults;
128     Json::Value* fBench;
129     Json::Value* fConfig;
130 };
131
132
133 #endif