| Index: src/gpu/GrDrawTarget.cpp
|
| diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
|
| index fc8c71b443cfdcef3b558cacbf776e85b9d0c140..cf3baa1a121bf8bce6d65496c18e769965ed470b 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: <combined forward>\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,
|
|
|