blob: bb8ff3de9a6662a328f89b3c6a4e115423c8dfe7 [file] [log] [blame]
commit-bot@chromium.orge3bb3bc2013-12-03 18:16:48 +00001/*
2 * Copyright 2013 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 * Classes for writing out bench results in various formats.
8 */
tfarinaf168b862014-06-19 12:32:29 -07009
commit-bot@chromium.orge3bb3bc2013-12-03 18:16:48 +000010#ifndef SkResultsWriter_DEFINED
11#define SkResultsWriter_DEFINED
12
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/core/SkString.h"
14#include "include/core/SkTypes.h"
Chris Dalton2e1381e2019-10-23 14:35:19 -060015#include "src/core/SkOSFile.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050016#include "src/utils/SkJSONWriter.h"
commit-bot@chromium.orge3bb3bc2013-12-03 18:16:48 +000017
commit-bot@chromium.orge3bb3bc2013-12-03 18:16:48 +000018/**
Brian Osman8c0a1ca2019-01-28 14:24:29 -050019 NanoJSONResultsWriter helps nanobench writes the test results out in the following format:
jcgregoriobf5e5232014-07-17 13:14:16 -070020
21 {
22 "key": {
23 "arch": "Arm7",
24 "gpu": "SGX540",
25 "os": "Android",
26 "model": "GalaxyNexus",
27 }
jcgregoriobf5e5232014-07-17 13:14:16 -070028 "gitHash": "d1830323662ae8ae06908b97f15180fd25808894",
mtklein1915b622014-08-20 11:45:00 -070029 "build_number": "1234",
jcgregoriobf5e5232014-07-17 13:14:16 -070030 "results" : {
31 "Xfermode_Luminosity_640_480" : {
32 "8888" : {
33 "median_ms" : 143.188128906250,
34 "min_ms" : 143.835957031250,
35 ...
36 },
37 ...
38*/
Brian Osman8c0a1ca2019-01-28 14:24:29 -050039class NanoJSONResultsWriter : public SkJSONWriter {
jcgregoriobf5e5232014-07-17 13:14:16 -070040public:
Brian Osman8c0a1ca2019-01-28 14:24:29 -050041 NanoJSONResultsWriter(SkWStream* stream, Mode mode) : SkJSONWriter(stream, mode) {}
mtklein1915b622014-08-20 11:45:00 -070042
Brian Osman8c0a1ca2019-01-28 14:24:29 -050043 void beginBench(const char* name, int32_t x, int32_t y) {
44 SkString id = SkStringPrintf("%s_%d_%d", name, x, y);
45 this->beginObject(id.c_str());
jcgregoriobf5e5232014-07-17 13:14:16 -070046 }
mtklein1915b622014-08-20 11:45:00 -070047
Brian Osman8c0a1ca2019-01-28 14:24:29 -050048 void endBench() { this->endObject(); }
49
50 void appendMetric(const char* name, double value) {
jcgregoriobf5e5232014-07-17 13:14:16 -070051 // Don't record if nan, or -nan.
Brian Osman8c0a1ca2019-01-28 14:24:29 -050052 if (!sk_double_isnan(value)) {
53 this->appendDoubleDigits(name, value, 16);
jcgregoriobf5e5232014-07-17 13:14:16 -070054 }
jcgregoriobf5e5232014-07-17 13:14:16 -070055 }
jcgregoriobf5e5232014-07-17 13:14:16 -070056};
57
Chris Dalton2e1381e2019-10-23 14:35:19 -060058/**
59 NanoFILEAppendAndCloseStream: re-open the file, append the data, then close on every write() call.
60
61 The purpose of this class is to not keep the file handle open between JSON flushes. SkJSONWriter
62 uses a 32k in-memory cache already, so it only flushes occasionally and is well equipped for a
63 steam like this.
64
65 See: https://b.corp.google.com/issues/143074513
66*/
67class NanoFILEAppendAndCloseStream : public SkWStream {
68public:
69 NanoFILEAppendAndCloseStream(const char* filePath) : fFilePath(filePath) {
70 // Open the file as "write" to ensure it exists and clear any contents before we begin
71 // appending.
72 FILE* file = sk_fopen(fFilePath.c_str(), kWrite_SkFILE_Flag);
73 if (!file) {
74 SkDebugf("Failed to open file %s for write.\n", fFilePath.c_str());
75 fFilePath.reset();
76 return;
77 }
78 sk_fclose(file);
79 }
80
81 size_t bytesWritten() const override { return fBytesWritten; }
82
83 bool write(const void* buffer, size_t size) override {
84 if (fFilePath.isEmpty()) {
85 return false;
86 }
87
88 FILE* file = sk_fopen(fFilePath.c_str(), kAppend_SkFILE_Flag);
89 if (!file) {
90 SkDebugf("Failed to open file %s for append.\n", fFilePath.c_str());
91 return false;
92 }
93
94 size_t bytesWritten = sk_fwrite(buffer, size, file);
95 fBytesWritten += bytesWritten;
96 sk_fclose(file);
97
98 if (bytesWritten != size) {
99 SkDebugf("NanoFILEAppendAndCloseStream failed writing %d bytes (wrote %d instead)\n",
100 size, bytesWritten);
101 return false;
102 }
103
104 return true;
105 }
106
107 void flush() override {}
108
109private:
110 SkString fFilePath;
111 size_t fBytesWritten = 0;
112};
113
commit-bot@chromium.orge3bb3bc2013-12-03 18:16:48 +0000114#endif