• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~ResultsWriter()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.
key(const char name[],const char value[])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.
property(const char name[],const char value[])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 timer can be called multiple times to record runs.
bench(const char name[],int32_t x,int32_t y)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".
config(const char name[])41     virtual void config(const char name[]) {}
42 
43     // Record the options for a configuration, such as "GL_RENDERER".
configOption(const char name[],const char * value)44     virtual void configOption(const char name[], const char* value) {}
45 
46     // Record a single test metric.
timer(const char name[],double ms)47     virtual void timer(const char name[], double ms) {}
48 };
49 
50 /**
51  NanoJSONResultsWriter writes the test results out in the following
52  format:
53 
54  {
55     "key": {
56       "arch": "Arm7",
57       "gpu": "SGX540",
58       "os": "Android",
59       "model": "GalaxyNexus",
60     }
61     "gitHash": "d1830323662ae8ae06908b97f15180fd25808894",
62     "build_number": "1234",
63     "results" : {
64         "Xfermode_Luminosity_640_480" : {
65            "8888" : {
66                  "median_ms" : 143.188128906250,
67                  "min_ms" : 143.835957031250,
68                  ...
69               },
70           ...
71 */
72 class NanoJSONResultsWriter : public ResultsWriter {
73 public:
NanoJSONResultsWriter(const char filename[])74     explicit NanoJSONResultsWriter(const char filename[])
75         : fFilename(filename)
76         , fRoot()
77         , fResults(fRoot["results"])
78         , fBench(NULL)
79         , fConfig(NULL) {}
80 
~NanoJSONResultsWriter()81     ~NanoJSONResultsWriter() {
82         SkFILEWStream stream(fFilename.c_str());
83         stream.writeText(Json::StyledWriter().write(fRoot).c_str());
84         stream.flush();
85     }
86 
87     // Added under "key".
key(const char name[],const char value[])88     virtual void key(const char name[], const char value[]) {
89         fRoot["key"][name] = value;
90     }
91     // Inserted directly into the root.
property(const char name[],const char value[])92     virtual void property(const char name[], const char value[]) {
93         fRoot[name] = value;
94     }
bench(const char name[],int32_t x,int32_t y)95     virtual void bench(const char name[], int32_t x, int32_t y) {
96         SkString id = SkStringPrintf( "%s_%d_%d", name, x, y);
97         fResults[id.c_str()] = Json::Value(Json::objectValue);
98         fBench = &fResults[id.c_str()];
99     }
config(const char name[])100     virtual void config(const char name[]) {
101         SkASSERT(fBench);
102         fConfig = &(*fBench)[name];
103     }
configOption(const char name[],const char * value)104     virtual void configOption(const char name[], const char* value) {
105         (*fConfig)["options"][name] = value;
106     }
timer(const char name[],double ms)107     virtual void timer(const char name[], double ms) {
108         // Don't record if nan, or -nan.
109         if (sk_double_isnan(ms)) {
110             return;
111         }
112         SkASSERT(fConfig);
113         (*fConfig)[name] = ms;
114     }
115 
116 private:
117     SkString fFilename;
118     Json::Value fRoot;
119     Json::Value& fResults;
120     Json::Value* fBench;
121     Json::Value* fConfig;
122 };
123 
124 
125 #endif
126