Update CircularRRectEffect 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.

Additionally, fixed up "xyzw" swizzles on rectangle coordinates to
"LTRB" for clarity.

Change-Id: Ifc9107070b8664b7158961748f9727e0a3d58640
Bug: skia:10217
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/295566
Reviewed-by: Greg Daniel <egdaniel@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
This commit is contained in:
John Stiles 2020-06-10 17:25:58 -04:00 committed by Skia Commit-Bot
parent 34f28691f0
commit 56bf90bf67

View File

@ -45,7 +45,8 @@ public:
// The flags are used to indicate which corners are circluar (unflagged corners are assumed to
// be square).
static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType,
static std::unique_ptr<GrFragmentProcessor> Make(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType,
uint32_t circularCornerFlags, const SkRRect&);
~CircularRRectEffect() override {}
@ -60,8 +61,11 @@ public:
GrClipEdgeType getEdgeType() const { return fEdgeType; }
int getInputFPIndex() const { return fInputFPIndex; }
private:
CircularRRectEffect(GrClipEdgeType, uint32_t circularCornerFlags, const SkRRect&);
CircularRRectEffect(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType, uint32_t circularCornerFlags, const SkRRect&);
GrGLSLFragmentProcessor* onCreateGLSLInstance() const override;
@ -69,36 +73,53 @@ private:
bool onIsEqual(const GrFragmentProcessor& other) const override;
SkRRect fRRect;
SkRRect fRRect;
GrClipEdgeType fEdgeType;
uint32_t fCircularCornerFlags;
uint32_t fCircularCornerFlags;
int fInputFPIndex;
GR_DECLARE_FRAGMENT_PROCESSOR_TEST
typedef GrFragmentProcessor INHERITED;
};
std::unique_ptr<GrFragmentProcessor> CircularRRectEffect::Make(GrClipEdgeType edgeType,
uint32_t circularCornerFlags,
const SkRRect& rrect) {
std::unique_ptr<GrFragmentProcessor> CircularRRectEffect::Make(
std::unique_ptr<GrFragmentProcessor> inputFP, GrClipEdgeType edgeType,
uint32_t circularCornerFlags, const SkRRect& rrect) {
if (GrClipEdgeType::kFillAA != edgeType && GrClipEdgeType::kInverseFillAA != edgeType) {
return nullptr;
}
return std::unique_ptr<GrFragmentProcessor>(
new CircularRRectEffect(edgeType, circularCornerFlags, rrect));
new CircularRRectEffect(std::move(inputFP), edgeType, circularCornerFlags, rrect));
}
CircularRRectEffect::CircularRRectEffect(GrClipEdgeType edgeType, uint32_t circularCornerFlags,
CircularRRectEffect::CircularRRectEffect(std::unique_ptr<GrFragmentProcessor> inputFP,
GrClipEdgeType edgeType, uint32_t circularCornerFlags,
const SkRRect& rrect)
: INHERITED(kCircularRRectEffect_ClassID, kCompatibleWithCoverageAsAlpha_OptimizationFlag)
: INHERITED(
kCircularRRectEffect_ClassID,
(inputFP ? ProcessorOptimizationFlags(inputFP.get()) : kAll_OptimizationFlags) &
kCompatibleWithCoverageAsAlpha_OptimizationFlag)
, fRRect(rrect)
, fEdgeType(edgeType)
, fCircularCornerFlags(circularCornerFlags) {
fInputFPIndex = inputFP
? this->registerChildProcessor(std::move(inputFP))
: -1;
}
std::unique_ptr<GrFragmentProcessor> CircularRRectEffect::clone() const {
return std::unique_ptr<GrFragmentProcessor>(
new CircularRRectEffect(fEdgeType, fCircularCornerFlags, fRRect));
std::unique_ptr<GrFragmentProcessor> inputFPClone;
if (fInputFPIndex >= 0) {
const GrFragmentProcessor& inputFP = this->childProcessor(fInputFPIndex);
inputFPClone = inputFP.clone();
if (inputFP.isSampledWithExplicitCoords()) {
inputFPClone->setSampledWithExplicitCoords();
}
}
return std::unique_ptr<GrFragmentProcessor>(new CircularRRectEffect(
std::move(inputFPClone), fEdgeType, fCircularCornerFlags, fRRect));
}
bool CircularRRectEffect::onIsEqual(const GrFragmentProcessor& other) const {
@ -191,85 +212,85 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
// alphas together.
switch (crre.getCircularCornerFlags()) {
case CircularRRectEffect::kAll_CornerFlags:
fragBuilder->codeAppendf("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
fragBuilder->codeAppendf("float2 dxy0 = %s.LT - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.RB;", rectName);
fragBuilder->codeAppend("float2 dxy = max(max(dxy0, dxy1), 0.0);");
fragBuilder->codeAppendf("half alpha = half(%s);", clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTopLeft_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(%s.xy - sk_FragCoord.xy, 0.0);",
fragBuilder->codeAppendf("float2 dxy = max(%s.LT - sk_FragCoord.xy, 0.0);",
rectName);
fragBuilder->codeAppendf("half rightAlpha = half(saturate(%s.z - sk_FragCoord.x));",
fragBuilder->codeAppendf("half rightAlpha = half(saturate(%s.R - sk_FragCoord.x));",
rectName);
fragBuilder->codeAppendf("half bottomAlpha = half(saturate(%s.w - sk_FragCoord.y));",
fragBuilder->codeAppendf("half bottomAlpha = half(saturate(%s.B - sk_FragCoord.y));",
rectName);
fragBuilder->codeAppendf("half alpha = bottomAlpha * rightAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTopRight_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(float2(sk_FragCoord.x - %s.z, "
"%s.y - sk_FragCoord.y), 0.0);",
fragBuilder->codeAppendf("float2 dxy = max(float2(sk_FragCoord.x - %s.R, "
"%s.T - sk_FragCoord.y), 0.0);",
rectName, rectName);
fragBuilder->codeAppendf("half leftAlpha = half(saturate(sk_FragCoord.x - %s.x));",
fragBuilder->codeAppendf("half leftAlpha = half(saturate(sk_FragCoord.x - %s.L));",
rectName);
fragBuilder->codeAppendf("half bottomAlpha = half(saturate(%s.w - sk_FragCoord.y));",
fragBuilder->codeAppendf("half bottomAlpha = half(saturate(%s.B - sk_FragCoord.y));",
rectName);
fragBuilder->codeAppendf("half alpha = bottomAlpha * leftAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottomRight_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(sk_FragCoord.xy - %s.zw, 0.0);",
fragBuilder->codeAppendf("float2 dxy = max(sk_FragCoord.xy - %s.RB, 0.0);",
rectName);
fragBuilder->codeAppendf("half leftAlpha = half(saturate(sk_FragCoord.x - %s.x));",
fragBuilder->codeAppendf("half leftAlpha = half(saturate(sk_FragCoord.x - %s.L));",
rectName);
fragBuilder->codeAppendf("half topAlpha = half(saturate(sk_FragCoord.y - %s.y));",
fragBuilder->codeAppendf("half topAlpha = half(saturate(sk_FragCoord.y - %s.T));",
rectName);
fragBuilder->codeAppendf("half alpha = topAlpha * leftAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottomLeft_CornerFlag:
fragBuilder->codeAppendf("float2 dxy = max(float2(%s.x - sk_FragCoord.x, "
"sk_FragCoord.y - %s.w), 0.0);",
fragBuilder->codeAppendf("float2 dxy = max(float2(%s.L - sk_FragCoord.x, "
"sk_FragCoord.y - %s.B), 0.0);",
rectName, rectName);
fragBuilder->codeAppendf("half rightAlpha = half(saturate(%s.z - sk_FragCoord.x));",
fragBuilder->codeAppendf("half rightAlpha = half(saturate(%s.R - sk_FragCoord.x));",
rectName);
fragBuilder->codeAppendf("half topAlpha = half(saturate(sk_FragCoord.y - %s.y));",
fragBuilder->codeAppendf("half topAlpha = half(saturate(sk_FragCoord.y - %s.T));",
rectName);
fragBuilder->codeAppendf("half alpha = topAlpha * rightAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kLeft_CornerFlags:
fragBuilder->codeAppendf("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float dy1 = sk_FragCoord.y - %s.w;", rectName);
fragBuilder->codeAppendf("float2 dxy0 = %s.LT - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float dy1 = sk_FragCoord.y - %s.B;", rectName);
fragBuilder->codeAppend("float2 dxy = max(float2(dxy0.x, max(dxy0.y, dy1)), 0.0);");
fragBuilder->codeAppendf("half rightAlpha = half(saturate(%s.z - sk_FragCoord.x));",
fragBuilder->codeAppendf("half rightAlpha = half(saturate(%s.R - sk_FragCoord.x));",
rectName);
fragBuilder->codeAppendf("half alpha = rightAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTop_CornerFlags:
fragBuilder->codeAppendf("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float dx1 = sk_FragCoord.x - %s.z;", rectName);
fragBuilder->codeAppendf("float2 dxy0 = %s.LT - sk_FragCoord.xy;", rectName);
fragBuilder->codeAppendf("float dx1 = sk_FragCoord.x - %s.R;", rectName);
fragBuilder->codeAppend("float2 dxy = max(float2(max(dxy0.x, dx1), dxy0.y), 0.0);");
fragBuilder->codeAppendf("half bottomAlpha = half(saturate(%s.w - sk_FragCoord.y));",
fragBuilder->codeAppendf("half bottomAlpha = half(saturate(%s.B - sk_FragCoord.y));",
rectName);
fragBuilder->codeAppendf("half alpha = bottomAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kRight_CornerFlags:
fragBuilder->codeAppendf("float dy0 = %s.y - sk_FragCoord.y;", rectName);
fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
fragBuilder->codeAppendf("float dy0 = %s.T - sk_FragCoord.y;", rectName);
fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.RB;", rectName);
fragBuilder->codeAppend("float2 dxy = max(float2(dxy1.x, max(dy0, dxy1.y)), 0.0);");
fragBuilder->codeAppendf("half leftAlpha = half(saturate(sk_FragCoord.x - %s.x));",
fragBuilder->codeAppendf("half leftAlpha = half(saturate(sk_FragCoord.x - %s.L));",
rectName);
fragBuilder->codeAppendf("half alpha = leftAlpha * half(%s);",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottom_CornerFlags:
fragBuilder->codeAppendf("float dx0 = %s.x - sk_FragCoord.x;", rectName);
fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
fragBuilder->codeAppendf("float dx0 = %s.L - sk_FragCoord.x;", rectName);
fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.RB;", rectName);
fragBuilder->codeAppend("float2 dxy = max(float2(max(dx0, dxy1.x), dxy1.y), 0.0);");
fragBuilder->codeAppendf("half topAlpha = half(saturate(sk_FragCoord.y - %s.y));",
fragBuilder->codeAppendf("half topAlpha = half(saturate(sk_FragCoord.y - %s.T));",
rectName);
fragBuilder->codeAppendf("half alpha = topAlpha * half(%s);",
clampedCircleDistance.c_str());
@ -280,7 +301,11 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
fragBuilder->codeAppend("alpha = 1.0 - alpha;");
}
fragBuilder->codeAppendf("%s = %s * alpha;", args.fOutputColor, args.fInputColor);
SkString inputSample = (crre.getInputFPIndex() >= 0)
? this->invokeChild(crre.getInputFPIndex(), args.fInputColor, args)
: SkString(args.fInputColor);
fragBuilder->codeAppendf("%s = %s * alpha;", args.fOutputColor, inputSample.c_str());
}
void GLCircularRRectEffect::GenKey(const GrProcessor& processor, const GrShaderCaps&,
@ -690,8 +715,8 @@ std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType
return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());
}
if (SkRRectPriv::GetSimpleRadii(rrect).fX == SkRRectPriv::GetSimpleRadii(rrect).fY) {
return CircularRRectEffect::Make(edgeType, CircularRRectEffect::kAll_CornerFlags,
rrect);
return CircularRRectEffect::Make(/*inputFP=*/nullptr, edgeType,
CircularRRectEffect::kAll_CornerFlags, rrect);
} else {
return EllipticalRRectEffect::Make(edgeType, rrect);
}
@ -749,7 +774,7 @@ std::unique_ptr<GrFragmentProcessor> GrRRectEffect::Make(GrClipEdgeType edgeType
if (squashedRadii) {
rr.writable()->setRectRadii(rrect.getBounds(), radii);
}
return CircularRRectEffect::Make(edgeType, cornerFlags, *rr);
return CircularRRectEffect::Make(/*inputFP=*/nullptr, edgeType, cornerFlags, *rr);
}
case CircularRRectEffect::kNone_CornerFlags:
return GrConvexPolyEffect::Make(edgeType, rrect.getBounds());