Automatically enable highp in fragment shaders on ESSL3

Most code using the translator already enables highp with the resources
flag when a shader spec that accepts ESSL3 is used, but for example the
shader_translator utility doesn't. This fix makes sure that highp is
always enabled when a fragment shader written in ESSL3 or newer is being
compiled. This will make shader_translator easier to use for testing
ESSL3 shaders.

BUG=541550
TEST=angle_unittests

Change-Id: Ia1911677c55f3c5d921829a8cbb808847ac8b636
Reviewed-on: https://chromium-review.googlesource.com/305190
Tryjob-Request: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 9707250..46dddc6 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -219,7 +219,7 @@
                                shaderType, shaderSpec, compileOptions, true,
                                infoSink, debugShaderPrecision);
 
-    parseContext.setFragmentPrecisionHigh(fragmentPrecisionHigh);
+    parseContext.setFragmentPrecisionHighOnESSL1(fragmentPrecisionHigh);
     SetGlobalParseContext(&parseContext);
 
     // We preserve symbols at the built-in level from compile-to-compile.
@@ -252,6 +252,9 @@
         root = parseContext.getTreeRoot();
         root = intermediate.postProcess(root);
 
+        // Highp might have been auto-enabled based on shader version
+        fragmentPrecisionHigh = parseContext.getFragmentPrecisionHigh();
+
         // Disallow expressions deemed too complex.
         if (success && (compileOptions & SH_LIMIT_EXPRESSION_COMPLEXITY))
             success = limitExpressionComplexity(root);
diff --git a/src/compiler/translator/ParseContext.h b/src/compiler/translator/ParseContext.h
index 35d2d3d..cb73fd9 100644
--- a/src/compiler/translator/ParseContext.h
+++ b/src/compiler/translator/ParseContext.h
@@ -50,7 +50,7 @@
           mCurrentFunctionType(nullptr),
           mFunctionReturnsValue(false),
           mChecksPrecisionErrors(checksPrecErrors),
-          mFragmentPrecisionHigh(false),
+          mFragmentPrecisionHighOnESSL1(false),
           mDefaultMatrixPacking(EmpColumnMajor),
           mDefaultBlockStorage(EbsShared),
           mDiagnostics(is),
@@ -81,10 +81,13 @@
     TIntermNode *getTreeRoot() const { return mTreeRoot; }
     void setTreeRoot(TIntermNode *treeRoot) { mTreeRoot = treeRoot; }
 
-    bool getFragmentPrecisionHigh() const { return mFragmentPrecisionHigh; }
-    void setFragmentPrecisionHigh(bool fragmentPrecisionHigh)
+    bool getFragmentPrecisionHigh() const
     {
-        mFragmentPrecisionHigh = fragmentPrecisionHigh;
+        return mFragmentPrecisionHighOnESSL1 || mShaderVersion >= 300;
+    }
+    void setFragmentPrecisionHighOnESSL1(bool fragmentPrecisionHigh)
+    {
+        mFragmentPrecisionHighOnESSL1 = fragmentPrecisionHigh;
     }
 
     bool getFunctionReturnsValue() const { return mFunctionReturnsValue; }
@@ -342,7 +345,8 @@
     const TType *mCurrentFunctionType;  // the return type of the function that's currently being parsed
     bool mFunctionReturnsValue;  // true if a non-void function has a return
     bool mChecksPrecisionErrors;  // true if an error will be generated when a variable is declared without precision, explicit or implicit.
-    bool mFragmentPrecisionHigh;  // true if highp precision is supported in the fragment language.
+    bool mFragmentPrecisionHighOnESSL1;  // true if highp precision is supported when compiling
+                                         // ESSL1.
     TLayoutMatrixPacking mDefaultMatrixPacking;
     TLayoutBlockStorage mDefaultBlockStorage;
     TString mHashErrMsg;