Home | History | Annotate | Download | only in dm
      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 
     25 void 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 
     33 void JsonWriter::AddTestFailure(const skiatest::Failure& failure) {
     34     SkAutoMutexAcquire lock(gFailureLock);
     35     gFailures.push_back(failure);
     36 }
     37 
     38 void 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 
     98 bool 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