|  | /* | 
|  | * 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 "DMJsonWriter.h" | 
|  |  | 
|  | #include "ProcStats.h" | 
|  | #include "SkCommonFlags.h" | 
|  | #include "SkData.h" | 
|  | #include "SkJSONCPP.h" | 
|  | #include "SkMutex.h" | 
|  | #include "SkOSFile.h" | 
|  | #include "SkOSPath.h" | 
|  | #include "SkStream.h" | 
|  | #include "SkTArray.h" | 
|  |  | 
|  | namespace DM { | 
|  |  | 
|  | SkTArray<JsonWriter::BitmapResult> gBitmapResults; | 
|  | SK_DECLARE_STATIC_MUTEX(gBitmapResultLock); | 
|  |  | 
|  | void JsonWriter::AddBitmapResult(const BitmapResult& result) { | 
|  | SkAutoMutexAcquire lock(&gBitmapResultLock); | 
|  | gBitmapResults.push_back(result); | 
|  | } | 
|  |  | 
|  | SkTArray<skiatest::Failure> gFailures; | 
|  | SK_DECLARE_STATIC_MUTEX(gFailureLock); | 
|  |  | 
|  | void JsonWriter::AddTestFailure(const skiatest::Failure& failure) { | 
|  | SkAutoMutexAcquire lock(gFailureLock); | 
|  | gFailures.push_back(failure); | 
|  | } | 
|  |  | 
|  | void JsonWriter::DumpJson() { | 
|  | if (FLAGS_writePath.isEmpty()) { | 
|  | return; | 
|  | } | 
|  |  | 
|  | Json::Value root; | 
|  |  | 
|  | for (int i = 1; i < FLAGS_properties.count(); i += 2) { | 
|  | root[FLAGS_properties[i-1]] = FLAGS_properties[i]; | 
|  | } | 
|  | for (int i = 1; i < FLAGS_key.count(); i += 2) { | 
|  | root["key"][FLAGS_key[i-1]] = FLAGS_key[i]; | 
|  | } | 
|  |  | 
|  | { | 
|  | SkAutoMutexAcquire lock(&gBitmapResultLock); | 
|  | for (int i = 0; i < gBitmapResults.count(); i++) { | 
|  | Json::Value result; | 
|  | result["key"]["name"]              = gBitmapResults[i].name.c_str(); | 
|  | result["key"]["config"]            = gBitmapResults[i].config.c_str(); | 
|  | result["key"]["source_type"]       = gBitmapResults[i].sourceType.c_str(); | 
|  | result["options"]["ext"]           = gBitmapResults[i].ext.c_str(); | 
|  | result["options"]["gamma_correct"] = gBitmapResults[i].gammaCorrect ? "yes" : "no"; | 
|  | result["md5"]                      = gBitmapResults[i].md5.c_str(); | 
|  |  | 
|  | // 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()) { | 
|  | result["key"]["source_options"] = gBitmapResults[i].sourceOptions.c_str(); | 
|  | } | 
|  |  | 
|  | root["results"].append(result); | 
|  | } | 
|  | } | 
|  |  | 
|  | { | 
|  | SkAutoMutexAcquire lock(gFailureLock); | 
|  | for (int i = 0; i < gFailures.count(); i++) { | 
|  | Json::Value result; | 
|  | result["file_name"]     = gFailures[i].fileName; | 
|  | result["line_no"]       = gFailures[i].lineNo; | 
|  | result["condition"]     = gFailures[i].condition; | 
|  | result["message"]       = gFailures[i].message.c_str(); | 
|  |  | 
|  | root["test_results"]["failures"].append(result); | 
|  | } | 
|  | } | 
|  |  | 
|  | int maxResidentSetSizeMB = sk_tools::getMaxResidentSetSizeMB(); | 
|  | if (maxResidentSetSizeMB != -1) { | 
|  | root["max_rss_MB"] = sk_tools::getMaxResidentSetSizeMB(); | 
|  | } | 
|  |  | 
|  | SkString path = SkOSPath::Join(FLAGS_writePath[0], "dm.json"); | 
|  | sk_mkdir(FLAGS_writePath[0]); | 
|  | SkFILEWStream stream(path.c_str()); | 
|  | stream.writeText(Json::StyledWriter().write(root).c_str()); | 
|  | stream.flush(); | 
|  | } | 
|  |  | 
|  | bool JsonWriter::ReadJson(const char* path, void(*callback)(BitmapResult)) { | 
|  | sk_sp<SkData> json(SkData::MakeFromFileName(path)); | 
|  | if (!json) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | Json::Reader reader; | 
|  | Json::Value root; | 
|  | const char* data = (const char*)json->data(); | 
|  | if (!reader.parse(data, data+json->size(), root)) { | 
|  | return false; | 
|  | } | 
|  |  | 
|  | const Json::Value& results = root["results"]; | 
|  | BitmapResult br; | 
|  | for (unsigned i = 0; i < results.size(); i++) { | 
|  | const Json::Value& r = results[i]; | 
|  | br.name         = r["key"]["name"].asCString(); | 
|  | br.config       = r["key"]["config"].asCString(); | 
|  | br.sourceType   = r["key"]["source_type"].asCString(); | 
|  | br.ext          = r["options"]["ext"].asCString(); | 
|  | br.gammaCorrect = 0 == strcmp("yes", r["options"]["gamma_correct"].asCString()); | 
|  | br.md5          = r["md5"].asCString(); | 
|  |  | 
|  | if (!r["key"]["source_options"].isNull()) { | 
|  | br.sourceOptions = r["key"]["source_options"].asCString(); | 
|  | } | 
|  | callback(br); | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | } // namespace DM |