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/libANGLE/Program.cpp b/src/libANGLE/Program.cpp
index 535e093..7ccd470 100644
--- a/src/libANGLE/Program.cpp
+++ b/src/libANGLE/Program.cpp
@@ -414,6 +414,20 @@
void InfoLog::reset()
{
+ if (mLazyStream)
+ {
+ mLazyStream.reset(nullptr);
+ }
+}
+
+bool InfoLog::empty() const
+{
+ if (!mLazyStream)
+ {
+ return true;
+ }
+
+ return mLazyStream->rdbuf()->in_avail() == 0;
}
// VariableLocation implementation.
diff --git a/src/libANGLE/Program.h b/src/libANGLE/Program.h
index 0dd8fb9..a2e53cf 100644
--- a/src/libANGLE/Program.h
+++ b/src/libANGLE/Program.h
@@ -119,6 +119,8 @@
std::string str() const { return mLazyStream ? mLazyStream->str() : ""; }
+ bool empty() const;
+
private:
void ensureInitialized()
{
diff --git a/src/libANGLE/renderer/d3d/ProgramD3D.cpp b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
index 9699e7e..80ae30b 100644
--- a/src/libANGLE/renderer/d3d/ProgramD3D.cpp
+++ b/src/libANGLE/renderer/d3d/ProgramD3D.cpp
@@ -1600,9 +1600,18 @@
WaitableEvent::WaitMany(&waitEvents);
- infoLog << vertexTask.getInfoLog().str();
- infoLog << pixelTask.getInfoLog().str();
- infoLog << geometryTask.getInfoLog().str();
+ if (!vertexTask.getInfoLog().empty())
+ {
+ infoLog << vertexTask.getInfoLog().str();
+ }
+ if (!pixelTask.getInfoLog().empty())
+ {
+ infoLog << pixelTask.getInfoLog().str();
+ }
+ if (!geometryTask.getInfoLog().empty())
+ {
+ infoLog << geometryTask.getInfoLog().str();
+ }
ANGLE_TRY(vertexTask.getError());
ANGLE_TRY(pixelTask.getError());
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(),