f15f78c905
This allows mskps produced with Chromium to be displayed in the debugger. Previously, the debugger would produce invalid json if any string contained characters which needed to be escaped. The debugger also treated all strings like NULL terminated strings, but json is Unicode based and code point U+0000 is a perfectly good code point. Change-Id: I28150bad666b02be9f1e4af4078a4ca1e65bf000 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/549098 Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Herb Derby <herb@google.com>
146 lines
4.7 KiB
C++
146 lines
4.7 KiB
C++
/*
|
|
* Copyright 2014 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "dm/DMJsonWriter.h"
|
|
|
|
#include "include/core/SkData.h"
|
|
#include "include/core/SkStream.h"
|
|
#include "include/private/SkMutex.h"
|
|
#include "include/private/SkTArray.h"
|
|
#include "src/core/SkOSFile.h"
|
|
#include "src/utils/SkJSON.h"
|
|
#include "src/utils/SkJSONWriter.h"
|
|
#include "src/utils/SkOSPath.h"
|
|
#include "tools/ProcStats.h"
|
|
|
|
namespace DM {
|
|
|
|
SkTArray<JsonWriter::BitmapResult> gBitmapResults;
|
|
static SkMutex& bitmap_result_mutex() {
|
|
static SkMutex& mutex = *(new SkMutex);
|
|
return mutex;
|
|
}
|
|
|
|
|
|
void JsonWriter::AddBitmapResult(const BitmapResult& result) {
|
|
SkAutoMutexExclusive lock(bitmap_result_mutex());
|
|
gBitmapResults.push_back(result);
|
|
}
|
|
|
|
void JsonWriter::DumpJson(const char* dir,
|
|
CommandLineFlags::StringArray key,
|
|
CommandLineFlags::StringArray properties) {
|
|
if (0 == strcmp(dir, "")) {
|
|
return;
|
|
}
|
|
|
|
SkString path = SkOSPath::Join(dir, "dm.json");
|
|
sk_mkdir(dir);
|
|
SkFILEWStream stream(path.c_str());
|
|
SkJSONWriter writer(&stream, SkJSONWriter::Mode::kPretty);
|
|
|
|
writer.beginObject(); // root
|
|
|
|
for (int i = 1; i < properties.count(); i += 2) {
|
|
writer.appendCString(properties[i-1], properties[i]);
|
|
}
|
|
|
|
writer.beginObject("key");
|
|
for (int i = 1; i < key.count(); i += 2) {
|
|
writer.appendCString(key[i-1], key[i]);
|
|
}
|
|
writer.endObject();
|
|
|
|
int maxResidentSetSizeMB = sk_tools::getMaxResidentSetSizeMB();
|
|
if (maxResidentSetSizeMB != -1) {
|
|
writer.appendS32("max_rss_MB", maxResidentSetSizeMB);
|
|
}
|
|
|
|
{
|
|
SkAutoMutexExclusive lock(bitmap_result_mutex());
|
|
writer.beginArray("results");
|
|
for (int i = 0; i < gBitmapResults.count(); i++) {
|
|
writer.beginObject();
|
|
|
|
writer.beginObject("key");
|
|
writer.appendString("name" , gBitmapResults[i].name);
|
|
writer.appendString("config" , gBitmapResults[i].config);
|
|
writer.appendString("source_type", gBitmapResults[i].sourceType);
|
|
|
|
// Source options only need to be part of the key if they exist.
|
|
// Source type by source type, we either always set options or never set options.
|
|
if (!gBitmapResults[i].sourceOptions.isEmpty()) {
|
|
writer.appendString("source_options", gBitmapResults[i].sourceOptions);
|
|
}
|
|
writer.endObject(); // key
|
|
|
|
writer.beginObject("options");
|
|
writer.appendString("ext" , gBitmapResults[i].ext);
|
|
writer.appendString("gamut", gBitmapResults[i].gamut);
|
|
writer.appendString("transfer_fn", gBitmapResults[i].transferFn);
|
|
writer.appendString("color_type", gBitmapResults[i].colorType);
|
|
writer.appendString("alpha_type", gBitmapResults[i].alphaType);
|
|
writer.appendString("color_depth", gBitmapResults[i].colorDepth);
|
|
writer.endObject(); // options
|
|
|
|
writer.appendString("md5", gBitmapResults[i].md5);
|
|
|
|
writer.endObject(); // 1 result
|
|
}
|
|
writer.endArray(); // results
|
|
}
|
|
|
|
writer.endObject(); // root
|
|
writer.flush();
|
|
stream.flush();
|
|
}
|
|
|
|
using namespace skjson;
|
|
|
|
bool JsonWriter::ReadJson(const char* path, void(*callback)(BitmapResult)) {
|
|
sk_sp<SkData> json(SkData::MakeFromFileName(path));
|
|
if (!json) {
|
|
return false;
|
|
}
|
|
|
|
DOM dom((const char*)json->data(), json->size());
|
|
const ObjectValue* root = dom.root();
|
|
if (!root) {
|
|
return false;
|
|
}
|
|
|
|
const ArrayValue* results = (*root)["results"];
|
|
if (!results) {
|
|
return false;
|
|
}
|
|
|
|
BitmapResult br;
|
|
for (const ObjectValue* r : *results) {
|
|
const ObjectValue& key = (*r)["key"].as<ObjectValue>();
|
|
const ObjectValue& options = (*r)["options"].as<ObjectValue>();
|
|
|
|
br.name = key["name"].as<StringValue>().begin();
|
|
br.config = key["config"].as<StringValue>().begin();
|
|
br.sourceType = key["source_type"].as<StringValue>().begin();
|
|
br.ext = options["ext"].as<StringValue>().begin();
|
|
br.gamut = options["gamut"].as<StringValue>().begin();
|
|
br.transferFn = options["transfer_fn"].as<StringValue>().begin();
|
|
br.colorType = options["color_type"].as<StringValue>().begin();
|
|
br.alphaType = options["alpha_type"].as<StringValue>().begin();
|
|
br.colorDepth = options["color_depth"].as<StringValue>().begin();
|
|
br.md5 = (*r)["md5"].as<StringValue>().begin();
|
|
|
|
if (const StringValue* so = key["source_options"]) {
|
|
br.sourceOptions = so->begin();
|
|
}
|
|
callback(br);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace DM
|