Commit 02f15239 by Jiawei Shao Committed by Commit Bot

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: 's avatarJamie Madill <jmadill@chromium.org>
parent bbd9d4c6
...@@ -414,6 +414,20 @@ void InfoLog::appendSanitized(const char *message) ...@@ -414,6 +414,20 @@ void InfoLog::appendSanitized(const char *message)
void InfoLog::reset() void InfoLog::reset()
{ {
if (mLazyStream)
{
mLazyStream.reset(nullptr);
}
}
bool InfoLog::empty() const
{
if (!mLazyStream)
{
return true;
}
return mLazyStream->rdbuf()->in_avail() == 0;
} }
// VariableLocation implementation. // VariableLocation implementation.
......
...@@ -119,6 +119,8 @@ class InfoLog : angle::NonCopyable ...@@ -119,6 +119,8 @@ class InfoLog : angle::NonCopyable
std::string str() const { return mLazyStream ? mLazyStream->str() : ""; } std::string str() const { return mLazyStream ? mLazyStream->str() : ""; }
bool empty() const;
private: private:
void ensureInitialized() void ensureInitialized()
{ {
......
...@@ -1600,9 +1600,18 @@ gl::LinkResult ProgramD3D::compileProgramExecutables(const gl::Context *context, ...@@ -1600,9 +1600,18 @@ gl::LinkResult ProgramD3D::compileProgramExecutables(const gl::Context *context,
WaitableEvent::WaitMany(&waitEvents); WaitableEvent::WaitMany(&waitEvents);
infoLog << vertexTask.getInfoLog().str(); if (!vertexTask.getInfoLog().empty())
infoLog << pixelTask.getInfoLog().str(); {
infoLog << geometryTask.getInfoLog().str(); 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(vertexTask.getError());
ANGLE_TRY(pixelTask.getError()); ANGLE_TRY(pixelTask.getError());
......
...@@ -431,6 +431,24 @@ class GLSLTest : public ANGLETest ...@@ -431,6 +431,24 @@ class GLSLTest : public ANGLETest
} }
} }
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; std::string mSimpleVSSource;
}; };
...@@ -3916,6 +3934,65 @@ TEST_P(GLSLTest_ES3, FlatVaryingUsedInFoldedTernary) ...@@ -3916,6 +3934,65 @@ TEST_P(GLSLTest_ES3, FlatVaryingUsedInFoldedTernary)
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green); 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. // Use this to select which configurations (e.g. which renderer, which GLES major version) these tests should be run against.
ANGLE_INSTANTIATE_TEST(GLSLTest, ANGLE_INSTANTIATE_TEST(GLSLTest,
ES2_D3D9(), ES2_D3D9(),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment