Promote circle clipping to full float
Bug: b/123437630
Change-Id: I13409286910067d83654ba7df787784ded6736f7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/212726
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/effects/GrCircleEffect.fp b/src/gpu/effects/GrCircleEffect.fp
index de4888f..957497a 100644
--- a/src/gpu/effects/GrCircleEffect.fp
+++ b/src/gpu/effects/GrCircleEffect.fp
@@ -6,14 +6,14 @@
*/
layout(key) in GrClipEdgeType edgeType;
-in half2 center;
-in half radius;
+in float2 center;
+in float radius;
-half2 prevCenter;
-half prevRadius = -1;
+float2 prevCenter;
+float prevRadius = -1;
// The circle uniform is (center.x, center.y, radius + 0.5, 1 / (radius + 0.5)) for regular
// fills and (..., radius - 0.5, 1 / (radius - 0.5)) for inverse fills.
-uniform half4 circle;
+uniform float4 circle;
@make {
static std::unique_ptr<GrFragmentProcessor> Make(GrClipEdgeType edgeType, SkPoint center,
@@ -47,9 +47,9 @@
}
void main() {
- // TODO: Right now the distance to circle caclulation is performed in a space normalized to the
- // radius and then denormalized. This is to prevent overflow on devices that have a "real"
- // mediump. It'd be nice to only do this on mediump devices.
+ // TODO: Right now the distance to circle calculation is performed in a space normalized to the
+ // radius and then denormalized. This is to mitigate overflow on devices that don't have full
+ // float.
half d;
@if (edgeType == GrClipEdgeType::kInverseFillBW ||
edgeType == GrClipEdgeType::kInverseFillAA) {
@@ -60,12 +60,10 @@
@if (edgeType == GrClipEdgeType::kFillAA ||
edgeType == GrClipEdgeType::kInverseFillAA ||
edgeType == GrClipEdgeType::kHairlineAA) {
- d = saturate(d);
+ sk_OutColor = sk_InColor * saturate(d);
} else {
- d = d > 0.5 ? 1.0 : 0.0;
+ sk_OutColor = d > 0.5 ? sk_InColor : half4(0);
}
-
- sk_OutColor = sk_InColor * d;
}
@test(testData) {
diff --git a/src/gpu/effects/generated/GrCircleEffect.cpp b/src/gpu/effects/generated/GrCircleEffect.cpp
index d049c76..e616fee 100644
--- a/src/gpu/effects/generated/GrCircleEffect.cpp
+++ b/src/gpu/effects/generated/GrCircleEffect.cpp
@@ -30,15 +30,14 @@
auto radius = _outer.radius;
(void)radius;
prevRadius = -1.0;
- circleVar =
- args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType, "circle");
+ circleVar = args.fUniformHandler->addUniform(kFragment_GrShaderFlag, kFloat4_GrSLType,
+ "circle");
fragBuilder->codeAppendf(
- "half2 prevCenter;\nhalf prevRadius = %f;\nhalf d;\n@if (%d == 2 || %d == 3) {\n "
- " d = half((length((float2(%s.xy) - sk_FragCoord.xy) * float(%s.w)) - 1.0) * "
- "float(%s.z));\n} else {\n d = half((1.0 - length((float2(%s.xy) - "
- "sk_FragCoord.xy) * float(%s.w))) * float(%s.z));\n}\n@if ((%d == 1 || %d == 3) || "
- "%d == 4) {\n d = clamp(d, 0.0, 1.0);\n} else {\n d = d > 0.5 ? 1.0 : "
- "0.0;\n}\n%s = %s * d;\n",
+ "float2 prevCenter;\nfloat prevRadius = %f;\nhalf d;\n@if (%d == 2 || %d == 3) {\n "
+ " d = half((length((%s.xy - sk_FragCoord.xy) * %s.w) - 1.0) * %s.z);\n} else {\n "
+ " d = half((1.0 - length((%s.xy - sk_FragCoord.xy) * %s.w)) * %s.z);\n}\n@if "
+ "((%d == 1 || %d == 3) || %d == 4) {\n %s = %s * clamp(d, 0.0, 1.0);\n} else "
+ "{\n %s = d > 0.5 ? %s : half4(0.0);\n}\n",
prevRadius, (int)_outer.edgeType, (int)_outer.edgeType,
args.fUniformHandler->getUniformCStr(circleVar),
args.fUniformHandler->getUniformCStr(circleVar),
@@ -46,7 +45,8 @@
args.fUniformHandler->getUniformCStr(circleVar),
args.fUniformHandler->getUniformCStr(circleVar),
args.fUniformHandler->getUniformCStr(circleVar), (int)_outer.edgeType,
- (int)_outer.edgeType, (int)_outer.edgeType, args.fOutputColor, args.fInputColor);
+ (int)_outer.edgeType, (int)_outer.edgeType, args.fOutputColor, args.fInputColor,
+ args.fOutputColor, args.fInputColor);
}
private:
@@ -78,7 +78,7 @@
prevRadius = radius;
}
}
- SkPoint prevCenter = half2(0);
+ SkPoint prevCenter = float2(0);
float prevRadius = 0;
UniformHandle circleVar;
};