Invariant related processing.

* Fix a bug in PreProcessor for STDGL pragma.
* Record all invariant settings and set them in ShaderVariable.
* Write #pragma STDGL invariant(all) in GL

BUG=angle:776
TEST=https://www.khronos.org/registry/webgl/sdk/tests/conformance/glsl/misc/shaders-with-invariance.html

Change-Id: Ie28b75480deed79f0c9f26e3b98f1778d1290182
Reviewed-on: https://chromium-review.googlesource.com/223610
Tested-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/VariableInfo.cpp b/src/compiler/translator/VariableInfo.cpp
index f26c156..cd92706 100644
--- a/src/compiler/translator/VariableInfo.cpp
+++ b/src/compiler/translator/VariableInfo.cpp
@@ -5,6 +5,7 @@
 //
 
 #include "angle_gl.h"
+#include "compiler/translator/SymbolTable.h"
 #include "compiler/translator/VariableInfo.h"
 #include "compiler/translator/util.h"
 #include "common/utilities.h"
@@ -131,7 +132,8 @@
                                    std::vector<sh::Uniform> *uniforms,
                                    std::vector<sh::Varying> *varyings,
                                    std::vector<sh::InterfaceBlock> *interfaceBlocks,
-                                   ShHashFunction64 hashFunction)
+                                   ShHashFunction64 hashFunction,
+                                   const TSymbolTable &symbolTable)
     : mAttribs(attribs),
       mOutputVariables(outputVariables),
       mUniforms(uniforms),
@@ -140,7 +142,10 @@
       mPointCoordAdded(false),
       mFrontFacingAdded(false),
       mFragCoordAdded(false),
-      mHashFunction(hashFunction)
+      mPositionAdded(false),
+      mPointSizeAdded(false),
+      mHashFunction(hashFunction),
+      mSymbolTable(symbolTable)
 {
 }
 
@@ -200,12 +205,14 @@
             if (!mFragCoordAdded)
             {
                 Varying info;
-                info.name = "gl_FragCoord";
-                info.mappedName = "gl_FragCoord";
+                const char kName[] = "gl_FragCoord";
+                info.name = kName;
+                info.mappedName = kName;
                 info.type = GL_FLOAT_VEC4;
                 info.arraySize = 0;
-                info.precision = GL_MEDIUM_FLOAT;  // Use mediump as it doesn't really matter.
+                info.precision = GL_MEDIUM_FLOAT;  // Defined by spec.
                 info.staticUse = true;
+                info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
                 mVaryings->push_back(info);
                 mFragCoordAdded = true;
             }
@@ -214,12 +221,14 @@
             if (!mFrontFacingAdded)
             {
                 Varying info;
-                info.name = "gl_FrontFacing";
-                info.mappedName = "gl_FrontFacing";
+                const char kName[] = "gl_FrontFacing";
+                info.name = kName;
+                info.mappedName = kName;
                 info.type = GL_BOOL;
                 info.arraySize = 0;
                 info.precision = GL_NONE;
                 info.staticUse = true;
+                info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
                 mVaryings->push_back(info);
                 mFrontFacingAdded = true;
             }
@@ -228,16 +237,50 @@
             if (!mPointCoordAdded)
             {
                 Varying info;
-                info.name = "gl_PointCoord";
-                info.mappedName = "gl_PointCoord";
+                const char kName[] = "gl_PointCoord";
+                info.name = kName;
+                info.mappedName = kName;
                 info.type = GL_FLOAT_VEC2;
                 info.arraySize = 0;
-                info.precision = GL_MEDIUM_FLOAT;  // Use mediump as it doesn't really matter.
+                info.precision = GL_MEDIUM_FLOAT;  // Defined by spec.
                 info.staticUse = true;
+                info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
                 mVaryings->push_back(info);
                 mPointCoordAdded = true;
             }
             return;
+          case EvqPosition:
+            if (!mPositionAdded)
+            {
+                Varying info;
+                const char kName[] = "gl_Position";
+                info.name = kName;
+                info.mappedName = kName;
+                info.type = GL_FLOAT_VEC4;
+                info.arraySize = 0;
+                info.precision = GL_HIGH_FLOAT;  // Defined by spec.
+                info.staticUse = true;
+                info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
+                mVaryings->push_back(info);
+                mPositionAdded = true;
+            }
+            return;
+          case EvqPointSize:
+            if (!mPointSizeAdded)
+            {
+                Varying info;
+                const char kName[] = "gl_PointSize";
+                info.name = kName;
+                info.mappedName = kName;
+                info.type = GL_FLOAT;
+                info.arraySize = 0;
+                info.precision = GL_MEDIUM_FLOAT;  // Defined by spec.
+                info.staticUse = true;
+                info.isInvariant = mSymbolTable.isVaryingInvariant(kName);
+                mVaryings->push_back(info);
+                mPointSizeAdded = true;
+            }
+            return;
           default:
             break;
         }
@@ -251,8 +294,10 @@
 class NameHashingTraverser : public GetVariableTraverser
 {
   public:
-    NameHashingTraverser(ShHashFunction64 hashFunction)
-        : mHashFunction(hashFunction)
+    NameHashingTraverser(ShHashFunction64 hashFunction,
+                         const TSymbolTable &symbolTable)
+        : GetVariableTraverser(symbolTable),
+          mHashFunction(hashFunction)
     {}
 
   private:
@@ -312,7 +357,7 @@
         const TString &fullFieldName = InterfaceBlockFieldName(*blockType, field);
         const TType &fieldType = *field.type();
 
-        GetVariableTraverser traverser;
+        GetVariableTraverser traverser(mSymbolTable);
         traverser.traverse(fieldType, fullFieldName, &interfaceBlock.fields);
 
         interfaceBlock.fields.back().isRowMajorLayout = (fieldType.getLayoutQualifier().matrixPacking == EmpRowMajor);
@@ -325,7 +370,7 @@
 void CollectVariables::visitVariable(const TIntermSymbol *variable,
                                      std::vector<VarT> *infoList) const
 {
-    NameHashingTraverser traverser(mHashFunction);
+    NameHashingTraverser traverser(mHashFunction, mSymbolTable);
     traverser.traverse(variable->getType(), variable->getSymbol(), infoList);
 }