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