Speculative render target ref/unref fixes
authorrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 1 Oct 2012 18:25:13 +0000 (18:25 +0000)
committerrobertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>
Mon, 1 Oct 2012 18:25:13 +0000 (18:25 +0000)
https://codereview.appspot.com/6592051/

git-svn-id: http://skia.googlecode.com/svn/trunk@5754 2bbb7eff-a529-9590-31e7-b0007b416f81

include/gpu/GrContext.h
src/gpu/GrClipMaskManager.cpp
src/gpu/GrContext.cpp
src/gpu/GrDefaultPathRenderer.cpp
src/gpu/SkGpuDevice.cpp

index 3c38fad9e2340a9029ee3680dd3306972835c647..16eab6668e090feca2e1277fe82f0fa9b461f7b0 100644 (file)
@@ -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)
index 5e1bd362b7109a4fc77cfbff19bbbe5e73a44d63..5ca714a577a2351439739daae6722bd5a46c7369 100644 (file)
@@ -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);
 
index 7eb3422d2cb3c99b0a8be97ce8632fb683116d3e..560c1a7e1a8c420a23e4e1907a34cad47c28087b 100644 (file)
@@ -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()) {
index eb4072d5fc79ae5c32124d9ede56b1143e46979f..162776edd84a1dadb35648efbb052c9d5c94a62a 100644 (file)
@@ -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() &&
index 528f8501dbbeaed060321cb323bef08d55bc1677..408f2db861c8093f88dd3da2d4731cb52e42d735 100644 (file)
@@ -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;