ES31: Refactor link mismatch error log

This patch intends to refactor the structure of logging link mismatch
errors to meet the new GLES 3.1 program link requirements and support
linking program with geometry shader.

This patch is mainly focusing on the following 4 issues:
1. There are totally 14 places that log the link mismatch errors
   in almost same format.
2. A temporary string is created (STRUCT_NAME.FIELD_NAME) before
   checking a field of a block, which is of no use if link succeeds.
3. LinkValidateVariablesBase needs to know "shaderTypes" if we support
   geometry shader based on current structure. Since uniforms are
   checked in the range of the whole program, it is unnecessary to
   know in which shader a uniform is defined if link succeeds.
4. GLES 3.1 regards varyings with same location but different names
   as matched, so it isn't enough to log errors only by one name.

This patch can solve all these issues by the following 3 changes:
1. Replace "infoLog" and "variableNames" by "mismatchedFieldName" (the
   complete field name if the mismatch occurs on a field of a struct
   or block).
2. Use enum LinkMismatchError as the return value of all linkValidate*
   functions to reflect the detail of the link mismatch error.
3. Log all the link mismatch errors by InfoLog::logLinkMismatch where
   we can get shader types instead of passing them into linkValidate*
   functions.

BUG=angleproject:1941, angleproject:2144
TEST=angle_end2end_tests
Change-Id: I3ed876d61f812cc7a45a6a3c5fec0b4a88b9cc2c
Reviewed-on: https://chromium-review.googlesource.com/844215
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
diff --git a/src/libANGLE/ProgramLinkedResources.cpp b/src/libANGLE/ProgramLinkedResources.cpp
index 7207ac4..fcd1bbc 100644
--- a/src/libANGLE/ProgramLinkedResources.cpp
+++ b/src/libANGLE/ProgramLinkedResources.cpp
@@ -4,9 +4,9 @@
 // found in the LICENSE file.
 //
 
-// UniformLinker.cpp: implements link-time checks for default block uniforms, and generates uniform
-// locations. Populates data structures related to uniforms so that they can be stored in program
-// state.
+// ProgramLinkedResources.cpp: implements link-time checks for default block uniforms, and generates
+// uniform locations. Populates data structures related to uniforms so that they can be stored in
+// program state.
 
 #include "libANGLE/ProgramLinkedResources.h"
 
@@ -131,10 +131,14 @@
         auto entry = linkedUniforms.find(fragmentUniform.name);
         if (entry != linkedUniforms.end())
         {
-            const sh::Uniform &linkedUniform = *(entry->second);
-            const std::string &uniformName   = "uniform '" + linkedUniform.name + "'";
-            if (!LinkValidateUniforms(infoLog, uniformName, linkedUniform, fragmentUniform))
+            const sh::Uniform &vertexUniform = *(entry->second);
+            std::string mismatchedStructFieldName;
+            LinkMismatchError linkError =
+                LinkValidateUniforms(vertexUniform, fragmentUniform, &mismatchedStructFieldName);
+            if (linkError != LinkMismatchError::NO_MISMATCH)
             {
+                LogLinkMismatch(infoLog, fragmentUniform.name, "uniform", linkError,
+                                mismatchedStructFieldName, GL_VERTEX_SHADER, GL_FRAGMENT_SHADER);
                 return false;
             }
         }
@@ -143,10 +147,9 @@
 }
 
 // GLSL ES Spec 3.00.3, section 4.3.5.
-bool UniformLinker::LinkValidateUniforms(InfoLog &infoLog,
-                                         const std::string &uniformName,
-                                         const sh::Uniform &vertexUniform,
-                                         const sh::Uniform &fragmentUniform)
+LinkMismatchError UniformLinker::LinkValidateUniforms(const sh::Uniform &uniform1,
+                                                      const sh::Uniform &uniform2,
+                                                      std::string *mismatchedStructFieldName)
 {
 #if ANGLE_PROGRAM_LINK_VALIDATE_UNIFORM_PRECISION == ANGLE_ENABLED
     const bool validatePrecision = true;
@@ -154,37 +157,31 @@
     const bool validatePrecision = false;
 #endif
 
-    if (!Program::LinkValidateVariablesBase(infoLog, uniformName, vertexUniform, fragmentUniform,
-                                            validatePrecision))
+    LinkMismatchError linkError = Program::LinkValidateVariablesBase(
+        uniform1, uniform2, validatePrecision, mismatchedStructFieldName);
+    if (linkError != LinkMismatchError::NO_MISMATCH)
     {
-        return false;
+        return linkError;
     }
 
     // GLSL ES Spec 3.10.4, section 4.4.5.
-    if (vertexUniform.binding != -1 && fragmentUniform.binding != -1 &&
-        vertexUniform.binding != fragmentUniform.binding)
+    if (uniform1.binding != -1 && uniform2.binding != -1 && uniform1.binding != uniform2.binding)
     {
-        infoLog << "Binding layout qualifiers for " << uniformName
-                << " differ between vertex and fragment shaders.";
-        return false;
+        return LinkMismatchError::BINDING_MISMATCH;
     }
 
     // GLSL ES Spec 3.10.4, section 9.2.1.
-    if (vertexUniform.location != -1 && fragmentUniform.location != -1 &&
-        vertexUniform.location != fragmentUniform.location)
+    if (uniform1.location != -1 && uniform2.location != -1 &&
+        uniform1.location != uniform2.location)
     {
-        infoLog << "Location layout qualifiers for " << uniformName
-                << " differ between vertex and fragment shaders.";
-        return false;
+        return LinkMismatchError::LOCATION_MISMATCH;
     }
-    if (vertexUniform.offset != fragmentUniform.offset)
+    if (uniform1.offset != uniform2.offset)
     {
-        infoLog << "Offset layout qualifiers for " << uniformName
-                << " differ between vertex and fragment shaders.";
-        return false;
+        return LinkMismatchError::OFFSET_MISMATCH;
     }
 
-    return true;
+    return LinkMismatchError::NO_MISMATCH;
 }
 
 bool UniformLinker::indexUniforms(InfoLog &infoLog, const ProgramBindings &uniformLocationBindings)