Clear error logs when starting a new link process

This patch intends to fix a bug in logging link errors.

OpenGL ES requires glGetProgramInfoLog return a string
that contains information about last link or validation
attempt on a program object (GLES 2.0 Chapter 6.1.8,
GLES 3.0 Chapter 6.1.12). So all the link error logs
should be cleared when a new link process is begun.

This patch also removes several redundant allocations
of mLazyStream in ProgramD3D::compileProgramExecutables.
Calling "<<" on InfoLog objects will initialize its
member mLazyStream from heap, so we will skip using "<<"
if there is actually nothing to output.

BUG=angleproject:2295
TEST=angle_end2end_tests
Change-Id: Ib81fffd3d05919a8ebccd9145ff780548ca86a70
Reviewed-on: https://chromium-review.googlesource.com/848324
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp
index 2cacd3e..888249b 100644
--- a/src/tests/gl_tests/GLSLTest.cpp
+++ b/src/tests/gl_tests/GLSLTest.cpp
@@ -431,6 +431,24 @@
         }
     }
 
+    std::string QueryErrorMessage(GLuint program)
+    {
+        GLint infoLogLength;
+        glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLength);
+        EXPECT_GL_NO_ERROR();
+
+        if (infoLogLength >= 1)
+        {
+            std::vector<GLchar> infoLog(infoLogLength);
+            glGetProgramInfoLog(program, static_cast<GLsizei>(infoLog.size()), nullptr,
+                                infoLog.data());
+            EXPECT_GL_NO_ERROR();
+            return infoLog.data();
+        }
+
+        return "";
+    }
+
     std::string mSimpleVSSource;
 };
 
@@ -3916,6 +3934,65 @@
     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
 }
 
+// Verify that the link error message from last link failure is cleared when the new link is
+// finished.
+TEST_P(GLSLTest, ClearLinkErrorLog)
+{
+    const std::string &vertexShader =
+        R"(
+
+        attribute vec4 vert_in;
+        varying vec4 vert_out;
+        void main()
+        {
+            gl_Position = vert_in;
+            vert_out = vert_in;
+        })";
+
+    const std::string &fragmentShader =
+        R"(
+
+        precision mediump float;
+        varying vec4 frag_in;
+        void main()
+        {
+            gl_FragColor = frag_in;
+        })";
+
+    GLuint vs = CompileShader(GL_VERTEX_SHADER, vertexShader);
+    GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragmentShader);
+
+    GLuint program = glCreateProgram();
+
+    // The first time the program link fails because of lack of fragment shader.
+    glAttachShader(program, vs);
+    glLinkProgram(program);
+    GLint linkStatus = GL_TRUE;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    ASSERT_FALSE(linkStatus);
+
+    const std::string &lackOfFragmentShader = QueryErrorMessage(program);
+
+    // The second time the program link fails because of the mismatch of the varying types.
+    glAttachShader(program, fs);
+    glLinkProgram(program);
+    linkStatus = GL_TRUE;
+    glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+    ASSERT_FALSE(linkStatus);
+
+    const std::string &varyingTypeMismatch = QueryErrorMessage(program);
+
+    EXPECT_EQ(std::string::npos, varyingTypeMismatch.find(lackOfFragmentShader));
+
+    glDetachShader(program, vs);
+    glDetachShader(program, fs);
+    glDeleteShader(vs);
+    glDeleteShader(fs);
+    glDeleteProgram(program);
+
+    ASSERT_GL_NO_ERROR();
+}
+
 // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
 ANGLE_INSTANTIATE_TEST(GLSLTest,
                        ES2_D3D9(),