For SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS, assign precision to temp variables.

Otherwise on Windows or other platforms with GLES backend, using this workaround
will trigger shader compile failure.

For the moment, to simplify the workaround, for any missing precisions in float,
we always assign the highest available precion to it.

BUG=angle:695
TEST=webgl conformance tests

Change-Id: I810579442bc7fc61d6a52b76aff31a779046fa22
Reviewed-on: https://chromium-review.googlesource.com/211253
Tested-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 79bb283..bcb431a 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -258,7 +258,8 @@
 
         if (success && (compileOptions & SH_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS))
         {
-            ScalarizeVecAndMatConstructorArgs scalarizer;
+            ScalarizeVecAndMatConstructorArgs scalarizer(
+                shaderType, fragmentPrecisionHigh);
             root->traverse(&scalarizer);
         }
 
diff --git a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
index 3a179f7..8857ad5 100644
--- a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
+++ b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.cpp
@@ -9,6 +9,7 @@
 
 #include <algorithm>
 
+#include "angle_gl.h"
 #include "common/angleutils.h"
 
 namespace
@@ -249,6 +250,16 @@
     TType type = original->getType();
     type.setQualifier(EvqTemporary);
 
+    if (mShaderType == GL_FRAGMENT_SHADER &&
+        type.getBasicType() == EbtFloat &&
+        type.getPrecision() == EbpUndefined)
+    {
+        // We use the highest available precision for the temporary variable
+        // to avoid computing the actual precision using the rules defined
+        // in GLSL ES 1.0 Section 4.5.2.
+        type.setPrecision(mFragmentPrecisionHigh ? EbpHigh : EbpMedium);
+    }
+
     TIntermBinary *init = new TIntermBinary(EOpInitialize);
     TIntermSymbol *symbolNode = new TIntermSymbol(-1, tempVarName, type);
     init->setLeft(symbolNode);
diff --git a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
index 6aeb0c4..c81c5cf 100644
--- a/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
+++ b/src/compiler/translator/ScalarizeVecAndMatConstructorArgs.h
@@ -12,8 +12,11 @@
 class ScalarizeVecAndMatConstructorArgs : public TIntermTraverser
 {
   public:
-    ScalarizeVecAndMatConstructorArgs()
-        : mTempVarCount(0) {}
+    ScalarizeVecAndMatConstructorArgs(sh::GLenum shaderType,
+                                      bool fragmentPrecisionHigh)
+        : mTempVarCount(0),
+          mShaderType(shaderType),
+          mFragmentPrecisionHigh(fragmentPrecisionHigh) {}
 
   protected:
     virtual bool visitAggregate(Visit visit, TIntermAggregate *node);
@@ -36,6 +39,9 @@
 
     std::vector<TIntermSequence> mSequenceStack;
     int mTempVarCount;
+
+    sh::GLenum mShaderType;
+    bool mFragmentPrecisionHigh;
 };
 
 #endif  // COMPILER_TRANSLATOR_SCALARIZE_VEC_AND_MAT_CONSTRUCTOR_ARGS_H_