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