| Index: src/gpu/GrDrawTarget.cpp
|
| diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
|
| index b4cd5a3675a75e62c3d81e07fe1d3a7f7a01caa5..b89d70ea2be724e2a8fb5bff5e1f6364efd5f31d 100644
|
| --- a/src/gpu/GrDrawTarget.cpp
|
| +++ b/src/gpu/GrDrawTarget.cpp
|
| @@ -384,15 +384,15 @@
|
| return true;
|
| }
|
|
|
| -bool GrDrawTarget::setupDstReadIfNecessary(const GrPipelineBuilder& pipelineBuilder,
|
| +bool GrDrawTarget::setupDstReadIfNecessary(GrPipelineBuilder* pipelineBuilder,
|
| GrDeviceCoordTexture* dstCopy,
|
| const SkRect* drawBounds) {
|
| - if (!pipelineBuilder.willXPNeedDstCopy(*this->caps())) {
|
| + if (this->caps()->dstReadInShaderSupport() || !pipelineBuilder->willEffectReadDstColor()) {
|
| return true;
|
| }
|
| SkIRect copyRect;
|
| const GrClipData* clip = this->getClip();
|
| - GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
|
| + GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
|
| clip->getConservativeBounds(rt, ©Rect);
|
|
|
| if (drawBounds) {
|
| @@ -416,9 +416,6 @@
|
| this->initCopySurfaceDstDesc(rt, &desc);
|
| desc.fWidth = copyRect.width();
|
| desc.fHeight = copyRect.height();
|
| - // Only xfer processors can use dst copies, and the contract with the XP is that we always
|
| - // supply a copy texture with origin in the top left.
|
| - desc.fOrigin = kTopLeft_GrSurfaceOrigin;
|
|
|
| SkAutoTUnref<GrTexture> copy(
|
| fContext->refScratchTexture(desc, GrContext::kApprox_ScratchTexMatch));
|
| @@ -473,9 +470,14 @@
|
| info.setDevBounds(*devBounds);
|
| }
|
|
|
| + // TODO: We should continue with incorrect blending.
|
| + GrDeviceCoordTexture dstCopy;
|
| + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) {
|
| + return;
|
| + }
|
| this->setDrawBuffers(&info, gp->getVertexStride());
|
|
|
| - this->onDraw(*pipelineBuilder, gp, info, scissorState);
|
| + this->onDraw(*pipelineBuilder, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
|
| }
|
| }
|
|
|
| @@ -512,9 +514,15 @@
|
| info.setDevBounds(*devBounds);
|
| }
|
|
|
| + // TODO: We should continue with incorrect blending.
|
| + GrDeviceCoordTexture dstCopy;
|
| + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) {
|
| + return;
|
| + }
|
| +
|
| this->setDrawBuffers(&info, gp->getVertexStride());
|
|
|
| - this->onDraw(*pipelineBuilder, gp, info, scissorState);
|
| + this->onDraw(*pipelineBuilder, gp, info, scissorState, dstCopy.texture() ? &dstCopy : NULL);
|
| }
|
| }
|
|
|
| @@ -533,7 +541,12 @@
|
| return;
|
| }
|
|
|
| - this->onDrawBatch(batch, *pipelineBuilder, scissorState, devBounds);
|
| + GrDeviceCoordTexture dstCopy;
|
| + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) {
|
| + return;
|
| + }
|
| +
|
| + this->onDrawBatch(batch, *pipelineBuilder, scissorState, dstCopy.texture() ? &dstCopy : NULL);
|
| }
|
|
|
| static const GrStencilSettings& winding_path_stencil_settings() {
|
| @@ -623,8 +636,13 @@
|
| pipelineBuilder->getRenderTarget()->getStencilBuffer(),
|
| &stencilSettings);
|
|
|
| + GrDeviceCoordTexture dstCopy;
|
| + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, &devBounds)) {
|
| + return;
|
| + }
|
| +
|
| this->onDrawPath(*pipelineBuilder, pathProc, path, scissorState, stencilSettings,
|
| - &devBounds);
|
| + dstCopy.texture() ? &dstCopy : NULL);
|
| }
|
|
|
| void GrDrawTarget::drawPaths(GrPipelineBuilder* pipelineBuilder,
|
| @@ -658,12 +676,18 @@
|
| pipelineBuilder->getRenderTarget()->getStencilBuffer(),
|
| &stencilSettings);
|
|
|
| - // Don't compute a bounding box for dst copy texture, we'll opt
|
| + // Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt
|
| // instead for it to just copy the entire dst. Realistically this is a moot
|
| // point, because any context that supports NV_path_rendering will also
|
| // support NV_blend_equation_advanced.
|
| + GrDeviceCoordTexture dstCopy;
|
| + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, NULL)) {
|
| + return;
|
| + }
|
| +
|
| this->onDrawPaths(*pipelineBuilder, pathProc, pathRange, indices, indexType, transformValues,
|
| - transformType, count, scissorState, stencilSettings, NULL);
|
| + transformType, count, scissorState, stencilSettings,
|
| + dstCopy.texture() ? &dstCopy : NULL);
|
| }
|
|
|
| void GrDrawTarget::clear(const SkIRect* rect,
|
| @@ -769,6 +793,12 @@
|
| info.setDevBounds(*devBounds);
|
| }
|
|
|
| + // TODO: We should continue with incorrect blending.
|
| + GrDeviceCoordTexture dstCopy;
|
| + if (!this->setupDstReadIfNecessary(pipelineBuilder, &dstCopy, devBounds)) {
|
| + return;
|
| + }
|
| +
|
| while (instanceCount) {
|
| info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw);
|
| info.fVertexCount = info.fInstanceCount * verticesPerInstance;
|
| @@ -782,7 +812,8 @@
|
| info.fVertexCount,
|
| info.fIndexCount)) {
|
| this->setDrawBuffers(&info, gp->getVertexStride());
|
| - this->onDraw(*pipelineBuilder, gp, info, scissorState);
|
| + this->onDraw(*pipelineBuilder, gp, info, scissorState,
|
| + dstCopy.texture() ? &dstCopy : NULL);
|
| }
|
| info.fStartVertex += info.fVertexCount;
|
| instanceCount -= info.fInstanceCount;
|
|
|