Make TF Feedback buffer mode a GL-level variable.

Don't query this as an Impl method, since it exists on the GL level.
Also some related refactorings and cleanups.

BUG=angleproject:1123

Change-Id: I3610bc0db2bcaa96408506e06a65a2f4dab93150
Reviewed-on: https://chromium-review.googlesource.com/293761
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Tested-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 38ade23..fb3449f 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -290,11 +290,15 @@
         return Error(GL_NO_ERROR);
     }
 
+    if (!linkVaryings(mInfoLog, mData.mAttachedVertexShader, mData.mAttachedFragmentShader))
+    {
+        return Error(GL_NO_ERROR);
+    }
+
     int registers;
     std::vector<LinkedVarying> linkedVaryings;
     rx::LinkResult result =
         mProgram->link(data, mInfoLog, mData.mAttachedFragmentShader, mData.mAttachedVertexShader,
-                       mData.mTransformFeedbackVaryings, mData.mTransformFeedbackBufferMode,
                        &registers, &linkedVaryings, &mOutputVariables);
     if (result.error.isError() || !result.linkSuccess)
     {
@@ -314,9 +318,7 @@
     }
 
     if (!gatherTransformFeedbackLinkedVaryings(
-            mInfoLog, linkedVaryings, mData.mTransformFeedbackVaryings,
-            mData.mTransformFeedbackBufferMode, &mProgram->getTransformFeedbackLinkedVaryings(),
-            *data.caps))
+            mInfoLog, linkedVaryings, &mProgram->getTransformFeedbackLinkedVaryings(), *data.caps))
     {
         return Error(GL_NO_ERROR);
     }
@@ -434,6 +436,8 @@
         mProgram->setShaderAttribute(attribIndex, type, precision, name, arraySize, location);
     }
 
+    stream.readInt(&mData.mTransformFeedbackBufferMode);
+
     rx::LinkResult result = mProgram->load(mInfoLog, &stream);
     if (result.error.isError() || !result.linkSuccess)
     {
@@ -478,6 +482,8 @@
         stream.writeInt(attrib.location);
     }
 
+    stream.writeInt(mData.mTransformFeedbackBufferMode);
+
     gl::Error error = mProgram->save(&stream);
     if (error.isError())
     {
@@ -1238,48 +1244,49 @@
     return mData.mTransformFeedbackBufferMode;
 }
 
-bool Program::linkVaryings(InfoLog &infoLog, Shader *fragmentShader, Shader *vertexShader)
+// static
+bool Program::linkVaryings(InfoLog &infoLog,
+                           const Shader *vertexShader,
+                           const Shader *fragmentShader)
 {
-    std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
-    std::vector<PackedVarying> &vertexVaryings = vertexShader->getVaryings();
+    const std::vector<PackedVarying> &vertexVaryings   = vertexShader->getVaryings();
+    const std::vector<PackedVarying> &fragmentVaryings = fragmentShader->getVaryings();
 
-    for (size_t fragVaryingIndex = 0; fragVaryingIndex < fragmentVaryings.size(); fragVaryingIndex++)
+    for (const PackedVarying &output : fragmentVaryings)
     {
-        PackedVarying *input = &fragmentVaryings[fragVaryingIndex];
         bool matched = false;
 
         // Built-in varyings obey special rules
-        if (input->isBuiltIn())
+        if (output.isBuiltIn())
         {
             continue;
         }
 
-        for (size_t vertVaryingIndex = 0; vertVaryingIndex < vertexVaryings.size(); vertVaryingIndex++)
+        for (const PackedVarying &input : vertexVaryings)
         {
-            PackedVarying *output = &vertexVaryings[vertVaryingIndex];
-            if (output->name == input->name)
+            if (output.name == input.name)
             {
-                if (!linkValidateVaryings(infoLog, output->name, *input, *output))
+                ASSERT(!input.isBuiltIn());
+                if (!linkValidateVaryings(infoLog, output.name, input, output))
                 {
                     return false;
                 }
 
-                output->registerIndex = input->registerIndex;
-                output->columnIndex = input->columnIndex;
-
                 matched = true;
                 break;
             }
         }
 
         // We permit unmatched, unreferenced varyings
-        if (!matched && input->staticUse)
+        if (!matched && output.staticUse)
         {
-            infoLog << "Fragment varying " << input->name << " does not match any vertex varying";
+            infoLog << "Fragment varying " << output.name << " does not match any vertex varying";
             return false;
         }
     }
 
+    // TODO(jmadill): verify no unmatched vertex varyings?
+
     return true;
 }
 
@@ -1583,8 +1590,6 @@
 }
 
 bool Program::gatherTransformFeedbackLinkedVaryings(InfoLog &infoLog, const std::vector<LinkedVarying> &linkedVaryings,
-                                                    const std::vector<std::string> &transformFeedbackVaryingNames,
-                                                    GLenum transformFeedbackBufferMode,
                                                     std::vector<LinkedVarying> *outTransformFeedbackLinkedVaryings,
                                                     const Caps &caps) const
 {
@@ -1592,12 +1597,12 @@
 
     // Gather the linked varyings that are used for transform feedback, they should all exist.
     outTransformFeedbackLinkedVaryings->clear();
-    for (size_t i = 0; i < transformFeedbackVaryingNames.size(); i++)
+    for (size_t i = 0; i < mData.mTransformFeedbackVaryings.size(); i++)
     {
         bool found = false;
         for (size_t j = 0; j < linkedVaryings.size(); j++)
         {
-            if (transformFeedbackVaryingNames[i] == linkedVaryings[j].name)
+            if (mData.mTransformFeedbackVaryings[i] == linkedVaryings[j].name)
             {
                 for (size_t k = 0; k < outTransformFeedbackLinkedVaryings->size(); k++)
                 {
@@ -1610,7 +1615,7 @@
                 }
 
                 size_t componentCount = linkedVaryings[j].semanticIndexCount * 4;
-                if (transformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
+                if (mData.mTransformFeedbackBufferMode == GL_SEPARATE_ATTRIBS &&
                     componentCount > caps.maxTransformFeedbackSeparateComponents)
                 {
                     infoLog << "Transform feedback varying's " << linkedVaryings[j].name
@@ -1633,7 +1638,7 @@
         UNUSED_ASSERTION_VARIABLE(found);
     }
 
-    if (transformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
+    if (mData.mTransformFeedbackBufferMode == GL_INTERLEAVED_ATTRIBS &&
         totalComponents > caps.maxTransformFeedbackInterleavedComponents)
     {
         infoLog << "Transform feedback varying total components (" << totalComponents