From aecc018f86d911198b7c7775cee04f61bd10b430 Mon Sep 17 00:00:00 2001 From: bsalomon Date: Mon, 7 Mar 2016 11:50:44 -0800 Subject: [PATCH] Attempt to combine batches in forward direction before flush GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1763883005 Review URL: https://codereview.chromium.org/1763883005 --- dm/DMSrcSink.cpp | 3 ++ include/gpu/GrContextOptions.h | 5 ++- src/gpu/GrContext.cpp | 1 + src/gpu/GrDrawTarget.cpp | 64 +++++++++++++++++++++++++++++++--- src/gpu/GrDrawTarget.h | 16 +++++---- 5 files changed, 77 insertions(+), 12 deletions(-) diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp index 2d2a455e7b..ead02c251e 100644 --- a/dm/DMSrcSink.cpp +++ b/dm/DMSrcSink.cpp @@ -869,6 +869,8 @@ DEFINE_bool(imm, false, "Run gpu configs in immediate mode."); DEFINE_bool(batchClip, false, "Clip each GrBatch to its device bounds for testing."); DEFINE_bool(batchBounds, false, "Draw a wireframe bounds of each GrBatch."); DEFINE_int32(batchLookback, -1, "Maximum GrBatch lookback for combining, negative means default."); +DEFINE_int32(batchLookahead, -1, "Maximum GrBatch lookahead for combining, negative means " + "default."); Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) const { GrContextOptions grOptions; @@ -876,6 +878,7 @@ Error GPUSink::draw(const Src& src, SkBitmap* dst, SkWStream*, SkString* log) co grOptions.fClipBatchToBounds = FLAGS_batchClip; grOptions.fDrawBatchBounds = FLAGS_batchBounds; grOptions.fMaxBatchLookback = FLAGS_batchLookback; + grOptions.fMaxBatchLookahead = FLAGS_batchLookahead; src.modifyGrContextOptions(&grOptions); diff --git a/include/gpu/GrContextOptions.h b/include/gpu/GrContextOptions.h index 8e6368a389..d7070db555 100644 --- a/include/gpu/GrContextOptions.h +++ b/include/gpu/GrContextOptions.h @@ -23,6 +23,7 @@ struct GrContextOptions { , fClipBatchToBounds(false) , fDrawBatchBounds(false) , fMaxBatchLookback(-1) + , fMaxBatchLookahead(-1) , fUseShaderSwizzling(false) {} // EXPERIMENTAL @@ -64,8 +65,10 @@ struct GrContextOptions { of their dev bounds. */ bool fDrawBatchBounds; - /** For debugging, override the default maximum look-back window for GrBatch combining. */ + /** For debugging, override the default maximum look-back or look-ahead window for GrBatch + combining. */ int fMaxBatchLookback; + int fMaxBatchLookahead; /** Force us to do all swizzling manually in the shader and don't rely on extensions to do swizzling. */ diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 8844f1ac83..a16d5c009a 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -95,6 +95,7 @@ void GrContext::initCommon(const GrContextOptions& options) { dtOptions.fClipBatchToBounds = options.fClipBatchToBounds; dtOptions.fDrawBatchBounds = options.fDrawBatchBounds; dtOptions.fMaxBatchLookback = options.fMaxBatchLookback; + dtOptions.fMaxBatchLookahead = options.fMaxBatchLookahead; fDrawingManager.reset(new GrDrawingManager(this, dtOptions, &fSingleOwner)); // GrBatchFontCache will eventually replace GrFontCache diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index fc8c71b443..cf3baa1a12 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -35,7 +35,8 @@ //////////////////////////////////////////////////////////////////////////////// // Experimentally we have found that most batching occurs within the first 10 comparisons. -static const int kDefaultMaxBatchLookback = 10; +static const int kDefaultMaxBatchLookback = 10; +static const int kDefaultMaxBatchLookahead = 10; GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* resourceProvider, GrAuditTrail* auditTrail, const Options& options) @@ -51,6 +52,8 @@ GrDrawTarget::GrDrawTarget(GrRenderTarget* rt, GrGpu* gpu, GrResourceProvider* r fDrawBatchBounds = options.fDrawBatchBounds; fMaxBatchLookback = (options.fMaxBatchLookback < 0) ? kDefaultMaxBatchLookback : options.fMaxBatchLookback; + fMaxBatchLookahead = (options.fMaxBatchLookahead < 0) ? kDefaultMaxBatchLookahead : + options.fMaxBatchLookahead; rt->setLastDrawTarget(this); @@ -113,11 +116,15 @@ void GrDrawTarget::dump() const { #if 0 SkDebugf("*******************************\n"); #endif - SkDebugf("%d: %s\n", i, fBatches[i]->name()); + if (fBatches[i]) { + SkDebugf("%d: \n", i); + } else { + SkDebugf("%d: %s\n", i, fBatches[i]->name()); #if 0 - SkString str = fBatches[i]->dumpInfo(); - SkDebugf("%s\n", str.c_str()); + SkString str = fBatches[i]->dumpInfo(); + SkDebugf("%s\n", str.c_str()); #endif + } } } #endif @@ -193,7 +200,9 @@ void GrDrawTarget::prepareBatches(GrBatchFlushState* flushState) { // Loop over the batches that haven't yet generated their geometry for (int i = 0; i < fBatches.count(); ++i) { - fBatches[i]->prepare(flushState); + if (fBatches[i]) { + fBatches[i]->prepare(flushState); + } } } @@ -201,6 +210,9 @@ void GrDrawTarget::drawBatches(GrBatchFlushState* flushState) { // Draw all the generated geometry. SkRandom random; for (int i = 0; i < fBatches.count(); ++i) { + if (!fBatches[i]) { + continue; + } if (fDrawBatchBounds) { const SkRect& bounds = fBatches[i]->bounds(); SkIRect ibounds; @@ -496,6 +508,48 @@ void GrDrawTarget::recordBatch(GrBatch* batch) { fBatches.push_back().reset(SkRef(batch)); } +void GrDrawTarget::forwardCombine() { + for (int i = 0; i < fBatches.count() - 2; ++i) { + GrBatch* batch = fBatches[i]; + int maxCandidateIdx = SkTMin(i + fMaxBatchLookahead, fBatches.count() - 1); + int j = i + 1; + while (true) { + GrBatch* candidate = fBatches[j]; + // We cannot continue to search if the render target changes + if (candidate->renderTargetUniqueID() != batch->renderTargetUniqueID()) { + GrBATCH_INFO("\t\tBreaking because of (%s, B%u) Rendertarget\n", + candidate->name(), candidate->uniqueID()); + break; + } + if (j == i +1) { + // We assume batch would have combined with candidate when the candidate was added + // via backwards combining in recordBatch. + SkASSERT(!batch->combineIfPossible(candidate, *this->caps())); + } 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); + fBatches[j].reset(SkRef(batch)); + fBatches[i].reset(nullptr); + break; + } + // Stop going traversing if we would cause a painter's order violation. + // TODO: The bounds used here do not fully consider the clip. It may be advantageous + // to clip each batch's bounds to the clip. + if (intersect(candidate->bounds(), batch->bounds())) { + GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(), + candidate->uniqueID()); + break; + } + ++j; + if (j > maxCandidateIdx) { + GrBATCH_INFO("\t\tReached max lookahead or end of batch array %d\n", i); + break; + } + } + } +} + /////////////////////////////////////////////////////////////////////////////// bool GrDrawTarget::installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder, diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h index 8b30ab9b60..9a6dbc9e71 100644 --- a/src/gpu/GrDrawTarget.h +++ b/src/gpu/GrDrawTarget.h @@ -45,10 +45,15 @@ class GrDrawTarget final : public SkRefCnt { public: /** Options for GrDrawTarget behavior. */ struct Options { - Options () : fClipBatchToBounds(false), fDrawBatchBounds(false), fMaxBatchLookback(-1) {} + Options () + : fClipBatchToBounds(false) + , fDrawBatchBounds(false) + , fMaxBatchLookback(-1) + , fMaxBatchLookahead(-1) {} bool fClipBatchToBounds; bool fDrawBatchBounds; int fMaxBatchLookback; + int fMaxBatchLookahead; }; GrDrawTarget(GrRenderTarget*, GrGpu*, GrResourceProvider*, GrAuditTrail*, const Options&); @@ -61,7 +66,9 @@ public: #ifdef ENABLE_MDB this->setFlag(kClosed_Flag); #endif + this->forwardCombine(); } + bool isClosed() const { return this->isSetFlag(kClosed_Flag); } // TODO: this entry point is only needed in the non-MDB world. Remove when @@ -216,6 +223,7 @@ private: }; void recordBatch(GrBatch*); + void forwardCombine(); bool installPipelineInDrawBatch(const GrPipelineBuilder* pipelineBuilder, const GrScissorState* scissor, GrDrawBatch* batch); @@ -232,11 +240,6 @@ private: void getPathStencilSettingsForFilltype(GrPathRendering::FillType, const GrStencilAttachment*, GrStencilSettings*); - bool setupClip(const GrPipelineBuilder&, - GrPipelineBuilder::AutoRestoreFragmentProcessorState*, - GrPipelineBuilder::AutoRestoreStencil*, - GrScissorState*, - const SkRect* devBounds); void addDependency(GrDrawTarget* dependedOn); @@ -260,6 +263,7 @@ private: bool fDrawBatchBounds; int fMaxBatchLookback; + int fMaxBatchLookahead; typedef SkRefCnt INHERITED; };