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); |