Reland of Simplify SkGpuBlurUtils::GaussianBlur method (patchset #1 id:1 of https://codereview.chromium.org/1956023002/ )
Reason for revert: May not be as bad as was thought Original issue's description: > 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 > > Committed: https://skia.googlesource.com/skia/+/67a58dcd4a1e79e5832161ae953526d27893aa61 TBR=bsalomon@google.com,jvanverth@google.com # Not skipping CQ checks because original CL landed more than 1 days ago. Review-Url: https://codereview.chromium.org/1961953002
This commit is contained in:
parent
57cd94a9de
commit
a8966a8a34
@ -202,7 +202,8 @@ public:
|
||||
int width, int height,
|
||||
GrPixelConfig config,
|
||||
int sampleCnt = 0,
|
||||
GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin);
|
||||
GrSurfaceOrigin origin = kDefault_GrSurfaceOrigin,
|
||||
const SkSurfaceProps* surfaceProps = nullptr);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Misc.
|
||||
|
@ -123,7 +123,6 @@ 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,
|
||||
|
@ -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,
|
||||
false, clipRect, nullptr,
|
||||
clipRect, nullptr,
|
||||
xformedSigma, xformedSigma);
|
||||
if (nullptr == *result) {
|
||||
return false;
|
||||
|
@ -165,7 +165,6 @@ static void convolve_gaussian(GrDrawContext* drawContext,
|
||||
|
||||
GrTexture* GaussianBlur(GrContext* context,
|
||||
GrTexture* srcTexture,
|
||||
bool canClobberSrc,
|
||||
bool gammaCorrect,
|
||||
const SkRect& dstBounds,
|
||||
const SkRect* srcBounds,
|
||||
@ -205,11 +204,38 @@ 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 = SkScalarFloorToInt(dstBounds.width());
|
||||
desc.fHeight = SkScalarFloorToInt(dstBounds.height());
|
||||
desc.fConfig = srcTexture->config();
|
||||
desc.fWidth = width;
|
||||
desc.fHeight = height;
|
||||
desc.fConfig = config;
|
||||
|
||||
GrTexture* dstTexture;
|
||||
GrTexture* tempTexture;
|
||||
@ -217,14 +243,10 @@ GrTexture* GaussianBlur(GrContext* context,
|
||||
|
||||
temp1.reset(context->textureProvider()->createApproxTexture(desc));
|
||||
dstTexture = temp1.get();
|
||||
if (canClobberSrc) {
|
||||
tempTexture = srcTexture;
|
||||
} else {
|
||||
temp2.reset(context->textureProvider()->createApproxTexture(desc));
|
||||
tempTexture = temp2.get();
|
||||
}
|
||||
temp2.reset(context->textureProvider()->createApproxTexture(desc));
|
||||
tempTexture = temp2.get();
|
||||
|
||||
if (nullptr == dstTexture || nullptr == tempTexture) {
|
||||
if (!dstTexture || !tempTexture) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -241,13 +263,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);
|
||||
SkAutoTUnref<const GrFragmentProcessor> fp(GrTextureDomainEffect::Create(
|
||||
srcTexture,
|
||||
matrix,
|
||||
domain,
|
||||
GrTextureDomain::kDecal_Mode,
|
||||
GrTextureParams::kBilerp_FilterMode));
|
||||
paint.addColorFragmentProcessor(fp);
|
||||
sk_sp<const GrFragmentProcessor> fp(GrTextureDomainEffect::Create(
|
||||
srcTexture,
|
||||
matrix,
|
||||
domain,
|
||||
GrTextureDomain::kDecal_Mode,
|
||||
GrTextureParams::kBilerp_FilterMode));
|
||||
paint.addColorFragmentProcessor(fp.get());
|
||||
srcRect.offset(-srcOffset);
|
||||
srcOffset.set(0, 0);
|
||||
} else {
|
||||
@ -272,100 +294,77 @@ GrTexture* GaussianBlur(GrContext* context,
|
||||
localSrcBounds = srcRect;
|
||||
}
|
||||
|
||||
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
|
||||
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));
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
sk_sp<GrDrawContext> dstDrawContext(
|
||||
context->drawContext(sk_ref_sp(dstTexture->asRenderTarget()), &props));
|
||||
if (!dstDrawContext) {
|
||||
return nullptr;
|
||||
}
|
||||
convolve_gaussian_2d(dstDrawContext.get(), clip, srcRect, srcOffset,
|
||||
srcTexture, radiusX, radiusY, sigmaX, sigmaY, srcBounds);
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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::kY_Direction, radiusY, sigmaY,
|
||||
srcBounds, srcOffset);
|
||||
|
||||
srcDrawContext.swap(dstDrawContext);
|
||||
srcRect.offsetTo(0, 0);
|
||||
srcTexture = dstTexture;
|
||||
srcRect.offsetTo(0, 0);
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
|
||||
} 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) {
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
// 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::kY_Direction, radiusY, sigmaY,
|
||||
srcBounds, srcOffset);
|
||||
|
||||
srcDrawContext.swap(dstDrawContext);
|
||||
srcTexture = dstTexture;
|
||||
srcRect.offsetTo(0, 0);
|
||||
SkTSwap(dstTexture, tempTexture);
|
||||
}
|
||||
}
|
||||
const SkIRect srcIRect = srcRect.roundOut();
|
||||
|
||||
srcIRect = srcRect.roundOut();
|
||||
|
||||
if (scaleFactorX > 1 || scaleFactorY > 1) {
|
||||
SkASSERT(srcDrawContext);
|
||||
|
@ -24,8 +24,6 @@ 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,
|
||||
@ -37,7 +35,6 @@ namespace SkGpuBlurUtils {
|
||||
*/
|
||||
GrTexture* GaussianBlur(GrContext* context,
|
||||
GrTexture* srcTexture,
|
||||
bool canClobberSrc,
|
||||
bool gammaCorrect,
|
||||
const SkRect& dstBounds,
|
||||
const SkRect* srcBounds,
|
||||
|
@ -658,7 +658,8 @@ sk_sp<GrDrawContext> GrContext::newDrawContext(SkBackingFit fit,
|
||||
int width, int height,
|
||||
GrPixelConfig config,
|
||||
int sampleCnt,
|
||||
GrSurfaceOrigin origin) {
|
||||
GrSurfaceOrigin origin,
|
||||
const SkSurfaceProps* surfaceProps) {
|
||||
GrSurfaceDesc desc;
|
||||
desc.fFlags = kRenderTarget_GrSurfaceFlag;
|
||||
desc.fOrigin = origin;
|
||||
@ -677,7 +678,8 @@ sk_sp<GrDrawContext> GrContext::newDrawContext(SkBackingFit fit,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
sk_sp<GrDrawContext> drawContext(this->drawContext(sk_ref_sp(tex->asRenderTarget())));
|
||||
sk_sp<GrDrawContext> drawContext(this->drawContext(sk_ref_sp(tex->asRenderTarget()),
|
||||
surfaceProps));
|
||||
if (!drawContext) {
|
||||
return nullptr;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user