| Index: include/private/GrAuditTrail.h
|
| diff --git a/include/private/GrAuditTrail.h b/include/private/GrAuditTrail.h
|
| index faf59ab0e46164985e95e923dbf52370f32aec93..72708644a516778d7073bb48149590e57bde9db1 100644
|
| --- a/include/private/GrAuditTrail.h
|
| +++ b/include/private/GrAuditTrail.h
|
| @@ -28,8 +28,27 @@
|
| class GrAuditTrail {
|
| public:
|
| GrAuditTrail()
|
| - : fClientID(kInvalidID)
|
| - , fEnabled(false) {}
|
| + : fEnabled(false)
|
| + , fUniqueID(0) {}
|
| +
|
| + class AutoFrame {
|
| + public:
|
| + AutoFrame(GrAuditTrail* auditTrail, const char* name)
|
| + : fAuditTrail(auditTrail) {
|
| + if (fAuditTrail->fEnabled) {
|
| + fAuditTrail->pushFrame(name);
|
| + }
|
| + }
|
| +
|
| + ~AutoFrame() {
|
| + if (fAuditTrail->fEnabled) {
|
| + fAuditTrail->popFrame();
|
| + }
|
| + }
|
| +
|
| + private:
|
| + GrAuditTrail* fAuditTrail;
|
| + };
|
|
|
| class AutoEnable {
|
| public:
|
| @@ -64,113 +83,99 @@
|
| GrAuditTrail* fAuditTrail;
|
| };
|
|
|
| - class AutoCollectBatches {
|
| - public:
|
| - AutoCollectBatches(GrAuditTrail* auditTrail, int clientID)
|
| - : fAutoEnable(auditTrail)
|
| - , fAuditTrail(auditTrail) {
|
| - fAuditTrail->setClientID(clientID);
|
| - }
|
| -
|
| - ~AutoCollectBatches() { fAuditTrail->setClientID(kInvalidID); }
|
| -
|
| - private:
|
| - AutoEnable fAutoEnable;
|
| - GrAuditTrail* fAuditTrail;
|
| - };
|
| + void pushFrame(const char* name) {
|
| + SkASSERT(fEnabled);
|
| + Frame* frame = new Frame;
|
| + fEvents.emplace_back(frame);
|
| + if (fStack.empty()) {
|
| + fFrames.push_back(frame);
|
| + } else {
|
| + fStack.back()->fChildren.push_back(frame);
|
| + }
|
| +
|
| + frame->fUniqueID = fUniqueID++;
|
| + frame->fName = name;
|
| + fStack.push_back(frame);
|
| + }
|
| +
|
| + void popFrame() {
|
| + SkASSERT(fEnabled);
|
| + fStack.pop_back();
|
| + }
|
|
|
| void addBatch(const char* name, const SkRect& bounds) {
|
| - SkASSERT(fEnabled);
|
| + SkASSERT(fEnabled && !fStack.empty());
|
| Batch* batch = new Batch;
|
| - fBatchPool.emplace_back(batch);
|
| + fEvents.emplace_back(batch);
|
| + fStack.back()->fChildren.push_back(batch);
|
| batch->fName = name;
|
| batch->fBounds = bounds;
|
| - batch->fClientID = kInvalidID;
|
| - batch->fBatchListID = kInvalidID;
|
| - batch->fChildID = kInvalidID;
|
| fCurrentBatch = batch;
|
| -
|
| - if (fClientID != kInvalidID) {
|
| - batch->fClientID = fClientID;
|
| - Batches** batchesLookup = fClientIDLookup.find(fClientID);
|
| - Batches* batches = nullptr;
|
| - if (!batchesLookup) {
|
| - batches = new Batches;
|
| - fClientIDLookup.set(fClientID, batches);
|
| - } else {
|
| - batches = *batchesLookup;
|
| - }
|
| -
|
| - batches->push_back(fCurrentBatch);
|
| - }
|
| }
|
|
|
| void batchingResultCombined(GrBatch* combiner);
|
|
|
| void batchingResultNew(GrBatch* batch);
|
|
|
| - // Because batching is heavily dependent on sequence of draw calls, these calls will only
|
| - // produce valid information for the given draw sequence which preceeded them.
|
| - // Specifically, future draw calls may change the batching and thus would invalidate
|
| - // the json. What this means is that for some sequence of draw calls N, the below toJson
|
| - // calls will only produce JSON which reflects N draw calls. This JSON may or may not be
|
| - // accurate for N + 1 or N - 1 draws depending on the actual batching algorithm used.
|
| - SkString toJson(bool prettyPrint = false) const;
|
| -
|
| - // returns a json string of all of the batches associated with a given client id
|
| - SkString toJson(int clientID, bool prettyPrint = false) const;
|
| + SkString toJson(bool batchList = false, bool prettyPrint = false) const;
|
|
|
| bool isEnabled() { return fEnabled; }
|
| void setEnabled(bool enabled) { fEnabled = enabled; }
|
|
|
| - void setClientID(int clientID) { fClientID = clientID; }
|
| + void reset() {
|
| + SkASSERT(fEnabled && fStack.empty());
|
| + fFrames.reset();
|
| + }
|
| +
|
| + void resetBatchList() {
|
| + SkASSERT(fEnabled);
|
| + fBatches.reset();
|
| + fIDLookup.reset();
|
| + }
|
|
|
| void fullReset() {
|
| SkASSERT(fEnabled);
|
| - fBatchList.reset();
|
| - fIDLookup.reset();
|
| - // free all client batches
|
| - fClientIDLookup.foreach([](const int&, Batches** batches) { delete *batches; });
|
| - fClientIDLookup.reset();
|
| - fBatchPool.reset(); // must be last, frees all of the memory
|
| - }
|
| -
|
| - static const int kInvalidID;
|
| + this->reset();
|
| + this->resetBatchList();
|
| + fEvents.reset(); // must be last, frees all of the memory
|
| + }
|
|
|
| private:
|
| // TODO if performance becomes an issue, we can move to using SkVarAlloc
|
| - struct Batch {
|
| - SkString toJson() const;
|
| - SkString fName;
|
| + struct Event {
|
| + virtual ~Event() {}
|
| + virtual SkString toJson() const=0;
|
| +
|
| + const char* fName;
|
| + uint64_t fUniqueID;
|
| + };
|
| +
|
| + struct Frame : public Event {
|
| + SkString toJson() const override;
|
| + SkTArray<Event*> fChildren;
|
| + };
|
| +
|
| + struct Batch : public Event {
|
| + SkString toJson() const override;
|
| SkRect fBounds;
|
| - int fClientID;
|
| - int fBatchListID;
|
| - int fChildID;
|
| - };
|
| - typedef SkTArray<SkAutoTDelete<Batch>, true> BatchPool;
|
| -
|
| - typedef SkTArray<Batch*> Batches;
|
| -
|
| - struct BatchNode {
|
| - SkString toJson() const;
|
| - SkRect fBounds;
|
| - Batches fChildren;
|
| - };
|
| - typedef SkTArray<SkAutoTDelete<BatchNode>, true> BatchList;
|
| + SkTArray<Batch*> fChildren;
|
| + };
|
| + typedef SkTArray<SkAutoTDelete<Event>, true> EventArrayPool;
|
|
|
| template <typename T>
|
| static void JsonifyTArray(SkString* json, const char* name, const T& array,
|
| bool addComma);
|
|
|
| + // We store both an array of frames, and also a flatter array just of the batches
|
| + bool fEnabled;
|
| + EventArrayPool fEvents; // manages the lifetimes of the events
|
| + SkTArray<Event*> fFrames;
|
| + SkTArray<Frame*> fStack;
|
| + uint64_t fUniqueID;
|
| +
|
| Batch* fCurrentBatch;
|
| - BatchPool fBatchPool;
|
| SkTHashMap<GrBatch*, int> fIDLookup;
|
| - SkTHashMap<int, Batches*> fClientIDLookup;
|
| - BatchList fBatchList;
|
| -
|
| - // The client cas pass in an optional client ID which we will use to mark the batches
|
| - int fClientID;
|
| - bool fEnabled;
|
| + SkTArray<Batch*> fBatches;
|
| };
|
|
|
| #define GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, invoke, ...) \
|
| @@ -179,11 +184,10 @@
|
| }
|
|
|
| #define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \
|
| - // TODO fill out the frame stuff
|
| - //GrAuditTrail::AutoFrame SK_MACRO_APPEND_LINE(auto_frame)(audit_trail, framename);
|
| + GrAuditTrail::AutoFrame SK_MACRO_APPEND_LINE(auto_frame)(audit_trail, framename);
|
|
|
| #define GR_AUDIT_TRAIL_RESET(audit_trail) \
|
| - //GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, reset);
|
| + GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, reset);
|
|
|
| #define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batchname, bounds) \
|
| GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addBatch, batchname, bounds);
|
|
|