Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef GrAuditTrail_DEFINED | 8 #ifndef GrAuditTrail_DEFINED |
| 9 #define GrAuditTrail_DEFINED | 9 #define GrAuditTrail_DEFINED |
| 10 | 10 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 21 * to json. | 21 * to json. |
| 22 * | 22 * |
| 23 * Capturing this information is expensive and consumes a lot of memory, therefo re it is important | 23 * Capturing this information is expensive and consumes a lot of memory, therefo re it is important |
| 24 * to enable auditing only when required and disable it promptly. The AutoEnable class helps to | 24 * to enable auditing only when required and disable it promptly. The AutoEnable class helps to |
| 25 * ensure that the audit trail is disabled in a timely fashion. Once the informa tion has been dealt | 25 * ensure that the audit trail is disabled in a timely fashion. Once the informa tion has been dealt |
| 26 * with, be sure to call reset(), or the log will simply keep growing. | 26 * with, be sure to call reset(), or the log will simply keep growing. |
| 27 */ | 27 */ |
| 28 class GrAuditTrail { | 28 class GrAuditTrail { |
| 29 public: | 29 public: |
| 30 GrAuditTrail() | 30 GrAuditTrail() |
| 31 : fEnabled(false) | 31 : fClientID(kInvalidID) |
| 32 , fUniqueID(0) {} | 32 , fEnabled(false) {} |
| 33 | |
| 34 class AutoFrame { | |
| 35 public: | |
| 36 AutoFrame(GrAuditTrail* auditTrail, const char* name) | |
| 37 : fAuditTrail(auditTrail) { | |
| 38 if (fAuditTrail->fEnabled) { | |
| 39 fAuditTrail->pushFrame(name); | |
| 40 } | |
| 41 } | |
| 42 | |
| 43 ~AutoFrame() { | |
| 44 if (fAuditTrail->fEnabled) { | |
| 45 fAuditTrail->popFrame(); | |
| 46 } | |
| 47 } | |
| 48 | |
| 49 private: | |
| 50 GrAuditTrail* fAuditTrail; | |
| 51 }; | |
| 52 | 33 |
| 53 class AutoEnable { | 34 class AutoEnable { |
| 54 public: | 35 public: |
| 55 AutoEnable(GrAuditTrail* auditTrail) | 36 AutoEnable(GrAuditTrail* auditTrail) |
| 56 : fAuditTrail(auditTrail) { | 37 : fAuditTrail(auditTrail) { |
| 57 SkASSERT(!fAuditTrail->isEnabled()); | 38 SkASSERT(!fAuditTrail->isEnabled()); |
| 58 fAuditTrail->setEnabled(true); | 39 fAuditTrail->setEnabled(true); |
| 59 } | 40 } |
| 60 | 41 |
| 61 ~AutoEnable() { | 42 ~AutoEnable() { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 76 | 57 |
| 77 ~AutoManageBatchList() { | 58 ~AutoManageBatchList() { |
| 78 fAuditTrail->fullReset(); | 59 fAuditTrail->fullReset(); |
| 79 } | 60 } |
| 80 | 61 |
| 81 private: | 62 private: |
| 82 AutoEnable fAutoEnable; | 63 AutoEnable fAutoEnable; |
| 83 GrAuditTrail* fAuditTrail; | 64 GrAuditTrail* fAuditTrail; |
| 84 }; | 65 }; |
| 85 | 66 |
| 86 void pushFrame(const char* name) { | 67 class AutoCollectBatches { |
| 87 SkASSERT(fEnabled); | 68 public: |
| 88 Frame* frame = new Frame; | 69 AutoCollectBatches(GrAuditTrail* auditTrail, int clientID) |
| 89 fEvents.emplace_back(frame); | 70 : fAutoEnable(auditTrail) |
| 90 if (fStack.empty()) { | 71 , fAuditTrail(auditTrail) { |
| 91 fFrames.push_back(frame); | 72 fAuditTrail->setClientID(clientID); |
| 92 } else { | |
| 93 fStack.back()->fChildren.push_back(frame); | |
| 94 } | 73 } |
| 95 | 74 |
| 96 frame->fUniqueID = fUniqueID++; | 75 ~AutoCollectBatches() { fAuditTrail->setClientID(kInvalidID); } |
| 97 frame->fName = name; | |
| 98 fStack.push_back(frame); | |
| 99 } | |
| 100 | 76 |
| 101 void popFrame() { | 77 private: |
| 102 SkASSERT(fEnabled); | 78 AutoEnable fAutoEnable; |
| 103 fStack.pop_back(); | 79 GrAuditTrail* fAuditTrail; |
| 104 } | 80 }; |
| 105 | 81 |
| 106 void addBatch(const char* name, const SkRect& bounds) { | 82 void addBatch(const char* name, const SkRect& bounds) { |
| 107 SkASSERT(fEnabled && !fStack.empty()); | 83 SkASSERT(fEnabled); |
| 108 Batch* batch = new Batch; | 84 Batch* batch = new Batch; |
| 109 fEvents.emplace_back(batch); | 85 fBatchPool.emplace_back(batch); |
| 110 fStack.back()->fChildren.push_back(batch); | |
| 111 batch->fName = name; | 86 batch->fName = name; |
| 112 batch->fBounds = bounds; | 87 batch->fBounds = bounds; |
| 88 batch->fClientID = kInvalidID; | |
| 89 batch->fBatchListID = kInvalidID; | |
| 90 batch->fChildID = kInvalidID; | |
| 113 fCurrentBatch = batch; | 91 fCurrentBatch = batch; |
| 92 | |
| 93 if (fClientID != kInvalidID) { | |
| 94 batch->fClientID = fClientID; | |
| 95 Batches** batchesLookup = fClientIDLookup.find(fClientID); | |
| 96 Batches* batches = nullptr; | |
| 97 if (!batchesLookup) { | |
| 98 batches = new Batches; | |
| 99 fClientIDLookup.set(fClientID, batches); | |
| 100 } else { | |
| 101 batches = *batchesLookup; | |
| 102 } | |
| 103 | |
| 104 batches->push_back(fCurrentBatch); | |
| 105 } | |
| 114 } | 106 } |
| 115 | 107 |
| 116 void batchingResultCombined(GrBatch* combiner); | 108 void batchingResultCombined(GrBatch* combiner); |
| 117 | 109 |
| 118 void batchingResultNew(GrBatch* batch); | 110 void batchingResultNew(GrBatch* batch); |
| 119 | 111 |
| 120 SkString toJson(bool batchList = false, bool prettyPrint = false) const; | 112 // NOTE these toJson methods only return correct incremental results. |
| 113 // The caller should be somewhat aware of how batching occurs before the res ults | |
| 114 // can be 'trusted' | |
|
ethannicholas
2016/02/26 20:55:32
I don't fully understand this comment.
joshualitt
2016/02/26 21:08:00
Sorry, try the comment now. Basically, you need t
| |
| 115 SkString toJson(bool prettyPrint = false) const; | |
| 116 | |
| 117 // returns a json string of all of the batches associated with a given clien t id | |
| 118 SkString toJson(int clientID, bool prettyPrint = false) const; | |
| 121 | 119 |
| 122 bool isEnabled() { return fEnabled; } | 120 bool isEnabled() { return fEnabled; } |
| 123 void setEnabled(bool enabled) { fEnabled = enabled; } | 121 void setEnabled(bool enabled) { fEnabled = enabled; } |
| 124 | 122 |
| 125 void reset() { | 123 void setClientID(int clientID) { fClientID = clientID; } |
| 126 SkASSERT(fEnabled && fStack.empty()); | |
| 127 fFrames.reset(); | |
| 128 } | |
| 129 | |
| 130 void resetBatchList() { | |
| 131 SkASSERT(fEnabled); | |
| 132 fBatches.reset(); | |
| 133 fIDLookup.reset(); | |
| 134 } | |
| 135 | 124 |
| 136 void fullReset() { | 125 void fullReset() { |
| 137 SkASSERT(fEnabled); | 126 SkASSERT(fEnabled); |
| 138 this->reset(); | 127 fBatchList.reset(); |
| 139 this->resetBatchList(); | 128 fIDLookup.reset(); |
| 140 fEvents.reset(); // must be last, frees all of the memory | 129 // free all client batches |
| 130 fClientIDLookup.foreach([](const int&, Batches** batches) { delete *batc hes; }); | |
| 131 fClientIDLookup.reset(); | |
| 132 fBatchPool.reset(); // must be last, frees all of the memory | |
| 141 } | 133 } |
| 142 | 134 |
| 135 static const int kInvalidID; | |
| 136 | |
| 143 private: | 137 private: |
| 144 // TODO if performance becomes an issue, we can move to using SkVarAlloc | 138 // TODO if performance becomes an issue, we can move to using SkVarAlloc |
| 145 struct Event { | 139 struct Batch { |
| 146 virtual ~Event() {} | 140 SkString toJson() const; |
| 147 virtual SkString toJson() const=0; | 141 SkString fName; |
| 142 SkRect fBounds; | |
| 143 int fClientID; | |
| 144 int fBatchListID; | |
| 145 int fChildID; | |
| 146 }; | |
| 147 typedef SkTArray<SkAutoTDelete<Batch>, true> BatchPool; | |
| 148 | 148 |
| 149 const char* fName; | 149 typedef SkTArray<Batch*> Batches; |
| 150 uint64_t fUniqueID; | 150 |
| 151 struct BatchNode { | |
| 152 SkString toJson() const; | |
| 153 SkRect fBounds; | |
| 154 Batches fChildren; | |
| 151 }; | 155 }; |
| 152 | 156 typedef SkTArray<SkAutoTDelete<BatchNode>, true> BatchList; |
| 153 struct Frame : public Event { | |
| 154 SkString toJson() const override; | |
| 155 SkTArray<Event*> fChildren; | |
| 156 }; | |
| 157 | |
| 158 struct Batch : public Event { | |
| 159 SkString toJson() const override; | |
| 160 SkRect fBounds; | |
| 161 SkTArray<Batch*> fChildren; | |
| 162 }; | |
| 163 typedef SkTArray<SkAutoTDelete<Event>, true> EventArrayPool; | |
| 164 | 157 |
| 165 template <typename T> | 158 template <typename T> |
| 166 static void JsonifyTArray(SkString* json, const char* name, const T& array, | 159 static void JsonifyTArray(SkString* json, const char* name, const T& array, |
| 167 bool addComma); | 160 bool addComma); |
| 168 | 161 |
| 169 // We store both an array of frames, and also a flatter array just of the ba tches | 162 Batch* fCurrentBatch; |
| 163 BatchPool fBatchPool; | |
| 164 SkTHashMap<GrBatch*, int> fIDLookup; | |
| 165 SkTHashMap<int, Batches*> fClientIDLookup; | |
| 166 BatchList fBatchList; | |
| 167 | |
| 168 // The client cas pass in an optional client ID which we will use to mark th e batches | |
| 169 int fClientID; | |
| 170 bool fEnabled; | 170 bool fEnabled; |
| 171 EventArrayPool fEvents; // manages the lifetimes of the events | |
| 172 SkTArray<Event*> fFrames; | |
| 173 SkTArray<Frame*> fStack; | |
| 174 uint64_t fUniqueID; | |
| 175 | |
| 176 Batch* fCurrentBatch; | |
| 177 SkTHashMap<GrBatch*, int> fIDLookup; | |
| 178 SkTArray<Batch*> fBatches; | |
| 179 }; | 171 }; |
| 180 | 172 |
| 181 #define GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, invoke, ...) \ | 173 #define GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, invoke, ...) \ |
| 182 if (audit_trail->isEnabled()) { \ | 174 if (audit_trail->isEnabled()) { \ |
| 183 audit_trail->invoke(__VA_ARGS__); \ | 175 audit_trail->invoke(__VA_ARGS__); \ |
| 184 } | 176 } |
| 185 | 177 |
| 186 #define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \ | 178 #define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \ |
| 187 GrAuditTrail::AutoFrame SK_MACRO_APPEND_LINE(auto_frame)(audit_trail, framen ame); | 179 // TODO fill out the frame stuff |
| 180 //GrAuditTrail::AutoFrame SK_MACRO_APPEND_LINE(auto_frame)(audit_trail, fram ename); | |
| 188 | 181 |
| 189 #define GR_AUDIT_TRAIL_RESET(audit_trail) \ | 182 #define GR_AUDIT_TRAIL_RESET(audit_trail) \ |
| 190 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, reset); | 183 //GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, reset); |
| 191 | 184 |
| 192 #define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batchname, bounds) \ | 185 #define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batchname, bounds) \ |
| 193 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addBatch, batchname, bounds); | 186 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addBatch, batchname, bounds); |
| 194 | 187 |
| 195 #define GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(audit_trail, combiner) \ | 188 #define GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(audit_trail, combiner) \ |
| 196 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, batchingResultCombined, combiner); | 189 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, batchingResultCombined, combiner); |
| 197 | 190 |
| 198 #define GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(audit_trail, batch) \ | 191 #define GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(audit_trail, batch) \ |
| 199 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, batchingResultNew, batch); | 192 GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, batchingResultNew, batch); |
| 200 | 193 |
| 201 #endif | 194 #endif |
| OLD | NEW |