Fix up GrAuditTrail to allow arbitrary reordering

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1765123002

Review URL: https://codereview.chromium.org/1765123002
This commit is contained in:
joshualitt 2016-03-08 10:43:41 -08:00 committed by Commit bot
parent d8a4f77211
commit b0666ad3a9
5 changed files with 74 additions and 52 deletions

View File

@ -84,11 +84,9 @@ public:
fCurrentStackTrace.push_back(SkString(framename));
}
void addBatch(const char* name, const SkRect& bounds);
void addBatch(const GrBatch* batch);
void batchingResultCombined(GrBatch* combiner);
void batchingResultNew(GrBatch* batch);
void batchingResultCombined(const GrBatch* consumer, const GrBatch* 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.
@ -153,10 +151,9 @@ private:
template <typename T>
static void JsonifyTArray(SkString* json, const char* name, const T& array,
bool addComma);
Batch* fCurrentBatch;
BatchPool fBatchPool;
SkTHashMap<GrBatch*, int> fIDLookup;
SkTHashMap<uint32_t, int> fIDLookup;
SkTHashMap<int, Batches*> fClientIDLookup;
BatchList fBatchList;
SkTArray<SkString> fCurrentStackTrace;
@ -177,13 +174,13 @@ private:
#define GR_AUDIT_TRAIL_RESET(audit_trail) \
//GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, fullReset);
#define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batchname, bounds) \
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addBatch, batchname, bounds);
#define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batch) \
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addBatch, batch);
#define GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(audit_trail, combiner) \
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, batchingResultCombined, combiner);
#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_BATCHING_RESULT_NEW(audit_trail, batch) \
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, batchingResultNew, batch);
// Doesn't do anything now, one day...
#endif

View File

@ -10,23 +10,22 @@
const int GrAuditTrail::kGrAuditTrailInvalidID = -1;
void GrAuditTrail::addBatch(const char* name, const SkRect& bounds) {
void GrAuditTrail::addBatch(const GrBatch* batch) {
SkASSERT(fEnabled);
Batch* batch = new Batch;
fBatchPool.emplace_back(batch);
batch->fName = name;
batch->fBounds = bounds;
batch->fClientID = kGrAuditTrailInvalidID;
batch->fBatchListID = kGrAuditTrailInvalidID;
batch->fChildID = kGrAuditTrailInvalidID;
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;
// consume the current stack trace if any
batch->fStackTrace = fCurrentStackTrace;
auditBatch->fStackTrace = fCurrentStackTrace;
fCurrentStackTrace.reset();
fCurrentBatch = batch;
if (fClientID != kGrAuditTrailInvalidID) {
batch->fClientID = fClientID;
auditBatch->fClientID = fClientID;
Batches** batchesLookup = fClientIDLookup.find(fClientID);
Batches* batches = nullptr;
if (!batchesLookup) {
@ -36,44 +35,61 @@ void GrAuditTrail::addBatch(const char* name, const SkRect& bounds) {
batches = *batchesLookup;
}
batches->push_back(fCurrentBatch);
batches->push_back(auditBatch);
}
}
void GrAuditTrail::batchingResultCombined(GrBatch* combiner) {
int* indexPtr = fIDLookup.find(combiner);
SkASSERT(indexPtr);
int index = *indexPtr;
SkASSERT(index < fBatchList.count());
BatchNode& batch = *fBatchList[index];
// set the ids for the child batch
fCurrentBatch->fBatchListID = index;
fCurrentBatch->fChildID = batch.fChildren.count();
// Update the bounds and store a pointer to the new batch
batch.fChildren.push_back(fCurrentBatch);
batch.fBounds = combiner->bounds();
}
void GrAuditTrail::batchingResultNew(GrBatch* batch) {
// Our algorithm doesn't bother to reorder inside of a BatchNode
// so the ChildID will start at 0
fCurrentBatch->fBatchListID = fBatchList.count();
fCurrentBatch->fChildID = 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, fCurrentBatch->fBatchListID);
fIDLookup.set(batch->uniqueID(), auditBatch->fBatchListID);
BatchNode* batchNode = new BatchNode;
batchNode->fBounds = fCurrentBatch->fBounds;
batchNode->fBounds = batch->bounds();
batchNode->fRenderTargetUniqueID = batch->renderTargetUniqueID();
batchNode->fChildren.push_back(fCurrentBatch);
batchNode->fChildren.push_back(auditBatch);
fBatchList.emplace_back(batchNode);
}
void GrAuditTrail::batchingResultCombined(const GrBatch* consumer, const GrBatch* consumed) {
// Look up the batch 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];
// Look up the batch 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];
// steal all of consumed's batches
for (int i = 0; i < consumedBatch.fChildren.count(); i++) {
Batch* childBatch = consumedBatch.fChildren[i];
// set the ids for the child batch
childBatch->fBatchListID = index;
childBatch->fChildID = consumerBatch.fChildren.count();
consumerBatch.fChildren.push_back(childBatch);
}
// Update the bounds for the combineWith node
consumerBatch.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);
fIDLookup.remove(consumed->uniqueID());
}
void GrAuditTrail::copyOutFromBatchList(BatchInfo* outBatchInfo, int batchListID) {
SkASSERT(batchListID < fBatchList.count());
const BatchNode* bn = fBatchList[batchListID];
SkASSERT(bn);
outBatchInfo->fBounds = bn->fBounds;
outBatchInfo->fRenderTargetUniqueID = bn->fRenderTargetUniqueID;
for (int j = 0; j < bn->fChildren.count(); j++) {
@ -132,6 +148,10 @@ void GrAuditTrail::JsonifyTArray(SkString* json, const char* name, const T& arra
}
json->appendf("\"%s\": [", name);
for (int i = 0; i < array.count(); i++) {
// Handle sentinel nullptrs
if (!array[i]) {
continue;
}
json->append(array[i]->toJson());
if (i < array.count() - 1) {
json->append(",");

View File

@ -461,7 +461,7 @@ void GrDrawTarget::recordBatch(GrBatch* batch) {
// 1) check every draw
// 2) intersect with something
// 3) find a 'blocker'
GR_AUDIT_TRAIL_ADDBATCH(fAuditTrail, batch->name(), batch->bounds());
GR_AUDIT_TRAIL_ADDBATCH(fAuditTrail, batch);
GrBATCH_INFO("Re-Recording (%s, B%u)\n"
"\tBounds LRTB (%f, %f, %f, %f)\n",
batch->name(),
@ -484,7 +484,7 @@ void GrDrawTarget::recordBatch(GrBatch* batch) {
if (candidate->combineIfPossible(batch, *this->caps())) {
GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name(),
candidate->uniqueID());
GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate);
GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate, batch);
return;
}
// Stop going backwards if we would cause a painter's order violation.
@ -528,7 +528,7 @@ void GrDrawTarget::forwardCombine() {
} else if (batch->combineIfPossible(candidate, *this->caps())) {
GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name(),
candidate->uniqueID());
GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate);
GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, batch, candidate);
fBatches[j].reset(SkRef(batch));
fBatches[i].reset(nullptr);
break;

View File

@ -334,6 +334,7 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index, int m) {
if (at) {
// just in case there is global reordering, we flush the canvas before querying
// GrAuditTrail
GrAuditTrail::AutoEnable ae(at);
canvas->flush();
// we pick three colorblind-safe colors, 75% alpha
@ -347,7 +348,6 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index, int m) {
uint32_t rtID = gbd->accessRenderTarget()->getUniqueID();
// get the bounding boxes to draw
GrAuditTrail::AutoEnable ae(at);
SkTArray<GrAuditTrail::BatchInfo> childrenBounds;
if (m == -1) {
at->getBoundsByClientID(&childrenBounds, index);
@ -434,7 +434,10 @@ Json::Value SkDebugCanvas::toJSON(UrlDataManager& urlDataManager, int n, SkCanva
}
// in case there is some kind of global reordering
canvas->flush();
{
GrAuditTrail::AutoEnable ae(at);
canvas->flush();
}
}
}
#endif
@ -459,6 +462,7 @@ Json::Value SkDebugCanvas::toJSON(UrlDataManager& urlDataManager, int n, SkCanva
}
#if SK_SUPPORT_GPU
if (at) {
GrAuditTrail::AutoEnable ae(at);
at->fullReset();
}
#endif

View File

@ -150,6 +150,7 @@ bool Request::initPictureFromStream(SkStream* stream) {
// for some reason we need to 'flush' the debug canvas by drawing all of the ops
fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp());
this->getCanvas()->flush();
return true;
}