blob: c6175501e1a0ec47b147918cdf9c4704651a47b3 [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"
Robert Phillips294870f2016-11-11 12:38:40 -050012#include "GrGpuResource.h"
Robert Phillipsf7a72612017-03-31 10:03:45 -040013#include "GrRenderTargetProxy.h"
joshualitt086cee12016-01-12 06:45:24 -080014#include "SkRect.h"
joshualitt27a48dc2016-01-08 07:19:47 -080015#include "SkString.h"
16#include "SkTArray.h"
joshualitt18d6b752016-02-26 08:07:50 -080017#include "SkTHash.h"
18
Brian Salomon25a88092016-12-01 09:36:50 -050019class GrOp;
joshualitt27a48dc2016-01-08 07:19:47 -080020
21/*
22 * GrAuditTrail collects a list of draw ops, detailed information about those ops, and can dump them
23 * to json.
ethannicholasc85d9fb2016-02-18 13:45:39 -080024 *
25 * Capturing this information is expensive and consumes a lot of memory, therefore it is important
Ben Wagner63fd7602017-10-09 15:45:33 -040026 * to enable auditing only when required and disable it promptly. The AutoEnable class helps to
ethannicholasc85d9fb2016-02-18 13:45:39 -080027 * ensure that the audit trail is disabled in a timely fashion. Once the information has been dealt
28 * with, be sure to call reset(), or the log will simply keep growing.
joshualitt27a48dc2016-01-08 07:19:47 -080029 */
30class GrAuditTrail {
31public:
Ben Wagner63fd7602017-10-09 15:45:33 -040032 GrAuditTrail()
joshualittb95c7722016-02-29 07:44:02 -080033 : fClientID(kGrAuditTrailInvalidID)
34 , fEnabled(false) {}
joshualitt87a721b2016-01-12 12:59:28 -080035
ethannicholasc85d9fb2016-02-18 13:45:39 -080036 class AutoEnable {
37 public:
38 AutoEnable(GrAuditTrail* auditTrail)
39 : fAuditTrail(auditTrail) {
40 SkASSERT(!fAuditTrail->isEnabled());
41 fAuditTrail->setEnabled(true);
42 }
43
44 ~AutoEnable() {
45 SkASSERT(fAuditTrail->isEnabled());
46 fAuditTrail->setEnabled(false);
47 }
48
49 private:
50 GrAuditTrail* fAuditTrail;
51 };
52
Brian Salomon42ad83a2016-12-20 16:14:45 -050053 class AutoManageOpList {
joshualitt18d6b752016-02-26 08:07:50 -080054 public:
Brian Salomon42ad83a2016-12-20 16:14:45 -050055 AutoManageOpList(GrAuditTrail* auditTrail)
56 : fAutoEnable(auditTrail), fAuditTrail(auditTrail) {}
joshualitt18d6b752016-02-26 08:07:50 -080057
Brian Salomon42ad83a2016-12-20 16:14:45 -050058 ~AutoManageOpList() { fAuditTrail->fullReset(); }
joshualitt18d6b752016-02-26 08:07:50 -080059
60 private:
61 AutoEnable fAutoEnable;
62 GrAuditTrail* fAuditTrail;
63 };
64
Brian Salomon42ad83a2016-12-20 16:14:45 -050065 class AutoCollectOps {
joshualittb95c7722016-02-29 07:44:02 -080066 public:
Brian Salomon42ad83a2016-12-20 16:14:45 -050067 AutoCollectOps(GrAuditTrail* auditTrail, int clientID)
68 : fAutoEnable(auditTrail), fAuditTrail(auditTrail) {
joshualittb95c7722016-02-29 07:44:02 -080069 fAuditTrail->setClientID(clientID);
joshualitt87a721b2016-01-12 12:59:28 -080070 }
71
Brian Salomon42ad83a2016-12-20 16:14:45 -050072 ~AutoCollectOps() { fAuditTrail->setClientID(kGrAuditTrailInvalidID); }
joshualitt27a48dc2016-01-08 07:19:47 -080073
joshualittb95c7722016-02-29 07:44:02 -080074 private:
75 AutoEnable fAutoEnable;
76 GrAuditTrail* fAuditTrail;
77 };
joshualitt87a721b2016-01-12 12:59:28 -080078
joshualittf55c3642016-03-02 08:11:34 -080079 void pushFrame(const char* framename) {
80 SkASSERT(fEnabled);
81 fCurrentStackTrace.push_back(SkString(framename));
82 }
83
Robert Phillips318c4192017-05-17 09:36:38 -040084 void addOp(const GrOp*, GrRenderTargetProxy::UniqueID proxyID);
joshualitt086cee12016-01-12 06:45:24 -080085
Brian Salomon42ad83a2016-12-20 16:14:45 -050086 void opsCombined(const GrOp* consumer, const GrOp* consumed);
joshualitt18d6b752016-02-26 08:07:50 -080087
Brian Salomon42ad83a2016-12-20 16:14:45 -050088 // Because op combining is heavily dependent on sequence of draw calls, these calls will only
89 // produce valid information for the given draw sequence which preceeded them. Specifically, ops
90 // of future draw calls may combine with previous ops and thus would invalidate the json. What
91 // this means is that for some sequence of draw calls N, the below toJson calls will only
92 // produce JSON which reflects N draw calls. This JSON may or may not be accurate for N + 1 or
93 // N - 1 draws depending on the actual combining algorithm used.
joshualittb95c7722016-02-29 07:44:02 -080094 SkString toJson(bool prettyPrint = false) const;
95
Brian Salomon42ad83a2016-12-20 16:14:45 -050096 // returns a json string of all of the ops associated with a given client id
joshualittb95c7722016-02-29 07:44:02 -080097 SkString toJson(int clientID, bool prettyPrint = false) const;
joshualitt27a48dc2016-01-08 07:19:47 -080098
ethannicholasc85d9fb2016-02-18 13:45:39 -080099 bool isEnabled() { return fEnabled; }
100 void setEnabled(bool enabled) { fEnabled = enabled; }
101
joshualittb95c7722016-02-29 07:44:02 -0800102 void setClientID(int clientID) { fClientID = clientID; }
joshualitt18d6b752016-02-26 08:07:50 -0800103
joshualitt10d8fc22016-02-29 11:15:06 -0800104 // We could just return our internal bookkeeping struct if copying the data out becomes
105 // a performance issue, but until then its nice to decouple
Brian Salomon42ad83a2016-12-20 16:14:45 -0500106 struct OpInfo {
Brian Salomon42ad83a2016-12-20 16:14:45 -0500107 struct Op {
Robert Phillipsf7a72612017-03-31 10:03:45 -0400108 int fClientID;
joshualitt10d8fc22016-02-29 11:15:06 -0800109 SkRect fBounds;
110 };
Robert Phillipsf7a72612017-03-31 10:03:45 -0400111
112 SkRect fBounds;
Robert Phillipsf7a72612017-03-31 10:03:45 -0400113 GrSurfaceProxy::UniqueID fProxyUniqueID;
114 SkTArray<Op> fOps;
joshualitt10d8fc22016-02-29 11:15:06 -0800115 };
116
Brian Salomon42ad83a2016-12-20 16:14:45 -0500117 void getBoundsByClientID(SkTArray<OpInfo>* outInfo, int clientID);
118 void getBoundsByOpListID(OpInfo* outInfo, int opListID);
joshualitt10d8fc22016-02-29 11:15:06 -0800119
joshualittdf3f2b02016-03-01 07:47:56 -0800120 void fullReset();
joshualitt27a48dc2016-01-08 07:19:47 -0800121
joshualittb95c7722016-02-29 07:44:02 -0800122 static const int kGrAuditTrailInvalidID;
123
joshualitt27a48dc2016-01-08 07:19:47 -0800124private:
joshualitt11fae872016-01-14 10:58:07 -0800125 // TODO if performance becomes an issue, we can move to using SkVarAlloc
Brian Salomon42ad83a2016-12-20 16:14:45 -0500126 struct Op {
joshualittb95c7722016-02-29 07:44:02 -0800127 SkString toJson() const;
128 SkString fName;
joshualittf55c3642016-03-02 08:11:34 -0800129 SkTArray<SkString> fStackTrace;
joshualitt08fc8072016-02-29 06:32:24 -0800130 SkRect fBounds;
joshualittb95c7722016-02-29 07:44:02 -0800131 int fClientID;
Brian Salomon42ad83a2016-12-20 16:14:45 -0500132 int fOpListID;
joshualittb95c7722016-02-29 07:44:02 -0800133 int fChildID;
joshualitt08fc8072016-02-29 06:32:24 -0800134 };
Brian Salomon42ad83a2016-12-20 16:14:45 -0500135 typedef SkTArray<std::unique_ptr<Op>, true> OpPool;
joshualittb95c7722016-02-29 07:44:02 -0800136
Brian Salomon42ad83a2016-12-20 16:14:45 -0500137 typedef SkTArray<Op*> Ops;
joshualittb95c7722016-02-29 07:44:02 -0800138
Brian Salomon42ad83a2016-12-20 16:14:45 -0500139 struct OpNode {
Robert Phillips318c4192017-05-17 09:36:38 -0400140 OpNode(const GrSurfaceProxy::UniqueID& proxyID) : fProxyUniqueID(proxyID) { }
joshualittb95c7722016-02-29 07:44:02 -0800141 SkString toJson() const;
Robert Phillipsf7a72612017-03-31 10:03:45 -0400142
Robert Phillips294870f2016-11-11 12:38:40 -0500143 SkRect fBounds;
Robert Phillipsf7a72612017-03-31 10:03:45 -0400144 Ops fChildren;
Robert Phillipsf7a72612017-03-31 10:03:45 -0400145 const GrSurfaceProxy::UniqueID fProxyUniqueID;
joshualittb95c7722016-02-29 07:44:02 -0800146 };
Brian Salomon42ad83a2016-12-20 16:14:45 -0500147 typedef SkTArray<std::unique_ptr<OpNode>, true> OpList;
joshualitt11fae872016-01-14 10:58:07 -0800148
Brian Salomon42ad83a2016-12-20 16:14:45 -0500149 void copyOutFromOpList(OpInfo* outOpInfo, int opListID);
joshualitt46b301d2016-03-02 08:32:37 -0800150
joshualitt18d6b752016-02-26 08:07:50 -0800151 template <typename T>
152 static void JsonifyTArray(SkString* json, const char* name, const T& array,
joshualittadab5a22016-02-18 05:04:39 -0800153 bool addComma);
bungeman6bd52842016-10-27 09:30:08 -0700154
Brian Salomon42ad83a2016-12-20 16:14:45 -0500155 OpPool fOpPool;
joshualittb0666ad2016-03-08 10:43:41 -0800156 SkTHashMap<uint32_t, int> fIDLookup;
Brian Salomon42ad83a2016-12-20 16:14:45 -0500157 SkTHashMap<int, Ops*> fClientIDLookup;
158 OpList fOpList;
joshualittf55c3642016-03-02 08:11:34 -0800159 SkTArray<SkString> fCurrentStackTrace;
joshualittb95c7722016-02-29 07:44:02 -0800160
Brian Salomon42ad83a2016-12-20 16:14:45 -0500161 // The client can pass in an optional client ID which we will use to mark the ops
joshualittb95c7722016-02-29 07:44:02 -0800162 int fClientID;
163 bool fEnabled;
joshualitt27a48dc2016-01-08 07:19:47 -0800164};
165
ethannicholasc85d9fb2016-02-18 13:45:39 -0800166#define GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, invoke, ...) \
167 if (audit_trail->isEnabled()) { \
168 audit_trail->invoke(__VA_ARGS__); \
joshualitt5651ee62016-01-11 10:39:11 -0800169 }
170
joshualitt87a721b2016-01-12 12:59:28 -0800171#define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \
joshualittf55c3642016-03-02 08:11:34 -0800172 GR_AUDIT_TRAIL_INVOKE_GUARD((audit_trail), pushFrame, framename);
joshualitt5651ee62016-01-11 10:39:11 -0800173
174#define GR_AUDIT_TRAIL_RESET(audit_trail) \
joshualittf55c3642016-03-02 08:11:34 -0800175 //GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, fullReset);
joshualitt5651ee62016-01-11 10:39:11 -0800176
Robert Phillips318c4192017-05-17 09:36:38 -0400177#define GR_AUDIT_TRAIL_ADD_OP(audit_trail, op, proxy_id) \
178 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addOp, op, proxy_id);
joshualitt086cee12016-01-12 06:45:24 -0800179
Brian Salomon42ad83a2016-12-20 16:14:45 -0500180#define GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(audit_trail, combineWith, op) \
181 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, opsCombined, combineWith, op);
joshualitt18d6b752016-02-26 08:07:50 -0800182
Brian Salomon42ad83a2016-12-20 16:14:45 -0500183#define GR_AUDIT_TRAIL_OP_RESULT_NEW(audit_trail, op) // Doesn't do anything now, one day...
joshualitt18d6b752016-02-26 08:07:50 -0800184
joshualitt27a48dc2016-01-08 07:19:47 -0800185#endif