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:
parent
d8a4f77211
commit
b0666ad3a9
@ -84,11 +84,9 @@ public:
|
|||||||
fCurrentStackTrace.push_back(SkString(framename));
|
fCurrentStackTrace.push_back(SkString(framename));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addBatch(const char* name, const SkRect& bounds);
|
void addBatch(const GrBatch* batch);
|
||||||
|
|
||||||
void batchingResultCombined(GrBatch* combiner);
|
void batchingResultCombined(const GrBatch* consumer, const GrBatch* consumed);
|
||||||
|
|
||||||
void batchingResultNew(GrBatch* batch);
|
|
||||||
|
|
||||||
// Because batching is heavily dependent on sequence of draw calls, these calls will only
|
// 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.
|
// produce valid information for the given draw sequence which preceeded them.
|
||||||
@ -153,10 +151,9 @@ private:
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
static void JsonifyTArray(SkString* json, const char* name, const T& array,
|
static void JsonifyTArray(SkString* json, const char* name, const T& array,
|
||||||
bool addComma);
|
bool addComma);
|
||||||
|
|
||||||
Batch* fCurrentBatch;
|
|
||||||
BatchPool fBatchPool;
|
BatchPool fBatchPool;
|
||||||
SkTHashMap<GrBatch*, int> fIDLookup;
|
SkTHashMap<uint32_t, int> fIDLookup;
|
||||||
SkTHashMap<int, Batches*> fClientIDLookup;
|
SkTHashMap<int, Batches*> fClientIDLookup;
|
||||||
BatchList fBatchList;
|
BatchList fBatchList;
|
||||||
SkTArray<SkString> fCurrentStackTrace;
|
SkTArray<SkString> fCurrentStackTrace;
|
||||||
@ -177,13 +174,13 @@ private:
|
|||||||
#define GR_AUDIT_TRAIL_RESET(audit_trail) \
|
#define GR_AUDIT_TRAIL_RESET(audit_trail) \
|
||||||
//GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, fullReset);
|
//GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, fullReset);
|
||||||
|
|
||||||
#define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batchname, bounds) \
|
#define GR_AUDIT_TRAIL_ADDBATCH(audit_trail, batch) \
|
||||||
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addBatch, batchname, bounds);
|
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addBatch, batch);
|
||||||
|
|
||||||
#define GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(audit_trail, combiner) \
|
#define GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(audit_trail, combineWith, batch) \
|
||||||
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, batchingResultCombined, combiner);
|
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, batchingResultCombined, combineWith, batch);
|
||||||
|
|
||||||
#define GR_AUDIT_TRAIL_BATCHING_RESULT_NEW(audit_trail, 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
|
#endif
|
||||||
|
@ -10,23 +10,22 @@
|
|||||||
|
|
||||||
const int GrAuditTrail::kGrAuditTrailInvalidID = -1;
|
const int GrAuditTrail::kGrAuditTrailInvalidID = -1;
|
||||||
|
|
||||||
void GrAuditTrail::addBatch(const char* name, const SkRect& bounds) {
|
void GrAuditTrail::addBatch(const GrBatch* batch) {
|
||||||
SkASSERT(fEnabled);
|
SkASSERT(fEnabled);
|
||||||
Batch* batch = new Batch;
|
Batch* auditBatch = new Batch;
|
||||||
fBatchPool.emplace_back(batch);
|
fBatchPool.emplace_back(auditBatch);
|
||||||
batch->fName = name;
|
auditBatch->fName = batch->name();
|
||||||
batch->fBounds = bounds;
|
auditBatch->fBounds = batch->bounds();
|
||||||
batch->fClientID = kGrAuditTrailInvalidID;
|
auditBatch->fClientID = kGrAuditTrailInvalidID;
|
||||||
batch->fBatchListID = kGrAuditTrailInvalidID;
|
auditBatch->fBatchListID = kGrAuditTrailInvalidID;
|
||||||
batch->fChildID = kGrAuditTrailInvalidID;
|
auditBatch->fChildID = kGrAuditTrailInvalidID;
|
||||||
|
|
||||||
// consume the current stack trace if any
|
// consume the current stack trace if any
|
||||||
batch->fStackTrace = fCurrentStackTrace;
|
auditBatch->fStackTrace = fCurrentStackTrace;
|
||||||
fCurrentStackTrace.reset();
|
fCurrentStackTrace.reset();
|
||||||
fCurrentBatch = batch;
|
|
||||||
|
|
||||||
if (fClientID != kGrAuditTrailInvalidID) {
|
if (fClientID != kGrAuditTrailInvalidID) {
|
||||||
batch->fClientID = fClientID;
|
auditBatch->fClientID = fClientID;
|
||||||
Batches** batchesLookup = fClientIDLookup.find(fClientID);
|
Batches** batchesLookup = fClientIDLookup.find(fClientID);
|
||||||
Batches* batches = nullptr;
|
Batches* batches = nullptr;
|
||||||
if (!batchesLookup) {
|
if (!batchesLookup) {
|
||||||
@ -36,44 +35,61 @@ void GrAuditTrail::addBatch(const char* name, const SkRect& bounds) {
|
|||||||
batches = *batchesLookup;
|
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
|
// Our algorithm doesn't bother to reorder inside of a BatchNode
|
||||||
// so the ChildID will start at 0
|
// so the ChildID will start at 0
|
||||||
fCurrentBatch->fBatchListID = fBatchList.count();
|
auditBatch->fBatchListID = fBatchList.count();
|
||||||
fCurrentBatch->fChildID = 0;
|
auditBatch->fChildID = 0;
|
||||||
|
|
||||||
// We use the batch pointer as a key to find the batchnode we are 'glomming' batches onto
|
// 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* batchNode = new BatchNode;
|
||||||
batchNode->fBounds = fCurrentBatch->fBounds;
|
batchNode->fBounds = batch->bounds();
|
||||||
batchNode->fRenderTargetUniqueID = batch->renderTargetUniqueID();
|
batchNode->fRenderTargetUniqueID = batch->renderTargetUniqueID();
|
||||||
batchNode->fChildren.push_back(fCurrentBatch);
|
batchNode->fChildren.push_back(auditBatch);
|
||||||
fBatchList.emplace_back(batchNode);
|
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) {
|
void GrAuditTrail::copyOutFromBatchList(BatchInfo* outBatchInfo, int batchListID) {
|
||||||
SkASSERT(batchListID < fBatchList.count());
|
SkASSERT(batchListID < fBatchList.count());
|
||||||
const BatchNode* bn = fBatchList[batchListID];
|
const BatchNode* bn = fBatchList[batchListID];
|
||||||
|
SkASSERT(bn);
|
||||||
outBatchInfo->fBounds = bn->fBounds;
|
outBatchInfo->fBounds = bn->fBounds;
|
||||||
outBatchInfo->fRenderTargetUniqueID = bn->fRenderTargetUniqueID;
|
outBatchInfo->fRenderTargetUniqueID = bn->fRenderTargetUniqueID;
|
||||||
for (int j = 0; j < bn->fChildren.count(); j++) {
|
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);
|
json->appendf("\"%s\": [", name);
|
||||||
for (int i = 0; i < array.count(); i++) {
|
for (int i = 0; i < array.count(); i++) {
|
||||||
|
// Handle sentinel nullptrs
|
||||||
|
if (!array[i]) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
json->append(array[i]->toJson());
|
json->append(array[i]->toJson());
|
||||||
if (i < array.count() - 1) {
|
if (i < array.count() - 1) {
|
||||||
json->append(",");
|
json->append(",");
|
||||||
|
@ -461,7 +461,7 @@ void GrDrawTarget::recordBatch(GrBatch* batch) {
|
|||||||
// 1) check every draw
|
// 1) check every draw
|
||||||
// 2) intersect with something
|
// 2) intersect with something
|
||||||
// 3) find a 'blocker'
|
// 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"
|
GrBATCH_INFO("Re-Recording (%s, B%u)\n"
|
||||||
"\tBounds LRTB (%f, %f, %f, %f)\n",
|
"\tBounds LRTB (%f, %f, %f, %f)\n",
|
||||||
batch->name(),
|
batch->name(),
|
||||||
@ -484,7 +484,7 @@ void GrDrawTarget::recordBatch(GrBatch* batch) {
|
|||||||
if (candidate->combineIfPossible(batch, *this->caps())) {
|
if (candidate->combineIfPossible(batch, *this->caps())) {
|
||||||
GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name(),
|
GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name(),
|
||||||
candidate->uniqueID());
|
candidate->uniqueID());
|
||||||
GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate);
|
GR_AUDIT_TRAIL_BATCHING_RESULT_COMBINED(fAuditTrail, candidate, batch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Stop going backwards if we would cause a painter's order violation.
|
// 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())) {
|
} else if (batch->combineIfPossible(candidate, *this->caps())) {
|
||||||
GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name(),
|
GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name(),
|
||||||
candidate->uniqueID());
|
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[j].reset(SkRef(batch));
|
||||||
fBatches[i].reset(nullptr);
|
fBatches[i].reset(nullptr);
|
||||||
break;
|
break;
|
||||||
|
@ -334,6 +334,7 @@ void SkDebugCanvas::drawTo(SkCanvas* canvas, int index, int m) {
|
|||||||
if (at) {
|
if (at) {
|
||||||
// just in case there is global reordering, we flush the canvas before querying
|
// just in case there is global reordering, we flush the canvas before querying
|
||||||
// GrAuditTrail
|
// GrAuditTrail
|
||||||
|
GrAuditTrail::AutoEnable ae(at);
|
||||||
canvas->flush();
|
canvas->flush();
|
||||||
|
|
||||||
// we pick three colorblind-safe colors, 75% alpha
|
// 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();
|
uint32_t rtID = gbd->accessRenderTarget()->getUniqueID();
|
||||||
|
|
||||||
// get the bounding boxes to draw
|
// get the bounding boxes to draw
|
||||||
GrAuditTrail::AutoEnable ae(at);
|
|
||||||
SkTArray<GrAuditTrail::BatchInfo> childrenBounds;
|
SkTArray<GrAuditTrail::BatchInfo> childrenBounds;
|
||||||
if (m == -1) {
|
if (m == -1) {
|
||||||
at->getBoundsByClientID(&childrenBounds, index);
|
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
|
// in case there is some kind of global reordering
|
||||||
canvas->flush();
|
{
|
||||||
|
GrAuditTrail::AutoEnable ae(at);
|
||||||
|
canvas->flush();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -459,6 +462,7 @@ Json::Value SkDebugCanvas::toJSON(UrlDataManager& urlDataManager, int n, SkCanva
|
|||||||
}
|
}
|
||||||
#if SK_SUPPORT_GPU
|
#if SK_SUPPORT_GPU
|
||||||
if (at) {
|
if (at) {
|
||||||
|
GrAuditTrail::AutoEnable ae(at);
|
||||||
at->fullReset();
|
at->fullReset();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -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
|
// for some reason we need to 'flush' the debug canvas by drawing all of the ops
|
||||||
fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp());
|
fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp());
|
||||||
|
this->getCanvas()->flush();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user