added SkSL support for mustForceNegatedAtanParamToFloat cap

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2413363002

Review-Url: https://codereview.chromium.org/2413363002
diff --git a/src/effects/gradients/SkSweepGradient.cpp b/src/effects/gradients/SkSweepGradient.cpp
index f4ef8ab..d62e2e5 100644
--- a/src/effects/gradients/SkSweepGradient.cpp
+++ b/src/effects/gradients/SkSweepGradient.cpp
@@ -210,15 +210,8 @@
     SkString coords2D = args.fFragBuilder->ensureCoords2D(args.fTransformedCoords[0]);
     SkString t;
     // 0.1591549430918 is 1/(2*pi), used since atan returns values [-pi, pi]
-    // On Intel GPU there is an issue where it reads the second arguement to atan "- %s.x" as an int
-    // thus must us -1.0 * %s.x to work correctly
-    if (args.fGLSLCaps->mustForceNegatedAtanParamToFloat()){
-        t.printf("(atan(- %s.y, -1.0 * %s.x) * 0.1591549430918 + 0.5)",
-                 coords2D.c_str(), coords2D.c_str());
-    } else {
-        t.printf("(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5)",
-                 coords2D.c_str(), coords2D.c_str());
-    }
+    t.printf("(atan(- %s.y, - %s.x) * 0.1591549430918 + 0.5)",
+             coords2D.c_str(), coords2D.c_str());
     this->emitColor(args.fFragBuilder,
                     args.fUniformHandler,
                     args.fGLSLCaps,
diff --git a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
index b26ce89..8e8bb9a 100644
--- a/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
+++ b/src/gpu/gl/builders/GrGLShaderStringBuilder.cpp
@@ -86,6 +86,7 @@
     result.fUsesPrecisionModifiers = glslCaps->usesPrecisionModifiers();
     result.fMustDeclareFragmentShaderOutput = glslCaps->mustDeclareFragmentShaderOutput();
     result.fCanUseMinAndAbsTogether = glslCaps->canUseMinAndAbsTogether();
+    result.fMustForceNegatedAtanParamToFloat = glslCaps->mustForceNegatedAtanParamToFloat();
     return result;
 }
 
diff --git a/src/sksl/SkSLGLSLCodeGenerator.cpp b/src/sksl/SkSLGLSLCodeGenerator.cpp
index 58cf7d3..45644e8 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.cpp
+++ b/src/sksl/SkSLGLSLCodeGenerator.cpp
@@ -163,6 +163,18 @@
             return;
         }
     }
+    if (fCaps.fMustForceNegatedAtanParamToFloat && c.fFunction.fName == "atan" && 
+        c.fArguments.size() == 2 && c.fArguments[1]->fKind == Expression::kPrefix_Kind) {
+        const PrefixExpression& p = (PrefixExpression&) *c.fArguments[1];
+        if (p.fOperator == Token::MINUS) {
+            this->write("atan(");
+            this->writeExpression(*c.fArguments[0], kSequence_Precedence);
+            this->write(", -1.0 * ");
+            this->writeExpression(*p.fOperand, kMultiplicative_Precedence);
+            this->write(")");
+            return;
+        }
+    }
     this->write(c.fFunction.fName + "(");
     const char* separator = "";
     for (const auto& arg : c.fArguments) {
diff --git a/src/sksl/SkSLGLSLCodeGenerator.h b/src/sksl/SkSLGLSLCodeGenerator.h
index 965721e..17ac90e 100644
--- a/src/sksl/SkSLGLSLCodeGenerator.h
+++ b/src/sksl/SkSLGLSLCodeGenerator.h
@@ -55,6 +55,10 @@
     bool fMustDeclareFragmentShaderOutput;
     // The Tegra3 compiler will sometimes never return if we have min(abs(x), y)
     bool fCanUseMinAndAbsTogether;
+    // On Intel GPU there is an issue where it misinterprets an atan argument (second argument only,
+    // apparently) of the form "-<expr>" as an int, so we rewrite it as "-1.0 * <expr>" to avoid
+    // this problem
+    bool fMustForceNegatedAtanParamToFloat;
 };
 
 /**
diff --git a/src/sksl/SkSLMain.cpp b/src/sksl/SkSLMain.cpp
index de1b981..fe925e0 100644
--- a/src/sksl/SkSLMain.cpp
+++ b/src/sksl/SkSLMain.cpp
@@ -23,7 +23,8 @@
              false, // isCoreProfile
              false, // usesPrecisionModifiers;
              false, // mustDeclareFragmentShaderOutput
-             true   // canUseMinAndAbsTogether
+             true,  // canUseMinAndAbsTogether
+             false  // mustForceNegatedAtanParamToFloat
            };
 }
 
diff --git a/tests/SkSLGLSLTest.cpp b/tests/SkSLGLSLTest.cpp
index dedddad..b615f67 100644
--- a/tests/SkSLGLSLTest.cpp
+++ b/tests/SkSLGLSLTest.cpp
@@ -33,7 +33,8 @@
              false, // isCoreProfile
              false, // usesPrecisionModifiers;
              false, // mustDeclareFragmentShaderOutput
-             true   // canUseMinAndAbsTogether
+             true,  // canUseMinAndAbsTogether
+             false  // mustForceNegatedAtanParamToFloat
            };
 }
 
@@ -315,6 +316,27 @@
          "}\n");
 }
 
+DEF_TEST(SkSLNegatedAtan, r) {
+    test(r,
+         "void main() { vec2 x = vec2(1, 2); float y = atan(x.x, -(2 * x.y)); }",
+         default_caps(),
+         "#version 400\n"
+         "void main() {\n"
+         "    vec2 x = vec2(1.0, 2.0);\n"
+         "    float y = atan(x.x, -(2.0 * x.y));\n"
+         "}\n");
+    SkSL::GLCaps caps = default_caps();
+    caps.fMustForceNegatedAtanParamToFloat = true;
+    test(r,
+         "void main() { vec2 x = vec2(1, 2); float y = atan(x.x, -(2 * x.y)); }",
+         caps,
+         "#version 400\n"
+         "void main() {\n"
+         "    vec2 x = vec2(1.0, 2.0);\n"
+         "    float y = atan(x.x, -1.0 * (2.0 * x.y));\n"
+         "}\n");
+}
+
 DEF_TEST(SkSLModifiersDeclaration, r) {
     test(r,
          "layout(blend_support_all_equations) out;"