Revert "Update GrCircleBlurFragmentProcessor to use a child FP."

This reverts commit 88c6539a3f.

Reason for revert: reduction in precision causes blocky blur effect on some GPUs (different order of casting in rewritten expression)

Original change's description:
> Update GrCircleBlurFragmentProcessor to use a child FP.
> 
> We are updating FPs to receive their input via a child FP where
> possible, instead of relying on the input color.
> 
> Change-Id: If7c42e556aff3464ec0392f362c97c2e8c6ff91d
> Bug: skia:10217
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/294258
> Reviewed-by: Michael Ludwig <michaelludwig@google.com>
> Commit-Queue: John Stiles <johnstiles@google.com>

TBR=michaelludwig@google.com,johnstiles@google.com

Change-Id: I24a7493f71caa2d9da4de568671f637707d05040
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:10217
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/295438
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2020-06-10 02:31:44 +00:00 committed by Skia Commit-Bot
parent 1c3a77ed8e
commit bce9bd60e7
4 changed files with 22 additions and 56 deletions

View File

@ -766,8 +766,7 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrRecordingContext* context,
fp = GrRectBlurEffect::Make(context, *context->priv().caps()->shaderCaps(),
devRRect.rect(), xformedSigma);
} else {
fp = GrCircleBlurFragmentProcessor::Make(/*inputFP=*/nullptr, context, devRRect.rect(),
xformedSigma);
fp = GrCircleBlurFragmentProcessor::Make(context, devRRect.rect(), xformedSigma);
}
if (!fp) {

View File

@ -5,7 +5,6 @@
* found in the LICENSE file.
*/
in fragmentProcessor? inputFP;
in half4 circleRect;
in half textureRadius;
in half solidRadius;
@ -18,14 +17,12 @@ in uniform sampler2D blurProfileSampler;
uniform half4 circleData;
@optimizationFlags {
(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
kCompatibleWithCoverageAsAlpha_OptimizationFlag
}
@make {
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext*, const SkRect& circle,
float sigma);
static std::unique_ptr<GrFragmentProcessor> Make(GrRecordingContext*,
const SkRect& circle, float sigma);
}
@setData(data) {
@ -268,8 +265,7 @@ uniform half4 circleData;
}
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
std::unique_ptr<GrFragmentProcessor> inputFP, GrRecordingContext* context,
const SkRect& circle, float sigma) {
GrRecordingContext* context, const SkRect& circle, float sigma) {
float solidRadius;
float textureRadius;
GrSurfaceProxyView profile = create_profile_texture(context, circle, sigma,
@ -278,23 +274,22 @@ uniform half4 circleData;
return nullptr;
}
return std::unique_ptr<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(
std::move(inputFP), circle, textureRadius, solidRadius, std::move(profile)));
circle, textureRadius, solidRadius, std::move(profile)));
}
}
void main() {
// We just want to compute "(length(vec) - circleData.z + 0.5) * circleData.w" but need to
// rearrange for precision.
half2 vec = (half2(sk_FragCoord.xy) - circleData.xy) * circleData.w;
half2 vec = half2(half((sk_FragCoord.x - circleData.x) * circleData.w),
half((sk_FragCoord.y - circleData.y) * circleData.w));
half dist = length(vec) + (0.5 - circleData.z) * circleData.w;
half4 inputColor = sample(inputFP, sk_InColor);
sk_OutColor = inputColor * sample(blurProfileSampler, half2(dist, 0.5)).a;
sk_OutColor = sk_InColor * sample(blurProfileSampler, half2(dist, 0.5)).a;
}
@test(testData) {
SkScalar wh = testData->fRandom->nextRangeScalar(100.f, 1000.f);
SkScalar sigma = testData->fRandom->nextRangeF(1.f,10.f);
SkRect circle = SkRect::MakeWH(wh, wh);
return GrCircleBlurFragmentProcessor::Make(/*inputFP=*/nullptr, testData->context(),
circle, sigma);
return GrCircleBlurFragmentProcessor::Make(testData->context(), circle, sigma);
}

View File

@ -255,10 +255,7 @@ static GrSurfaceProxyView create_profile_texture(GrRecordingContext* context,
}
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext* context,
const SkRect& circle,
float sigma) {
GrRecordingContext* context, const SkRect& circle, float sigma) {
float solidRadius;
float textureRadius;
GrSurfaceProxyView profile =
@ -267,7 +264,7 @@ std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
return nullptr;
}
return std::unique_ptr<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(
std::move(inputFP), circle, textureRadius, solidRadius, std::move(profile)));
circle, textureRadius, solidRadius, std::move(profile)));
}
#include "src/gpu/GrTexture.h"
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
@ -292,23 +289,16 @@ public:
circleDataVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
kHalf4_GrSLType, "circleData");
fragBuilder->codeAppendf(
"half2 vec = (half2(sk_FragCoord.xy) - %s.xy) * %s.w;\nhalf dist = length(vec) + "
"(0.5 - %s.z) * %s.w;",
"half2 vec = half2(half((sk_FragCoord.x - float(%s.x)) * float(%s.w)), "
"half((sk_FragCoord.y - float(%s.y)) * float(%s.w)));\nhalf dist = length(vec) + "
"(0.5 - %s.z) * %s.w;\n%s = %s * sample(%s, float2(half2(dist, 0.5))).%s.w;\n",
args.fUniformHandler->getUniformCStr(circleDataVar),
args.fUniformHandler->getUniformCStr(circleDataVar),
args.fUniformHandler->getUniformCStr(circleDataVar),
args.fUniformHandler->getUniformCStr(circleDataVar));
SkString _input13170 = SkStringPrintf("%s", args.fInputColor);
SkString _sample13170;
if (_outer.inputFP_index >= 0) {
_sample13170 = this->invokeChild(_outer.inputFP_index, _input13170.c_str(), args);
} else {
_sample13170 = _input13170;
}
fragBuilder->codeAppendf(
"\nhalf4 inputColor = %s;\n%s = inputColor * sample(%s, float2(half2(dist, "
"0.5))).%s.w;\n",
_sample13170.c_str(), args.fOutputColor,
args.fUniformHandler->getUniformCStr(circleDataVar),
args.fUniformHandler->getUniformCStr(circleDataVar),
args.fUniformHandler->getUniformCStr(circleDataVar), args.fOutputColor,
args.fInputColor,
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
fragBuilder->getProgramBuilder()
->samplerSwizzle(args.fTexSamplers[0])
@ -354,18 +344,10 @@ bool GrCircleBlurFragmentProcessor::onIsEqual(const GrFragmentProcessor& other)
GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(
const GrCircleBlurFragmentProcessor& src)
: INHERITED(kGrCircleBlurFragmentProcessor_ClassID, src.optimizationFlags())
, inputFP_index(src.inputFP_index)
, circleRect(src.circleRect)
, textureRadius(src.textureRadius)
, solidRadius(src.solidRadius)
, blurProfileSampler(src.blurProfileSampler) {
if (inputFP_index >= 0) {
auto clone = src.childProcessor(inputFP_index).clone();
if (src.childProcessor(inputFP_index).isSampledWithExplicitCoords()) {
clone->setSampledWithExplicitCoords();
}
this->registerChildProcessor(std::move(clone));
}
this->setTextureSamplerCnt(1);
}
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::clone() const {
@ -382,7 +364,6 @@ std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::TestCreate(
SkScalar wh = testData->fRandom->nextRangeScalar(100.f, 1000.f);
SkScalar sigma = testData->fRandom->nextRangeF(1.f, 10.f);
SkRect circle = SkRect::MakeWH(wh, wh);
return GrCircleBlurFragmentProcessor::Make(/*inputFP=*/nullptr, testData->context(), circle,
sigma);
return GrCircleBlurFragmentProcessor::Make(testData->context(), circle, sigma);
}
#endif

View File

@ -17,37 +17,28 @@
#include "src/gpu/GrFragmentProcessor.h"
class GrCircleBlurFragmentProcessor : public GrFragmentProcessor {
public:
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrRecordingContext*,
static std::unique_ptr<GrFragmentProcessor> Make(GrRecordingContext*,
const SkRect& circle,
float sigma);
GrCircleBlurFragmentProcessor(const GrCircleBlurFragmentProcessor& src);
std::unique_ptr<GrFragmentProcessor> clone() const override;
const char* name() const override { return "CircleBlurFragmentProcessor"; }
int inputFP_index = -1;
SkRect circleRect;
float textureRadius;
float solidRadius;
TextureSampler blurProfileSampler;
private:
GrCircleBlurFragmentProcessor(std::unique_ptr<GrFragmentProcessor> inputFP,
SkRect circleRect,
GrCircleBlurFragmentProcessor(SkRect circleRect,
float textureRadius,
float solidRadius,
GrSurfaceProxyView blurProfileSampler)
: INHERITED(kGrCircleBlurFragmentProcessor_ClassID,
(OptimizationFlags)(inputFP ? ProcessorOptimizationFlags(inputFP.get())
: kAll_OptimizationFlags) &
kCompatibleWithCoverageAsAlpha_OptimizationFlag)
(OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
, circleRect(circleRect)
, textureRadius(textureRadius)
, solidRadius(solidRadius)
, blurProfileSampler(std::move(blurProfileSampler)) {
if (inputFP) {
inputFP_index = this->numChildProcessors();
this->registerChildProcessor(std::move(inputFP));
}
this->setTextureSamplerCnt(1);
}
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;