Bug 1301803 - Handle context loss during QueryProgramInfo. r=lsalzman
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 30 Jan 2019 03:24:04 +0000
changeset 513997 cd7547ae0876c4101414cae7d8703cef10c73916
parent 513996 d2bb10ec687e38b878a7512652e70cdd6d0bb2fc
child 513998 00494efd99e7935d1de77aaa2aa62467d706fa05
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1301803
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1301803 - Handle context loss during QueryProgramInfo. r=lsalzman Differential Revision: https://phabricator.services.mozilla.com/D17998
dom/canvas/WebGLProgram.cpp
--- a/dom/canvas/WebGLProgram.cpp
+++ b/dom/canvas/WebGLProgram.cpp
@@ -158,17 +158,17 @@ webgl::UniformInfo::UniformInfo(WebGLAct
     mSamplerValues.assign(mActiveInfo->mElemCount, 0);
   }
 }
 
 //////////
 
 //#define DUMP_SHADERVAR_MAPPINGS
 
-static already_AddRefed<const webgl::LinkedProgramInfo> QueryProgramInfo(
+static RefPtr<const webgl::LinkedProgramInfo> QueryProgramInfo(
     WebGLProgram* prog, gl::GLContext* gl) {
   WebGLContext* const webgl = prog->mContext;
 
   RefPtr<webgl::LinkedProgramInfo> info(new webgl::LinkedProgramInfo(prog));
 
   GLuint maxAttribLenWithNull = 0;
   gl->fGetProgramiv(prog->mGLName, LOCAL_GL_ACTIVE_ATTRIBUTE_MAX_LENGTH,
                     (GLint*)&maxAttribLenWithNull);
@@ -207,19 +207,22 @@ static already_AddRefed<const webgl::Lin
     mappedName.SetLength(maxAttribLenWithNull - 1);
 
     GLsizei lengthWithoutNull = 0;
     GLint elemCount = 0;  // `size`
     GLenum elemType = 0;  // `type`
     gl->fGetActiveAttrib(prog->mGLName, i, mappedName.Length() + 1,
                          &lengthWithoutNull, &elemCount, &elemType,
                          mappedName.BeginWriting());
-    GLenum error = gl->fGetError();
-    if (error != LOCAL_GL_NO_ERROR) {
-      gfxCriticalNote << "Failed to do glGetActiveAttrib: " << error;
+    if (!elemType) {
+      const auto error = gl->fGetError();
+      if (error != LOCAL_GL_CONTEXT_LOST) {
+        gfxCriticalError() << "Failed to do glGetActiveAttrib: " << error;
+      }
+      return nullptr;
     }
 
     mappedName.SetLength(lengthWithoutNull);
 
     ////
 
     nsCString userName;
     if (!prog->FindAttribUserNameByMappedName(mappedName, &userName)) {
@@ -267,16 +270,23 @@ static already_AddRefed<const webgl::Lin
     mappedName.SetLength(maxUniformLenWithNull - 1);
 
     GLsizei lengthWithoutNull = 0;
     GLint elemCount = 0;  // `size`
     GLenum elemType = 0;  // `type`
     gl->fGetActiveUniform(prog->mGLName, i, mappedName.Length() + 1,
                           &lengthWithoutNull, &elemCount, &elemType,
                           mappedName.BeginWriting());
+    if (!elemType) {
+      const auto error = gl->fGetError();
+      if (error != LOCAL_GL_CONTEXT_LOST) {
+        gfxCriticalError() << "Failed to do glGetActiveAttrib: " << error;
+      }
+      return nullptr;
+    }
 
     mappedName.SetLength(lengthWithoutNull);
 
     ///////
 
     nsAutoCString baseMappedName;
     bool isArray;
     size_t arrayIndex;
@@ -383,16 +393,25 @@ static already_AddRefed<const webgl::Lin
       mappedName.SetLength(maxTransformFeedbackVaryingLenWithNull - 1);
 
       GLint lengthWithoutNull;
       GLsizei elemCount;
       GLenum elemType;
       gl->fGetTransformFeedbackVarying(
           prog->mGLName, i, maxTransformFeedbackVaryingLenWithNull,
           &lengthWithoutNull, &elemCount, &elemType, mappedName.BeginWriting());
+
+      if (!elemType) {
+        const auto error = gl->fGetError();
+        if (error != LOCAL_GL_CONTEXT_LOST) {
+          gfxCriticalError() << "Failed to do glGetActiveAttrib: " << error;
+        }
+        return nullptr;
+      }
+
       mappedName.SetLength(lengthWithoutNull);
 
       ////
 
       nsAutoCString baseMappedName;
       bool isArray;
       size_t arrayIndex;
       if (!ParseName(mappedName, &baseMappedName, &isArray, &arrayIndex))
@@ -416,17 +435,17 @@ static already_AddRefed<const webgl::Lin
       info->transformFeedbackVaryings.push_back(activeInfo);
     }
   }
 
   // Frag outputs
 
   prog->EnumerateFragOutputs(info->fragDataMap);
 
-  return info.forget();
+  return info;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 
 webgl::LinkedProgramInfo::LinkedProgramInfo(WebGLProgram* prog)
     : prog(prog),
       transformFeedbackBufferMode(prog->mNextLink_TransformFeedbackBufferMode),
       attrib0Active(false) {}
@@ -1415,19 +1434,18 @@ void WebGLProgram::LinkAndUpdate() {
   } else {
     mLinkLog.SetLength(0);
   }
 
   GLint ok = 0;
   gl->fGetProgramiv(mGLName, LOCAL_GL_LINK_STATUS, &ok);
   if (!ok) return;
 
-  mMostRecentLinkInfo = QueryProgramInfo(this, gl);
-  MOZ_RELEASE_ASSERT(mMostRecentLinkInfo,
-                     "GFX: most recent link info not set.");
+  mMostRecentLinkInfo =
+      QueryProgramInfo(this, gl);  // Fallible after context loss.
 }
 
 bool WebGLProgram::FindAttribUserNameByMappedName(
     const nsACString& mappedName, nsCString* const out_userName) const {
   if (mVertShader->FindAttribUserNameByMappedName(mappedName, out_userName))
     return true;
 
   return false;