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