Add batch names and bounds to json debug information
BUG=skia: GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1577093003 Review URL: https://codereview.chromium.org/1577093003
This commit is contained in:
parent
1ad0415b03
commit
086cee12de
@ -9,6 +9,7 @@
|
||||
#define GrAuditTrail_DEFINED
|
||||
|
||||
#include "GrConfig.h"
|
||||
#include "SkRect.h"
|
||||
#include "SkString.h"
|
||||
#include "SkTArray.h"
|
||||
|
||||
@ -18,11 +19,18 @@
|
||||
*/
|
||||
class GrAuditTrail {
|
||||
public:
|
||||
void addOp(SkString name) {
|
||||
void addOp(const SkString& name) {
|
||||
SkASSERT(GR_BATCH_DEBUGGING_OUTPUT);
|
||||
fOps.push_back().fName = name;
|
||||
}
|
||||
|
||||
void addBatch(const SkString& name, const SkRect& bounds) {
|
||||
SkASSERT(GR_BATCH_DEBUGGING_OUTPUT);
|
||||
Op::Batch& batch = fOps.back().fBatches.push_back();
|
||||
batch.fName = name;
|
||||
batch.fBounds = bounds;
|
||||
}
|
||||
|
||||
SkString toJson() const;
|
||||
|
||||
void reset() { SkASSERT(GR_BATCH_DEBUGGING_OUTPUT); fOps.reset(); }
|
||||
@ -30,7 +38,14 @@ public:
|
||||
private:
|
||||
struct Op {
|
||||
SkString toJson() const;
|
||||
struct Batch {
|
||||
SkString toJson() const;
|
||||
SkString fName;
|
||||
SkRect fBounds;
|
||||
};
|
||||
|
||||
SkString fName;
|
||||
SkTArray<Batch> fBatches;
|
||||
};
|
||||
|
||||
SkTArray<Op> fOps;
|
||||
@ -41,11 +56,13 @@ private:
|
||||
invoke(__VA_ARGS__); \
|
||||
}
|
||||
|
||||
|
||||
#define GR_AUDIT_TRAIL_ADDOP(audit_trail, opname) \
|
||||
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail->addOp, opname);
|
||||
|
||||
#define GR_AUDIT_TRAIL_RESET(audit_trail) \
|
||||
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, SkString(batchname), bounds);
|
||||
|
||||
#endif
|
||||
|
@ -7,26 +7,116 @@
|
||||
|
||||
#include "GrAuditTrail.h"
|
||||
|
||||
SkString GrAuditTrail::toJson() const {
|
||||
SkString json;
|
||||
json.append("{\n");
|
||||
json.append("\"Ops\": [\n");
|
||||
for (int i = 0; i < fOps.count(); i++) {
|
||||
json.append(fOps[i].toJson());
|
||||
if (i < fOps.count() - 1) {
|
||||
json.append(",\n");
|
||||
template <class T>
|
||||
static void jsonify_tarray(SkString* json, const SkTArray<T>& array) {
|
||||
for (int i = 0; i < array.count(); i++) {
|
||||
json->append(array[i].toJson());
|
||||
if (i < array.count() - 1) {
|
||||
json->append(",");
|
||||
}
|
||||
}
|
||||
json.append("]\n");
|
||||
json.append("}\n");
|
||||
return json;
|
||||
}
|
||||
|
||||
// This will pretty print a very small subset of json
|
||||
// The parsing rules are straightforward, aside from the fact that we do not want an extra newline
|
||||
// before ',' and after '}', so we have a comma exception rule.
|
||||
class PrettyPrintJson {
|
||||
public:
|
||||
SkString prettify(const SkString& json) {
|
||||
fPrettyJson.reset();
|
||||
fTabCount = 0;
|
||||
fFreshLine = false;
|
||||
fCommaException = false;
|
||||
for (size_t i = 0; i < json.size(); i++) {
|
||||
if ('[' == json[i] || '{' == json[i]) {
|
||||
this->newline();
|
||||
this->appendChar(json[i]);
|
||||
fTabCount++;
|
||||
this->newline();
|
||||
} else if (']' == json[i] || '}' == json[i]) {
|
||||
fTabCount--;
|
||||
this->newline();
|
||||
this->appendChar(json[i]);
|
||||
fCommaException = true;
|
||||
} else if (',' == json[i]) {
|
||||
this->appendChar(json[i]);
|
||||
this->newline();
|
||||
} else {
|
||||
this->appendChar(json[i]);
|
||||
}
|
||||
}
|
||||
return fPrettyJson;
|
||||
}
|
||||
private:
|
||||
void appendChar(char appendee) {
|
||||
if (fCommaException && ',' != appendee) {
|
||||
this->newline();
|
||||
}
|
||||
this->tab();
|
||||
fPrettyJson += appendee;
|
||||
fFreshLine = false;
|
||||
fCommaException = false;
|
||||
}
|
||||
|
||||
void tab() {
|
||||
if (fFreshLine) {
|
||||
for (int i = 0; i < fTabCount; i++) {
|
||||
fPrettyJson += '\t';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void newline() {
|
||||
if (!fFreshLine) {
|
||||
fFreshLine = true;
|
||||
fPrettyJson += '\n';
|
||||
}
|
||||
}
|
||||
|
||||
SkString fPrettyJson;
|
||||
int fTabCount;
|
||||
bool fFreshLine;
|
||||
bool fCommaException;
|
||||
};
|
||||
|
||||
static SkString pretty_print_json(SkString json) {
|
||||
class PrettyPrintJson prettyPrintJson;
|
||||
return prettyPrintJson.prettify(json);
|
||||
}
|
||||
|
||||
SkString GrAuditTrail::toJson() const {
|
||||
SkString json;
|
||||
json.append("{");
|
||||
json.append("\"Ops\": [");
|
||||
jsonify_tarray(&json, fOps);
|
||||
json.append("]");
|
||||
json.append("}");
|
||||
|
||||
// TODO if this becomes a performance issue we should make pretty print configurable
|
||||
return pretty_print_json(json);
|
||||
}
|
||||
|
||||
SkString GrAuditTrail::Op::toJson() const {
|
||||
SkString json;
|
||||
json.append("{\n");
|
||||
json.appendf("\"Name\": \"%s\"\n", fName.c_str());
|
||||
json.append("}\n");
|
||||
json.append("{");
|
||||
json.appendf("\"Name\": \"%s\",", fName.c_str());
|
||||
json.append("\"Batches\": [");
|
||||
jsonify_tarray(&json, fBatches);
|
||||
json.append("]");
|
||||
json.append("}");
|
||||
return json;
|
||||
}
|
||||
|
||||
SkString GrAuditTrail::Op::Batch::toJson() const {
|
||||
SkString json;
|
||||
json.append("{");
|
||||
json.appendf("\"Name\": \"%s\",", fName.c_str());
|
||||
json.append("\"Bounds\": {");
|
||||
json.appendf("\"Left\": %f,", fBounds.fLeft);
|
||||
json.appendf("\"Right\": %f,", fBounds.fRight);
|
||||
json.appendf("\"Top\": %f,", fBounds.fTop);
|
||||
json.appendf("\"Bottom\": %f", fBounds.fBottom);
|
||||
json.append("}");
|
||||
json.append("}");
|
||||
return json;
|
||||
}
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "GrDrawTarget.h"
|
||||
|
||||
#include "GrAuditTrail.h"
|
||||
#include "GrCaps.h"
|
||||
#include "GrGpu.h"
|
||||
#include "GrPath.h"
|
||||
@ -20,6 +21,8 @@
|
||||
#include "GrTexture.h"
|
||||
#include "GrVertexBuffer.h"
|
||||
|
||||
#include "SkStrokeRec.h"
|
||||
|
||||
#include "batches/GrClearBatch.h"
|
||||
#include "batches/GrCopySurfaceBatch.h"
|
||||
#include "batches/GrDiscardBatch.h"
|
||||
@ -28,17 +31,16 @@
|
||||
#include "batches/GrRectBatchFactory.h"
|
||||
#include "batches/GrStencilPathBatch.h"
|
||||
|
||||
#include "SkStrokeRec.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Experimentally we have found that most batching occurs within the first 10 comparisons.
|
||||
static const int kDefaultMaxBatchLookback = 10;
|
||||
|
||||
GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* resourceProvider,
|
||||
const Options& options)
|
||||
GrAuditTrail* auditTrail, const Options& options)
|
||||
: fGpu(SkRef(gpu))
|
||||
, fResourceProvider(resourceProvider)
|
||||
, fAuditTrail(auditTrail)
|
||||
, fFlags(0)
|
||||
, fRenderTarget(rt) {
|
||||
// TODO: Stop extracting the context (currently needed by GrClipMaskManager)
|
||||
@ -466,7 +468,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());
|
||||
GrBATCH_INFO("Re-Recording (%s, B%u)\n"
|
||||
"\tBounds LRTB (%f, %f, %f, %f)\n",
|
||||
batch->name(),
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
//#define ENABLE_MDB 1
|
||||
|
||||
class GrAuditTrail;
|
||||
class GrBatch;
|
||||
class GrClip;
|
||||
class GrCaps;
|
||||
@ -50,7 +51,7 @@ public:
|
||||
int fMaxBatchLookback;
|
||||
};
|
||||
|
||||
GrDrawTarget(GrRenderTarget*, GrGpu*, GrResourceProvider*, const Options&);
|
||||
GrDrawTarget(GrRenderTarget*, GrGpu*, GrResourceProvider*, GrAuditTrail*, const Options&);
|
||||
|
||||
~GrDrawTarget() override;
|
||||
|
||||
@ -288,6 +289,7 @@ private:
|
||||
GrContext* fContext;
|
||||
GrGpu* fGpu;
|
||||
GrResourceProvider* fResourceProvider;
|
||||
GrAuditTrail* fAuditTrail;
|
||||
|
||||
SkDEBUGCODE(int fDebugID;)
|
||||
uint32_t fFlags;
|
||||
|
@ -114,6 +114,13 @@ void GrDrawingManager::flush() {
|
||||
fDrawTargets.reset();
|
||||
#endif
|
||||
|
||||
// Clear batch debugging output
|
||||
if (GR_BATCH_DEBUGGING_OUTPUT) {
|
||||
SkDebugf("%s\n", fContext->getAuditTrail()->toJson().c_str());
|
||||
// TODO This currently crashes because not all ops are accounted for
|
||||
//GR_AUDIT_TRAIL_RESET(fContext->getAuditTrail());
|
||||
}
|
||||
|
||||
fFlushState.reset();
|
||||
fFlushing = false;
|
||||
}
|
||||
@ -162,7 +169,7 @@ GrDrawTarget* GrDrawingManager::newDrawTarget(GrRenderTarget* rt) {
|
||||
#endif
|
||||
|
||||
GrDrawTarget* dt = new GrDrawTarget(rt, fContext->getGpu(), fContext->resourceProvider(),
|
||||
fOptionsForDrawTargets);
|
||||
fContext->getAuditTrail(), fOptionsForDrawTargets);
|
||||
|
||||
*fDrawTargets.append() = dt;
|
||||
|
||||
|
@ -411,6 +411,7 @@ static bool needs_antialiasing(SkCanvas::PointMode mode, size_t count, const SkP
|
||||
void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
|
||||
size_t count, const SkPoint pts[], const SkPaint& paint) {
|
||||
ASSERT_SINGLE_OWNER
|
||||
GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPoints", fContext);
|
||||
CHECK_FOR_ANNOTATION(paint);
|
||||
CHECK_SHOULD_DRAW(draw);
|
||||
|
||||
@ -1784,12 +1785,6 @@ void SkGpuDevice::flush() {
|
||||
ASSERT_SINGLE_OWNER
|
||||
DO_DEFERRED_CLEAR();
|
||||
fRenderTarget->prepareForExternalIO();
|
||||
|
||||
// Clear batch debugging output
|
||||
if (GR_BATCH_DEBUGGING_OUTPUT) {
|
||||
SkDebugf("%s\n", fContext->getAuditTrail()->toJson().c_str());
|
||||
GR_AUDIT_TRAIL_RESET(fContext->getAuditTrail());
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user