Fix issues with ProgramGL.

 * Don't re-create the native GL program every link, some program state should
   persist between re-linking such as bound attribute locations.
 * Forward glBindAttribLocation calls to the ProgramImpl, fixes some chromium
   rendering issues because chromium always binds attribute locations,
   sometimes with gaps.
 * Query the real attrib location before inserting it into the list of attribs.
   It was unsafe to rely on the attrib having the same location as its index
   into the active attributes.

BUG=angleproject:882

Change-Id: If14b4c4c2f5ebcdaa4f7c5a890b9519d6d4e6e43
Reviewed-on: https://chromium-review.googlesource.com/269991
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Tested-by: Geoff Lang <geofflang@chromium.org>
diff --git a/src/libANGLE/renderer/gl/ProgramGL.cpp b/src/libANGLE/renderer/gl/ProgramGL.cpp
index 4cd1155..63c224d 100644
--- a/src/libANGLE/renderer/gl/ProgramGL.cpp
+++ b/src/libANGLE/renderer/gl/ProgramGL.cpp
@@ -25,15 +25,14 @@
 {
     ASSERT(mFunctions);
     ASSERT(mStateManager);
+
+    mProgramID = mFunctions->createProgram();
 }
 
 ProgramGL::~ProgramGL()
 {
-    if (mProgramID != 0)
-    {
-        mFunctions->deleteProgram(mProgramID);
-        mProgramID = 0;
-    }
+    mFunctions->deleteProgram(mProgramID);
+    mProgramID = 0;
 }
 
 bool ProgramGL::usesPointSize() const
@@ -85,19 +84,18 @@
     ShaderGL *vertexShaderGL = GetImplAs<ShaderGL>(vertexShader);
     ShaderGL *fragmentShaderGL = GetImplAs<ShaderGL>(fragmentShader);
 
-    // Generate a new program, make sure one doesn't already exist
-    ASSERT(mProgramID == 0);
-    mProgramID = mFunctions->createProgram();
-
     // Attach the shaders
     mFunctions->attachShader(mProgramID, vertexShaderGL->getShaderID());
     mFunctions->attachShader(mProgramID, fragmentShaderGL->getShaderID());
 
-    // TODO: bind attribute locations?
-
     // Link and verify
     mFunctions->linkProgram(mProgramID);
 
+    // Detach the shaders
+    mFunctions->detachShader(mProgramID, vertexShaderGL->getShaderID());
+    mFunctions->detachShader(mProgramID, fragmentShaderGL->getShaderID());
+
+    // Verify the link
     GLint linkStatus = GL_FALSE;
     mFunctions->getProgramiv(mProgramID, GL_LINK_STATUS, &linkStatus);
     ASSERT(linkStatus == GL_TRUE);
@@ -183,13 +181,20 @@
 
         std::string attributeName(&attributeNameBuffer[0], attributeNameLength);
 
+        GLint location = mFunctions->getAttribLocation(mProgramID, attributeName.c_str());
+
         // TODO: determine attribute precision
-        setShaderAttribute(static_cast<size_t>(i), attributeType, GL_NONE, attributeName, attributeSize, i);
+        setShaderAttribute(static_cast<size_t>(i), attributeType, GL_NONE, attributeName, attributeSize, location);
     }
 
     return LinkResult(true, gl::Error(GL_NO_ERROR));
 }
 
+void ProgramGL::bindAttributeLocation(GLuint index, const std::string &name)
+{
+    mFunctions->bindAttribLocation(mProgramID, index, name.c_str());
+}
+
 void ProgramGL::setUniform1fv(GLint location, GLsizei count, const GLfloat *v)
 {
     mStateManager->useProgram(mProgramID);
@@ -403,9 +408,6 @@
 void ProgramGL::reset()
 {
     ProgramImpl::reset();
-
-    mStateManager->deleteProgram(mProgramID);
-    mProgramID = 0;
 }
 
 GLuint ProgramGL::getProgramID() const