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 "SkOSFile.h"
     15 #include "SkStream.h"
     16 #include "SkTArray.h"
     17 #include "SkThread.h"
     18 
     19 namespace DM {
     20 
     21 SkTArray<JsonWriter::BitmapResult> gBitmapResults;
     22 SK_DECLARE_STATIC_MUTEX(gBitmapResultLock);
     23 
     24 void JsonWriter::AddBitmapResult(const BitmapResult& result) {
     25     SkAutoMutexAcquire lock(&gBitmapResultLock);
     26     gBitmapResults.push_back(result);
     27 }
     28 
     29 SkTArray<skiatest::Failure> gFailures;
     30 SK_DECLARE_STATIC_MUTEX(gFailureLock);
     31 
     32 void JsonWriter::AddTestFailure(const skiatest::Failure& failure) {
     33     SkAutoMutexAcquire lock(gFailureLock);
     34     gFailures.push_back(failure);
     35 }
     36 
     37 void 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 
     96 bool 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