Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
GrAuditTrail.h
Go to the documentation of this file.
1/*
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
11#include "include/gpu/GrTypes.h"
12
13#include "include/core/SkRect.h"
16#include "src/core/SkTHash.h"
18
19class GrOp;
20class SkJSONWriter;
21
22/*
23 * GrAuditTrail collects a list of draw ops, detailed information about those ops, and can dump them
24 * to json.
25 *
26 * Capturing this information is expensive and consumes a lot of memory, therefore it is important
27 * to enable auditing only when required and disable it promptly. The AutoEnable class helps to
28 * ensure that the audit trail is disabled in a timely fashion. Once the information has been dealt
29 * with, be sure to call reset(), or the log will simply keep growing.
30 */
32public:
33 GrAuditTrail() : fClientID(kGrAuditTrailInvalidID), fEnabled(false) {}
34
35 class AutoEnable {
36 public:
38 : fAuditTrail(auditTrail) {
39 SkASSERT(!fAuditTrail->isEnabled());
40 fAuditTrail->setEnabled(true);
41 }
42
44 SkASSERT(fAuditTrail->isEnabled());
45 fAuditTrail->setEnabled(false);
46 }
47
48 private:
49 GrAuditTrail* fAuditTrail;
50 };
51
53 public:
55 : fAutoEnable(auditTrail), fAuditTrail(auditTrail) {}
56
57 ~AutoManageOpsTask() { fAuditTrail->fullReset(); }
58
59 private:
60 AutoEnable fAutoEnable;
61 GrAuditTrail* fAuditTrail;
62 };
63
65 public:
66 AutoCollectOps(GrAuditTrail* auditTrail, int clientID)
67 : fAutoEnable(auditTrail), fAuditTrail(auditTrail) {
68 fAuditTrail->setClientID(clientID);
69 }
70
72
73 private:
74 AutoEnable fAutoEnable;
75 GrAuditTrail* fAuditTrail;
76 };
77
78 void pushFrame(const char* framename) {
79 SkASSERT(fEnabled);
80 fCurrentStackTrace.push_back(SkString(framename));
81 }
82
83 void addOp(const GrOp*, GrRenderTargetProxy::UniqueID proxyID);
84
85 void opsCombined(const GrOp* consumer, const GrOp* consumed);
86
87 // Because op combining is heavily dependent on sequence of draw calls, these calls will only
88 // produce valid information for the given draw sequence which preceeded them. Specifically, ops
89 // of future draw calls may combine with previous ops and thus would invalidate the json. What
90 // this means is that for some sequence of draw calls N, the below toJson calls will only
91 // produce JSON which reflects N draw calls. This JSON may or may not be accurate for N + 1 or
92 // N - 1 draws depending on the actual combining algorithm used.
93 void toJson(SkJSONWriter& writer) const;
94
95 // returns a json string of all of the ops associated with a given client id
96 void toJson(SkJSONWriter& writer, int clientID) const;
97
98 bool isEnabled() { return fEnabled; }
99 void setEnabled(bool enabled) { fEnabled = enabled; }
100
101 void setClientID(int clientID) { fClientID = clientID; }
102
103 // We could just return our internal bookkeeping struct if copying the data out becomes
104 // a performance issue, but until then its nice to decouple
115
116 void getBoundsByClientID(skia_private::TArray<OpInfo>* outInfo, int clientID);
117 void getBoundsByOpsTaskID(OpInfo* outInfo, int opsTaskID);
118
119 void fullReset();
120
121 static const int kGrAuditTrailInvalidID;
122
123private:
124 // TODO if performance becomes an issue, we can move to using SkVarAlloc
125 struct Op {
126 void toJson(SkJSONWriter& writer) const;
130 int fClientID;
131 int fOpsTaskID;
132 int fChildID;
133 };
134 typedef skia_private::TArray<std::unique_ptr<Op>, true> OpPool;
135
136 typedef skia_private::TArray<Op*> Ops;
137
138 struct OpNode {
139 OpNode(const GrSurfaceProxy::UniqueID& proxyID) : fProxyUniqueID(proxyID) { }
140 void toJson(SkJSONWriter& writer) const;
141
143 Ops fChildren;
144 const GrSurfaceProxy::UniqueID fProxyUniqueID;
145 };
147
148 void copyOutFromOpsTask(OpInfo* outOpInfo, int opsTask);
149
150 template <typename T>
151 static void JsonifyTArray(SkJSONWriter& writer, const char* name, const T& array);
152
153 OpPool fOpPool;
155 skia_private::THashMap<int, Ops*> fClientIDLookup;
156 OpsTask fOpsTask;
157 skia_private::TArray<SkString> fCurrentStackTrace;
158
159 // The client can pass in an optional client ID which we will use to mark the ops
160 int fClientID;
161 bool fEnabled;
162};
163
164#define GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, invoke, ...) \
165 if (audit_trail->isEnabled()) audit_trail->invoke(__VA_ARGS__)
166
167#define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \
168 GR_AUDIT_TRAIL_INVOKE_GUARD((audit_trail), pushFrame, framename)
169
170#define GR_AUDIT_TRAIL_ADD_OP(audit_trail, op, proxy_id) \
171 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addOp, op, proxy_id)
172
173#define GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(audit_trail, combineWith, op) \
174 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, opsCombined, combineWith, op)
175
176#endif // GrAuditTrail_DEFINED
const char * fName
const SkRect fBounds
#define SkASSERT(cond)
Definition SkAssert.h:116
AutoCollectOps(GrAuditTrail *auditTrail, int clientID)
AutoEnable(GrAuditTrail *auditTrail)
AutoManageOpsTask(GrAuditTrail *auditTrail)
void pushFrame(const char *framename)
void setEnabled(bool enabled)
void setClientID(int clientID)
bool isEnabled()
void getBoundsByOpsTaskID(OpInfo *outInfo, int opsTaskID)
void getBoundsByClientID(skia_private::TArray< OpInfo > *outInfo, int clientID)
void opsCombined(const GrOp *consumer, const GrOp *consumed)
void toJson(SkJSONWriter &writer) const
static const int kGrAuditTrailInvalidID
void addOp(const GrOp *, GrRenderTargetProxy::UniqueID proxyID)
Definition GrOp.h:70
const char * name
Definition fuchsia.cc:50
#define T
GrSurfaceProxy::UniqueID fProxyUniqueID
skia_private::TArray< Op > fOps