diff options
Diffstat (limited to 'src/effects/gradients/SkSweepGradient.cpp')
-rw-r--r-- | src/effects/gradients/SkSweepGradient.cpp | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp index 1608ae2f72..64778c3a54 100644 --- a/src/effects/gradients/SkSweepGradient.cpp +++ b/src/effects/gradients/SkSweepGradient.cpp @@ -210,8 +210,18 @@ void GrSweepGradient::GLSLSweepProcessor::emitCode(EmitArgs& args) { SkString coords2D = args.fFragBuilder->ensureCoords2D(args.fTransformedCoords[0]); SkString t; // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi] - t.printf("(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5)", - coords2D.c_str(), coords2D.c_str()); + if (args.fShaderCaps->atan2ImplementedAsAtanYOverX()) { + // On some devices they incorrectly implement atan2(y,x) as atan(y/x). In actuality it is + // atan2(y,x) = 2 * atan(y / (sqrt(x^2 + y^2) + x)). So to work around this we pass in + // (sqrt(x^2 + y^2) + x) as the second parameter to atan2 in these cases. We let the device + // handle the undefined behavior of the second paramenter being 0 instead of doing the + // divide ourselves and using atan instead. + t.printf("(2.0 * atan(- %s.y, length(%s) - %s.x) * 0.1591549430918 + 0.5)", + coords2D.c_str(), coords2D.c_str(), coords2D.c_str()); + } else { + t.printf("(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5)", + coords2D.c_str(), coords2D.c_str()); + } this->emitColor(args.fFragBuilder, args.fUniformHandler, args.fShaderCaps, |