GrAuditTrail can now be enabled/disabled at runtime

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

TBR=bsalomon@google.com
Doesn't actually change the public API

Review URL: https://codereview.chromium.org/1712753002
This commit is contained in:
ethannicholas 2016-02-18 13:45:39 -08:00 committed by Commit bot
parent dd9ffea9ce
commit c85d9fbc0a
5 changed files with 42 additions and 35 deletions

View File

@ -674,12 +674,6 @@
},
}],
[ 'skia_build_server', {
'defines': [
'GR_BATCH_DEBUGGING_OUTPUT=1',
],
}],
], # end 'conditions'
# The Xcode SYMROOT must be at the root. See build/common.gypi in chromium for more details
'xcode_settings': {

View File

@ -185,15 +185,6 @@ typedef unsigned __int64 uint64_t;
#endif
#endif
/**
* Enable batch debugging output as json. The enabler of this flag is responsible for making sure
* GrAuditTrail is reset occasionally.
* TODO make this runtime configurable
*/
#if !defined(GR_BATCH_DEBUGGING_OUTPUT)
#define GR_BATCH_DEBUGGING_OUTPUT 0
#endif
/**
* Set to 1 to enable pixel local storage path rendering on supported devices.
*/

View File

@ -16,22 +16,29 @@
/*
* GrAuditTrail collects a list of draw ops, detailed information about those ops, and can dump them
* to json.
*
* Capturing this information is expensive and consumes a lot of memory, therefore it is important
* to enable auditing only when required and disable it promptly. The AutoEnable class helps to
* ensure that the audit trail is disabled in a timely fashion. Once the information has been dealt
* with, be sure to call reset(), or the log will simply keep growing.
*/
class GrAuditTrail {
public:
GrAuditTrail() : fUniqueID(0) {}
GrAuditTrail()
: fEnabled(false)
, fUniqueID(0) {}
class AutoFrame {
public:
AutoFrame(GrAuditTrail* auditTrail, const char* name)
: fAuditTrail(auditTrail) {
if (GR_BATCH_DEBUGGING_OUTPUT) {
if (fAuditTrail->fEnabled) {
fAuditTrail->pushFrame(name);
}
}
~AutoFrame() {
if (GR_BATCH_DEBUGGING_OUTPUT) {
if (fAuditTrail->fEnabled) {
fAuditTrail->popFrame();
}
}
@ -40,8 +47,25 @@ public:
GrAuditTrail* fAuditTrail;
};
class AutoEnable {
public:
AutoEnable(GrAuditTrail* auditTrail)
: fAuditTrail(auditTrail) {
SkASSERT(!fAuditTrail->isEnabled());
fAuditTrail->setEnabled(true);
}
~AutoEnable() {
SkASSERT(fAuditTrail->isEnabled());
fAuditTrail->setEnabled(false);
}
private:
GrAuditTrail* fAuditTrail;
};
void pushFrame(const char* name) {
SkASSERT(GR_BATCH_DEBUGGING_OUTPUT);
SkASSERT(fEnabled);
Frame* frame = new Frame;
if (fStack.empty()) {
fFrames.emplace_back(frame);
@ -55,12 +79,12 @@ public:
}
void popFrame() {
SkASSERT(GR_BATCH_DEBUGGING_OUTPUT);
SkASSERT(fEnabled);
fStack.pop_back();
}
void addBatch(const char* name, const SkRect& bounds) {
SkASSERT(GR_BATCH_DEBUGGING_OUTPUT && !fStack.empty());
SkASSERT(fEnabled && !fStack.empty());
Batch* batch = new Batch;
fStack.back()->fChildren.emplace_back(batch);
batch->fName = name;
@ -69,7 +93,10 @@ public:
SkString toJson(bool prettyPrint = false) const;
void reset() { SkASSERT(GR_BATCH_DEBUGGING_OUTPUT && fStack.empty()); fFrames.reset(); }
bool isEnabled() { return fEnabled; }
void setEnabled(bool enabled) { fEnabled = enabled; }
void reset() { SkASSERT(fEnabled && fStack.empty()); fFrames.reset(); }
private:
// TODO if performance becomes an issue, we can move to using SkVarAlloc
@ -95,23 +122,24 @@ private:
static void JsonifyTArray(SkString* json, const char* name, const FrameArray& array,
bool addComma);
bool fEnabled;
FrameArray fFrames;
SkTArray<Frame*> fStack;
uint64_t fUniqueID;
};
#define GR_AUDIT_TRAIL_INVOKE_GUARD(invoke, ...) \
if (GR_BATCH_DEBUGGING_OUTPUT) { \
invoke(__VA_ARGS__); \
#define GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, invoke, ...) \
if (audit_trail->isEnabled()) { \
audit_trail->invoke(__VA_ARGS__); \
}
#define GR_AUDIT_TRAIL_AUTO_FRAME(audit_trail, framename) \
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);
GR_AUDIT_TRAIL_INVOKE_GUARD(audit_trail, addBatch, batchname, bounds);
#endif

View File

@ -1761,13 +1761,6 @@ bool SkGpuDevice::onShouldDisableLCD(const SkPaint& paint) const {
void SkGpuDevice::flush() {
ASSERT_SINGLE_OWNER
// Clear batch debugging output
// TODO not exactly sure where this should live
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());
}
fRenderTarget->prepareForExternalIO();
}

View File

@ -236,8 +236,9 @@ Json::Value SkDrawCommand::drawToAndCollectJSON(SkCanvas* canvas,
if (rt) {
GrContext* ctx = rt->getContext();
if(ctx) {
this->execute(canvas);
GrAuditTrail* at = ctx->getAuditTrail();
GrAuditTrail::AutoEnable enable(at);
this->execute(canvas);
// TODO if this is inefficient we could add a method to GrAuditTrail which takes
// a Json::Value and is only compiled in this file