Make GrGLShaderBuilder::fragmentPosition() return a vec4, with 1.0 as the zw components when in the y-flip case. This works around an Adreno driver bug.

Revert "Stop referencing gl_FragCoord z and w components."

This reverts commit 160a52ba217012ed73c240f6d67b3bbf2b4879d6.

R=jvanverth@google.com

Author: bsalomon@google.com

Review URL: https://codereview.chromium.org/354663002
diff --git a/src/effects/SkBlurMaskFilter.cpp b/src/effects/SkBlurMaskFilter.cpp
index 5f7f5b8..fca38a1 100644
--- a/src/effects/SkBlurMaskFilter.cpp
+++ b/src/effects/SkBlurMaskFilter.cpp
@@ -1015,7 +1015,7 @@
     // warp the fragment position to the appropriate part of the 9patch blur texture
 
     builder->fsCodeAppendf("\t\tvec2 rectCenter = (%s.xy + %s.zw)/2.0;\n", rectName, rectName);
-    builder->fsCodeAppendf("\t\tvec2 translatedFragPos = %s - %s.xy;\n", fragmentPos, rectName);
+    builder->fsCodeAppendf("\t\tvec2 translatedFragPos = %s.xy - %s.xy;\n", fragmentPos, rectName);
     builder->fsCodeAppendf("\t\tfloat threshold = %s + 2.0*%s;\n", cornerRadiusName, blurRadiusName );
     builder->fsCodeAppendf("\t\tvec2 middle = %s.zw - %s.xy - 2.0*threshold;\n", rectName, rectName );
 
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index b5d2db9..497b3cf 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -200,7 +200,7 @@
             builder->fsCodeAppend("\tfloat scaleH = min(1.0, 2.0*insetH/spanH);\n");
 
             // Compute the coverage for the rect's width
-            builder->fsCodeAppendf("\tvec2 offset = %s - %s.xy;\n",
+            builder->fsCodeAppendf("\tvec2 offset = %s.xy - %s.xy;\n",
                                    builder->fragmentPosition(), fsRectEdgeName);
             builder->fsCodeAppendf("\tfloat perpDot = abs(offset.x * %s.w - offset.y * %s.z);\n",
                                    fsRectEdgeName, fsRectEdgeName);
diff --git a/src/gpu/effects/GrDitherEffect.cpp b/src/gpu/effects/GrDitherEffect.cpp
index e82b565..7409e5f 100644
--- a/src/gpu/effects/GrDitherEffect.cpp
+++ b/src/gpu/effects/GrDitherEffect.cpp
@@ -102,7 +102,7 @@
     // For each channel c, add the random offset to the pixel to either bump
     // it up or let it remain constant during quantization.
     builder->fsCodeAppendf("\t\tfloat r = "
-                           "fract(sin(dot(%s ,vec2(12.9898,78.233))) * 43758.5453);\n",
+                           "fract(sin(dot(%s.xy ,vec2(12.9898,78.233))) * 43758.5453);\n",
                            builder->fragmentPosition());
     builder->fsCodeAppendf("\t\t%s = (1.0/255.0) * vec4(r, r, r, r) + %s;\n",
                            outputColor, GrGLSLExpr4(inputColor).c_str());
diff --git a/src/gpu/effects/GrOvalEffect.cpp b/src/gpu/effects/GrOvalEffect.cpp
index 1297331..f2ee278 100644
--- a/src/gpu/effects/GrOvalEffect.cpp
+++ b/src/gpu/effects/GrOvalEffect.cpp
@@ -147,10 +147,10 @@
 
     SkASSERT(kHairlineAA_GrEffectEdgeType != ce.getEdgeType());
     if (GrEffectEdgeTypeIsInverseFill(ce.getEdgeType())) {
-        builder->fsCodeAppendf("\t\tfloat d = length(%s.xy - %s) - %s.z;\n",
+        builder->fsCodeAppendf("\t\tfloat d = length(%s.xy - %s.xy) - %s.z;\n",
                                 circleName, fragmentPos, circleName);
     } else {
-        builder->fsCodeAppendf("\t\tfloat d = %s.z - length(%s - %s.xy);\n",
+        builder->fsCodeAppendf("\t\tfloat d = %s.z - length(%s.xy - %s.xy);\n",
                                circleName, fragmentPos, circleName);
     }
     if (GrEffectEdgeTypeIsAA(ce.getEdgeType())) {
@@ -318,7 +318,7 @@
     const char* fragmentPos = builder->fragmentPosition();
 
     // d is the offset to the ellipse center
-    builder->fsCodeAppendf("\t\tvec2 d = %s - %s.xy;\n", fragmentPos, ellipseName);
+    builder->fsCodeAppendf("\t\tvec2 d = %s.xy - %s.xy;\n", fragmentPos, ellipseName);
     builder->fsCodeAppendf("\t\tvec2 Z = d * %s.zw;\n", ellipseName);
     // implicit is the evaluation of (x/rx)^2 + (y/ry)^2 - 1.
     builder->fsCodeAppend("\t\tfloat implicit = dot(Z, d) - 1.0;\n");
diff --git a/src/gpu/effects/GrRRectEffect.cpp b/src/gpu/effects/GrRRectEffect.cpp
index 0f2178b..11d8a18 100644
--- a/src/gpu/effects/GrRRectEffect.cpp
+++ b/src/gpu/effects/GrRRectEffect.cpp
@@ -199,8 +199,8 @@
     // alphas together.
     switch (crre.getCircularCornerFlags()) {
         case CircularRRectEffect::kAll_CornerFlags:
-            builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s;\n", rectName, fragmentPos);
-            builder->fsCodeAppendf("\t\tvec2 dxy1 = %s - %s.zw;\n", fragmentPos, rectName);
+            builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
+            builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
             builder->fsCodeAppend("\t\tvec2 dxy = max(max(dxy0, dxy1), 0.0);\n");
             builder->fsCodeAppendf("\t\tfloat alpha = clamp(%s - length(dxy), 0.0, 1.0);\n",
                                    radiusPlusHalfName);
@@ -537,8 +537,8 @@
     // 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.
-    builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s;\n", rectName, fragmentPos);
-    builder->fsCodeAppendf("\t\tvec2 dxy1 = %s - %s.zw;\n", fragmentPos, rectName);
+    builder->fsCodeAppendf("\t\tvec2 dxy0 = %s.xy - %s.xy;\n", rectName, fragmentPos);
+    builder->fsCodeAppendf("\t\tvec2 dxy1 = %s.xy - %s.zw;\n", fragmentPos, rectName);
     switch (erre.getRRect().getType()) {
         case SkRRect::kSimple_Type: {
             const char *invRadiiXYSqdName;
diff --git a/src/gpu/gl/GrGLShaderBuilder.cpp b/src/gpu/gl/GrGLShaderBuilder.cpp
index c2ebce2..764d482 100644
--- a/src/gpu/gl/GrGLShaderBuilder.cpp
+++ b/src/gpu/gl/GrGLShaderBuilder.cpp
@@ -499,7 +499,7 @@
     // declaration varies in earlier GLSL specs. So it is simpler to omit it.
     if (fTopLeftFragPosRead) {
         fSetupFragPosition = true;
-        return "(gl_FragCoord.xy)";
+        return "gl_FragCoord";
     } else if (fGpu->glCaps().fragCoordConventionsSupport()) {
         if (!fSetupFragPosition) {
             SkAssertResult(this->enablePrivateFeature(kFragCoordConventions_GLSLPrivateFeature));
@@ -510,7 +510,7 @@
                                       GrGLShaderVar::kUpperLeft_Origin);
             fSetupFragPosition = true;
         }
-        return "(gl_FragCoord.xy)";
+        return "gl_FragCoord";
     } else {
         static const char* kCoordName = "fragCoordYDown";
         if (!fSetupFragPosition) {
@@ -523,8 +523,11 @@
             fOutput.fUniformHandles.fRTHeightUni =
                 this->addUniform(kFragment_Visibility, kFloat_GrSLType, "RTHeight", &rtHeightName);
 
-            this->fFSCode.prependf("\tvec2 %s = vec2(gl_FragCoord.x, %s - gl_FragCoord.y);\n",
-                                   kCoordName, rtHeightName);
+            // Using glFragCoord.zw for the last two components tickles an Adreno driver bug that
+            // causes programs to fail to link. Making this function return a vec2() didn't fix the
+            // problem but using 1.0 for the last two components does.
+            this->fFSCode.prependf("\tvec4 %s = vec4(gl_FragCoord.x, %s - gl_FragCoord.y, 1.0, "
+                                   "1.0);\n", kCoordName, rtHeightName);
             fSetupFragPosition = true;
         }
         SkASSERT(fOutput.fUniformHandles.fRTHeightUni.isValid());