• Home
  • History
  • Annotate
  • 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 metric 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.
metric(const char name[],double ms)47      virtual void metric(const char name[], double ms) {}
48  
49      // Flush to storage now please.
flush()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:
NanoJSONResultsWriter(const char filename[])77      explicit NanoJSONResultsWriter(const char filename[])
78          : fFilename(filename)
79          , fRoot()
80          , fResults(fRoot["results"])
81          , fBench(NULL)
82          , fConfig(NULL) {}
83  
~NanoJSONResultsWriter()84      ~NanoJSONResultsWriter() {
85          this->flush();
86      }
87  
88      // Added under "key".
key(const char name[],const char value[])89      virtual void key(const char name[], const char value[]) {
90          fRoot["key"][name] = value;
91      }
92      // Inserted directly into the root.
property(const char name[],const char value[])93      virtual void property(const char name[], const char value[]) {
94          fRoot[name] = value;
95      }
bench(const char name[],int32_t x,int32_t y)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      }
config(const char name[])101      virtual void config(const char name[]) {
102          SkASSERT(fBench);
103          fConfig = &(*fBench)[name];
104      }
configOption(const char name[],const char * value)105      virtual void configOption(const char name[], const char* value) {
106          (*fConfig)["options"][name] = value;
107      }
metric(const char name[],double ms)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.
flush()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
134