aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/effects/GrRRectEffect.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpu/effects/GrRRectEffect.cpp')
-rw-r--r--src/gpu/effects/GrRRectEffect.cpp133
1 files changed, 62 insertions, 71 deletions
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 6d47e58292..7ad354cee3 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -160,15 +160,11 @@ void GLCircularRRectEffect::emitCode(EmitArgs& args) {
// edges correspond to components x, y, z, and w, respectively. When a side of the rrect has
// only rectangular corners, that side's value corresponds to the rect edge's value outset by
// half a pixel.
- fInnerRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
- kVec4f_GrSLType, kDefault_GrSLPrecision,
- "innerRect",
- &rectName);
+ fInnerRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
+ "innerRect", &rectName);
// x is (r + .5) and y is 1/(r + .5)
- fRadiusPlusHalfUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
- kVec2f_GrSLType, kDefault_GrSLPrecision,
- "radiusPlusHalf",
- &radiusPlusHalfName);
+ fRadiusPlusHalfUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType,
+ "radiusPlusHalf", &radiusPlusHalfName);
// If we're on a device with a "real" mediump then the length calculation could overflow.
SkString clampedCircleDistance;
@@ -197,87 +193,87 @@ 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->codeAppend("float2 dxy = max(max(dxy0, dxy1), 0.0);");
- fragBuilder->codeAppendf("float alpha = %s;", clampedCircleDistance.c_str());
+ fragBuilder->codeAppendf("half2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
+ fragBuilder->codeAppendf("half2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
+ fragBuilder->codeAppend("half2 dxy = max(max(dxy0, dxy1), 0.0);");
+ fragBuilder->codeAppendf("half alpha = %s;", clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kTopLeft_CornerFlag:
- fragBuilder->codeAppendf("float2 dxy = max(%s.xy - sk_FragCoord.xy, 0.0);",
+ fragBuilder->codeAppendf("half2 dxy = max(%s.xy - sk_FragCoord.xy, 0.0);",
rectName);
- fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float alpha = bottomAlpha * rightAlpha * %s;",
+ fragBuilder->codeAppendf("half alpha = bottomAlpha * rightAlpha * %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("half2 dxy = max(half2(sk_FragCoord.x - %s.z, "
+ "%s.y - sk_FragCoord.y), 0.0);",
rectName, rectName);
- fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float alpha = bottomAlpha * leftAlpha * %s;",
+ fragBuilder->codeAppendf("half alpha = bottomAlpha * leftAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottomRight_CornerFlag:
- fragBuilder->codeAppendf("float2 dxy = max(sk_FragCoord.xy - %s.zw, 0.0);",
+ fragBuilder->codeAppendf("half2 dxy = max(sk_FragCoord.xy - %s.zw, 0.0);",
rectName);
- fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float alpha = topAlpha * leftAlpha * %s;",
+ fragBuilder->codeAppendf("half alpha = topAlpha * leftAlpha * %s;",
clampedCircleDistance.c_str());
break;
case CircularRRectEffect::kBottomLeft_CornerFlag:
- fragBuilder->codeAppendf("float2 dxy = max(float2(%s.x - sk_FragCoord.x, sk_FragCoord.y - "
+ fragBuilder->codeAppendf("half2 dxy = max(half2(%s.x - sk_FragCoord.x, sk_FragCoord.y - "
"%s.w), 0.0);",
rectName, rectName);
- fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float alpha = topAlpha * rightAlpha * %s;",
+ fragBuilder->codeAppendf("half alpha = topAlpha * rightAlpha * %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->codeAppend("float2 dxy = max(float2(dxy0.x, max(dxy0.y, dy1)), 0.0);");
- fragBuilder->codeAppendf("float rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
+ fragBuilder->codeAppendf("half dy1 = sk_FragCoord.y - %s.w;", rectName);
+ fragBuilder->codeAppend("half2 dxy = max(half2(dxy0.x, max(dxy0.y, dy1)), 0.0);");
+ fragBuilder->codeAppendf("half rightAlpha = clamp(%s.z - sk_FragCoord.x, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float alpha = rightAlpha * %s;",
+ fragBuilder->codeAppendf("half alpha = rightAlpha * %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->codeAppend("float2 dxy = max(float2(max(dxy0.x, dx1), dxy0.y), 0.0);");
- fragBuilder->codeAppendf("float bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
+ fragBuilder->codeAppendf("half dx1 = sk_FragCoord.x - %s.z;", rectName);
+ fragBuilder->codeAppend("half2 dxy = max(half2(max(dxy0.x, dx1), dxy0.y), 0.0);");
+ fragBuilder->codeAppendf("half bottomAlpha = clamp(%s.w - sk_FragCoord.y, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float alpha = bottomAlpha * %s;",
+ fragBuilder->codeAppendf("half alpha = bottomAlpha * %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->codeAppend("float2 dxy = max(float2(dxy1.x, max(dy0, dxy1.y)), 0.0);");
- fragBuilder->codeAppendf("float leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half dy0 = %s.y - sk_FragCoord.y;", rectName);
+ fragBuilder->codeAppendf("half2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
+ fragBuilder->codeAppend("half2 dxy = max(half2(dxy1.x, max(dy0, dxy1.y)), 0.0);");
+ fragBuilder->codeAppendf("half leftAlpha = clamp(sk_FragCoord.x - %s.x, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float alpha = leftAlpha * %s;",
+ fragBuilder->codeAppendf("half alpha = leftAlpha * %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->codeAppend("float2 dxy = max(float2(max(dx0, dxy1.x), dxy1.y), 0.0);");
- fragBuilder->codeAppendf("float topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
+ fragBuilder->codeAppendf("half dx0 = %s.x - sk_FragCoord.x;", rectName);
+ fragBuilder->codeAppendf("half2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
+ fragBuilder->codeAppend("half2 dxy = max(half2(max(dx0, dxy1.x), dxy1.y), 0.0);");
+ fragBuilder->codeAppendf("half topAlpha = clamp(sk_FragCoord.y - %s.y, 0.0, 1.0);",
rectName);
- fragBuilder->codeAppendf("float alpha = topAlpha * %s;",
+ fragBuilder->codeAppendf("half alpha = topAlpha * %s;",
clampedCircleDistance.c_str());
break;
}
@@ -514,10 +510,8 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
GrGLSLUniformHandler* uniformHandler = args.fUniformHandler;
const char *rectName;
// The inner rect is the rrect bounds inset by the x/y radii
- fInnerRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
- kVec4f_GrSLType, kDefault_GrSLPrecision,
- "innerRect",
- &rectName);
+ fInnerRectUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf4_GrSLType,
+ "innerRect", &rectName);
GrGLSLFPFragmentBuilder* fragBuilder = args.fFragBuilder;
// At each quarter-ellipse corner we compute a vector that is the offset of the fragment pos
@@ -532,17 +526,16 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
// The code below is a simplified version of the above that performs maxs on the vector
// components before computing distances and alpha values so that only one distance computation
// need be computed to determine the min alpha.
- fragBuilder->codeAppendf("float2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
- fragBuilder->codeAppendf("float2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
+ fragBuilder->codeAppendf("half2 dxy0 = %s.xy - sk_FragCoord.xy;", rectName);
+ fragBuilder->codeAppendf("half2 dxy1 = sk_FragCoord.xy - %s.zw;", rectName);
// If we're on a device with a "real" mediump then we'll do the distance computation in a space
// that is normalized by the largest radius. The scale uniform will be scale, 1/scale. The
// radii uniform values are already in this normalized space.
const char* scaleName = nullptr;
if (args.fShaderCaps->floatPrecisionVaries()) {
- fScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
- kVec2f_GrSLType, kDefault_GrSLPrecision,
- "scale", &scaleName);
+ fScaleUniform = uniformHandler->addUniform(kFragment_GrShaderFlag, kHalf2_GrSLType, "scale",
+ &scaleName);
}
// The uniforms with the inv squared radii are highp to prevent underflow.
@@ -550,34 +543,32 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
case SkRRect::kSimple_Type: {
const char *invRadiiXYSqdName;
fInvRadiiSqdUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
- kVec2f_GrSLType,
- kDefault_GrSLPrecision,
+ kHalf2_GrSLType,
"invRadiiXY",
&invRadiiXYSqdName);
- fragBuilder->codeAppend("float2 dxy = max(max(dxy0, dxy1), 0.0);");
+ fragBuilder->codeAppend("half2 dxy = max(max(dxy0, dxy1), 0.0);");
if (scaleName) {
fragBuilder->codeAppendf("dxy *= %s.y;", scaleName);
}
// Z is the x/y offsets divided by squared radii.
- fragBuilder->codeAppendf("float2 Z = dxy * %s.xy;", invRadiiXYSqdName);
+ fragBuilder->codeAppendf("half2 Z = dxy * %s.xy;", invRadiiXYSqdName);
break;
}
case SkRRect::kNinePatch_Type: {
const char *invRadiiLTRBSqdName;
fInvRadiiSqdUniform = uniformHandler->addUniform(kFragment_GrShaderFlag,
- kVec4f_GrSLType,
- kDefault_GrSLPrecision,
+ kHalf4_GrSLType,
"invRadiiLTRB",
&invRadiiLTRBSqdName);
if (scaleName) {
fragBuilder->codeAppendf("dxy0 *= %s.y;", scaleName);
fragBuilder->codeAppendf("dxy1 *= %s.y;", scaleName);
}
- fragBuilder->codeAppend("float2 dxy = max(max(dxy0, dxy1), 0.0);");
+ fragBuilder->codeAppend("half2 dxy = max(max(dxy0, dxy1), 0.0);");
// Z is the x/y offsets divided by squared radii. We only care about the (at most) one
// corner where both the x and y offsets are positive, hence the maxes. (The inverse
// squared radii will always be positive.)
- fragBuilder->codeAppendf("float2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);",
+ fragBuilder->codeAppendf("half2 Z = max(max(dxy0 * %s.xy, dxy1 * %s.zw), 0.0);",
invRadiiLTRBSqdName, invRadiiLTRBSqdName);
break;
@@ -586,20 +577,20 @@ void GLEllipticalRRectEffect::emitCode(EmitArgs& args) {
SK_ABORT("RRect should always be simple or nine-patch.");
}
// implicit is the evaluation of (x/a)^2 + (y/b)^2 - 1.
- fragBuilder->codeAppend("float implicit = dot(Z, dxy) - 1.0;");
+ fragBuilder->codeAppend("half implicit = dot(Z, dxy) - 1.0;");
// grad_dot is the squared length of the gradient of the implicit.
- fragBuilder->codeAppend("float grad_dot = 4.0 * dot(Z, Z);");
+ fragBuilder->codeAppend("half grad_dot = 4.0 * dot(Z, Z);");
// avoid calling inversesqrt on zero.
fragBuilder->codeAppend("grad_dot = max(grad_dot, 1.0e-4);");
- fragBuilder->codeAppend("float approx_dist = implicit * inversesqrt(grad_dot);");
+ fragBuilder->codeAppend("half approx_dist = implicit * inversesqrt(grad_dot);");
if (scaleName) {
fragBuilder->codeAppendf("approx_dist *= %s.x;", scaleName);
}
if (kFillAA_GrProcessorEdgeType == erre.getEdgeType()) {
- fragBuilder->codeAppend("float alpha = clamp(0.5 - approx_dist, 0.0, 1.0);");
+ fragBuilder->codeAppend("half alpha = clamp(0.5 - approx_dist, 0.0, 1.0);");
} else {
- fragBuilder->codeAppend("float alpha = clamp(0.5 + approx_dist, 0.0, 1.0);");
+ fragBuilder->codeAppend("half alpha = clamp(0.5 + approx_dist, 0.0, 1.0);");
}
fragBuilder->codeAppendf("%s = %s * alpha;", args.fOutputColor, args.fInputColor);