aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/GrDrawTarget.cpp
diff options
context:
space:
mode:
authorGravatar bsalomon <bsalomon@google.com>2015-09-10 10:42:55 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2015-09-10 10:42:55 -0700
commit512be5340c2a29550053d35bc058d3aecd5c1fc7 (patch)
tree05969b66ede9cca1e593579369938f01785cbeb4 /src/gpu/GrDrawTarget.cpp
parent4a37d08382a16717cde52c3d2687b021c5413464 (diff)
Cleanup GrDrawTarget now that all paths lead to GrBatch
Diffstat (limited to 'src/gpu/GrDrawTarget.cpp')
-rw-r--r--src/gpu/GrDrawTarget.cpp94
1 files changed, 85 insertions, 9 deletions
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 0e7e6bce90..7eaa8bc762 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -36,7 +36,8 @@ GrDrawTarget::GrDrawTarget(GrGpu* gpu, GrResourceProvider* resourceProvider)
: fGpu(SkRef(gpu))
, fCaps(SkRef(gpu->caps()))
, fResourceProvider(resourceProvider)
- , fFlushing(false) {
+ , fFlushing(false)
+ , fLastFlushToken(0) {
}
GrDrawTarget::~GrDrawTarget() {
@@ -119,12 +120,31 @@ void GrDrawTarget::flush() {
}
fFlushing = true;
- this->onFlush();
+ GrBatchFlushState flushState(fGpu, fResourceProvider, fLastFlushToken);
+
+ // Loop over all batches and generate geometry
+ for (int i = 0; i < fBatches.count(); ++i) {
+ fBatches[i]->prepare(&flushState);
+ }
+
+ // Upload all data to the GPU
+ flushState.preIssueDraws();
+
+ // Draw all the generated geometry.
+ for (int i = 0; i < fBatches.count(); ++i) {
+ fBatches[i]->draw(&flushState);
+ }
+
+ fLastFlushToken = flushState.lastFlushedToken();
fFlushing = false;
this->reset();
}
+void GrDrawTarget::reset() {
+ fBatches.reset();
+}
+
void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBatch* batch) {
// Setup clip
GrScissorState scissorState;
@@ -148,7 +168,7 @@ void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawBat
if (!batch->installPipeline(pipelineInfo.pipelineCreateArgs())) {
return;
}
- this->onDrawBatch(batch);
+ this->recordBatch(batch);
}
static const GrStencilSettings& winding_path_stencil_settings() {
@@ -213,7 +233,7 @@ void GrDrawTarget::stencilPath(const GrPipelineBuilder& pipelineBuilder,
stencilSettings, scissorState,
pipelineBuilder.getRenderTarget(),
path);
- this->onDrawBatch(batch);
+ this->recordBatch(batch);
batch->unref();
}
@@ -269,7 +289,7 @@ void GrDrawTarget::drawPathBatch(const GrPipelineBuilder& pipelineBuilder,
return;
}
- this->onDrawBatch(batch);
+ this->recordBatch(batch);
}
void GrDrawTarget::drawNonAARect(const GrPipelineBuilder& pipelineBuilder,
@@ -344,7 +364,7 @@ void GrDrawTarget::clear(const SkIRect* rect,
this->drawNonAARect(pipelineBuilder, color, SkMatrix::I(), *rect);
} else {
GrBatch* batch = new GrClearBatch(*rect, color, renderTarget);
- this->onDrawBatch(batch);
+ this->recordBatch(batch);
batch->unref();
}
}
@@ -352,7 +372,7 @@ void GrDrawTarget::clear(const SkIRect* rect,
void GrDrawTarget::discard(GrRenderTarget* renderTarget) {
if (this->caps()->discardRenderTargetSupport()) {
GrBatch* batch = new GrDiscardBatch(renderTarget);
- this->onDrawBatch(batch);
+ this->recordBatch(batch);
batch->unref();
}
}
@@ -365,11 +385,67 @@ void GrDrawTarget::copySurface(GrSurface* dst,
const SkIPoint& dstPoint) {
GrBatch* batch = GrCopySurfaceBatch::Create(dst, src, srcRect, dstPoint);
if (batch) {
- this->onDrawBatch(batch);
+ this->recordBatch(batch);
batch->unref();
}
}
+template <class Left, class Right> static bool intersect(const Left& a, const Right& b) {
+ SkASSERT(a.fLeft <= a.fRight && a.fTop <= a.fBottom &&
+ b.fLeft <= b.fRight && b.fTop <= b.fBottom);
+ return a.fLeft < b.fRight && b.fLeft < a.fRight && a.fTop < b.fBottom && b.fTop < a.fBottom;
+}
+
+void GrDrawTarget::recordBatch(GrBatch* batch) {
+ // Check if there is a Batch Draw we can batch with by linearly searching back until we either
+ // 1) check every draw
+ // 2) intersect with something
+ // 3) find a 'blocker'
+ // Experimentally we have found that most batching occurs within the first 10 comparisons.
+ static const int kMaxLookback = 10;
+
+ GrBATCH_INFO("Re-Recording (%s, B%u)\n"
+ "\tBounds (%f, %f, %f, %f)\n",
+ batch->name(),
+ batch->uniqueID(),
+ batch->bounds().fLeft, batch->bounds().fRight,
+ batch->bounds().fTop, batch->bounds().fBottom);
+ GrBATCH_INFO(SkTabString(batch->dumpInfo(), 1).c_str());
+ GrBATCH_INFO("\tOutcome:\n");
+ int maxCandidates = SkTMin(kMaxLookback, fBatches.count());
+ if (maxCandidates) {
+ int i = 0;
+ while (true) {
+ GrBatch* candidate = fBatches.fromBack(i);
+ // We cannot continue to search backwards 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 (candidate->combineIfPossible(batch, *this->caps())) {
+ GrBATCH_INFO("\t\tCombining with (%s, B%u)\n", candidate->name(),
+ candidate->uniqueID());
+ return;
+ }
+ // Stop going backwards if we would cause a painter's order violation.
+ if (intersect(candidate->bounds(), batch->bounds())) {
+ GrBATCH_INFO("\t\tIntersects with (%s, B%u)\n", candidate->name(),
+ candidate->uniqueID());
+ break;
+ }
+ ++i;
+ if (i == maxCandidates) {
+ GrBATCH_INFO("\t\tReached max lookback or beginning of batch array %d\n", i);
+ break;
+ }
+ }
+ } else {
+ GrBATCH_INFO("\t\tFirstBatch\n");
+ }
+ fBatches.push_back().reset(SkRef(batch));
+}
+
///////////////////////////////////////////////////////////////////////////////
GrDrawTarget::PipelineInfo::PipelineInfo(const GrPipelineBuilder* pipelineBuilder,
@@ -416,6 +492,6 @@ void GrClipTarget::purgeResources() {
void GrClipTarget::clearStencilClip(const SkIRect& rect, bool insideClip, GrRenderTarget* rt) {
GrBatch* batch = new GrClearStencilClipBatch(rect, insideClip, rt);
- this->onDrawBatch(batch);
+ this->recordBatch(batch);
batch->unref();
}