Bug 1263018 - Only update mActiveProgramLinkInfo if re-linking active draft
authorJeff Gilbert <jdashg@gmail.com>
Thu, 07 Apr 2016 14:21:49 -0700
changeset 348699 9a4573d10df9dbddfa7732f7972f3a5ab427a880
parent 346302 bccb11375f2af838cda714d42fd8cef78f5c7bf1
child 348700 a91451c16781d04fa08aa4871c967cef22e08ed6
push id14890
push userjgilbert@mozilla.com
push dateThu, 07 Apr 2016 22:36:48 +0000
bugs1263018
milestone48.0a1
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
dom/canvas/WebGLContextGL.cpp
dom/canvas/WebGLProgram.cpp
dom/canvas/WebGLProgram.h
--- 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;