| Index: include/private/GrAuditTrail.h
|
| diff --git a/include/private/GrAuditTrail.h b/include/private/GrAuditTrail.h
|
| index 72708644a516778d7073bb48149590e57bde9db1..66e578c9e8b99019524f34ccd52699ab5dc81ee6 100644
|
| --- a/include/private/GrAuditTrail.h
|
| +++ b/include/private/GrAuditTrail.h
|
| @@ -28,27 +28,8 @@ class GrBatch;
|
| class GrAuditTrail {
|
| public:
|
| GrAuditTrail()
|
| - : 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;
|
| - };
|
| + : fClientID(kGrAuditTrailInvalidID)
|
| + , fEnabled(false) {}
|
|
|
| class AutoEnable {
|
| public:
|
| @@ -83,99 +64,113 @@ public:
|
| 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);
|
| + class AutoCollectBatches {
|
| + public:
|
| + AutoCollectBatches(GrAuditTrail* auditTrail, int clientID)
|
| + : fAutoEnable(auditTrail)
|
| + , fAuditTrail(auditTrail) {
|
| + fAuditTrail->setClientID(clientID);
|
| }
|
|
|
| - frame->fUniqueID = fUniqueID++;
|
| - frame->fName = name;
|
| - fStack.push_back(frame);
|
| - }
|
| + ~AutoCollectBatches() { fAuditTrail->setClientID(kGrAuditTrailInvalidID); }
|
|
|
| - void popFrame() {
|
| - SkASSERT(fEnabled);
|
| - fStack.pop_back();
|
| - }
|
| + private:
|
| + AutoEnable fAutoEnable;
|
| + GrAuditTrail* fAuditTrail;
|
| + };
|
|
|
| void addBatch(const char* name, const SkRect& bounds) {
|
| - SkASSERT(fEnabled && !fStack.empty());
|
| + SkASSERT(fEnabled);
|
| Batch* batch = new Batch;
|
| - fEvents.emplace_back(batch);
|
| - fStack.back()->fChildren.push_back(batch);
|
| + fBatchPool.emplace_back(batch);
|
| batch->fName = name;
|
| batch->fBounds = bounds;
|
| + batch->fClientID = kGrAuditTrailInvalidID;
|
| + batch->fBatchListID = kGrAuditTrailInvalidID;
|
| + batch->fChildID = kGrAuditTrailInvalidID;
|
| fCurrentBatch = batch;
|
| +
|
| + if (fClientID != kGrAuditTrailInvalidID) {
|
| + 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);
|
|
|
| - SkString toJson(bool batchList = false, bool prettyPrint = false) const;
|
| + // 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;
|
|
|
| bool isEnabled() { return fEnabled; }
|
| void setEnabled(bool enabled) { fEnabled = enabled; }
|
|
|
| - void reset() {
|
| - SkASSERT(fEnabled && fStack.empty());
|
| - fFrames.reset();
|
| - }
|
| + void setClientID(int clientID) { fClientID = clientID; }
|
|
|
| - void resetBatchList() {
|
| + void fullReset() {
|
| SkASSERT(fEnabled);
|
| - fBatches.reset();
|
| + 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
|
| }
|
|
|
| - void fullReset() {
|
| - SkASSERT(fEnabled);
|
| - this->reset();
|
| - this->resetBatchList();
|
| - fEvents.reset(); // must be last, frees all of the memory
|
| - }
|
| + static const int kGrAuditTrailInvalidID;
|
|
|
| private:
|
| // TODO if performance becomes an issue, we can move to using SkVarAlloc
|
| - struct Event {
|
| - virtual ~Event() {}
|
| - virtual SkString toJson() const=0;
|
| -
|
| - const char* fName;
|
| - uint64_t fUniqueID;
|
| + struct Batch {
|
| + SkString toJson() const;
|
| + SkString fName;
|
| + SkRect fBounds;
|
| + int fClientID;
|
| + int fBatchListID;
|
| + int fChildID;
|
| };
|
| + typedef SkTArray<SkAutoTDelete<Batch>, true> BatchPool;
|
|
|
| - struct Frame : public Event {
|
| - SkString toJson() const override;
|
| - SkTArray<Event*> fChildren;
|
| - };
|
| + typedef SkTArray<Batch*> Batches;
|
|
|
| - struct Batch : public Event {
|
| - SkString toJson() const override;
|
| + struct BatchNode {
|
| + SkString toJson() const;
|
| SkRect fBounds;
|
| - SkTArray<Batch*> fChildren;
|
| + Batches fChildren;
|
| };
|
| - typedef SkTArray<SkAutoTDelete<Event>, true> EventArrayPool;
|
| + typedef SkTArray<SkAutoTDelete<BatchNode>, true> BatchList;
|
|
|
| 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;
|
| - SkTArray<Batch*> fBatches;
|
| + 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;
|
| };
|
|
|
| #define GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, invoke, ...) \
|
| @@ -184,10 +179,11 @@ private:
|
| }
|
|
|
| #define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \
|
| - GrAuditTrail::AutoFrame SK_MACRO_APPEND_LINE(auto_frame)(audit_trail, framename);
|
| + // TODO fill out the frame stuff
|
| + //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);
|
|
|