| Index: src/gpu/effects/GrOvalEffect.cpp
|
| diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp
|
| index 0adbb67b9c30cbfdacec0da71f7d9c688235322f..97cb4d8dc9809c7264c038fea89d7bc6afe84f32 100644
|
| --- a/src/gpu/effects/GrOvalEffect.cpp
|
| +++ b/src/gpu/effects/GrOvalEffect.cpp
|
| @@ -128,10 +128,10 @@ void GLCircleEffect::emitCode(GrGLFPBuilder* builder,
|
| const TextureSamplerArray& samplers) {
|
| const CircleEffect& ce = fp.cast<CircleEffect>();
|
| const char *circleName;
|
| - // The circle uniform is (center.x, center.y, radius + 0.5) for regular fills and
|
| - // (... ,radius - 0.5) for inverse fills.
|
| + // 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.
|
| fCircleUniform = builder->addUniform(GrGLProgramBuilder::kFragment_Visibility,
|
| - kVec3f_GrSLType, kDefault_GrSLPrecision,
|
| + kVec4f_GrSLType, kDefault_GrSLPrecision,
|
| "circle",
|
| &circleName);
|
|
|
| @@ -139,12 +139,16 @@ void GLCircleEffect::emitCode(GrGLFPBuilder* builder,
|
| const char* fragmentPos = fsBuilder->fragmentPosition();
|
|
|
| SkASSERT(kHairlineAA_GrProcessorEdgeType != ce.getEdgeType());
|
| + // 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 to this on mediump devices but we currently don't have the
|
| + // caps here.
|
| if (GrProcessorEdgeTypeIsInverseFill(ce.getEdgeType())) {
|
| - fsBuilder->codeAppendf("\t\tfloat d = length(%s.xy - %s.xy) - %s.z;\n",
|
| - circleName, fragmentPos, circleName);
|
| + fsBuilder->codeAppendf("\t\tfloat d = (length((%s.xy - %s.xy) * %s.w) - 1.0) * %s.z;\n",
|
| + circleName, fragmentPos, circleName, circleName);
|
| } else {
|
| - fsBuilder->codeAppendf("\t\tfloat d = %s.z - length(%s.xy - %s.xy);\n",
|
| - circleName, fragmentPos, circleName);
|
| + fsBuilder->codeAppendf("\t\tfloat d = (1.0 - length((%s.xy - %s.xy) * %s.w)) * %s.z;\n",
|
| + circleName, fragmentPos, circleName, circleName);
|
| }
|
| if (GrProcessorEdgeTypeIsAA(ce.getEdgeType())) {
|
| fsBuilder->codeAppend("\t\td = clamp(d, 0.0, 1.0);\n");
|
| @@ -171,7 +175,8 @@ void GLCircleEffect::setData(const GrGLProgramDataManager& pdman, const GrProces
|
| } else {
|
| radius += 0.5f;
|
| }
|
| - pdman.set3f(fCircleUniform, ce.getCenter().fX, ce.getCenter().fY, radius);
|
| + pdman.set4f(fCircleUniform, ce.getCenter().fX, ce.getCenter().fY, radius,
|
| + SkScalarInvert(radius));
|
| fPrevCenter = ce.getCenter();
|
| fPrevRadius = ce.getRadius();
|
| }
|
|
|