Bug 745292 - Log non-empty shader/program infoLogs as WebGL (JS) warnings - r=jgilbert

This commit is contained in:
Benoit Jacob 2012-05-29 14:44:31 -04:00
parent 0f79713e95
commit 3acd5b0163
5 changed files with 89 additions and 29 deletions

View File

@ -153,7 +153,7 @@ WebGLContext::WebGLContext()
mContextStatus = ContextStable;
mContextLostErrorSet = false;
mAlreadyReportedMessages = 0;
mAlreadyGeneratedWarnings = 0;
}
WebGLContext::~WebGLContext()

View File

@ -809,11 +809,13 @@ public:
WebGLenum pname,
ErrorResult& rv);
JS::Value GetProgramParameter(WebGLProgram *prog, WebGLenum pname);
void GetProgramInfoLog(WebGLProgram *prog, nsACString& retval, ErrorResult& rv);
void GetProgramInfoLog(WebGLProgram *prog, nsAString& retval, ErrorResult& rv);
JS::Value GetRenderbufferParameter(WebGLenum target, WebGLenum pname);
JS::Value GetShaderParameter(WebGLShader *shader, WebGLenum pname);
already_AddRefed<WebGLShaderPrecisionFormat>
GetShaderPrecisionFormat(WebGLenum shadertype, WebGLenum precisiontype);
void GetShaderInfoLog(WebGLShader *shader, nsACString& retval, ErrorResult& rv);
void GetShaderInfoLog(WebGLShader *shader, nsAString& retval, ErrorResult& rv);
void GetShaderSource(WebGLShader *shader, nsAString& retval);
JS::Value GetTexParameter(WebGLenum target, WebGLenum pname);
@ -1362,7 +1364,11 @@ protected:
ContextStatus mContextStatus;
bool mContextLostErrorSet;
int mAlreadyReportedMessages;
int mAlreadyGeneratedWarnings;
bool ShouldGenerateWarnings() const {
return mAlreadyGeneratedWarnings < 32;
}
#ifdef XP_MACOSX
// see bug 713305. This RAII helper guarantees that we're on the discrete GPU, during its lifetime

View File

@ -2993,6 +2993,15 @@ WebGLContext::GetProgramInfoLog(nsIWebGLProgram *pobj, nsAString& retval)
void
WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsAString& retval,
ErrorResult& rv)
{
nsCAutoString s;
GetProgramInfoLog(prog, s, rv);
CopyASCIItoUTF16(s, retval);
}
void
WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsACString& retval,
ErrorResult& rv)
{
if (!IsContextStable())
{
@ -3022,14 +3031,9 @@ WebGLContext::GetProgramInfoLog(WebGLProgram *prog, nsAString& retval,
return;
}
nsCAutoString log;
log.SetCapacity(k);
gl->fGetProgramInfoLog(progname, k, &k, (char*) log.BeginWriting());
log.SetLength(k);
CopyASCIItoUTF16(log, retval);
retval.SetCapacity(k);
gl->fGetProgramInfoLog(progname, k, &k, (char*) retval.BeginWriting());
retval.SetLength(k);
}
// here we have to support all pnames with both int and float params.
@ -3685,6 +3689,8 @@ WebGLContext::LinkProgram(WebGLProgram *program, ErrorResult& rv)
}
if (!program->HasBothShaderTypesAttached()) {
GenerateWarning("linkProgram: this program doesn't have both a vertex shader"
" and a fragment shader");
program->SetLinkStatus(false);
return;
}
@ -3699,6 +3705,53 @@ WebGLContext::LinkProgram(WebGLProgram *program, ErrorResult& rv)
program->SetLinkStatus(updateInfoSucceeded);
} else {
program->SetLinkStatus(false);
if (ShouldGenerateWarnings()) {
// report shader/program infoLogs as warnings.
// note that shader compilation errors can be deferred to linkProgram,
// which is why we can't do anything in compileShader. In practice we could
// report in compileShader the translation errors generated by ANGLE,
// but it seems saner to keep a single way of obtaining shader infologs.
ErrorResult rv;
nsCAutoString log;
bool alreadyReportedShaderInfoLog = false;
for (size_t i = 0; i < program->AttachedShaders().Length(); i++) {
WebGLShader* shader = program->AttachedShaders()[i];
GetShaderInfoLog(shader, log, rv);
if (rv.Failed() || log.IsEmpty())
continue;
const char *shaderTypeName = nsnull;
if (shader->ShaderType() == LOCAL_GL_VERTEX_SHADER) {
shaderTypeName = "vertex";
} else if (shader->ShaderType() == LOCAL_GL_FRAGMENT_SHADER) {
shaderTypeName = "fragment";
} else {
// should have been validated earlier
NS_ABORT();
shaderTypeName = "<unknown>";
}
GenerateWarning("linkProgram: a %s shader used in this program failed to "
"compile, with this log:\n%s\n",
shaderTypeName,
log.get());
alreadyReportedShaderInfoLog = true;
}
if (!alreadyReportedShaderInfoLog) {
GetProgramInfoLog(program, log, rv);
if (!(rv.Failed() || log.IsEmpty())) {
GenerateWarning("linkProgram failed, with this log:\n%s\n",
log.get());
}
}
}
}
}
@ -5232,6 +5285,15 @@ WebGLContext::GetShaderInfoLog(nsIWebGLShader *sobj, nsAString& retval)
void
WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsAString& retval,
ErrorResult& rv)
{
nsCAutoString s;
GetShaderInfoLog(shader, s, rv);
CopyASCIItoUTF16(s, retval);
}
void
WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsACString& retval,
ErrorResult& rv)
{
if (!IsContextStable())
{
@ -5242,9 +5304,8 @@ WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsAString& retval,
if (!ValidateObject("getShaderInfoLog: shader", shader))
return;
const nsCString& tlog = shader->TranslationLog();
if (!tlog.IsVoid()) {
CopyASCIItoUTF16(tlog, retval);
retval = shader->TranslationLog();
if (!retval.IsVoid()) {
return;
}
@ -5262,14 +5323,9 @@ WebGLContext::GetShaderInfoLog(WebGLShader *shader, nsAString& retval,
return;
}
nsCAutoString log;
log.SetCapacity(k);
gl->fGetShaderInfoLog(shadername, k, &k, (char*) log.BeginWriting());
log.SetLength(k);
CopyASCIItoUTF16(log, retval);
retval.SetCapacity(k);
gl->fGetShaderInfoLog(shadername, k, &k, (char*) retval.BeginWriting());
retval.SetLength(k);
}
NS_IMETHODIMP

View File

@ -45,12 +45,10 @@ WebGLContext::GenerateWarning(const char *fmt, ...)
void
WebGLContext::GenerateWarning(const char *fmt, va_list ap)
{
const int MaxReportedMessages = 32;
if (mAlreadyReportedMessages >= MaxReportedMessages)
if (!ShouldGenerateWarnings())
return;
mAlreadyReportedMessages++;
mAlreadyGeneratedWarnings++;
char buf[1024];
PR_vsnprintf(buf, 1024, fmt, ap);
@ -61,10 +59,10 @@ WebGLContext::GenerateWarning(const char *fmt, va_list ap)
JSContext* ccx = nsnull;
if (stack && NS_SUCCEEDED(stack->Peek(&ccx)) && ccx) {
JS_ReportWarning(ccx, "WebGL: %s", buf);
if (mAlreadyReportedMessages == MaxReportedMessages) {
if (!ShouldGenerateWarnings()) {
JS_ReportWarning(ccx,
"WebGL: no further warnings will be reported for this WebGL context "
"(already reported %d warnings)", mAlreadyReportedMessages);
"WebGL: No further warnings will be reported for this WebGL context "
"(already reported %d warnings)", mAlreadyGeneratedWarnings);
}
}
}

View File

@ -54,7 +54,7 @@ WebGLProgram::UpdateInfo()
if (loc < mContext->mGLMaxVertexAttribs) {
mAttribsInUse[loc] = true;
} else {
mContext->ErrorInvalidOperation("program exceeds MAX_VERTEX_ATTRIBS");
mContext->GenerateWarning("program exceeds MAX_VERTEX_ATTRIBS");
return false;
}
}