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>
This commit is contained in:
parent
1ce11e676e
commit
88c6539a3f
@ -766,7 +766,8 @@ bool SkBlurMaskFilterImpl::directFilterMaskGPU(GrRecordingContext* context,
|
|||||||
fp = GrRectBlurEffect::Make(context, *context->priv().caps()->shaderCaps(),
|
fp = GrRectBlurEffect::Make(context, *context->priv().caps()->shaderCaps(),
|
||||||
devRRect.rect(), xformedSigma);
|
devRRect.rect(), xformedSigma);
|
||||||
} else {
|
} else {
|
||||||
fp = GrCircleBlurFragmentProcessor::Make(context, devRRect.rect(), xformedSigma);
|
fp = GrCircleBlurFragmentProcessor::Make(/*inputFP=*/nullptr, context, devRRect.rect(),
|
||||||
|
xformedSigma);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fp) {
|
if (!fp) {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
* found in the LICENSE file.
|
* found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
in fragmentProcessor? inputFP;
|
||||||
in half4 circleRect;
|
in half4 circleRect;
|
||||||
in half textureRadius;
|
in half textureRadius;
|
||||||
in half solidRadius;
|
in half solidRadius;
|
||||||
@ -17,12 +18,14 @@ in uniform sampler2D blurProfileSampler;
|
|||||||
uniform half4 circleData;
|
uniform half4 circleData;
|
||||||
|
|
||||||
@optimizationFlags {
|
@optimizationFlags {
|
||||||
|
(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
|
||||||
kCompatibleWithCoverageAsAlpha_OptimizationFlag
|
kCompatibleWithCoverageAsAlpha_OptimizationFlag
|
||||||
}
|
}
|
||||||
|
|
||||||
@make {
|
@make {
|
||||||
static std::unique_ptr<GrFragmentProcessor> Make(GrRecordingContext*,
|
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||||
const SkRect& circle, float sigma);
|
GrRecordingContext*, const SkRect& circle,
|
||||||
|
float sigma);
|
||||||
}
|
}
|
||||||
|
|
||||||
@setData(data) {
|
@setData(data) {
|
||||||
@ -265,7 +268,8 @@ uniform half4 circleData;
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
|
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
|
||||||
GrRecordingContext* context, const SkRect& circle, float sigma) {
|
std::unique_ptr<GrFragmentProcessor> inputFP, GrRecordingContext* context,
|
||||||
|
const SkRect& circle, float sigma) {
|
||||||
float solidRadius;
|
float solidRadius;
|
||||||
float textureRadius;
|
float textureRadius;
|
||||||
GrSurfaceProxyView profile = create_profile_texture(context, circle, sigma,
|
GrSurfaceProxyView profile = create_profile_texture(context, circle, sigma,
|
||||||
@ -274,22 +278,23 @@ uniform half4 circleData;
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return std::unique_ptr<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(
|
return std::unique_ptr<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(
|
||||||
circle, textureRadius, solidRadius, std::move(profile)));
|
std::move(inputFP), circle, textureRadius, solidRadius, std::move(profile)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
// We just want to compute "(length(vec) - circleData.z + 0.5) * circleData.w" but need to
|
// We just want to compute "(length(vec) - circleData.z + 0.5) * circleData.w" but need to
|
||||||
// rearrange for precision.
|
// rearrange for precision.
|
||||||
half2 vec = half2(half((sk_FragCoord.x - circleData.x) * circleData.w),
|
half2 vec = (half2(sk_FragCoord.xy) - circleData.xy) * circleData.w;
|
||||||
half((sk_FragCoord.y - circleData.y) * circleData.w));
|
|
||||||
half dist = length(vec) + (0.5 - circleData.z) * circleData.w;
|
half dist = length(vec) + (0.5 - circleData.z) * circleData.w;
|
||||||
sk_OutColor = sk_InColor * sample(blurProfileSampler, half2(dist, 0.5)).a;
|
half4 inputColor = sample(inputFP, sk_InColor);
|
||||||
|
sk_OutColor = inputColor * sample(blurProfileSampler, half2(dist, 0.5)).a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@test(testData) {
|
@test(testData) {
|
||||||
SkScalar wh = testData->fRandom->nextRangeScalar(100.f, 1000.f);
|
SkScalar wh = testData->fRandom->nextRangeScalar(100.f, 1000.f);
|
||||||
SkScalar sigma = testData->fRandom->nextRangeF(1.f,10.f);
|
SkScalar sigma = testData->fRandom->nextRangeF(1.f,10.f);
|
||||||
SkRect circle = SkRect::MakeWH(wh, wh);
|
SkRect circle = SkRect::MakeWH(wh, wh);
|
||||||
return GrCircleBlurFragmentProcessor::Make(testData->context(), circle, sigma);
|
return GrCircleBlurFragmentProcessor::Make(/*inputFP=*/nullptr, testData->context(),
|
||||||
|
circle, sigma);
|
||||||
}
|
}
|
||||||
|
@ -255,7 +255,10 @@ static GrSurfaceProxyView create_profile_texture(GrRecordingContext* context,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
|
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
|
||||||
GrRecordingContext* context, const SkRect& circle, float sigma) {
|
std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||||
|
GrRecordingContext* context,
|
||||||
|
const SkRect& circle,
|
||||||
|
float sigma) {
|
||||||
float solidRadius;
|
float solidRadius;
|
||||||
float textureRadius;
|
float textureRadius;
|
||||||
GrSurfaceProxyView profile =
|
GrSurfaceProxyView profile =
|
||||||
@ -264,7 +267,7 @@ std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::Make(
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return std::unique_ptr<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(
|
return std::unique_ptr<GrFragmentProcessor>(new GrCircleBlurFragmentProcessor(
|
||||||
circle, textureRadius, solidRadius, std::move(profile)));
|
std::move(inputFP), circle, textureRadius, solidRadius, std::move(profile)));
|
||||||
}
|
}
|
||||||
#include "src/gpu/GrTexture.h"
|
#include "src/gpu/GrTexture.h"
|
||||||
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
|
#include "src/gpu/glsl/GrGLSLFragmentProcessor.h"
|
||||||
@ -289,16 +292,23 @@ public:
|
|||||||
circleDataVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
|
circleDataVar = args.fUniformHandler->addUniform(&_outer, kFragment_GrShaderFlag,
|
||||||
kHalf4_GrSLType, "circleData");
|
kHalf4_GrSLType, "circleData");
|
||||||
fragBuilder->codeAppendf(
|
fragBuilder->codeAppendf(
|
||||||
"half2 vec = half2(half((sk_FragCoord.x - float(%s.x)) * float(%s.w)), "
|
"half2 vec = (half2(sk_FragCoord.xy) - %s.xy) * %s.w;\nhalf dist = length(vec) + "
|
||||||
"half((sk_FragCoord.y - float(%s.y)) * float(%s.w)));\nhalf dist = length(vec) + "
|
"(0.5 - %s.z) * %s.w;",
|
||||||
"(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),
|
||||||
args.fUniformHandler->getUniformCStr(circleDataVar),
|
args.fUniformHandler->getUniformCStr(circleDataVar),
|
||||||
args.fUniformHandler->getUniformCStr(circleDataVar),
|
args.fUniformHandler->getUniformCStr(circleDataVar));
|
||||||
args.fUniformHandler->getUniformCStr(circleDataVar),
|
SkString _input13170 = SkStringPrintf("%s", args.fInputColor);
|
||||||
args.fUniformHandler->getUniformCStr(circleDataVar), args.fOutputColor,
|
SkString _sample13170;
|
||||||
args.fInputColor,
|
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,
|
||||||
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
|
fragBuilder->getProgramBuilder()->samplerVariable(args.fTexSamplers[0]),
|
||||||
fragBuilder->getProgramBuilder()
|
fragBuilder->getProgramBuilder()
|
||||||
->samplerSwizzle(args.fTexSamplers[0])
|
->samplerSwizzle(args.fTexSamplers[0])
|
||||||
@ -344,10 +354,18 @@ bool GrCircleBlurFragmentProcessor::onIsEqual(const GrFragmentProcessor& other)
|
|||||||
GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(
|
GrCircleBlurFragmentProcessor::GrCircleBlurFragmentProcessor(
|
||||||
const GrCircleBlurFragmentProcessor& src)
|
const GrCircleBlurFragmentProcessor& src)
|
||||||
: INHERITED(kGrCircleBlurFragmentProcessor_ClassID, src.optimizationFlags())
|
: INHERITED(kGrCircleBlurFragmentProcessor_ClassID, src.optimizationFlags())
|
||||||
|
, inputFP_index(src.inputFP_index)
|
||||||
, circleRect(src.circleRect)
|
, circleRect(src.circleRect)
|
||||||
, textureRadius(src.textureRadius)
|
, textureRadius(src.textureRadius)
|
||||||
, solidRadius(src.solidRadius)
|
, solidRadius(src.solidRadius)
|
||||||
, blurProfileSampler(src.blurProfileSampler) {
|
, 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);
|
this->setTextureSamplerCnt(1);
|
||||||
}
|
}
|
||||||
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::clone() const {
|
std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::clone() const {
|
||||||
@ -364,6 +382,7 @@ std::unique_ptr<GrFragmentProcessor> GrCircleBlurFragmentProcessor::TestCreate(
|
|||||||
SkScalar wh = testData->fRandom->nextRangeScalar(100.f, 1000.f);
|
SkScalar wh = testData->fRandom->nextRangeScalar(100.f, 1000.f);
|
||||||
SkScalar sigma = testData->fRandom->nextRangeF(1.f, 10.f);
|
SkScalar sigma = testData->fRandom->nextRangeF(1.f, 10.f);
|
||||||
SkRect circle = SkRect::MakeWH(wh, wh);
|
SkRect circle = SkRect::MakeWH(wh, wh);
|
||||||
return GrCircleBlurFragmentProcessor::Make(testData->context(), circle, sigma);
|
return GrCircleBlurFragmentProcessor::Make(/*inputFP=*/nullptr, testData->context(), circle,
|
||||||
|
sigma);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -17,28 +17,37 @@
|
|||||||
#include "src/gpu/GrFragmentProcessor.h"
|
#include "src/gpu/GrFragmentProcessor.h"
|
||||||
class GrCircleBlurFragmentProcessor : public GrFragmentProcessor {
|
class GrCircleBlurFragmentProcessor : public GrFragmentProcessor {
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<GrFragmentProcessor> Make(GrRecordingContext*,
|
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||||
|
GrRecordingContext*,
|
||||||
const SkRect& circle,
|
const SkRect& circle,
|
||||||
float sigma);
|
float sigma);
|
||||||
GrCircleBlurFragmentProcessor(const GrCircleBlurFragmentProcessor& src);
|
GrCircleBlurFragmentProcessor(const GrCircleBlurFragmentProcessor& src);
|
||||||
std::unique_ptr<GrFragmentProcessor> clone() const override;
|
std::unique_ptr<GrFragmentProcessor> clone() const override;
|
||||||
const char* name() const override { return "CircleBlurFragmentProcessor"; }
|
const char* name() const override { return "CircleBlurFragmentProcessor"; }
|
||||||
|
int inputFP_index = -1;
|
||||||
SkRect circleRect;
|
SkRect circleRect;
|
||||||
float textureRadius;
|
float textureRadius;
|
||||||
float solidRadius;
|
float solidRadius;
|
||||||
TextureSampler blurProfileSampler;
|
TextureSampler blurProfileSampler;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrCircleBlurFragmentProcessor(SkRect circleRect,
|
GrCircleBlurFragmentProcessor(std::unique_ptr<GrFragmentProcessor> inputFP,
|
||||||
|
SkRect circleRect,
|
||||||
float textureRadius,
|
float textureRadius,
|
||||||
float solidRadius,
|
float solidRadius,
|
||||||
GrSurfaceProxyView blurProfileSampler)
|
GrSurfaceProxyView blurProfileSampler)
|
||||||
: INHERITED(kGrCircleBlurFragmentProcessor_ClassID,
|
: INHERITED(kGrCircleBlurFragmentProcessor_ClassID,
|
||||||
(OptimizationFlags)kCompatibleWithCoverageAsAlpha_OptimizationFlag)
|
(OptimizationFlags)(inputFP ? ProcessorOptimizationFlags(inputFP.get())
|
||||||
|
: kAll_OptimizationFlags) &
|
||||||
|
kCompatibleWithCoverageAsAlpha_OptimizationFlag)
|
||||||
, circleRect(circleRect)
|
, circleRect(circleRect)
|
||||||
, textureRadius(textureRadius)
|
, textureRadius(textureRadius)
|
||||||
, solidRadius(solidRadius)
|
, solidRadius(solidRadius)
|
||||||
, blurProfileSampler(std::move(blurProfileSampler)) {
|
, blurProfileSampler(std::move(blurProfileSampler)) {
|
||||||
|
if (inputFP) {
|
||||||
|
inputFP_index = this->numChildProcessors();
|
||||||
|
this->registerChildProcessor(std::move(inputFP));
|
||||||
|
}
|
||||||
this->setTextureSamplerCnt(1);
|
this->setTextureSamplerCnt(1);
|
||||||
}
|
}
|
||||||
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
|
||||||
|
Loading…
Reference in New Issue
Block a user