blob: 59201f4450104c240c7ddc8fc412016c14300479 [file] [log] [blame]
joshualitt27a48dc2016-01-08 07:19:47 -08001/*
2 * Copyright 2016 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 "GrAuditTrail.h"
joshualitt18d6b752016-02-26 08:07:50 -08009#include "batches/GrBatch.h"
joshualitt27a48dc2016-01-08 07:19:47 -080010
joshualitt18d6b752016-02-26 08:07:50 -080011void GrAuditTrail::batchingResultCombined(GrBatch* combiner) {
12 int* indexPtr = fIDLookup.find(combiner);
13 SkASSERT(indexPtr);
14 int index = *indexPtr;
15 SkASSERT(index < fBatches.count());
16 Batch& batch = *fBatches[index];
17
18 // if this is our first child, we also push back a copy of the original batch and its
19 // bounds
20 if (batch.fChildren.empty()) {
21 Batch* firstBatch = new Batch;
22 firstBatch->fName = batch.fName;
23 firstBatch->fBounds = batch.fBounds;
24 fEvents.emplace_back(firstBatch);
25 batch.fChildren.push_back(firstBatch);
26 }
27 batch.fChildren.push_back(fCurrentBatch);
28 batch.fBounds = combiner->bounds();
29}
30
31void GrAuditTrail::batchingResultNew(GrBatch* batch) {
32 fIDLookup.set(batch, fBatches.count());
33 fBatches.push_back(fCurrentBatch);
34}
35
36template <typename T>
37void GrAuditTrail::JsonifyTArray(SkString* json, const char* name, const T& array,
joshualittadab5a22016-02-18 05:04:39 -080038 bool addComma) {
joshualitt87a721b2016-01-12 12:59:28 -080039 if (array.count()) {
joshualittadab5a22016-02-18 05:04:39 -080040 if (addComma) {
41 json->appendf(",");
42 }
joshualitt87a721b2016-01-12 12:59:28 -080043 json->appendf("\"%s\": [", name);
44 for (int i = 0; i < array.count(); i++) {
joshualitt11fae872016-01-14 10:58:07 -080045 json->append(array[i]->toJson());
joshualitt87a721b2016-01-12 12:59:28 -080046 if (i < array.count() - 1) {
47 json->append(",");
48 }
joshualitt27a48dc2016-01-08 07:19:47 -080049 }
joshualitt87a721b2016-01-12 12:59:28 -080050 json->append("]");
joshualitt27a48dc2016-01-08 07:19:47 -080051 }
joshualitt086cee12016-01-12 06:45:24 -080052}
53
54// This will pretty print a very small subset of json
55// The parsing rules are straightforward, aside from the fact that we do not want an extra newline
56// before ',' and after '}', so we have a comma exception rule.
57class PrettyPrintJson {
58public:
59 SkString prettify(const SkString& json) {
60 fPrettyJson.reset();
61 fTabCount = 0;
62 fFreshLine = false;
63 fCommaException = false;
64 for (size_t i = 0; i < json.size(); i++) {
65 if ('[' == json[i] || '{' == json[i]) {
66 this->newline();
67 this->appendChar(json[i]);
68 fTabCount++;
69 this->newline();
70 } else if (']' == json[i] || '}' == json[i]) {
71 fTabCount--;
72 this->newline();
73 this->appendChar(json[i]);
74 fCommaException = true;
75 } else if (',' == json[i]) {
76 this->appendChar(json[i]);
77 this->newline();
78 } else {
79 this->appendChar(json[i]);
80 }
81 }
82 return fPrettyJson;
83 }
84private:
85 void appendChar(char appendee) {
86 if (fCommaException && ',' != appendee) {
87 this->newline();
88 }
89 this->tab();
90 fPrettyJson += appendee;
91 fFreshLine = false;
92 fCommaException = false;
93 }
94
95 void tab() {
96 if (fFreshLine) {
97 for (int i = 0; i < fTabCount; i++) {
98 fPrettyJson += '\t';
99 }
100 }
101 }
102
103 void newline() {
104 if (!fFreshLine) {
105 fFreshLine = true;
106 fPrettyJson += '\n';
107 }
108 }
109
110 SkString fPrettyJson;
111 int fTabCount;
112 bool fFreshLine;
113 bool fCommaException;
114};
115
116static SkString pretty_print_json(SkString json) {
117 class PrettyPrintJson prettyPrintJson;
118 return prettyPrintJson.prettify(json);
119}
120
joshualitt18d6b752016-02-26 08:07:50 -0800121SkString GrAuditTrail::toJson(bool batchList, bool prettyPrint) const {
joshualitt086cee12016-01-12 06:45:24 -0800122 SkString json;
123 json.append("{");
joshualitt18d6b752016-02-26 08:07:50 -0800124 if (!batchList) {
125 JsonifyTArray(&json, "Stacks", fFrames, false);
126 } else {
127 JsonifyTArray(&json, "Batches", fBatches, false);
128 }
joshualitt086cee12016-01-12 06:45:24 -0800129 json.append("}");
130
joshualitt6b3cf732016-02-17 11:20:26 -0800131 if (prettyPrint) {
132 return pretty_print_json(json);
133 } else {
134 return json;
135 }
joshualitt27a48dc2016-01-08 07:19:47 -0800136}
137
joshualitt87a721b2016-01-12 12:59:28 -0800138SkString GrAuditTrail::Frame::toJson() const {
joshualitt27a48dc2016-01-08 07:19:47 -0800139 SkString json;
joshualitt086cee12016-01-12 06:45:24 -0800140 json.append("{");
joshualittadab5a22016-02-18 05:04:39 -0800141 json.appendf("\"Name\": \"%s\"", fName);
142 JsonifyTArray(&json, "Frames", fChildren, true);
joshualitt086cee12016-01-12 06:45:24 -0800143 json.append("}");
joshualitt27a48dc2016-01-08 07:19:47 -0800144 return json;
145}
146
joshualitt11fae872016-01-14 10:58:07 -0800147SkString GrAuditTrail::Batch::toJson() const {
joshualitt086cee12016-01-12 06:45:24 -0800148 SkString json;
149 json.append("{");
joshualitt87a721b2016-01-12 12:59:28 -0800150 json.appendf("\"Name\": \"%s\",", fName);
joshualitt086cee12016-01-12 06:45:24 -0800151 json.append("\"Bounds\": {");
152 json.appendf("\"Left\": %f,", fBounds.fLeft);
153 json.appendf("\"Right\": %f,", fBounds.fRight);
154 json.appendf("\"Top\": %f,", fBounds.fTop);
155 json.appendf("\"Bottom\": %f", fBounds.fBottom);
joshualitt18d6b752016-02-26 08:07:50 -0800156 JsonifyTArray(&json, "Children", fChildren, true);
joshualitt086cee12016-01-12 06:45:24 -0800157 json.append("}");
158 json.append("}");
159 return json;
160}