Bug 1263018 - Only update mActiveProgramLinkInfo if re-linking active
From cf341928a4b3afc660ec84cc3fa6f7f1112861ea Mon Sep 17 00:00:00 2001
prog
r?jrmuizel
---
dom/canvas/WebGLContextGL.cpp | 11 ++++++++---
dom/canvas/WebGLProgram.cpp | 30 ++++++++++++------------------
dom/canvas/WebGLProgram.h | 4 ++--
3 files changed, 22 insertions(+), 23 deletions(-)
MozReview-Commit-ID: ATU3qAO4aJt
--- a/dom/canvas/WebGLContextGL.cpp
+++ b/dom/canvas/WebGLContextGL.cpp
@@ -1083,24 +1083,29 @@ WebGLContext::LinkProgram(WebGLProgram*
if (IsContextLost())
return;
if (!ValidateObject("linkProgram", prog))
return;
prog->LinkProgram();
- if (prog->IsLinked()) {
+ if (!prog->IsLinked()) {
+ // If we failed to link, but `prog == mCurrentProgram`, we are *not* supposed to
+ // null out mActiveProgramLinkInfo.
+ return;
+ }
+
+ if (prog == mCurrentProgram) {
mActiveProgramLinkInfo = prog->LinkInfo();
if (gl->WorkAroundDriverBugs() &&
gl->Vendor() == gl::GLVendor::NVIDIA)
{
- if (mCurrentProgram == prog)
- gl->fUseProgram(prog->mGLName);
+ gl->fUseProgram(prog->mGLName);
}
}
}
void
WebGLContext::PixelStorei(GLenum pname, GLint param)
{
if (IsContextLost())
--- a/dom/canvas/WebGLProgram.cpp
+++ b/dom/canvas/WebGLProgram.cpp
@@ -880,64 +880,64 @@ WebGLProgram::UniformBlockBinding(GLuint
return;
}
gl::GLContext* gl = mContext->GL();
gl->MakeCurrent();
gl->fUniformBlockBinding(mGLName, uniformBlockIndex, uniformBlockBinding);
}
-bool
+void
WebGLProgram::LinkProgram()
{
mContext->InvalidateBufferFetching(); // we do it early in this function
// as some of the validation below changes program state
mLinkLog.Truncate();
mMostRecentLinkInfo = nullptr;
if (!mVertShader || !mVertShader->IsCompiled()) {
mLinkLog.AssignLiteral("Must have a compiled vertex shader attached.");
mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
- return false;
+ return;
}
if (!mFragShader || !mFragShader->IsCompiled()) {
mLinkLog.AssignLiteral("Must have an compiled fragment shader attached.");
mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
- return false;
+ return;
}
if (!mFragShader->CanLinkTo(mVertShader, &mLinkLog)) {
mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
- return false;
+ return;
}
gl::GLContext* gl = mContext->gl;
gl->MakeCurrent();
if (gl->WorkAroundDriverBugs() &&
mContext->mIsMesa)
{
// Bug 777028: Mesa can't handle more than 16 samplers per program,
// counting each array entry.
size_t numSamplerUniforms_upperBound = mVertShader->CalcNumSamplerUniforms() +
mFragShader->CalcNumSamplerUniforms();
if (numSamplerUniforms_upperBound > 16) {
mLinkLog.AssignLiteral("Programs with more than 16 samplers are disallowed on"
" Mesa drivers to avoid crashing.");
mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
- return false;
+ return;
}
// Bug 1203135: Mesa crashes internally if we exceed the reported maximum attribute count.
if (mVertShader->NumAttributes() > mContext->MaxVertexAttribs()) {
mLinkLog.AssignLiteral("Number of attributes exceeds Mesa's reported max attribute count.");
mContext->GenerateWarning("linkProgram: %s", mLinkLog.BeginReading());
- return false;
+ return;
}
}
// Bind the attrib locations.
// This can't be done trivially, because we have to deal with mapped attrib names.
for (auto itr = mBoundAttribLocs.begin(); itr != mBoundAttribLocs.end(); ++itr) {
const nsCString& name = itr->first;
GLuint index = itr->second;
@@ -949,34 +949,33 @@ WebGLProgram::LinkProgram()
// Bind the transform feedback varyings.
// This can't be done trivially, because we have to deal with mapped names too.
mVertShader->ApplyTransformFeedbackVaryings(mGLName,
mTransformFeedbackVaryings,
mTransformFeedbackBufferMode,
&mTempMappedVaryings);
}
- if (LinkAndUpdate())
- return true;
+ LinkAndUpdate();
+ if (IsLinked())
+ return;
// Failed link.
if (mContext->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.
if (!mLinkLog.IsEmpty()) {
mContext->GenerateWarning("linkProgram: Failed to link, leaving the following"
" log:\n%s\n",
mLinkLog.BeginReading());
}
}
-
- return false;
}
bool
WebGLProgram::UseProgram() const
{
if (!mMostRecentLinkInfo) {
mContext->ErrorInvalidOperation("useProgram: Program has not been successfully"
" linked.");
@@ -1008,17 +1007,17 @@ WebGLProgram::ValidateProgram() const
#endif
gl->fValidateProgram(mGLName);
}
////////////////////////////////////////////////////////////////////////////////
-bool
+void
WebGLProgram::LinkAndUpdate()
{
mMostRecentLinkInfo = nullptr;
gl::GLContext* gl = mContext->gl;
gl->fLinkProgram(mGLName);
// Grab the program log.
@@ -1034,25 +1033,20 @@ WebGLProgram::LinkAndUpdate()
// Post link, temporary mapped varying names for transform feedback can be discarded.
// The memory can only be deleted after log is queried or the link status will fail.
std::vector<std::string> empty;
empty.swap(mTempMappedVaryings);
GLint ok = 0;
gl->fGetProgramiv(mGLName, LOCAL_GL_LINK_STATUS, &ok);
if (!ok)
- return false;
+ return;
mMostRecentLinkInfo = QueryProgramInfo(this, gl);
-
- MOZ_ASSERT(mMostRecentLinkInfo);
- if (!mMostRecentLinkInfo)
- mLinkLog.AssignLiteral("Failed to gather program info.");
-
- return mMostRecentLinkInfo;
+ MOZ_RELEASE_ASSERT(mMostRecentLinkInfo);
}
bool
WebGLProgram::FindActiveOutputMappedNameByUserName(const nsACString& userName,
nsCString* const out_mappedName) const
{
if (mFragShader->FindActiveOutputMappedNameByUserName(userName, out_mappedName)) {
return true;
--- a/dom/canvas/WebGLProgram.h
+++ b/dom/canvas/WebGLProgram.h
@@ -151,17 +151,17 @@ public:
void GetActiveUniformBlockActiveUniforms(JSContext* cx, GLuint uniformBlockIndex,
dom::Nullable<dom::OwningUnsignedLongOrUint32ArrayOrBoolean>& retval,
ErrorResult& rv) const;
already_AddRefed<WebGLUniformLocation> GetUniformLocation(const nsAString& name) const;
void GetUniformIndices(const dom::Sequence<nsString>& uniformNames,
dom::Nullable< nsTArray<GLuint> >& retval) const;
void UniformBlockBinding(GLuint uniformBlockIndex, GLuint uniformBlockBinding) const;
- bool LinkProgram();
+ void LinkProgram();
bool UseProgram() const;
void ValidateProgram() const;
////////////////
bool FindActiveOutputMappedNameByUserName(const nsACString& userName,
nsCString* const out_mappedName) const;
bool FindAttribUserNameByMappedName(const nsACString& mappedName,
@@ -190,17 +190,17 @@ public:
return mContext;
}
virtual JSObject* WrapObject(JSContext* js, JS::Handle<JSObject*> givenProto) override;
private:
~WebGLProgram();
- bool LinkAndUpdate();
+ void LinkAndUpdate();
public:
const GLuint mGLName;
private:
WebGLRefPtr<WebGLShader> mVertShader;
WebGLRefPtr<WebGLShader> mFragShader;
std::map<nsCString, GLuint> mBoundAttribLocs;