• 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 "dm/DMJsonWriter.h"
9 
10 #include "include/core/SkData.h"
11 #include "include/core/SkStream.h"
12 #include "include/private/SkMutex.h"
13 #include "include/private/SkTArray.h"
14 #include "src/core/SkOSFile.h"
15 #include "src/utils/SkJSON.h"
16 #include "src/utils/SkJSONWriter.h"
17 #include "src/utils/SkOSPath.h"
18 #include "tools/ProcStats.h"
19 
20 namespace DM {
21 
22 SkTArray<JsonWriter::BitmapResult> gBitmapResults;
bitmap_result_mutex()23 static SkMutex& bitmap_result_mutex() {
24     static SkMutex& mutex = *(new SkMutex);
25     return mutex;
26 }
27 
28 
AddBitmapResult(const BitmapResult & result)29 void JsonWriter::AddBitmapResult(const BitmapResult& result) {
30     SkAutoMutexExclusive lock(bitmap_result_mutex());
31     gBitmapResults.push_back(result);
32 }
33 
DumpJson(const char * dir,CommandLineFlags::StringArray key,CommandLineFlags::StringArray properties)34 void JsonWriter::DumpJson(const char* dir,
35                           CommandLineFlags::StringArray key,
36                           CommandLineFlags::StringArray properties) {
37     if (0 == strcmp(dir, "")) {
38         return;
39     }
40 
41     SkString path = SkOSPath::Join(dir, "dm.json");
42     sk_mkdir(dir);
43     SkFILEWStream stream(path.c_str());
44     SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
45 
46     writer.beginObject(); // root
47 
48     for (int i = 1; i < properties.count(); i += 2) {
49         writer.appendString(properties[i-1], properties[i]);
50     }
51 
52     writer.beginObject("key");
53     for (int i = 1; i < key.count(); i += 2) {
54         writer.appendString(key[i-1], key[i]);
55     }
56     writer.endObject();
57 
58     int maxResidentSetSizeMB = sk_tools::getMaxResidentSetSizeMB();
59     if (maxResidentSetSizeMB != -1) {
60         writer.appendS32("max_rss_MB", maxResidentSetSizeMB);
61     }
62 
63     {
64         SkAutoMutexExclusive lock(bitmap_result_mutex());
65         writer.beginArray("results");
66         for (int i = 0; i < gBitmapResults.count(); i++) {
67             writer.beginObject();
68 
69             writer.beginObject("key");
70             writer.appendString("name"       , gBitmapResults[i].name.c_str());
71             writer.appendString("config"     , gBitmapResults[i].config.c_str());
72             writer.appendString("source_type", gBitmapResults[i].sourceType.c_str());
73 
74             // Source options only need to be part of the key if they exist.
75             // Source type by source type, we either always set options or never set options.
76             if (!gBitmapResults[i].sourceOptions.isEmpty()) {
77                 writer.appendString("source_options", gBitmapResults[i].sourceOptions.c_str());
78             }
79             writer.endObject(); // key
80 
81             writer.beginObject("options");
82             writer.appendString("ext"  ,       gBitmapResults[i].ext.c_str());
83             writer.appendString("gamut",       gBitmapResults[i].gamut.c_str());
84             writer.appendString("transfer_fn", gBitmapResults[i].transferFn.c_str());
85             writer.appendString("color_type",  gBitmapResults[i].colorType.c_str());
86             writer.appendString("alpha_type",  gBitmapResults[i].alphaType.c_str());
87             writer.appendString("color_depth", gBitmapResults[i].colorDepth.c_str());
88             writer.endObject(); // options
89 
90             writer.appendString("md5", gBitmapResults[i].md5.c_str());
91 
92             writer.endObject(); // 1 result
93         }
94         writer.endArray(); // results
95     }
96 
97     writer.endObject(); // root
98     writer.flush();
99     stream.flush();
100 }
101 
102 using namespace skjson;
103 
ReadJson(const char * path,void (* callback)(BitmapResult))104 bool JsonWriter::ReadJson(const char* path, void(*callback)(BitmapResult)) {
105     sk_sp<SkData> json(SkData::MakeFromFileName(path));
106     if (!json) {
107         return false;
108     }
109 
110     DOM dom((const char*)json->data(), json->size());
111     const ObjectValue* root = dom.root();
112     if (!root) {
113         return false;
114     }
115 
116     const ArrayValue* results = (*root)["results"];
117     if (!results) {
118         return false;
119     }
120 
121     BitmapResult br;
122     for (const ObjectValue* r : *results) {
123         const ObjectValue& key = (*r)["key"].as<ObjectValue>();
124         const ObjectValue& options = (*r)["options"].as<ObjectValue>();
125 
126         br.name         = key["name"].as<StringValue>().begin();
127         br.config       = key["config"].as<StringValue>().begin();
128         br.sourceType   = key["source_type"].as<StringValue>().begin();
129         br.ext          = options["ext"].as<StringValue>().begin();
130         br.gamut        = options["gamut"].as<StringValue>().begin();
131         br.transferFn   = options["transfer_fn"].as<StringValue>().begin();
132         br.colorType    = options["color_type"].as<StringValue>().begin();
133         br.alphaType    = options["alpha_type"].as<StringValue>().begin();
134         br.colorDepth   = options["color_depth"].as<StringValue>().begin();
135         br.md5          = (*r)["md5"].as<StringValue>().begin();
136 
137         if (const StringValue* so = key["source_options"]) {
138             br.sourceOptions = so->begin();
139         }
140         callback(br);
141     }
142     return true;
143 }
144 
145 } // namespace DM
146