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
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 5e1bd36..5ca714a 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -1211,15 +1211,7 @@
     // 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 7eb3422..560c1a7 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -1839,7 +1839,9 @@
                                    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 @@
         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 eb4072d..162776e 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -465,7 +465,7 @@
                 // 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 528f850..408f2db 100644
--- a/src/gpu/SkGpuDevice.cpp
+++ b/src/gpu/SkGpuDevice.cpp
@@ -886,71 +886,66 @@
     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));
+    {
+        GrContext::AutoRenderTarget art(context, pathTexture->asRenderTarget());
+        GrContext::AutoClip ac(context, srcRect);
 
-    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->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;
         }
-        context->drawRect(paint, srcRect);
+        // 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->setRenderTarget(oldRenderTarget);
-    context->setClip(oldClipData);
 
     if (!grp->preConcatSamplerMatricesWithInverse(matrix)) {
         return false;