diff options
author | 2016-05-06 13:05:09 -0700 | |
---|---|---|
committer | 2016-05-06 13:05:09 -0700 | |
commit | 67a58dcd4a1e79e5832161ae953526d27893aa61 (patch) | |
tree | d9c98235c533dc18813956d372e68cd62a9c6dbd | |
parent | 50c46c7b189caf94abb79cdc125245a6c0de0b4e (diff) |
Revert of Simplify SkGpuBlurUtils::GaussianBlur method (patchset #2 id:20001 of https://codereview.chromium.org/1958603002/ )
Reason for revert:
Looks like it's causing some issues with the bleed_image GM.
Original issue's description:
> Simplify SkGpuBlurUtils::GaussianBlur method
>
> No one was using the canClobberSrc capability and moving the direct filtering case forward makes the rest of the logic simpler.
>
> Split out of: https://codereview.chromium.org/1959493002/ (Retract GrRenderTarget from SkGpuBlurUtils)
>
> GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1958603002
>
> Committed: https://skia.googlesource.com/skia/+/56a85e69a8d034e0fdee00e8207cda0a9da06fee
TBR=bsalomon@google.com,robertphillips@google.com
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
Review-Url: https://codereview.chromium.org/1956023002
-rw-r--r-- | include/gpu/GrContext.h | 3 | ||||
-rw-r--r-- | src/effects/SkBlurImageFilter.cpp | 1 | ||||
-rw-r--r-- | src/effects/SkBlurMaskFilter.cpp | 2 | ||||
-rw-r--r-- | src/effects/SkGpuBlurUtils.cpp | 185 | ||||
-rw-r--r-- | src/effects/SkGpuBlurUtils.h | 3 | ||||
-rw-r--r-- | src/gpu/GrContext.cpp | 6 |
6 files changed, 101 insertions, 99 deletions
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index 1c9a27e25f..b6fa30bc35 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -202,8 +202,7 @@ public: int width, int height, GrPixelConfig config, int sampleCnt = 0, - GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin, - const SkSurfaceProps* surfaceProps = nullptr); + GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin); /////////////////////////////////////////////////////////////////////////// // Misc. diff --git a/src/effects/SkBlurImageFilter.cpp b/src/effects/SkBlurImageFilter.cpp index 4e1fde250b..bbe351db47 100644 --- a/src/effects/SkBlurImageFilter.cpp +++ b/src/effects/SkBlurImageFilter.cpp @@ -123,6 +123,7 @@ sk_sp<SkSpecialImage> SkBlurImageFilter::onFilterImage(SkSpecialImage* source, SkRect inputBoundsF(SkRect::Make(inputBounds)); sk_sp<GrTexture> tex(SkGpuBlurUtils::GaussianBlur(context, inputTexture.get(), + false, source->props().isGammaCorrect(), SkRect::Make(dstBounds), &inputBoundsF, diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp index 37d6c960d7..8e9eb52e94 100644 --- a/src/effects/SkBlurMaskFilter.cpp +++ b/src/effects/SkBlurMaskFilter.cpp @@ -1249,7 +1249,7 @@ bool SkBlurMaskFilterImpl::filterMaskGPU(GrTexture* src, // gaussianBlur. Otherwise, we need to save it for later compositing. bool isNormalBlur = (kNormal_SkBlurStyle == fBlurStyle); *result = SkGpuBlurUtils::GaussianBlur(context, src, isNormalBlur && canOverwriteSrc, - clipRect, nullptr, + false, clipRect, nullptr, xformedSigma, xformedSigma); if (nullptr == *result) { return false; diff --git a/src/effects/SkGpuBlurUtils.cpp b/src/effects/SkGpuBlurUtils.cpp index 1cb2d1dd12..c3681faca5 100644 --- a/src/effects/SkGpuBlurUtils.cpp +++ b/src/effects/SkGpuBlurUtils.cpp @@ -165,6 +165,7 @@ static void convolve_gaussian(GrDrawContext* drawContext, GrTexture* GaussianBlur(GrContext* context, GrTexture* srcTexture, + bool canClobberSrc, bool gammaCorrect, const SkRect& dstBounds, const SkRect* srcBounds, @@ -204,38 +205,11 @@ GrTexture* GaussianBlur(GrContext* context, kSBGRA_8888_GrPixelConfig == srcTexture->config() || kAlpha_8_GrPixelConfig == srcTexture->config()); - const int width = SkScalarFloorToInt(dstBounds.width()); - const int height = SkScalarFloorToInt(dstBounds.height()); - const GrPixelConfig config = srcTexture->config(); - - const SkSurfaceProps props(gammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0, - SkSurfaceProps::kLegacyFontHost_InitType); - - // 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 && - (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) { - // 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); - - return dstDrawContext->asTexture().release(); - } - GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; - desc.fWidth = width; - desc.fHeight = height; - desc.fConfig = config; + desc.fWidth = SkScalarFloorToInt(dstBounds.width()); + desc.fHeight = SkScalarFloorToInt(dstBounds.height()); + desc.fConfig = srcTexture->config(); GrTexture* dstTexture; GrTexture* tempTexture; @@ -243,10 +217,14 @@ GrTexture* GaussianBlur(GrContext* context, temp1.reset(context->textureProvider()->createApproxTexture(desc)); dstTexture = temp1.get(); - temp2.reset(context->textureProvider()->createApproxTexture(desc)); - tempTexture = temp2.get(); + if (canClobberSrc) { + tempTexture = srcTexture; + } else { + temp2.reset(context->textureProvider()->createApproxTexture(desc)); + tempTexture = temp2.get(); + } - if (!dstTexture || !tempTexture) { + if (nullptr == dstTexture || nullptr == tempTexture) { return nullptr; } @@ -263,13 +241,13 @@ GrTexture* GaussianBlur(GrContext* context, matrix.mapRect(&domain, *srcBounds); 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, - matrix, - domain, - GrTextureDomain::kDecal_Mode, - GrTextureParams::kBilerp_FilterMode)); - paint.addColorFragmentProcessor(fp.get()); + SkAutoTUnref<const GrFragmentProcessor> fp(GrTextureDomainEffect::Create( + srcTexture, + matrix, + domain, + GrTextureDomain::kDecal_Mode, + GrTextureParams::kBilerp_FilterMode)); + paint.addColorFragmentProcessor(fp); srcRect.offset(-srcOffset); srcOffset.set(0, 0); } else { @@ -294,77 +272,100 @@ GrTexture* GaussianBlur(GrContext* context, localSrcBounds = srcRect; } - srcRect = localDstBounds; - - scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); - srcRect.roundOut(&srcRect); - 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; - } - } + SkSurfaceProps props(gammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0, + SkSurfaceProps::kLegacyFontHost_InitType); - // 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()); - srcDrawContext->clear(&clearRect, 0x0, false); - } + // 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 + srcRect = localDstBounds; + 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((1 == scaleFactorX) && (1 == scaleFactorY)); 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, - srcBounds, srcOffset); + convolve_gaussian_2d(dstDrawContext.get(), clip, srcRect, srcOffset, + srcTexture, radiusX, radiusY, sigmaX, sigmaY, srcBounds); + srcDrawContext.swap(dstDrawContext); - srcTexture = dstTexture; srcRect.offsetTo(0, 0); + srcTexture = dstTexture; SkTSwap(dstTexture, tempTexture); - 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())); + } else { + scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY); + srcRect.roundOut(&srcRect); + const 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) { - return nullptr; + srcDrawContext = context->drawContext(sk_ref_sp(srcTexture->asRenderTarget())); + if (!srcDrawContext) { + return nullptr; + } } + + // 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()); + srcDrawContext->clear(&clearRect, 0x0, false); } - // 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); - 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, + srcBounds, srcOffset); + srcDrawContext.swap(dstDrawContext); + srcTexture = dstTexture; + srcRect.offsetTo(0, 0); + SkTSwap(dstTexture, tempTexture); + localSrcBounds = srcRect; + srcOffset.set(0, 0); } - 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, - srcBounds, srcOffset); + 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; + } + } - srcDrawContext.swap(dstDrawContext); - srcTexture = dstTexture; - srcRect.offsetTo(0, 0); - SkTSwap(dstTexture, tempTexture); - } + // 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); + srcDrawContext->clear(&clearRect, 0x0, false); + } - srcIRect = srcRect.roundOut(); + 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, + srcBounds, srcOffset); + + srcDrawContext.swap(dstDrawContext); + srcTexture = dstTexture; + srcRect.offsetTo(0, 0); + SkTSwap(dstTexture, tempTexture); + } + } + const SkIRect srcIRect = srcRect.roundOut(); if (scaleFactorX > 1 || scaleFactorY > 1) { SkASSERT(srcDrawContext); diff --git a/src/effects/SkGpuBlurUtils.h b/src/effects/SkGpuBlurUtils.h index 8bc4377f59..7dbfa138ea 100644 --- a/src/effects/SkGpuBlurUtils.h +++ b/src/effects/SkGpuBlurUtils.h @@ -24,6 +24,8 @@ namespace SkGpuBlurUtils { * Applies a 2D Gaussian blur to a given texture. * @param context The GPU context * @param srcTexture The source texture to be blurred. + * @param canClobberSrc If true, srcTexture may be overwritten, and + * may be returned as the result. * @param gammaCorrect Should blur be gamma-correct (sRGB to linear, etc...) * @param dstBounds The destination bounds, relative to the source texture. * @param srcBounds The source bounds, relative to the source texture. If non-null, @@ -35,6 +37,7 @@ namespace SkGpuBlurUtils { */ GrTexture* GaussianBlur(GrContext* context, GrTexture* srcTexture, + bool canClobberSrc, bool gammaCorrect, const SkRect& dstBounds, const SkRect* srcBounds, diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 443494073a..3ea67c9f01 100644 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -658,8 +658,7 @@ sk_sp<GrDrawContext> GrContext::newDrawContext(SkBackingFit fit, int width, int height, GrPixelConfig config, int sampleCnt, - GrSurfaceOrigin origin, - const SkSurfaceProps* surfaceProps) { + GrSurfaceOrigin origin) { GrSurfaceDesc desc; desc.fFlags = kRenderTarget_GrSurfaceFlag; desc.fOrigin = origin; @@ -678,8 +677,7 @@ sk_sp<GrDrawContext> GrContext::newDrawContext(SkBackingFit fit, return nullptr; } - sk_sp<GrDrawContext> drawContext(this->drawContext(sk_ref_sp(tex->asRenderTarget()), - surfaceProps)); + sk_sp<GrDrawContext> drawContext(this->drawContext(sk_ref_sp(tex->asRenderTarget()))); if (!drawContext) { return nullptr; } |