Bug 777883 - Avoid calling glLinkProgram when we know that a bad shader is attached - r=jgilbert

This commit is contained in:
Benoit Jacob 2012-07-26 19:58:52 -04:00
Родитель c26add417d
Коммит 467321359c
3 изменённых файлов: 43 добавлений и 10 удалений

Просмотреть файл

@ -2121,6 +2121,7 @@ public:
, mType(stype)
, mNeedsTranslation(true)
, mAttribMaxNameLength(0)
, mCompileStatus(false)
{
mContext->MakeContextCurrent();
mGLName = mContext->gl->fCreateShader(mType);
@ -2158,6 +2159,14 @@ public:
void SetNeedsTranslation() { mNeedsTranslation = true; }
bool NeedsTranslation() const { return mNeedsTranslation; }
void SetCompileStatus (bool status) {
mCompileStatus = status;
}
bool CompileStatus() const {
return mCompileStatus;
}
void SetTranslationSuccess() {
mTranslationLog.SetIsVoid(true);
mNeedsTranslation = false;
@ -2183,6 +2192,7 @@ protected:
nsTArray<WebGLMappedIdentifier> mUniforms;
nsTArray<WebGLUniformInfo> mUniformInfos;
int mAttribMaxNameLength;
bool mCompileStatus;
};
/** Takes an ASCII string like "foo[i]", turns it into "foo" and returns "[i]" in bracketPart
@ -2304,6 +2314,15 @@ public:
HasAttachedShaderOfType(LOCAL_GL_FRAGMENT_SHADER);
}
bool HasBadShaderAttached() {
for (uint32_t i = 0; i < mAttachedShaders.Length(); ++i) {
if (mAttachedShaders[i] && !mAttachedShaders[i]->CompileStatus()) {
return true;
}
}
return false;
}
bool NextGeneration()
{
if (!(mGeneration + 1).isValid())

Просмотреть файл

@ -2967,9 +2967,7 @@ WebGLContext::GetProgramParameter(WebGLProgram *prog, WebGLenum pname)
return JS::BooleanValue(prog->IsDeleteRequested());
case LOCAL_GL_LINK_STATUS:
{
GLint i = 0;
gl->fGetProgramiv(progname, pname, &i);
return JS::BooleanValue(bool(i));
return JS::BooleanValue(prog->LinkStatus());
}
case LOCAL_GL_VALIDATE_STATUS:
{
@ -3709,11 +3707,20 @@ WebGLContext::LinkProgram(WebGLProgram *program, ErrorResult& rv)
return;
}
MakeContextCurrent();
gl->fLinkProgram(progname);
GLint ok;
gl->fGetProgramiv(progname, LOCAL_GL_LINK_STATUS, &ok);
if (gl->WorkAroundDriverBugs() &&
program->HasBadShaderAttached())
{
// it's a common driver bug, caught by program-test.html, that linkProgram doesn't
// correctly preserve the state of an in-use program that has been attached a bad shader
// see bug 777883
ok = false;
} else {
MakeContextCurrent();
gl->fLinkProgram(progname);
gl->fGetProgramiv(progname, LOCAL_GL_LINK_STATUS, &ok);
}
if (ok) {
bool updateInfoSucceeded = program->UpdateInfo();
program->SetLinkStatus(updateInfoSucceeded);
@ -3745,8 +3752,8 @@ WebGLContext::LinkProgram(WebGLProgram *program, ErrorResult& rv)
for (size_t i = 0; i < program->AttachedShaders().Length(); i++) {
WebGLShader* shader = program->AttachedShaders()[i];
GetShaderInfoLog(shader, log, rv);
if (rv.Failed() || log.IsEmpty())
if (shader->CompileStatus())
continue;
const char *shaderTypeName = nsnull;
@ -3760,6 +3767,8 @@ WebGLContext::LinkProgram(WebGLProgram *program, ErrorResult& rv)
shaderTypeName = "<unknown>";
}
GetShaderInfoLog(shader, log, rv);
GenerateWarning("linkProgram: a %s shader used in this program failed to "
"compile, with this log:\n%s\n",
shaderTypeName,
@ -4911,6 +4920,8 @@ WebGLContext::CompileShader(WebGLShader *shader)
WebGLuint shadername = shader->GLName();
shader->SetCompileStatus(false);
MakeContextCurrent();
ShShaderOutput targetShaderSourceLanguage = gl->IsGLES2() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT;
@ -4993,6 +5004,7 @@ WebGLContext::CompileShader(WebGLShader *shader)
shader->SetTranslationFailure(NS_LITERAL_CSTRING("Internal error: failed to get shader info log"));
}
ShDestruct(compiler);
shader->SetCompileStatus(false);
return;
}
@ -5081,6 +5093,9 @@ WebGLContext::CompileShader(WebGLShader *shader)
ShDestruct(compiler);
gl->fCompileShader(shadername);
GLint ok;
gl->fGetShaderiv(shadername, LOCAL_GL_COMPILE_STATUS, &ok);
shader->SetCompileStatus(ok);
}
#endif
}

Просмотреть файл

@ -1,2 +1 @@
conformance/glsl/misc/glsl-function-nodes.html
conformance/programs/program-test.html