diff options
author | 2012-10-01 18:25:13 +0000 | |
---|---|---|
committer | 2012-10-01 18:25:13 +0000 | |
commit | ccb39504096db647dafdb254cae59ae172969b8e (patch) | |
tree | 376bd2f514586a2edd45f7515d5aa94ed3dc73c6 | |
parent | 7ec0015ec307151418bad8426cb5434823a38dfd (diff) |
Speculative render target ref/unref fixes
https://codereview.appspot.com/6592051/
git-svn-id: http://skia.googlecode.com/svn/trunk@5754 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | include/gpu/GrContext.h | 14 | ||||
-rw-r--r-- | src/gpu/GrClipMaskManager.cpp | 8 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 5 | ||||
-rw-r--r-- | src/gpu/GrDefaultPathRenderer.cpp | 2 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 115 |
5 files changed, 68 insertions, 76 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 3c38fad9e2..16eab6668e 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -640,21 +640,24 @@ public: /////////////////////////////////////////////////////////////////////////// // Helpers - class AutoRenderTarget : ::GrNoncopyable { + class AutoRenderTarget : public ::GrNoncopyable { public: AutoRenderTarget(GrContext* context, GrRenderTarget* target) { fPrevTarget = context->getRenderTarget(); + GrSafeRef(fPrevTarget); context->setRenderTarget(target); fContext = context; } AutoRenderTarget(GrContext* context) { fPrevTarget = context->getRenderTarget(); + GrSafeRef(fPrevTarget); fContext = context; } ~AutoRenderTarget() { - if (fContext) { + if (NULL != fContext) { fContext->setRenderTarget(fPrevTarget); } + GrSafeUnref(fPrevTarget); } private: GrContext* fContext; @@ -728,12 +731,13 @@ public: kWideOpen_InitialClip, }; - AutoClip(GrContext* context, InitialClip initialState) { + AutoClip(GrContext* context, InitialClip initialState) + : fContext(context) { GrAssert(kWideOpen_InitialClip == initialState); - fOldClip = context->getClip(); fNewClipData.fClipStack = &fNewClipStack; + + fOldClip = context->getClip(); context->setClip(&fNewClipData); - fContext = context; } AutoClip(GrContext* context, const GrRect& newClipRect) diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 5e1bd362b7..5ca714a577 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -1211,15 +1211,7 @@ bool GrClipMaskManager::createSoftwareClipMask(const GrClipData& clipDataIn, // Because we are using the scratch texture cache, "accum" may be // larger than expected and have some cruft in the areas we aren't using. // Clear it out. - - // TODO: need a simpler way to clear the texture - can we combine - // the clear and the writePixels (inside toTexture) - GrDrawState* drawState = fGpu->drawState(); - GrAssert(NULL != drawState); - GrRenderTarget* temp = drawState->getRenderTarget(); fGpu->clear(NULL, 0x00000000, accum->asRenderTarget()); - // can't leave the accum bound as a rendertarget - drawState->setRenderTarget(temp); helper.toTexture(accum, clearToInside ? 0xFF : 0x00); diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 7eb3422d2c..560c1a7e1a 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -1839,7 +1839,9 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, const SkRect& rect, float sigmaX, float sigmaY) { ASSERT_OWNED_RESOURCE(srcTexture); - GrRenderTarget* oldRenderTarget = this->getRenderTarget(); + + AutoRenderTarget art(this); + AutoMatrix avm(this, GrMatrix::I()); SkIRect clearRect; int scaleFactorX, radiusX; @@ -1946,7 +1948,6 @@ GrTexture* GrContext::gaussianBlur(GrTexture* srcTexture, srcTexture = dstTexture; SkTSwap(dstTexture, tempTexture); } - this->setRenderTarget(oldRenderTarget); if (srcTexture == temp1.texture()) { return temp1.detach(); } else if (srcTexture == temp2.texture()) { diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp index eb4072d5fc..162776edd8 100644 --- a/src/gpu/GrDefaultPathRenderer.cpp +++ b/src/gpu/GrDefaultPathRenderer.cpp @@ -465,7 +465,7 @@ bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path, // draw over the whole world. bounds.setLTRB(0, 0, GrIntToScalar(drawState->getRenderTarget()->width()), - GrIntToScalar(drawState->getRenderTarget()->height())); + GrIntToScalar(drawState->8getRenderTarget()->height())); GrMatrix vmi; // mapRect through persp matrix may not be correct if (!drawState->getViewMatrix().hasPerspective() && diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index 528f8501db..408f2db861 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -886,71 +886,66 @@ bool drawWithGPUMaskFilter(GrContext* context, const SkPath& path, if (NULL == pathTexture) { return false; } - GrRenderTarget* oldRenderTarget = context->getRenderTarget(); - // Once this code moves into GrContext, this should be changed to use - // an AutoClipRestore. - const GrClipData* oldClipData = context->getClip(); - context->setRenderTarget(pathTexture->asRenderTarget()); - - SkClipStack newClipStack(srcRect); - GrClipData newClipData; - newClipData.fClipStack = &newClipStack; - context->setClip(&newClipData); - - context->clear(NULL, 0); - GrPaint tempPaint; - tempPaint.reset(); + SkAutoTUnref<GrTexture> blurTexture; GrContext::AutoMatrix avm(context, GrMatrix::I()); - tempPaint.fAntiAlias = grp->fAntiAlias; - if (tempPaint.fAntiAlias) { - // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst - // blend coeff of zero requires dual source blending support in order - // to properly blend partially covered pixels. This means the AA - // code path may not be taken. So we use a dst blend coeff of ISA. We - // could special case AA draws to a dst surface with known alpha=0 to - // use a zero dst coeff when dual source blending isn't available. - tempPaint.fSrcBlendCoeff = kOne_GrBlendCoeff; - tempPaint.fDstBlendCoeff = kISC_GrBlendCoeff; - } - // Draw hard shadow to pathTexture with path topleft at origin 0,0. - context->drawPath(tempPaint, path, pathFillType, &offset); - - // If we're doing a normal blur, we can clobber the pathTexture in the - // gaussianBlur. Otherwise, we need to save it for later compositing. - bool isNormalBlur = blurType == SkMaskFilter::kNormal_BlurType; - SkAutoTUnref<GrTexture> blurTexture(context->gaussianBlur( - pathTexture, isNormalBlur, srcRect, sigma, sigma)); - - if (!isNormalBlur) { - GrPaint paint; - paint.reset(); - paint.textureSampler(0)->matrix()->setIDiv(pathTexture->width(), - pathTexture->height()); - // Blend pathTexture over blurTexture. - context->setRenderTarget(blurTexture->asRenderTarget()); - paint.textureSampler(0)->setCustomStage(SkNEW_ARGS - (GrSingleTextureEffect, (pathTexture)))->unref(); - if (SkMaskFilter::kInner_BlurType == blurType) { - // inner: dst = dst * src - paint.fSrcBlendCoeff = kDC_GrBlendCoeff; - paint.fDstBlendCoeff = kZero_GrBlendCoeff; - } else if (SkMaskFilter::kSolid_BlurType == blurType) { - // solid: dst = src + dst - src * dst - // = (1 - dst) * src + 1 * dst - paint.fSrcBlendCoeff = kIDC_GrBlendCoeff; - paint.fDstBlendCoeff = kOne_GrBlendCoeff; - } else if (SkMaskFilter::kOuter_BlurType == blurType) { - // outer: dst = dst * (1 - src) - // = 0 * src + (1 - src) * dst - paint.fSrcBlendCoeff = kZero_GrBlendCoeff; - paint.fDstBlendCoeff = kISC_GrBlendCoeff; + + { + GrContext::AutoRenderTarget art(context, pathTexture->asRenderTarget()); + GrContext::AutoClip ac(context, srcRect); + + context->clear(NULL, 0); + GrPaint tempPaint; + tempPaint.reset(); + + tempPaint.fAntiAlias = grp->fAntiAlias; + if (tempPaint.fAntiAlias) { + // AA uses the "coverage" stages on GrDrawTarget. Coverage with a dst + // blend coeff of zero requires dual source blending support in order + // to properly blend partially covered pixels. This means the AA + // code path may not be taken. So we use a dst blend coeff of ISA. We + // could special case AA draws to a dst surface with known alpha=0 to + // use a zero dst coeff when dual source blending isn't available. + tempPaint.fSrcBlendCoeff = kOne_GrBlendCoeff; + tempPaint.fDstBlendCoeff = kISC_GrBlendCoeff; + } + // Draw hard shadow to pathTexture with path topleft at origin 0,0. + context->drawPath(tempPaint, path, pathFillType, &offset); + + // If we're doing a normal blur, we can clobber the pathTexture in the + // gaussianBlur. Otherwise, we need to save it for later compositing. + bool isNormalBlur = blurType == SkMaskFilter::kNormal_BlurType; + blurTexture.reset(context->gaussianBlur(pathTexture, isNormalBlur, + srcRect, sigma, sigma)); + + if (!isNormalBlur) { + GrPaint paint; + paint.reset(); + paint.textureSampler(0)->matrix()->setIDiv(pathTexture->width(), + pathTexture->height()); + // Blend pathTexture over blurTexture. + context->setRenderTarget(blurTexture->asRenderTarget()); + paint.textureSampler(0)->setCustomStage(SkNEW_ARGS + (GrSingleTextureEffect, (pathTexture)))->unref(); + if (SkMaskFilter::kInner_BlurType == blurType) { + // inner: dst = dst * src + paint.fSrcBlendCoeff = kDC_GrBlendCoeff; + paint.fDstBlendCoeff = kZero_GrBlendCoeff; + } else if (SkMaskFilter::kSolid_BlurType == blurType) { + // solid: dst = src + dst - src * dst + // = (1 - dst) * src + 1 * dst + paint.fSrcBlendCoeff = kIDC_GrBlendCoeff; + paint.fDstBlendCoeff = kOne_GrBlendCoeff; + } else if (SkMaskFilter::kOuter_BlurType == blurType) { + // outer: dst = dst * (1 - src) + // = 0 * src + (1 - src) * dst + paint.fSrcBlendCoeff = kZero_GrBlendCoeff; + paint.fDstBlendCoeff = kISC_GrBlendCoeff; + } + context->drawRect(paint, srcRect); } - context->drawRect(paint, srcRect); } - context->setRenderTarget(oldRenderTarget); - context->setClip(oldClipData); if (!grp->preConcatSamplerMatricesWithInverse(matrix)) { return false; |