Bug 775843 - Always BindAttribLocation something to attrib 0 if possible. r=jgilbert

This commit is contained in:
Mina Almasry 2013-08-27 09:01:44 -04:00
parent df74ac6562
commit 0a77b28320
4 changed files with 71 additions and 4 deletions

View File

@ -872,6 +872,7 @@ private:
void VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr); void VertexAttrib4fv_base(WebGLuint idx, uint32_t arrayLength, const WebGLfloat* ptr);
bool ValidateBufferFetching(const char *info); bool ValidateBufferFetching(const char *info);
bool BindArrayAttribToLocation0(WebGLProgram *program);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// PROTECTED // PROTECTED

View File

@ -1966,6 +1966,36 @@ WebGLContext::IsTexture(WebGLTexture *tex)
tex->HasEverBeenBound(); tex->HasEverBeenBound();
} }
// Try to bind an attribute that is an array to location 0:
bool WebGLContext::BindArrayAttribToLocation0(WebGLProgram *program)
{
if (mBoundVertexArray->mAttribBuffers[0].enabled) {
return false;
}
GLint leastArrayLocation = -1;
std::map<GLint, nsCString>::iterator itr;
for (itr = program->mActiveAttribMap.begin();
itr != program->mActiveAttribMap.end();
itr++) {
int32_t index = itr->first;
if (mBoundVertexArray->mAttribBuffers[index].enabled &&
index < leastArrayLocation)
{
leastArrayLocation = index;
}
}
if (leastArrayLocation > 0) {
nsCString& attrName = program->mActiveAttribMap.find(leastArrayLocation)->second;
const char* attrNameCStr = attrName.get();
gl->fBindAttribLocation(program->GLName(), 0, attrNameCStr);
return true;
}
return false;
}
void void
WebGLContext::LinkProgram(WebGLProgram *program) WebGLContext::LinkProgram(WebGLProgram *program)
{ {
@ -2003,7 +2033,8 @@ WebGLContext::LinkProgram(WebGLProgram *program)
return; return;
} }
GLint ok; bool updateInfoSucceeded = false;
GLint ok = 0;
if (gl->WorkAroundDriverBugs() && if (gl->WorkAroundDriverBugs() &&
program->HasBadShaderAttached()) program->HasBadShaderAttached())
{ {
@ -2015,12 +2046,25 @@ WebGLContext::LinkProgram(WebGLProgram *program)
MakeContextCurrent(); MakeContextCurrent();
gl->fLinkProgram(progname); gl->fLinkProgram(progname);
gl->fGetProgramiv(progname, LOCAL_GL_LINK_STATUS, &ok); gl->fGetProgramiv(progname, LOCAL_GL_LINK_STATUS, &ok);
if (ok) {
updateInfoSucceeded = program->UpdateInfo();
program->SetLinkStatus(updateInfoSucceeded);
if (BindArrayAttribToLocation0(program)) {
GenerateWarning("linkProgram: relinking program to make attrib0 an "
"array.");
gl->fLinkProgram(progname);
gl->fGetProgramiv(progname, LOCAL_GL_LINK_STATUS, &ok);
if (ok) {
updateInfoSucceeded = program->UpdateInfo();
program->SetLinkStatus(updateInfoSucceeded);
}
}
}
} }
if (ok) { if (ok) {
bool updateInfoSucceeded = program->UpdateInfo();
program->SetLinkStatus(updateInfoSucceeded);
// Bug 750527 // Bug 750527
if (gl->WorkAroundDriverBugs() && if (gl->WorkAroundDriverBugs() &&
updateInfoSucceeded && updateInfoSucceeded &&

View File

@ -86,6 +86,25 @@ WebGLProgram::UpdateInfo()
} }
} }
mActiveAttribMap.clear();
GLint numActiveAttrs = 0;
mContext->gl->fGetProgramiv(mGLName, LOCAL_GL_ACTIVE_ATTRIBUTES, &numActiveAttrs);
// Spec says the maximum attrib name length is 256 chars, so this is
// sufficient to hold any attrib name.
char attrName[257];
GLint dummySize;
GLenum dummyType;
for (GLint i = 0; i < numActiveAttrs; i++) {
mContext->gl->fGetActiveAttrib(mGLName, i, 257, nullptr, &dummySize,
&dummyType, attrName);
GLint attrLoc = mContext->gl->fGetAttribLocation(mGLName, attrName);
MOZ_ASSERT(attrLoc >= 0);
mActiveAttribMap.insert(std::make_pair(attrLoc, nsCString(attrName)));
}
return true; return true;
} }

View File

@ -110,6 +110,9 @@ public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLProgram) NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(WebGLProgram)
// public post-link data
std::map<GLint, nsCString> mActiveAttribMap;
protected: protected:
WebGLuint mGLName; WebGLuint mGLName;