GrAuditTrail.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. #ifndef GrAuditTrail_DEFINED
  8. #define GrAuditTrail_DEFINED
  9. #include "include/core/SkRect.h"
  10. #include "include/core/SkString.h"
  11. #include "include/gpu/GrConfig.h"
  12. #include "include/gpu/GrGpuResource.h"
  13. #include "include/private/SkTArray.h"
  14. #include "include/private/SkTHash.h"
  15. #include "src/gpu/GrRenderTargetProxy.h"
  16. class GrOp;
  17. class SkJSONWriter;
  18. /*
  19. * GrAuditTrail collects a list of draw ops, detailed information about those ops, and can dump them
  20. * to json.
  21. *
  22. * Capturing this information is expensive and consumes a lot of memory, therefore it is important
  23. * to enable auditing only when required and disable it promptly. The AutoEnable class helps to
  24. * ensure that the audit trail is disabled in a timely fashion. Once the information has been dealt
  25. * with, be sure to call reset(), or the log will simply keep growing.
  26. */
  27. class GrAuditTrail {
  28. public:
  29. GrAuditTrail()
  30. : fClientID(kGrAuditTrailInvalidID)
  31. , fEnabled(false) {}
  32. class AutoEnable {
  33. public:
  34. AutoEnable(GrAuditTrail* auditTrail)
  35. : fAuditTrail(auditTrail) {
  36. SkASSERT(!fAuditTrail->isEnabled());
  37. fAuditTrail->setEnabled(true);
  38. }
  39. ~AutoEnable() {
  40. SkASSERT(fAuditTrail->isEnabled());
  41. fAuditTrail->setEnabled(false);
  42. }
  43. private:
  44. GrAuditTrail* fAuditTrail;
  45. };
  46. class AutoManageOpList {
  47. public:
  48. AutoManageOpList(GrAuditTrail* auditTrail)
  49. : fAutoEnable(auditTrail), fAuditTrail(auditTrail) {}
  50. ~AutoManageOpList() { fAuditTrail->fullReset(); }
  51. private:
  52. AutoEnable fAutoEnable;
  53. GrAuditTrail* fAuditTrail;
  54. };
  55. class AutoCollectOps {
  56. public:
  57. AutoCollectOps(GrAuditTrail* auditTrail, int clientID)
  58. : fAutoEnable(auditTrail), fAuditTrail(auditTrail) {
  59. fAuditTrail->setClientID(clientID);
  60. }
  61. ~AutoCollectOps() { fAuditTrail->setClientID(kGrAuditTrailInvalidID); }
  62. private:
  63. AutoEnable fAutoEnable;
  64. GrAuditTrail* fAuditTrail;
  65. };
  66. void pushFrame(const char* framename) {
  67. SkASSERT(fEnabled);
  68. fCurrentStackTrace.push_back(SkString(framename));
  69. }
  70. void addOp(const GrOp*, GrRenderTargetProxy::UniqueID proxyID);
  71. void opsCombined(const GrOp* consumer, const GrOp* consumed);
  72. // Because op combining is heavily dependent on sequence of draw calls, these calls will only
  73. // produce valid information for the given draw sequence which preceeded them. Specifically, ops
  74. // of future draw calls may combine with previous ops and thus would invalidate the json. What
  75. // this means is that for some sequence of draw calls N, the below toJson calls will only
  76. // produce JSON which reflects N draw calls. This JSON may or may not be accurate for N + 1 or
  77. // N - 1 draws depending on the actual combining algorithm used.
  78. void toJson(SkJSONWriter& writer) const;
  79. // returns a json string of all of the ops associated with a given client id
  80. void toJson(SkJSONWriter& writer, int clientID) const;
  81. bool isEnabled() { return fEnabled; }
  82. void setEnabled(bool enabled) { fEnabled = enabled; }
  83. void setClientID(int clientID) { fClientID = clientID; }
  84. // We could just return our internal bookkeeping struct if copying the data out becomes
  85. // a performance issue, but until then its nice to decouple
  86. struct OpInfo {
  87. struct Op {
  88. int fClientID;
  89. SkRect fBounds;
  90. };
  91. SkRect fBounds;
  92. GrSurfaceProxy::UniqueID fProxyUniqueID;
  93. SkTArray<Op> fOps;
  94. };
  95. void getBoundsByClientID(SkTArray<OpInfo>* outInfo, int clientID);
  96. void getBoundsByOpListID(OpInfo* outInfo, int opListID);
  97. void fullReset();
  98. static const int kGrAuditTrailInvalidID;
  99. private:
  100. // TODO if performance becomes an issue, we can move to using SkVarAlloc
  101. struct Op {
  102. void toJson(SkJSONWriter& writer) const;
  103. SkString fName;
  104. SkTArray<SkString> fStackTrace;
  105. SkRect fBounds;
  106. int fClientID;
  107. int fOpListID;
  108. int fChildID;
  109. };
  110. typedef SkTArray<std::unique_ptr<Op>, true> OpPool;
  111. typedef SkTArray<Op*> Ops;
  112. struct OpNode {
  113. OpNode(const GrSurfaceProxy::UniqueID& proxyID) : fProxyUniqueID(proxyID) { }
  114. void toJson(SkJSONWriter& writer) const;
  115. SkRect fBounds;
  116. Ops fChildren;
  117. const GrSurfaceProxy::UniqueID fProxyUniqueID;
  118. };
  119. typedef SkTArray<std::unique_ptr<OpNode>, true> OpList;
  120. void copyOutFromOpList(OpInfo* outOpInfo, int opListID);
  121. template <typename T>
  122. static void JsonifyTArray(SkJSONWriter& writer, const char* name, const T& array);
  123. OpPool fOpPool;
  124. SkTHashMap<uint32_t, int> fIDLookup;
  125. SkTHashMap<int, Ops*> fClientIDLookup;
  126. OpList fOpList;
  127. SkTArray<SkString> fCurrentStackTrace;
  128. // The client can pass in an optional client ID which we will use to mark the ops
  129. int fClientID;
  130. bool fEnabled;
  131. };
  132. #define GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, invoke, ...) \
  133. if (audit_trail->isEnabled()) audit_trail->invoke(__VA_ARGS__)
  134. #define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \
  135. GR_AUDIT_TRAIL_INVOKE_GUARD((audit_trail), pushFrame, framename)
  136. #define GR_AUDIT_TRAIL_RESET(audit_trail) \
  137. //GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, fullReset);
  138. #define GR_AUDIT_TRAIL_ADD_OP(audit_trail, op, proxy_id) \
  139. GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addOp, op, proxy_id)
  140. #define GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(audit_trail, combineWith, op) \
  141. GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, opsCombined, combineWith, op)
  142. #endif