| 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);
|
|
|