| Index: src/effects/SkGpuBlurUtils.cpp
|
| diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp
|
| index ad268d6961ef69f919e9472f11b5347cc3854328..f8b9c752807d01a17457c4851f0692e23911d706 100644
|
| --- a/src/effects/SkGpuBlurUtils.cpp
|
| +++ b/src/effects/SkGpuBlurUtils.cpp
|
| @@ -197,10 +197,9 @@ GrTexture* GaussianBlur(GrContext* context,
|
| return NULL;
|
| }
|
|
|
| - GrDrawContext* drawContext = context->drawContext();
|
| - if (!drawContext) {
|
| - return NULL;
|
| - }
|
| + // TODO: it seems we should be able to do better than this. Pass in the
|
| + // source draw context?
|
| + GrDrawContext* srcDrawContext = NULL;
|
|
|
| for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
|
| GrPaint paint;
|
| @@ -226,8 +225,20 @@ GrTexture* GaussianBlur(GrContext* context,
|
| }
|
| scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
|
| i < scaleFactorY ? 0.5f : 1.0f);
|
| - drawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint, SkMatrix::I(),
|
| - dstRect, srcRect);
|
| +
|
| + GrDrawContext* dstDrawContext = context->drawContext(dstTexture->asRenderTarget());
|
| + if (!dstDrawContext) {
|
| + return NULL;
|
| + }
|
| + if (srcDrawContext) {
|
| + dstDrawContext->uses(srcDrawContext);
|
| + } else {
|
| + dstDrawContext->uses(srcTexture);
|
| + }
|
| + dstDrawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint,
|
| + SkMatrix::I(), dstRect, srcRect);
|
| +
|
| + srcDrawContext = dstDrawContext;
|
| srcRect = dstRect;
|
| srcTexture = dstTexture;
|
| SkTSwap(dstTexture, tempTexture);
|
| @@ -235,32 +246,64 @@ GrTexture* GaussianBlur(GrContext* context,
|
|
|
| const SkIRect srcIRect = srcRect.roundOut();
|
|
|
| - // For really small blurs(Certainly no wider than 5x5 on desktop gpus) it is faster to just
|
| + // For really small blurs (certainly no wider than 5x5 on desktop gpus) it is faster to just
|
| // launch a single non separable kernel vs two launches
|
| - if (sigmaX > 0.0f && sigmaY > 0 &&
|
| + if (sigmaX > 0.0f && sigmaY > 0.0f &&
|
| (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
|
| // We shouldn't be scaling because this is a small size blur
|
| - SkASSERT((scaleFactorX == scaleFactorY) == 1);
|
| + SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY));
|
| SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
|
| - convolve_gaussian_2d(drawContext, dstTexture->asRenderTarget(), clip, srcRect, dstRect,
|
| +
|
| + GrDrawContext* dstDrawContext = context->drawContext(dstTexture->asRenderTarget());
|
| + if (!dstDrawContext) {
|
| + return NULL;
|
| + }
|
| + if (srcDrawContext) {
|
| + dstDrawContext->uses(srcDrawContext);
|
| + } else {
|
| + dstDrawContext->uses(srcTexture);
|
| + }
|
| + convolve_gaussian_2d(dstDrawContext, dstTexture->asRenderTarget(), clip, srcRect, dstRect,
|
| srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropToRect, srcIRect);
|
| - srcTexture = dstTexture;
|
| +
|
| + srcDrawContext = dstDrawContext;
|
| srcRect = dstRect;
|
| + srcTexture = dstTexture;
|
| SkTSwap(dstTexture, tempTexture);
|
|
|
| } else {
|
| if (sigmaX > 0.0f) {
|
| if (scaleFactorX > 1) {
|
| + // TODO: if we pass in the source draw context we don't need this here
|
| + if (!srcDrawContext) {
|
| + srcDrawContext = context->drawContext(srcTexture->asRenderTarget());
|
| + if (!srcDrawContext) {
|
| + return NULL;
|
| + }
|
| + }
|
| +
|
| // Clear out a radius to the right of the srcRect to prevent the
|
| // X convolution from reading garbage.
|
| clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
|
| radiusX, srcIRect.height());
|
| - drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
|
| + srcDrawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
|
| }
|
| SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
|
| - convolve_gaussian(drawContext, dstTexture->asRenderTarget(), clip, srcRect, dstRect,
|
| +
|
| + GrDrawContext* dstDrawContext = context->drawContext(dstTexture->asRenderTarget());
|
| + if (!dstDrawContext) {
|
| + return NULL;
|
| + }
|
| + if (srcDrawContext) {
|
| + dstDrawContext->uses(srcDrawContext);
|
| + } else {
|
| + dstDrawContext->uses(srcTexture);
|
| + }
|
| + convolve_gaussian(dstDrawContext, dstTexture->asRenderTarget(), clip, srcRect, dstRect,
|
| srcTexture, Gr1DKernelEffect::kX_Direction, radiusX, sigmaX,
|
| cropToRect);
|
| +
|
| + srcDrawContext = dstDrawContext;
|
| srcTexture = dstTexture;
|
| srcRect = dstRect;
|
| SkTSwap(dstTexture, tempTexture);
|
| @@ -268,17 +311,37 @@ GrTexture* GaussianBlur(GrContext* context,
|
|
|
| if (sigmaY > 0.0f) {
|
| if (scaleFactorY > 1 || sigmaX > 0.0f) {
|
| + // TODO: if we pass in the source draw context we don't need this here
|
| + if (!srcDrawContext) {
|
| + srcDrawContext = context->drawContext(srcTexture->asRenderTarget());
|
| + if (!srcDrawContext) {
|
| + return NULL;
|
| + }
|
| + }
|
| +
|
| // Clear out a radius below the srcRect to prevent the Y
|
| // convolution from reading garbage.
|
| clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
|
| srcIRect.width(), radiusY);
|
| - drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
|
| + srcDrawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
|
| }
|
|
|
| SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
|
| - convolve_gaussian(drawContext, dstTexture->asRenderTarget(), clip, srcRect,
|
| +
|
| + GrDrawContext* dstDrawContext = context->drawContext(dstTexture->asRenderTarget());
|
| + if (!dstDrawContext) {
|
| + return NULL;
|
| + }
|
| + if (srcDrawContext) {
|
| + dstDrawContext->uses(srcDrawContext);
|
| + } else {
|
| + dstDrawContext->uses(srcTexture);
|
| + }
|
| + convolve_gaussian(dstDrawContext, dstTexture->asRenderTarget(), clip, srcRect,
|
| dstRect, srcTexture, Gr1DKernelEffect::kY_Direction, radiusY, sigmaY,
|
| cropToRect);
|
| +
|
| + srcDrawContext = dstDrawContext;
|
| srcTexture = dstTexture;
|
| srcRect = dstRect;
|
| SkTSwap(dstTexture, tempTexture);
|
| @@ -286,14 +349,16 @@ GrTexture* GaussianBlur(GrContext* context,
|
| }
|
|
|
| if (scaleFactorX > 1 || scaleFactorY > 1) {
|
| + SkASSERT(srcDrawContext);
|
| +
|
| // Clear one pixel to the right and below, to accommodate bilinear
|
| // upsampling.
|
| clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
|
| srcIRect.width() + 1, 1);
|
| - drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
|
| + srcDrawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
|
| clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
|
| 1, srcIRect.height());
|
| - drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
|
| + srcDrawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
|
| SkMatrix matrix;
|
| matrix.setIDiv(srcTexture->width(), srcTexture->height());
|
|
|
| @@ -304,8 +369,16 @@ GrTexture* GaussianBlur(GrContext* context,
|
|
|
| SkRect dstRect(srcRect);
|
| scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
|
| - drawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint,
|
| - SkMatrix::I(), dstRect, srcRect);
|
| +
|
| + GrDrawContext* dstDrawContext = context->drawContext(dstTexture->asRenderTarget());
|
| + if (!dstDrawContext) {
|
| + return NULL;
|
| + }
|
| + dstDrawContext->uses(srcDrawContext);
|
| + dstDrawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint,
|
| + SkMatrix::I(), dstRect, srcRect);
|
| +
|
| + srcDrawContext = dstDrawContext;
|
| srcRect = dstRect;
|
| srcTexture = dstTexture;
|
| SkTSwap(dstTexture, tempTexture);
|
|
|