blob: 67eecadf6741b4d081c3d52ba3c690bbc1a2083e [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#ifndef GrAuditTrail_DEFINED
9#define GrAuditTrail_DEFINED
10
joshualitt5651ee62016-01-11 10:39:11 -080011#include "GrConfig.h"
joshualitt086cee12016-01-12 06:45:24 -080012#include "SkRect.h"
joshualitt27a48dc2016-01-08 07:19:47 -080013#include "SkString.h"
14#include "SkTArray.h"
15
16/*
17 * GrAuditTrail collects a list of draw ops, detailed information about those ops, and can dump them
18 * to json.
19 */
20class GrAuditTrail {
21public:
joshualitt87a721b2016-01-12 12:59:28 -080022 GrAuditTrail() : fUniqueID(0) {}
23
24 class AutoFrame {
25 public:
26 AutoFrame(GrAuditTrail* auditTrail, const char* name)
27 : fAuditTrail(auditTrail) {
28 if (GR_BATCH_DEBUGGING_OUTPUT) {
29 fAuditTrail->pushFrame(name);
30 }
31 }
32
33 ~AutoFrame() {
34 if (GR_BATCH_DEBUGGING_OUTPUT) {
35 fAuditTrail->popFrame();
36 }
37 }
38
39 private:
40 GrAuditTrail* fAuditTrail;
41 };
42
43 void pushFrame(const char* name) {
joshualitt5651ee62016-01-11 10:39:11 -080044 SkASSERT(GR_BATCH_DEBUGGING_OUTPUT);
joshualitt11fae872016-01-14 10:58:07 -080045 Frame* frame = new Frame;
joshualitt87a721b2016-01-12 12:59:28 -080046 if (fStack.empty()) {
joshualitt11fae872016-01-14 10:58:07 -080047 fFrames.emplace_back(frame);
joshualitt87a721b2016-01-12 12:59:28 -080048 } else {
joshualitt11fae872016-01-14 10:58:07 -080049 fStack.back()->fChildren.emplace_back(frame);
joshualitt87a721b2016-01-12 12:59:28 -080050 }
51
52 frame->fUniqueID = fUniqueID++;
53 frame->fName = name;
54 fStack.push_back(frame);
joshualitt27a48dc2016-01-08 07:19:47 -080055 }
56
joshualitt87a721b2016-01-12 12:59:28 -080057 void popFrame() {
joshualitt086cee12016-01-12 06:45:24 -080058 SkASSERT(GR_BATCH_DEBUGGING_OUTPUT);
joshualitt87a721b2016-01-12 12:59:28 -080059 fStack.pop_back();
60 }
61
62 void addBatch(const char* name, const SkRect& bounds) {
joshualitt11fae872016-01-14 10:58:07 -080063 SkASSERT(GR_BATCH_DEBUGGING_OUTPUT && !fStack.empty());
64 Batch* batch = new Batch;
65 fStack.back()->fChildren.emplace_back(batch);
66 batch->fName = name;
67 batch->fBounds = bounds;
joshualitt086cee12016-01-12 06:45:24 -080068 }
69
joshualitt6b3cf732016-02-17 11:20:26 -080070 SkString toJson(bool prettyPrint = false) const;
joshualitt27a48dc2016-01-08 07:19:47 -080071
joshualitt87a721b2016-01-12 12:59:28 -080072 void reset() { SkASSERT(GR_BATCH_DEBUGGING_OUTPUT && fStack.empty()); fFrames.reset(); }
joshualitt27a48dc2016-01-08 07:19:47 -080073
74private:
joshualitt11fae872016-01-14 10:58:07 -080075 // TODO if performance becomes an issue, we can move to using SkVarAlloc
76 struct Event {
77 virtual ~Event() {}
78 virtual SkString toJson() const=0;
joshualitt086cee12016-01-12 06:45:24 -080079
joshualitt87a721b2016-01-12 12:59:28 -080080 const char* fName;
joshualitt87a721b2016-01-12 12:59:28 -080081 uint64_t fUniqueID;
joshualitt27a48dc2016-01-08 07:19:47 -080082 };
83
joshualitt11fae872016-01-14 10:58:07 -080084 typedef SkTArray<SkAutoTDelete<Event>, true> FrameArray;
85 struct Frame : public Event {
86 SkString toJson() const override;
87 FrameArray fChildren;
88 };
89
90 struct Batch : public Event {
91 SkString toJson() const override;
92 SkRect fBounds;
93 };
94
95 static void JsonifyTArray(SkString* json, const char* name, const FrameArray& array);
96
97 FrameArray fFrames;
joshualitt87a721b2016-01-12 12:59:28 -080098 SkTArray<Frame*> fStack;
99 uint64_t fUniqueID;
joshualitt27a48dc2016-01-08 07:19:47 -0800100};
101
joshualitt5651ee62016-01-11 10:39:11 -0800102#define GR_AUDIT_TRAIL_INVOKE_GUARD(invoke, ...) \
103 if (GR_BATCH_DEBUGGING_OUTPUT) { \
104 invoke(__VA_ARGS__); \
105 }
106
joshualitt87a721b2016-01-12 12:59:28 -0800107#define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \
108 GrAuditTrail::AutoFrame SK_MACRO_APPEND_LINE(auto_frame)(audit_trail, framename);
joshualitt5651ee62016-01-11 10:39:11 -0800109
110#define GR_AUDIT_TRAIL_RESET(audit_trail) \
111 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail->reset);
112
joshualitt086cee12016-01-12 06:45:24 -0800113#define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batchname, bounds) \
joshualitt87a721b2016-01-12 12:59:28 -0800114 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail->addBatch, batchname, bounds);
joshualitt086cee12016-01-12 06:45:24 -0800115
joshualitt27a48dc2016-01-08 07:19:47 -0800116#endif