aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/effects/gradients/SkSweepGradient.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/effects/gradients/SkSweepGradient.cpp')
-rw-r--r--src/effects/gradients/SkSweepGradient.cpp14
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,