aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-01 18:25:13 +0000
committerGravatar robertphillips@google.com <robertphillips@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-10-01 18:25:13 +0000
commitccb39504096db647dafdb254cae59ae172969b8e (patch)
tree376bd2f514586a2edd45f7515d5aa94ed3dc73c6
parent7ec0015ec307151418bad8426cb5434823a38dfd (diff)
Speculative render target ref/unref fixes
-rw-r--r--include/gpu/GrContext.h14
-rw-r--r--src/gpu/GrClipMaskManager.cpp8
-rw-r--r--src/gpu/GrContext.cpp5
-rw-r--r--src/gpu/GrDefaultPathRenderer.cpp2
-rw-r--r--src/gpu/SkGpuDevice.cpp115
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;