| Index: src/effects/SkGpuBlurUtils.cpp
|
| diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp
|
| index 1cb2d1dd125692b5e348491aa6eb81254b119761..c157a6e2e637c752c634096185d589f3ec3c807f 100644
|
| --- a/src/effects/SkGpuBlurUtils.cpp
|
| +++ b/src/effects/SkGpuBlurUtils.cpp
|
| @@ -163,13 +163,13 @@ static void convolve_gaussian(GrDrawContext* drawContext,
|
| }
|
| }
|
|
|
| -GrTexture* GaussianBlur(GrContext* context,
|
| - GrTexture* srcTexture,
|
| - bool gammaCorrect,
|
| - const SkRect& dstBounds,
|
| - const SkRect* srcBounds,
|
| - float sigmaX,
|
| - float sigmaY) {
|
| +sk_sp<GrDrawContext> GaussianBlur(GrContext* context,
|
| + GrTexture* origSrc,
|
| + bool gammaCorrect,
|
| + const SkRect& dstBounds,
|
| + const SkRect* srcBounds,
|
| + float sigmaX,
|
| + float sigmaY) {
|
| SkASSERT(context);
|
| SkIRect clearRect;
|
| int scaleFactorX, radiusX;
|
| @@ -198,6 +198,8 @@ GrTexture* GaussianBlur(GrContext* context,
|
| // setup new clip
|
| GrClip clip(localDstBounds);
|
|
|
| + sk_sp<GrTexture> srcTexture(sk_ref_sp(origSrc));
|
| +
|
| SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
|
| kRGBA_8888_GrPixelConfig == srcTexture->config() ||
|
| kSRGBA_8888_GrPixelConfig == srcTexture->config() ||
|
| @@ -211,6 +213,14 @@ GrTexture* GaussianBlur(GrContext* context,
|
| const SkSurfaceProps props(gammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0,
|
| SkSurfaceProps::kLegacyFontHost_InitType);
|
|
|
| + sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(SkBackingFit::kApprox,
|
| + width, height, config,
|
| + 0, kDefault_GrSurfaceOrigin,
|
| + &props));
|
| + if (!dstDrawContext) {
|
| + return nullptr;
|
| + }
|
| +
|
| // 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.0f &&
|
| @@ -218,35 +228,17 @@ GrTexture* GaussianBlur(GrContext* context,
|
| // We shouldn't be scaling because this is a small size blur
|
| SkASSERT((1 == scaleFactorX) && (1 == scaleFactorY));
|
|
|
| - sk_sp<GrDrawContext> dstDrawContext(context->newDrawContext(SkBackingFit::kApprox,
|
| - width, height, config,
|
| - 0, kDefault_GrSurfaceOrigin,
|
| - &props));
|
| - if (!dstDrawContext) {
|
| - return nullptr;
|
| - }
|
| convolve_gaussian_2d(dstDrawContext.get(), clip, localDstBounds, srcOffset,
|
| - srcTexture, radiusX, radiusY, sigmaX, sigmaY, srcBounds);
|
| + srcTexture.get(), radiusX, radiusY, sigmaX, sigmaY, srcBounds);
|
|
|
| - return dstDrawContext->asTexture().release();
|
| + return dstDrawContext;
|
| }
|
|
|
| - GrSurfaceDesc desc;
|
| - desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
| - desc.fWidth = width;
|
| - desc.fHeight = height;
|
| - desc.fConfig = config;
|
| -
|
| - GrTexture* dstTexture;
|
| - GrTexture* tempTexture;
|
| - SkAutoTUnref<GrTexture> temp1, temp2;
|
| -
|
| - temp1.reset(context->textureProvider()->createApproxTexture(desc));
|
| - dstTexture = temp1.get();
|
| - temp2.reset(context->textureProvider()->createApproxTexture(desc));
|
| - tempTexture = temp2.get();
|
| -
|
| - if (!dstTexture || !tempTexture) {
|
| + sk_sp<GrDrawContext> tmpDrawContext(context->newDrawContext(SkBackingFit::kApprox,
|
| + width, height, config,
|
| + 0, kDefault_GrSurfaceOrigin,
|
| + &props));
|
| + if (!tmpDrawContext) {
|
| return nullptr;
|
| }
|
|
|
| @@ -264,7 +256,7 @@ GrTexture* GaussianBlur(GrContext* context,
|
| domain.inset((i < scaleFactorX) ? SK_ScalarHalf / srcTexture->width() : 0.0f,
|
| (i < scaleFactorY) ? SK_ScalarHalf / srcTexture->height() : 0.0f);
|
| sk_sp<const GrFragmentProcessor> fp(GrTextureDomainEffect::Create(
|
| - srcTexture,
|
| + srcTexture.get(),
|
| matrix,
|
| domain,
|
| GrTextureDomain::kDecal_Mode,
|
| @@ -274,23 +266,18 @@ GrTexture* GaussianBlur(GrContext* context,
|
| srcOffset.set(0, 0);
|
| } else {
|
| GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
|
| - paint.addColorTextureProcessor(srcTexture, matrix, params);
|
| + paint.addColorTextureProcessor(srcTexture.get(), matrix, params);
|
| }
|
| paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
| scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
|
| i < scaleFactorY ? 0.5f : 1.0f);
|
|
|
| - sk_sp<GrDrawContext> dstDrawContext(
|
| - context->drawContext(sk_ref_sp(dstTexture->asRenderTarget())));
|
| - if (!dstDrawContext) {
|
| - return nullptr;
|
| - }
|
| dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
|
|
|
| - srcDrawContext.swap(dstDrawContext);
|
| + srcDrawContext = dstDrawContext;
|
| srcRect = dstRect;
|
| - srcTexture = dstTexture;
|
| - SkTSwap(dstTexture, tempTexture);
|
| + srcTexture = srcDrawContext->asTexture();
|
| + dstDrawContext.swap(tmpDrawContext);
|
| localSrcBounds = srcRect;
|
| }
|
|
|
| @@ -301,13 +288,7 @@ GrTexture* GaussianBlur(GrContext* context,
|
| SkIRect srcIRect = srcRect.roundOut();
|
| 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(sk_ref_sp(srcTexture->asRenderTarget()));
|
| - if (!srcDrawContext) {
|
| - return nullptr;
|
| - }
|
| - }
|
| + SkASSERT(srcDrawContext);
|
|
|
| // Clear out a radius to the right of the srcRect to prevent the
|
| // X convolution from reading garbage.
|
| @@ -316,31 +297,20 @@ GrTexture* GaussianBlur(GrContext* context,
|
| srcDrawContext->clear(&clearRect, 0x0, false);
|
| }
|
|
|
| - sk_sp<GrDrawContext> dstDrawContext(
|
| - context->drawContext(sk_ref_sp(dstTexture->asRenderTarget()), &props));
|
| - if (!dstDrawContext) {
|
| - return nullptr;
|
| - }
|
| convolve_gaussian(dstDrawContext.get(), clip, srcRect,
|
| - srcTexture, Gr1DKernelEffect::kX_Direction, radiusX, sigmaX,
|
| + srcTexture.get(), Gr1DKernelEffect::kX_Direction, radiusX, sigmaX,
|
| srcBounds, srcOffset);
|
| - srcDrawContext.swap(dstDrawContext);
|
| - srcTexture = dstTexture;
|
| + srcDrawContext = dstDrawContext;
|
| + srcTexture = srcDrawContext->asTexture();
|
| srcRect.offsetTo(0, 0);
|
| - SkTSwap(dstTexture, tempTexture);
|
| + dstDrawContext.swap(tmpDrawContext);
|
| localSrcBounds = srcRect;
|
| srcOffset.set(0, 0);
|
| }
|
|
|
| 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(sk_ref_sp(srcTexture->asRenderTarget()));
|
| - if (!srcDrawContext) {
|
| - return nullptr;
|
| - }
|
| - }
|
| + SkASSERT(srcDrawContext);
|
|
|
| // Clear out a radius below the srcRect to prevent the Y
|
| // convolution from reading garbage.
|
| @@ -349,61 +319,48 @@ GrTexture* GaussianBlur(GrContext* context,
|
| srcDrawContext->clear(&clearRect, 0x0, false);
|
| }
|
|
|
| - sk_sp<GrDrawContext> dstDrawContext(
|
| - context->drawContext(sk_ref_sp(dstTexture->asRenderTarget()), &props));
|
| - if (!dstDrawContext) {
|
| - return nullptr;
|
| - }
|
| convolve_gaussian(dstDrawContext.get(), clip, srcRect,
|
| - srcTexture, Gr1DKernelEffect::kY_Direction, radiusY, sigmaY,
|
| + srcTexture.get(), Gr1DKernelEffect::kY_Direction, radiusY, sigmaY,
|
| srcBounds, srcOffset);
|
|
|
| - srcDrawContext.swap(dstDrawContext);
|
| - srcTexture = dstTexture;
|
| + srcDrawContext = dstDrawContext;
|
| srcRect.offsetTo(0, 0);
|
| - SkTSwap(dstTexture, tempTexture);
|
| + dstDrawContext.swap(tmpDrawContext);
|
| }
|
|
|
| + SkASSERT(srcDrawContext);
|
| + srcTexture = nullptr; // we don't use this from here on out
|
| srcIRect = srcRect.roundOut();
|
|
|
| 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);
|
| + // Clear one pixel to the right and below, to accommodate bilinear upsampling.
|
| + clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom, srcIRect.width() + 1, 1);
|
| srcDrawContext->clear(&clearRect, 0x0, false);
|
| - clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
|
| - 1, srcIRect.height());
|
| + clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop, 1, srcIRect.height());
|
| srcDrawContext->clear(&clearRect, 0x0, false);
|
| +
|
| SkMatrix matrix;
|
| - matrix.setIDiv(srcTexture->width(), srcTexture->height());
|
| + matrix.setIDiv(srcDrawContext->width(), srcDrawContext->height());
|
|
|
| GrPaint paint;
|
| paint.setGammaCorrect(gammaCorrect);
|
| // FIXME: this should be mitchell, not bilinear.
|
| GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
|
| - paint.addColorTextureProcessor(srcTexture, matrix, params);
|
| + sk_sp<GrTexture> tex(srcDrawContext->asTexture());
|
| + paint.addColorTextureProcessor(tex.get(), matrix, params);
|
| paint.setPorterDuffXPFactory(SkXfermode::kSrc_Mode);
|
|
|
| SkRect dstRect(srcRect);
|
| scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
|
|
|
| - sk_sp<GrDrawContext> dstDrawContext(
|
| - context->drawContext(sk_ref_sp(dstTexture->asRenderTarget())));
|
| - if (!dstDrawContext) {
|
| - return nullptr;
|
| - }
|
| dstDrawContext->fillRectToRect(clip, paint, SkMatrix::I(), dstRect, srcRect);
|
|
|
| - srcDrawContext.swap(dstDrawContext);
|
| + srcDrawContext = dstDrawContext;
|
| srcRect = dstRect;
|
| - srcTexture = dstTexture;
|
| - SkTSwap(dstTexture, tempTexture);
|
| + dstDrawContext.swap(tmpDrawContext);
|
| }
|
|
|
| - return SkRef(srcTexture);
|
| + return srcDrawContext;
|
| }
|
| #endif
|
|
|
|
|