diff --git a/src/core/SkBlurMF.cpp b/src/core/SkBlurMF.cpp index 8bae1f05f1..b75fd16f6c 100644 --- a/src/core/SkBlurMF.cpp +++ b/src/core/SkBlurMF.cpp @@ -758,7 +758,8 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrContext* context, SkScalar pad = 3.0f * xformedSigma; rect.outset(pad, pad); - fp = GrRectBlurEffect::Make(proxyProvider, rect, xformedSigma); + fp = GrRectBlurEffect::Make(proxyProvider, *context->caps()->shaderCaps(), rect, + xformedSigma); } else if (path.isOval(&rect) && SkScalarNearlyEqual(rect.width(), rect.height())) { fp = GrCircleBlurFragmentProcessor::Make(proxyProvider, rect, xformedSigma); @@ -811,7 +812,8 @@ bool SkBlurMaskFilterImpl::directFilterRRectMaskGPU(GrContext* context, SkScalar pad = 3.0f * xformedSigma; const SkRect dstCoverageRect = devRRect.rect().makeOutset(pad, pad); - fp = GrRectBlurEffect::Make(proxyProvider, dstCoverageRect, xformedSigma); + fp = GrRectBlurEffect::Make(proxyProvider, *context->caps()->shaderCaps(), + dstCoverageRect, xformedSigma); } else { fp = GrCircleBlurFragmentProcessor::Make(proxyProvider, devRRect.rect(), xformedSigma); diff --git a/src/gpu/effects/GrRectBlurEffect.cpp b/src/gpu/effects/GrRectBlurEffect.cpp index f537361cad..219fefa713 100644 --- a/src/gpu/effects/GrRectBlurEffect.cpp +++ b/src/gpu/effects/GrRectBlurEffect.cpp @@ -160,6 +160,7 @@ std::unique_ptr GrRectBlurEffect::TestCreate(GrProcessorTes float sigma = data->fRandom->nextRangeF(3, 8); float width = data->fRandom->nextRangeF(200, 300); float height = data->fRandom->nextRangeF(200, 300); - return GrRectBlurEffect::Make(data->proxyProvider(), SkRect::MakeWH(width, height), sigma); + return GrRectBlurEffect::Make(data->proxyProvider(), *data->caps()->shaderCaps(), + SkRect::MakeWH(width, height), sigma); } #endif diff --git a/src/gpu/effects/GrRectBlurEffect.fp b/src/gpu/effects/GrRectBlurEffect.fp index ed9a1e715f..e5a5aad75c 100644 --- a/src/gpu/effects/GrRectBlurEffect.fp +++ b/src/gpu/effects/GrRectBlurEffect.fp @@ -84,7 +84,17 @@ uniform half profileSize; @make { static std::unique_ptr Make(GrProxyProvider* proxyProvider, + const GrShaderCaps& caps, const SkRect& rect, float sigma) { + if (!caps.floatIs32Bits()) { + // We promote the rect uniform from half to float when it has large values for + // precision. If we don't have full float then fail. + if (abs(rect.fLeft) > 16000 || abs(rect.fTop) > 16000 || + abs(rect.fRight) > 16000 || abs(rect.fBottom) > 16000 || + abs(rect.width()) > 16000 || abs(rect.height()) > 16000) { + return nullptr; + } + } int doubleProfileSize = SkScalarCeilToInt(12*sigma); if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) { @@ -142,5 +152,6 @@ void main() { float sigma = data->fRandom->nextRangeF(3,8); float width = data->fRandom->nextRangeF(200,300); float height = data->fRandom->nextRangeF(200,300); - return GrRectBlurEffect::Make(data->proxyProvider(), SkRect::MakeWH(width, height), sigma); + return GrRectBlurEffect::Make(data->proxyProvider(), *data->caps()->shaderCaps(), + SkRect::MakeWH(width, height), sigma); } diff --git a/src/gpu/effects/GrRectBlurEffect.h b/src/gpu/effects/GrRectBlurEffect.h index 47e9dc3851..42c2829d6d 100644 --- a/src/gpu/effects/GrRectBlurEffect.h +++ b/src/gpu/effects/GrRectBlurEffect.h @@ -63,7 +63,17 @@ public: float sigma() const { return fSigma; } static std::unique_ptr Make(GrProxyProvider* proxyProvider, - const SkRect& rect, float sigma) { + const GrShaderCaps& caps, const SkRect& rect, + float sigma) { + if (!caps.floatIs32Bits()) { + // We promote the rect uniform from half to float when it has large values for + // precision. If we don't have full float then fail. + if (abs(rect.fLeft) > 16000 || abs(rect.fTop) > 16000 || abs(rect.fRight) > 16000 || + abs(rect.fBottom) > 16000 || abs(rect.width()) > 16000 || + abs(rect.height()) > 16000) { + return nullptr; + } + } int doubleProfileSize = SkScalarCeilToInt(12 * sigma); if (doubleProfileSize >= rect.width() || doubleProfileSize >= rect.height()) {