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