• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 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 
8 #include "DMJsonWriter.h"
9 
10 #include "ProcStats.h"
11 #include "SkCommonFlags.h"
12 #include "SkData.h"
13 #include "SkJSONCPP.h"
14 #include "SkMutex.h"
15 #include "SkOSFile.h"
16 #include "SkOSPath.h"
17 #include "SkStream.h"
18 #include "SkTArray.h"
19 
20 namespace DM {
21 
22 SkTArray<JsonWriter::BitmapResult> gBitmapResults;
23 SK_DECLARE_STATIC_MUTEX(gBitmapResultLock);
24 
AddBitmapResult(const BitmapResult & result)25 void JsonWriter::AddBitmapResult(const BitmapResult& result) {
26     SkAutoMutexAcquire lock(&gBitmapResultLock);
27     gBitmapResults.push_back(result);
28 }
29 
30 SkTArray<skiatest::Failure> gFailures;
31 SK_DECLARE_STATIC_MUTEX(gFailureLock);
32 
AddTestFailure(const skiatest::Failure & failure)33 void JsonWriter::AddTestFailure(const skiatest::Failure& failure) {
34     SkAutoMutexAcquire lock(gFailureLock);
35     gFailures.push_back(failure);
36 }
37 
DumpJson()38 void JsonWriter::DumpJson() {
39     if (FLAGS_writePath.isEmpty()) {
40         return;
41     }
42 
43     Json::Value root;
44 
45     for (int i = 1; i < FLAGS_properties.count(); i += 2) {
46         root[FLAGS_properties[i-1]] = FLAGS_properties[i];
47     }
48     for (int i = 1; i < FLAGS_key.count(); i += 2) {
49         root["key"][FLAGS_key[i-1]] = FLAGS_key[i];
50     }
51 
52     {
53         SkAutoMutexAcquire lock(&gBitmapResultLock);
54         for (int i = 0; i < gBitmapResults.count(); i++) {
55             Json::Value result;
56             result["key"]["name"]              = gBitmapResults[i].name.c_str();
57             result["key"]["config"]            = gBitmapResults[i].config.c_str();
58             result["key"]["source_type"]       = gBitmapResults[i].sourceType.c_str();
59             result["options"]["ext"]           = gBitmapResults[i].ext.c_str();
60             result["options"]["gamma_correct"] = gBitmapResults[i].gammaCorrect ? "yes" : "no";
61             result["md5"]                      = gBitmapResults[i].md5.c_str();
62 
63             // Source options only need to be part of the key if they exist.
64             // Source type by source type, we either always set options or never set options.
65             if (!gBitmapResults[i].sourceOptions.isEmpty()) {
66                 result["key"]["source_options"] = gBitmapResults[i].sourceOptions.c_str();
67             }
68 
69             root["results"].append(result);
70         }
71     }
72 
73     {
74         SkAutoMutexAcquire lock(gFailureLock);
75         for (int i = 0; i < gFailures.count(); i++) {
76             Json::Value result;
77             result["file_name"]     = gFailures[i].fileName;
78             result["line_no"]       = gFailures[i].lineNo;
79             result["condition"]     = gFailures[i].condition;
80             result["message"]       = gFailures[i].message.c_str();
81 
82             root["test_results"]["failures"].append(result);
83         }
84     }
85 
86     int maxResidentSetSizeMB = sk_tools::getMaxResidentSetSizeMB();
87     if (maxResidentSetSizeMB != -1) {
88         root["max_rss_MB"] = sk_tools::getMaxResidentSetSizeMB();
89     }
90 
91     SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json");
92     sk_mkdir(FLAGS_writePath[0]);
93     SkFILEWStream stream(path.c_str());
94     stream.writeText(Json::StyledWriter().write(root).c_str());
95     stream.flush();
96 }
97 
ReadJson(const char * path,void (* callback)(BitmapResult))98 bool JsonWriter::ReadJson(const char* path, void(*callback)(BitmapResult)) {
99     sk_sp<SkData> json(SkData::MakeFromFileName(path));
100     if (!json) {
101         return false;
102     }
103 
104     Json::Reader reader;
105     Json::Value root;
106     const char* data = (const char*)json->data();
107     if (!reader.parse(data, data+json->size(), root)) {
108         return false;
109     }
110 
111     const Json::Value& results = root["results"];
112     BitmapResult br;
113     for (unsigned i = 0; i < results.size(); i++) {
114         const Json::Value& r = results[i];
115         br.name         = r["key"]["name"].asCString();
116         br.config       = r["key"]["config"].asCString();
117         br.sourceType   = r["key"]["source_type"].asCString();
118         br.ext          = r["options"]["ext"].asCString();
119         br.gammaCorrect = 0 == strcmp("yes", r["options"]["gamma_correct"].asCString());
120         br.md5          = r["md5"].asCString();
121 
122         if (!r["key"]["source_options"].isNull()) {
123             br.sourceOptions = r["key"]["source_options"].asCString();
124         }
125         callback(br);
126     }
127     return true;
128 }
129 
130 } // namespace DM
131