Bug 1521992 - Fix incomplete-fb error for webgl.getParameter. r=lsalzman
authorJeff Gilbert <jgilbert@mozilla.com>
Wed, 23 Jan 2019 17:53:43 +0000
changeset 515361 4b17b7e5bd5a582ddb9d1b9e1bb1ed56d41d3cc2
parent 515360 62d37f1cbdbd2d579414d36e6c9284ecfd8063cb
child 515362 63049c1db4fc9be3bfd673920dfa1a801da7a56d
child 515394 93a452407d5a66bea3a10a11198a8262abef1876
push id1953
push userffxbld-merge
push dateMon, 11 Mar 2019 12:10:20 +0000
treeherdermozilla-release@9c35dcbaa899 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman
bugs1521992
milestone66.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 1521992 - Fix incomplete-fb error for webgl.getParameter. r=lsalzman Differential Revision: https://phabricator.services.mozilla.com/D17306
dom/canvas/WebGLContext.cpp
dom/canvas/WebGLContext.h
dom/canvas/WebGLContextState.cpp
dom/canvas/WebGLContextUtils.cpp
dom/canvas/WebGLFramebuffer.cpp
dom/canvas/WebGLFramebuffer.h
--- a/dom/canvas/WebGLContext.cpp
+++ b/dom/canvas/WebGLContext.cpp
@@ -1715,18 +1715,19 @@ gfx::IntSize WebGLContext::DrawingBuffer
   const gfx::IntSize zeros{0, 0};
   if (IsContextLost()) return zeros;
 
   if (!EnsureDefaultFB()) return zeros;
 
   return mDefaultFB->mSize;
 }
 
-bool WebGLContext::ValidateAndInitFB(const WebGLFramebuffer* const fb) {
-  if (fb) return fb->ValidateAndInitAttachments();
+bool WebGLContext::ValidateAndInitFB(const WebGLFramebuffer* const fb,
+                                     const GLenum incompleteFbError) {
+  if (fb) return fb->ValidateAndInitAttachments(incompleteFbError);
 
   if (!EnsureDefaultFB()) return false;
 
   if (mDefaultFB_IsInvalid) {
     // Clear it!
     gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mDefaultFB->mFB);
     const webgl::ScopedPrepForResourceClear scopedPrep(*this);
     if (!mOptions.alpha) {
@@ -1753,21 +1754,21 @@ bool WebGLContext::BindCurFBForDraw() {
   if (!ValidateAndInitFB(fb)) return false;
 
   DoBindFB(fb);
   return true;
 }
 
 bool WebGLContext::BindCurFBForColorRead(
     const webgl::FormatUsageInfo** const out_format, uint32_t* const out_width,
-    uint32_t* const out_height) {
+    uint32_t* const out_height, const GLenum incompleteFbError) {
   const auto& fb = mBoundReadFramebuffer;
 
   if (fb) {
-    if (!ValidateAndInitFB(fb)) return false;
+    if (!ValidateAndInitFB(fb, incompleteFbError)) return false;
     if (!fb->ValidateForColorRead(out_format, out_width, out_height))
       return false;
 
     gl->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb->mGLName);
     return true;
   }
 
   if (!BindDefaultFBForRead()) return false;
--- a/dom/canvas/WebGLContext.h
+++ b/dom/canvas/WebGLContext.h
@@ -415,17 +415,17 @@ class WebGLContext : public nsICanvasRen
     void OnCheckContextLost() const {
 #ifdef DEBUG
       mStillNeedsToCheckContextLost = false;
 #endif
     }
   };
 
   void SynthesizeGLError(GLenum err) const;
-  void SynthesizeGLError(GLenum err, const char* fmt, ...) const
+  void GenerateError(GLenum err, const char* fmt, ...) const
       MOZ_FORMAT_PRINTF(3, 4);
 
   void ErrorInvalidEnum(const char* fmt = 0, ...) const MOZ_FORMAT_PRINTF(2, 3);
   void ErrorInvalidOperation(const char* fmt = 0, ...) const
       MOZ_FORMAT_PRINTF(2, 3);
   void ErrorInvalidValue(const char* fmt = 0, ...) const
       MOZ_FORMAT_PRINTF(2, 3);
   void ErrorInvalidFramebufferOperation(const char* fmt = 0, ...) const
@@ -1944,23 +1944,27 @@ class WebGLContext : public nsICanvasRen
   mutable gfx::IntSize mRequestedSize;
   mutable UniquePtr<gl::MozFramebuffer> mDefaultFB;
   mutable bool mDefaultFB_IsInvalid = false;
   mutable UniquePtr<gl::MozFramebuffer> mResolvedDefaultFB;
 
   // --
 
   bool EnsureDefaultFB();
-  bool ValidateAndInitFB(const WebGLFramebuffer* fb);
+  bool ValidateAndInitFB(
+      const WebGLFramebuffer* fb,
+      GLenum incompleteFbError = LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
   void DoBindFB(const WebGLFramebuffer* fb,
                 GLenum target = LOCAL_GL_FRAMEBUFFER) const;
 
   bool BindCurFBForDraw();
-  bool BindCurFBForColorRead(const webgl::FormatUsageInfo** out_format,
-                             uint32_t* out_width, uint32_t* out_height);
+  bool BindCurFBForColorRead(
+      const webgl::FormatUsageInfo** out_format, uint32_t* out_width,
+      uint32_t* out_height,
+      GLenum incompleteFbError = LOCAL_GL_INVALID_FRAMEBUFFER_OPERATION);
   void DoColorMask(uint8_t bitmask) const;
   void BlitBackbufferToCurDriverFB() const;
   bool BindDefaultFBForRead();
 
   // --
 
  public:
   void LoseOldestWebGLContextIfLimitExceeded();
--- a/dom/canvas/WebGLContextState.cpp
+++ b/dom/canvas/WebGLContextState.cpp
@@ -233,17 +233,18 @@ JS::Value WebGLContext::GetParameter(JSC
 
     case LOCAL_GL_GENERATE_MIPMAP_HINT:
       return JS::NumberValue(mGenerateMipmapHint);
 
     case LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT:
     case LOCAL_GL_IMPLEMENTATION_COLOR_READ_TYPE: {
       const webgl::FormatUsageInfo* usage;
       uint32_t width, height;
-      if (!BindCurFBForColorRead(&usage, &width, &height))
+      if (!BindCurFBForColorRead(&usage, &width, &height,
+                                 LOCAL_GL_INVALID_OPERATION))
         return JS::NullValue();
 
       const auto implPI = ValidImplementationColorReadPI(usage);
 
       GLenum ret;
       if (pname == LOCAL_GL_IMPLEMENTATION_COLOR_READ_FORMAT) {
         ret = implPI.format;
       } else {
--- a/dom/canvas/WebGLContextUtils.cpp
+++ b/dom/canvas/WebGLContextUtils.cpp
@@ -136,17 +136,18 @@ void WebGLContext::SynthesizeGLError(GLe
    * multiple 'flags', as errors might be caught in different parts of
    * a distributed implementation.
    * We're signing up as a distributed implementation here, with
    * separate flags for WebGL and the underlying GLContext.
    */
   if (!mWebGLError) mWebGLError = err;
 }
 
-void WebGLContext::SynthesizeGLError(GLenum err, const char* fmt, ...) const {
+void WebGLContext::GenerateError(const GLenum err, const char* const fmt,
+                                 ...) const {
   va_list va;
   va_start(va, fmt);
   GenerateWarning(fmt, va);
   va_end(va);
 
   return SynthesizeGLError(err);
 }
 
--- a/dom/canvas/WebGLFramebuffer.cpp
+++ b/dom/canvas/WebGLFramebuffer.cpp
@@ -675,24 +675,25 @@ FBStatus WebGLFramebuffer::PrecheckFrame
   }
 
   return LOCAL_GL_FRAMEBUFFER_COMPLETE;
 }
 
 ////////////////////////////////////////
 // Validation
 
-bool WebGLFramebuffer::ValidateAndInitAttachments() const {
+bool WebGLFramebuffer::ValidateAndInitAttachments(
+    const GLenum incompleteFbError) const {
   MOZ_ASSERT(mContext->mBoundDrawFramebuffer == this ||
              mContext->mBoundReadFramebuffer == this);
 
   const auto fbStatus = CheckFramebufferStatus();
   if (fbStatus == LOCAL_GL_FRAMEBUFFER_COMPLETE) return true;
 
-  mContext->ErrorInvalidFramebufferOperation("Framebuffer must be complete.");
+  mContext->GenerateError(incompleteFbError, "Framebuffer must be complete.");
   return false;
 }
 
 bool WebGLFramebuffer::ValidateClearBufferType(GLenum buffer,
                                                uint32_t drawBuffer,
                                                GLenum funcType) const {
   if (buffer != LOCAL_GL_COLOR) return true;
 
--- a/dom/canvas/WebGLFramebuffer.h
+++ b/dom/canvas/WebGLFramebuffer.h
@@ -213,17 +213,17 @@ class WebGLFramebuffer final : public ns
   void DoDeferredAttachments() const;
   void RefreshDrawBuffers() const;
   void RefreshReadBuffer() const;
   void ResolveAttachmentData() const;
 
  public:
   void DetachTexture(const WebGLTexture* tex);
   void DetachRenderbuffer(const WebGLRenderbuffer* rb);
-  bool ValidateAndInitAttachments() const;
+  bool ValidateAndInitAttachments(GLenum incompleteFbError) const;
   bool ValidateClearBufferType(GLenum buffer, uint32_t drawBuffer,
                                GLenum funcType) const;
 
   bool ValidateForColorRead(const webgl::FormatUsageInfo** out_format,
                             uint32_t* out_width, uint32_t* out_height) const;
 
   ////////////////
   // Getters