GrAuditTrail* fAuditTrail;
};
- class AutoManageBatchList {
+ class AutoManageOpList {
public:
- AutoManageBatchList(GrAuditTrail* auditTrail)
- : fAutoEnable(auditTrail)
- , fAuditTrail(auditTrail) {
- }
+ AutoManageOpList(GrAuditTrail* auditTrail)
+ : fAutoEnable(auditTrail), fAuditTrail(auditTrail) {}
- ~AutoManageBatchList() {
- fAuditTrail->fullReset();
- }
+ ~AutoManageOpList() { fAuditTrail->fullReset(); }
private:
AutoEnable fAutoEnable;
GrAuditTrail* fAuditTrail;
};
- class AutoCollectBatches {
+ class AutoCollectOps {
public:
- AutoCollectBatches(GrAuditTrail* auditTrail, int clientID)
- : fAutoEnable(auditTrail)
- , fAuditTrail(auditTrail) {
+ AutoCollectOps(GrAuditTrail* auditTrail, int clientID)
+ : fAutoEnable(auditTrail), fAuditTrail(auditTrail) {
fAuditTrail->setClientID(clientID);
}
- ~AutoCollectBatches() { fAuditTrail->setClientID(kGrAuditTrailInvalidID); }
+ ~AutoCollectOps() { fAuditTrail->setClientID(kGrAuditTrailInvalidID); }
private:
AutoEnable fAutoEnable;
fCurrentStackTrace.push_back(SkString(framename));
}
- void addBatch(const GrOp* batch);
+ void addOp(const GrOp*);
- void batchingResultCombined(const GrOp* consumer, const GrOp* consumed);
+ void opsCombined(const GrOp* consumer, const GrOp* consumed);
- // 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.
+ // Because op combining is heavily dependent on sequence of draw calls, these calls will only
+ // produce valid information for the given draw sequence which preceeded them. Specifically, ops
+ // of future draw calls may combine with previous ops 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 combining algorithm used.
SkString toJson(bool prettyPrint = false) const;
- // returns a json string of all of the batches associated with a given client id
+ // returns a json string of all of the ops associated with a given client id
SkString toJson(int clientID, bool prettyPrint = false) const;
bool isEnabled() { return fEnabled; }
// We could just return our internal bookkeeping struct if copying the data out becomes
// a performance issue, but until then its nice to decouple
- struct BatchInfo {
- SkRect fBounds;
+ struct OpInfo {
+ SkRect fBounds;
// TODO: switch over to GrSurfaceProxy::UniqueID
GrGpuResource::UniqueID fRenderTargetUniqueID;
- struct Batch {
+ struct Op {
int fClientID;
SkRect fBounds;
};
- SkTArray<Batch> fBatches;
+ SkTArray<Op> fOps;
};
- void getBoundsByClientID(SkTArray<BatchInfo>* outInfo, int clientID);
- void getBoundsByBatchListID(BatchInfo* outInfo, int batchListID);
+ void getBoundsByClientID(SkTArray<OpInfo>* outInfo, int clientID);
+ void getBoundsByOpListID(OpInfo* outInfo, int opListID);
void fullReset();
private:
// TODO if performance becomes an issue, we can move to using SkVarAlloc
- struct Batch {
+ struct Op {
SkString toJson() const;
SkString fName;
SkTArray<SkString> fStackTrace;
SkRect fBounds;
int fClientID;
- int fBatchListID;
+ int fOpListID;
int fChildID;
};
- typedef SkTArray<std::unique_ptr<Batch>, true> BatchPool;
+ typedef SkTArray<std::unique_ptr<Op>, true> OpPool;
- typedef SkTArray<Batch*> Batches;
+ typedef SkTArray<Op*> Ops;
- struct BatchNode {
- BatchNode(const GrGpuResource::UniqueID& id) : fRenderTargetUniqueID(id) { }
+ struct OpNode {
+ OpNode(const GrGpuResource::UniqueID& id) : fRenderTargetUniqueID(id) {}
SkString toJson() const;
SkRect fBounds;
- Batches fChildren;
+ Ops fChildren;
const GrGpuResource::UniqueID fRenderTargetUniqueID;
};
- typedef SkTArray<std::unique_ptr<BatchNode>, true> BatchList;
+ typedef SkTArray<std::unique_ptr<OpNode>, true> OpList;
- void copyOutFromBatchList(BatchInfo* outBatchInfo, int batchListID);
+ void copyOutFromOpList(OpInfo* outOpInfo, int opListID);
template <typename T>
static void JsonifyTArray(SkString* json, const char* name, const T& array,
bool addComma);
- BatchPool fBatchPool;
+ OpPool fOpPool;
SkTHashMap<uint32_t, int> fIDLookup;
- SkTHashMap<int, Batches*> fClientIDLookup;
- BatchList fBatchList;
+ SkTHashMap<int, Ops*> fClientIDLookup;
+ OpList fOpList;
SkTArray<SkString> fCurrentStackTrace;
- // The client cas pass in an optional client ID which we will use to mark the batches
+ // The client can pass in an optional client ID which we will use to mark the ops
int fClientID;
bool fEnabled;
};
#define GR_AUDIT_TRAIL_RESET(audit_trail) \
//GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, fullReset);
-#define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batch) \
- GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addBatch, batch);
+#define GR_AUDIT_TRAIL_ADD_OP(audit_trail, op) GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addOp, op);
-#define GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(audit_trail, combineWith, batch) \
- GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, batchingResultCombined, combineWith, batch);
+#define GR_AUDIT_TRAIL_OPS_RESULT_COMBINED(audit_trail, combineWith, op) \
+ GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, opsCombined, combineWith, op);
-#define GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(audit_trail, batch) \
- // Doesn't do anything now, one day...
+#define GR_AUDIT_TRAIL_OP_RESULT_NEW(audit_trail, op) // Doesn't do anything now, one day...
#endif
const int GrAuditTrail::kGrAuditTrailInvalidID = -1;
-void GrAuditTrail::addBatch(const GrOp* batch) {
+void GrAuditTrail::addOp(const GrOp* op) {
SkASSERT(fEnabled);
- Batch* auditBatch = new Batch;
- fBatchPool.emplace_back(auditBatch);
- auditBatch->fName = batch->name();
- auditBatch->fBounds = batch->bounds();
- auditBatch->fClientID = kGrAuditTrailInvalidID;
- auditBatch->fBatchListID = kGrAuditTrailInvalidID;
- auditBatch->fChildID = kGrAuditTrailInvalidID;
+ Op* auditOp = new Op;
+ fOpPool.emplace_back(auditOp);
+ auditOp->fName = op->name();
+ auditOp->fBounds = op->bounds();
+ auditOp->fClientID = kGrAuditTrailInvalidID;
+ auditOp->fOpListID = kGrAuditTrailInvalidID;
+ auditOp->fChildID = kGrAuditTrailInvalidID;
// consume the current stack trace if any
- auditBatch->fStackTrace = fCurrentStackTrace;
+ auditOp->fStackTrace = fCurrentStackTrace;
fCurrentStackTrace.reset();
if (fClientID != kGrAuditTrailInvalidID) {
- auditBatch->fClientID = fClientID;
- Batches** batchesLookup = fClientIDLookup.find(fClientID);
- Batches* batches = nullptr;
- if (!batchesLookup) {
- batches = new Batches;
- fClientIDLookup.set(fClientID, batches);
+ auditOp->fClientID = fClientID;
+ Ops** opsLookup = fClientIDLookup.find(fClientID);
+ Ops* ops = nullptr;
+ if (!opsLookup) {
+ ops = new Ops;
+ fClientIDLookup.set(fClientID, ops);
} else {
- batches = *batchesLookup;
+ ops = *opsLookup;
}
- batches->push_back(auditBatch);
+ ops->push_back(auditOp);
}
- // Our algorithm doesn't bother to reorder inside of a BatchNode
- // so the ChildID will start at 0
- auditBatch->fBatchListID = fBatchList.count();
- auditBatch->fChildID = 0;
-
- // We use the batch pointer as a key to find the batchnode we are 'glomming' batches onto
- fIDLookup.set(batch->uniqueID(), auditBatch->fBatchListID);
- BatchNode* batchNode = new BatchNode(batch->renderTargetUniqueID());
- batchNode->fBounds = batch->bounds();
- batchNode->fChildren.push_back(auditBatch);
- fBatchList.emplace_back(batchNode);
+ // Our algorithm doesn't bother to reorder inside of an OpNode so the ChildID will start at 0
+ auditOp->fOpListID = fOpList.count();
+ auditOp->fChildID = 0;
+
+ // We use the op pointer as a key to find the OpNode we are 'glomming' ops onto
+ fIDLookup.set(op->uniqueID(), auditOp->fOpListID);
+ OpNode* opNode = new OpNode(op->renderTargetUniqueID());
+ opNode->fBounds = op->bounds();
+ opNode->fChildren.push_back(auditOp);
+ fOpList.emplace_back(opNode);
}
-void GrAuditTrail::batchingResultCombined(const GrOp* consumer, const GrOp* consumed) {
- // Look up the batch we are going to glom onto
+void GrAuditTrail::opsCombined(const GrOp* consumer, const GrOp* consumed) {
+ // Look up the op we are going to glom onto
int* indexPtr = fIDLookup.find(consumer->uniqueID());
SkASSERT(indexPtr);
int index = *indexPtr;
- SkASSERT(index < fBatchList.count() && fBatchList[index]);
- BatchNode& consumerBatch = *fBatchList[index];
+ SkASSERT(index < fOpList.count() && fOpList[index]);
+ OpNode& consumerOp = *fOpList[index];
- // Look up the batch which will be glommed
+ // Look up the op which will be glommed
int* consumedPtr = fIDLookup.find(consumed->uniqueID());
SkASSERT(consumedPtr);
int consumedIndex = *consumedPtr;
- SkASSERT(consumedIndex < fBatchList.count() && fBatchList[consumedIndex]);
- BatchNode& consumedBatch = *fBatchList[consumedIndex];
+ SkASSERT(consumedIndex < fOpList.count() && fOpList[consumedIndex]);
+ OpNode& consumedOp = *fOpList[consumedIndex];
- // steal all of consumed's batches
- for (int i = 0; i < consumedBatch.fChildren.count(); i++) {
- Batch* childBatch = consumedBatch.fChildren[i];
+ // steal all of consumed's ops
+ for (int i = 0; i < consumedOp.fChildren.count(); i++) {
+ Op* childOp = consumedOp.fChildren[i];
- // set the ids for the child batch
- childBatch->fBatchListID = index;
- childBatch->fChildID = consumerBatch.fChildren.count();
- consumerBatch.fChildren.push_back(childBatch);
+ // set the ids for the child op
+ childOp->fOpListID = index;
+ childOp->fChildID = consumerOp.fChildren.count();
+ consumerOp.fChildren.push_back(childOp);
}
// Update the bounds for the combineWith node
- consumerBatch.fBounds = consumer->bounds();
+ consumerOp.fBounds = consumer->bounds();
- // remove the old node from our batchlist and clear the combinee's lookup
- // NOTE: because we can't change the shape of the batchlist, we use a sentinel
- fBatchList[consumedIndex].reset(nullptr);
+ // remove the old node from our opList and clear the combinee's lookup
+ // NOTE: because we can't change the shape of the oplist, we use a sentinel
+ fOpList[consumedIndex].reset(nullptr);
fIDLookup.remove(consumed->uniqueID());
}
-void GrAuditTrail::copyOutFromBatchList(BatchInfo* outBatchInfo, int batchListID) {
- SkASSERT(batchListID < fBatchList.count());
- const BatchNode* bn = fBatchList[batchListID].get();
+void GrAuditTrail::copyOutFromOpList(OpInfo* outOpInfo, int opListID) {
+ SkASSERT(opListID < fOpList.count());
+ const OpNode* bn = fOpList[opListID].get();
SkASSERT(bn);
- outBatchInfo->fBounds = bn->fBounds;
- outBatchInfo->fRenderTargetUniqueID = bn->fRenderTargetUniqueID;
+ outOpInfo->fBounds = bn->fBounds;
+ outOpInfo->fRenderTargetUniqueID = bn->fRenderTargetUniqueID;
for (int j = 0; j < bn->fChildren.count(); j++) {
- BatchInfo::Batch& outBatch = outBatchInfo->fBatches.push_back();
- const Batch* currentBatch = bn->fChildren[j];
- outBatch.fBounds = currentBatch->fBounds;
- outBatch.fClientID = currentBatch->fClientID;
+ OpInfo::Op& outOp = outOpInfo->fOps.push_back();
+ const Op* currentOp = bn->fChildren[j];
+ outOp.fBounds = currentOp->fBounds;
+ outOp.fClientID = currentOp->fClientID;
}
}
-void GrAuditTrail::getBoundsByClientID(SkTArray<BatchInfo>* outInfo, int clientID) {
- Batches** batchesLookup = fClientIDLookup.find(clientID);
- if (batchesLookup) {
- // We track which batchlistID we're currently looking at. If it changes, then we
- // need to push back a new batch info struct. We happen to know that batches are
- // in sequential order in the batchlist, otherwise we'd have to do more bookkeeping
- int currentBatchListID = kGrAuditTrailInvalidID;
- for (int i = 0; i < (*batchesLookup)->count(); i++) {
- const Batch* batch = (**batchesLookup)[i];
-
- // Because we will copy out all of the batches associated with a given
- // batch list id everytime the id changes, we only have to update our struct
- // when the id changes.
- if (kGrAuditTrailInvalidID == currentBatchListID ||
- batch->fBatchListID != currentBatchListID) {
- BatchInfo& outBatchInfo = outInfo->push_back();
-
- // copy out all of the batches so the client can display them even if
- // they have a different clientID
- this->copyOutFromBatchList(&outBatchInfo, batch->fBatchListID);
+void GrAuditTrail::getBoundsByClientID(SkTArray<OpInfo>* outInfo, int clientID) {
+ Ops** opsLookup = fClientIDLookup.find(clientID);
+ if (opsLookup) {
+ // We track which oplistID we're currently looking at. If it changes, then we need to push
+ // back a new op info struct. We happen to know that ops are in sequential order in the
+ // oplist, otherwise we'd have to do more bookkeeping
+ int currentOpListID = kGrAuditTrailInvalidID;
+ for (int i = 0; i < (*opsLookup)->count(); i++) {
+ const Op* op = (**opsLookup)[i];
+
+ // Because we will copy out all of the ops associated with a given op list id everytime
+ // the id changes, we only have to update our struct when the id changes.
+ if (kGrAuditTrailInvalidID == currentOpListID || op->fOpListID != currentOpListID) {
+ OpInfo& outOpInfo = outInfo->push_back();
+
+ // copy out all of the ops so the client can display them even if they have a
+ // different clientID
+ this->copyOutFromOpList(&outOpInfo, op->fOpListID);
}
}
}
}
-void GrAuditTrail::getBoundsByBatchListID(BatchInfo* outInfo, int batchListID) {
- this->copyOutFromBatchList(outInfo, batchListID);
+void GrAuditTrail::getBoundsByOpListID(OpInfo* outInfo, int opListID) {
+ this->copyOutFromOpList(outInfo, opListID);
}
void GrAuditTrail::fullReset() {
SkASSERT(fEnabled);
- fBatchList.reset();
+ fOpList.reset();
fIDLookup.reset();
- // free all client batches
- fClientIDLookup.foreach([](const int&, Batches** batches) { delete *batches; });
+ // free all client ops
+ fClientIDLookup.foreach ([](const int&, Ops** ops) { delete *ops; });
fClientIDLookup.reset();
- fBatchPool.reset(); // must be last, frees all of the memory
+ fOpPool.reset(); // must be last, frees all of the memory
}
template <typename T>
SkString GrAuditTrail::toJson(bool prettyPrint) const {
SkString json;
json.append("{");
- JsonifyTArray(&json, "Batches", fBatchList, false);
+ JsonifyTArray(&json, "Batches", fOpList, false);
json.append("}");
if (prettyPrint) {
SkString GrAuditTrail::toJson(int clientID, bool prettyPrint) const {
SkString json;
json.append("{");
- Batches** batches = fClientIDLookup.find(clientID);
- if (batches) {
- JsonifyTArray(&json, "Batches", **batches, false);
+ Ops** ops = fClientIDLookup.find(clientID);
+ if (ops) {
+ JsonifyTArray(&json, "Batches", **ops, false);
}
json.appendf("}");
json->append("}");
}
-SkString GrAuditTrail::Batch::toJson() const {
+SkString GrAuditTrail::Op::toJson() const {
SkString json;
json.append("{");
json.appendf("\"Name\": \"%s\",", fName.c_str());
json.appendf("\"ClientID\": \"%d\",", fClientID);
- json.appendf("\"BatchListID\": \"%d\",", fBatchListID);
+ json.appendf("\"BatchListID\": \"%d\",", fOpListID);
json.appendf("\"ChildID\": \"%d\",", fChildID);
skrect_to_json(&json, "Bounds", fBounds);
if (fStackTrace.count()) {
return json;
}
-SkString GrAuditTrail::BatchNode::toJson() const {
+SkString GrAuditTrail::OpNode::toJson() const {
SkString json;
json.append("{");
json.appendf("\"RenderTarget\": \"%u\",", fRenderTargetUniqueID.asUInt());