diff --git a/gyp/common_conditions.gypi b/gyp/common_conditions.gypi index 9af0c19b7f..85f3e20376 100644 --- a/gyp/common_conditions.gypi +++ b/gyp/common_conditions.gypi @@ -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': { diff --git a/include/gpu/GrConfig.h b/include/gpu/GrConfig.h index 202887ee5d..4b6fe48cdb 100644 --- a/include/gpu/GrConfig.h +++ b/include/gpu/GrConfig.h @@ -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. */ diff --git a/include/private/GrAuditTrail.h b/include/private/GrAuditTrail.h index 21236566b9..52a7c9031d 100644 --- a/include/private/GrAuditTrail.h +++ b/include/private/GrAuditTrail.h @@ -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 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 diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index df5c7a73a1..0b44a4281a 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -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(); } diff --git a/tools/debugger/SkDrawCommand.cpp b/tools/debugger/SkDrawCommand.cpp index b46e4925a3..5ca725088a 100644 --- a/tools/debugger/SkDrawCommand.cpp +++ b/tools/debugger/SkDrawCommand.cpp @@ -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