Index: src/effects/SkGpuBlurUtils.cpp |
diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp |
index 2e6a7d6bde96f9b43d9b8032ec813c5c90b8af7d..040fcb0b548acb927603abee05604310dd985c4f 100644 |
--- a/src/effects/SkGpuBlurUtils.cpp |
+++ b/src/effects/SkGpuBlurUtils.cpp |
@@ -57,7 +57,7 @@ static void convolve_gaussian_1d(GrDrawContext* drawContext, |
float bounds[2]) { |
GrPaint paint; |
SkAutoTUnref<GrFragmentProcessor> conv(GrConvolutionEffect::CreateGaussian( |
- texture, direction, radius, sigma, useBounds, bounds)); |
+ texture, direction, radius, sigma, useBounds, bounds, drawContext->rt_remove_me())); |
paint.addColorFragmentProcessor(conv); |
SkMatrix localMatrix = SkMatrix::MakeTrans(srcOffset.x(), srcOffset.y()); |
drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, localMatrix); |
@@ -87,7 +87,7 @@ static void convolve_gaussian_2d(GrDrawContext* drawContext, |
SkAutoTUnref<GrFragmentProcessor> conv(GrMatrixConvolutionEffect::CreateGaussian( |
texture, bounds, size, 1.0, 0.0, kernelOffset, |
srcBounds ? GrTextureDomain::kDecal_Mode : GrTextureDomain::kIgnore_Mode, |
- true, sigmaX, sigmaY)); |
+ true, sigmaX, sigmaY, drawContext->rt_remove_me())); |
paint.addColorFragmentProcessor(conv); |
drawContext->fillRectWithLocalMatrix(clip, paint, SkMatrix::I(), dstRect, localMatrix); |
} |
@@ -168,6 +168,12 @@ GrTexture* GaussianBlur(GrContext* context, |
float sigmaY, |
GrTextureProvider::SizeConstraint constraint) { |
SkASSERT(context); |
+ |
+ SkAutoTUnref<GrDrawContext> srcDrawContext; |
+ if (srcTexture->asRenderTarget()) { |
+ srcDrawContext.reset(context->drawContext(srcTexture->asRenderTarget())); |
+ } |
+ |
SkIRect clearRect; |
int scaleFactorX, radiusX; |
int scaleFactorY, radiusY; |
@@ -205,24 +211,30 @@ GrTexture* GaussianBlur(GrContext* context, |
desc.fHeight = SkScalarFloorToInt(dstBounds.height()); |
desc.fConfig = srcTexture->config(); |
- GrTexture* dstTexture; |
- GrTexture* tempTexture; |
SkAutoTUnref<GrTexture> temp1, temp2; |
temp1.reset(context->textureProvider()->createTexture(desc, constraint)); |
- dstTexture = temp1.get(); |
+ GrTexture* dstTexture = temp1.get(); |
+ SkAutoTUnref<GrDrawContext> dstDrawContext(context->drawContext(dstTexture->asRenderTarget())); |
+ |
+ SkAutoTUnref<GrDrawContext> tmpDrawContext; |
+ GrTexture* tempTexture; |
if (canClobberSrc) { |
tempTexture = srcTexture; |
+ tmpDrawContext.reset(SkRef(srcDrawContext.get())); |
} else { |
temp2.reset(context->textureProvider()->createTexture(desc, constraint)); |
tempTexture = temp2.get(); |
+ tmpDrawContext.reset(context->drawContext(tempTexture->asRenderTarget())); |
} |
- if (nullptr == dstTexture || nullptr == tempTexture) { |
- return nullptr; |
+ if (srcTexture == tempTexture) { |
+ SkASSERT(srcDrawContext == tmpDrawContext); |
} |
- SkAutoTUnref<GrDrawContext> srcDrawContext; |
+ if (nullptr == dstTexture || nullptr == tempTexture || !dstDrawContext || !tmpDrawContext) { |
+ return nullptr; |
+ } |
for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) { |
GrPaint paint; |
@@ -239,29 +251,43 @@ GrTexture* GaussianBlur(GrContext* context, |
matrix, |
domain, |
GrTextureDomain::kDecal_Mode, |
- GrTextureParams::kBilerp_FilterMode)); |
+ GrTextureParams::kBilerp_FilterMode, |
+ kLocal_GrCoordSet, |
+ dstTexture->asRenderTarget())); |
paint.addColorFragmentProcessor(fp); |
srcRect.offset(-srcOffset); |
srcOffset.set(0, 0); |
} else { |
GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode); |
- paint.addColorTextureProcessor(srcTexture, matrix, params); |
+ paint.addColorTextureProcessor(srcTexture, matrix, params, dstTexture->asRenderTarget()); |
} |
scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f, |
i < scaleFactorY ? 0.5f : 1.0f); |
- SkAutoTUnref<GrDrawContext> dstDrawContext( |
- context->drawContext(dstTexture->asRenderTarget())); |
- if (!dstDrawContext) { |
- return nullptr; |
- } |
dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect); |
- srcDrawContext.swap(dstDrawContext); |
+ if (srcTexture == tempTexture) { |
+ // This guy was closed by the preceding draw since a dependant read |
+ // on him was created by the draw call - reopen him |
+ SkASSERT(srcDrawContext == tmpDrawContext); |
+ srcDrawContext.reset(context->drawContext(srcTexture->asRenderTarget())); |
+ tmpDrawContext.reset(SkRef(srcDrawContext.get())); |
+ } |
+ |
+ dstDrawContext.reset(context->drawContext(dstTexture->asRenderTarget())); |
+ |
+ srcDrawContext.reset(SkRef(dstDrawContext.get())); |
+ |
srcRect = dstRect; |
srcTexture = dstTexture; |
+ |
+ dstDrawContext.swap(tmpDrawContext); |
SkTSwap(dstTexture, tempTexture); |
localSrcBounds = srcRect; |
+ |
+ if (srcTexture == tempTexture) { |
+ SkASSERT(srcDrawContext == tmpDrawContext); |
+ } |
} |
// For really small blurs (certainly no wider than 5x5 on desktop gpus) it is faster to just |
@@ -271,19 +297,20 @@ GrTexture* GaussianBlur(GrContext* context, |
// We shouldn't be scaling because this is a small size blur |
SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY)); |
- SkAutoTUnref<GrDrawContext> dstDrawContext( |
- context->drawContext(dstTexture->asRenderTarget())); |
- if (!dstDrawContext) { |
- return nullptr; |
- } |
convolve_gaussian_2d(dstDrawContext, clip, srcRect, |
srcTexture, radiusX, radiusY, sigmaX, sigmaY, srcBounds); |
- srcDrawContext.swap(dstDrawContext); |
+ srcDrawContext.reset(SkRef(dstDrawContext.get())); |
+ |
srcRect.offsetTo(0, 0); |
srcTexture = dstTexture; |
+ |
+ dstDrawContext.swap(tmpDrawContext); |
SkTSwap(dstTexture, tempTexture); |
+ if (srcTexture == tempTexture) { |
+ SkASSERT(srcDrawContext == tmpDrawContext); |
+ } |
} else { |
srcRect = localDstBounds; |
scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); |
@@ -306,17 +333,25 @@ GrTexture* GaussianBlur(GrContext* context, |
srcDrawContext->clear(&clearRect, 0x0, false); |
} |
- SkAutoTUnref<GrDrawContext> dstDrawContext( |
- context->drawContext(dstTexture->asRenderTarget())); |
- if (!dstDrawContext) { |
- return nullptr; |
- } |
convolve_gaussian(dstDrawContext, clip, srcRect, |
srcTexture, Gr1DKernelEffect::kX_Direction, radiusX, sigmaX, |
srcBounds, srcOffset); |
- srcDrawContext.swap(dstDrawContext); |
+ if (srcTexture == tempTexture) { |
+ // This guy was closed by the preceding draw - reopen him |
+ SkASSERT(srcDrawContext == tmpDrawContext); |
+ srcDrawContext.reset(context->drawContext(srcTexture->asRenderTarget())); |
+ tmpDrawContext.reset(SkRef(srcDrawContext.get())); |
+ } |
+ |
+ dstDrawContext.reset(context->drawContext(dstTexture->asRenderTarget())); |
+ |
+ |
+ srcDrawContext.reset(SkRef(dstDrawContext.get())); |
+ |
srcTexture = dstTexture; |
srcRect.offsetTo(0, 0); |
+ |
+ dstDrawContext.swap(tmpDrawContext); |
SkTSwap(dstTexture, tempTexture); |
localSrcBounds = srcRect; |
srcOffset.set(0, 0); |
@@ -339,18 +374,27 @@ GrTexture* GaussianBlur(GrContext* context, |
srcDrawContext->clear(&clearRect, 0x0, false); |
} |
- SkAutoTUnref<GrDrawContext> dstDrawContext( |
- context->drawContext(dstTexture->asRenderTarget())); |
- if (!dstDrawContext) { |
- return nullptr; |
- } |
+// SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height()); |
+ |
convolve_gaussian(dstDrawContext, clip, srcRect, |
srcTexture, Gr1DKernelEffect::kY_Direction, radiusY, sigmaY, |
srcBounds, srcOffset); |
- srcDrawContext.swap(dstDrawContext); |
+ if (srcTexture == tempTexture) { |
+ // This guy was closed by the preceding draw - reopen him |
+ SkASSERT(srcDrawContext == tmpDrawContext); |
+ srcDrawContext.reset(context->drawContext(srcTexture->asRenderTarget())); |
+ tmpDrawContext.reset(SkRef(srcDrawContext.get())); |
+ } |
+ |
+ dstDrawContext.reset(context->drawContext(dstTexture->asRenderTarget())); |
+ |
+ srcDrawContext.reset(SkRef(dstDrawContext.get())); |
+ |
srcTexture = dstTexture; |
srcRect.offsetTo(0, 0); |
+ |
+ dstDrawContext.swap(tmpDrawContext); |
SkTSwap(dstTexture, tempTexture); |
} |
} |
@@ -373,22 +417,32 @@ GrTexture* GaussianBlur(GrContext* context, |
GrPaint paint; |
// FIXME: this should be mitchell, not bilinear. |
GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode); |
- paint.addColorTextureProcessor(srcTexture, matrix, params); |
+ paint.addColorTextureProcessor(srcTexture, matrix, params, dstTexture->asRenderTarget()); |
SkRect dstRect(srcRect); |
scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY); |
- SkAutoTUnref<GrDrawContext> dstDrawContext( |
- context->drawContext(dstTexture->asRenderTarget())); |
- if (!dstDrawContext) { |
- return nullptr; |
- } |
dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect); |
- srcDrawContext.swap(dstDrawContext); |
+ // Don't need to do this since we're exiting |
+ if (false && srcTexture == tempTexture) { |
+ // This guy was closed by the preceding draw - reopen him |
+ SkASSERT(srcDrawContext == tmpDrawContext); |
+ srcDrawContext.reset(context->drawContext(srcTexture->asRenderTarget())); |
+ tmpDrawContext.reset(SkRef(srcDrawContext.get())); |
+ } |
+ |
+ dstDrawContext.reset(context->drawContext(dstTexture->asRenderTarget())); |
+ |
+ srcDrawContext.reset(SkRef(dstDrawContext.get())); |
+ |
srcRect = dstRect; |
srcTexture = dstTexture; |
+ |
+ dstDrawContext.swap(tmpDrawContext); |
SkTSwap(dstTexture, tempTexture); |
+ |
+ // Since we're exiting some of the DC's can now be closed |
} |
return SkRef(srcTexture); |