Return an Error from Framebuffer::syncState.

This pipes errors up from the Impl to the top level. There are
still a few places were error swallowing is needed, because the
Framebuffer API doesn't support returning an error.

Bug: angleproject:2372
Change-Id: Idc06bda1817fd28075940f69874d8b6ba69194f9
Reviewed-on: https://chromium-review.googlesource.com/954290
Commit-Queue: Jamie Madill <jmadill@chromium.org>
Reviewed-by: Geoff Lang <geofflang@chromium.org>
Reviewed-by: Luc Ferron <lucferron@chromium.org>
diff --git a/src/libANGLE/Framebuffer.cpp b/src/libANGLE/Framebuffer.cpp
index 3500d83..64c0f07 100644
--- a/src/libANGLE/Framebuffer.cpp
+++ b/src/libANGLE/Framebuffer.cpp
@@ -1199,7 +1199,8 @@
         }
     }
 
-    syncState(context);
+    // TODO(jmadill): Don't swallow an error here. http://anglebug.com/2372
+    ANGLE_SWALLOW_ERR(syncState(context));
     if (!mImpl->checkStatus(context))
     {
         return GL_FRAMEBUFFER_UNSUPPORTED;
@@ -1781,12 +1782,12 @@
     setAttachment(context, GL_NONE, binding, ImageIndex::MakeInvalid(), nullptr);
 }
 
-void Framebuffer::syncState(const Context *context)
+Error Framebuffer::syncState(const Context *context)
 {
     if (mDirtyBits.any())
     {
         mDirtyBitsGuard = mDirtyBits;
-        mImpl->syncState(context, mDirtyBits);
+        ANGLE_TRY(mImpl->syncState(context, mDirtyBits));
         mDirtyBits.reset();
         if (mId != 0)
         {
@@ -1794,6 +1795,7 @@
         }
         mDirtyBitsGuard.reset();
     }
+    return NoError();
 }
 
 void Framebuffer::onSubjectStateChange(const Context *context,
diff --git a/src/libANGLE/Framebuffer.h b/src/libANGLE/Framebuffer.h
index fb8afdf..e62c333 100644
--- a/src/libANGLE/Framebuffer.h
+++ b/src/libANGLE/Framebuffer.h
@@ -305,7 +305,7 @@
     using DirtyBits = angle::BitSet<DIRTY_BIT_MAX>;
     bool hasAnyDirtyBit() const { return mDirtyBits.any(); }
 
-    void syncState(const Context *context);
+    Error syncState(const Context *context);
 
     // Observer implementation
     void onSubjectStateChange(const Context *context,
diff --git a/src/libANGLE/State.cpp b/src/libANGLE/State.cpp
index 66873aa..2fe3294 100644
--- a/src/libANGLE/State.cpp
+++ b/src/libANGLE/State.cpp
@@ -2243,11 +2243,11 @@
         {
             case DIRTY_OBJECT_READ_FRAMEBUFFER:
                 ASSERT(mReadFramebuffer);
-                mReadFramebuffer->syncState(context);
+                ANGLE_TRY(mReadFramebuffer->syncState(context));
                 break;
             case DIRTY_OBJECT_DRAW_FRAMEBUFFER:
                 ASSERT(mDrawFramebuffer);
-                mDrawFramebuffer->syncState(context);
+                ANGLE_TRY(mDrawFramebuffer->syncState(context));
                 break;
             case DIRTY_OBJECT_VERTEX_ARRAY:
                 ASSERT(mVertexArray);
diff --git a/src/libANGLE/renderer/FramebufferImpl.h b/src/libANGLE/renderer/FramebufferImpl.h
index ebb166c..dbe9a85 100644
--- a/src/libANGLE/renderer/FramebufferImpl.h
+++ b/src/libANGLE/renderer/FramebufferImpl.h
@@ -80,8 +80,8 @@
 
     virtual bool checkStatus(const gl::Context *context) const = 0;
 
-    virtual void syncState(const gl::Context *context,
-                           const gl::Framebuffer::DirtyBits &dirtyBits) = 0;
+    virtual gl::Error syncState(const gl::Context *context,
+                                const gl::Framebuffer::DirtyBits &dirtyBits) = 0;
 
     virtual gl::Error getSamplePosition(size_t index, GLfloat *xy) const = 0;
 
diff --git a/src/libANGLE/renderer/FramebufferImpl_mock.h b/src/libANGLE/renderer/FramebufferImpl_mock.h
index c2d0696..358b06a 100644
--- a/src/libANGLE/renderer/FramebufferImpl_mock.h
+++ b/src/libANGLE/renderer/FramebufferImpl_mock.h
@@ -50,7 +50,7 @@
 
     MOCK_CONST_METHOD1(checkStatus, bool(const gl::Context *));
 
-    MOCK_METHOD2(syncState, void(const gl::Context *, const gl::Framebuffer::DirtyBits &));
+    MOCK_METHOD2(syncState, gl::Error(const gl::Context *, const gl::Framebuffer::DirtyBits &));
 
     MOCK_METHOD0(destructor, void());
 };
diff --git a/src/libANGLE/renderer/RenderTargetCache.h b/src/libANGLE/renderer/RenderTargetCache.h
index 4474d19..7c2aef2 100644
--- a/src/libANGLE/renderer/RenderTargetCache.h
+++ b/src/libANGLE/renderer/RenderTargetCache.h
@@ -26,9 +26,9 @@
     RenderTargetCache();
     ~RenderTargetCache();
 
-    void update(const gl::Context *context,
-                const gl::FramebufferState &state,
-                const gl::Framebuffer::DirtyBits &dirtyBits);
+    gl::Error update(const gl::Context *context,
+                     const gl::FramebufferState &state,
+                     const gl::Framebuffer::DirtyBits &dirtyBits);
 
     using RenderTargetArray = gl::AttachmentArray<RenderTargetT *>;
 
@@ -38,15 +38,15 @@
     RenderTargetT *getColorRead(const gl::FramebufferState &state) const;
 
   private:
-    void updateCachedRenderTarget(const gl::Context *context,
-                                  const gl::FramebufferAttachment *attachment,
-                                  RenderTargetT **cachedRenderTarget);
+    gl::Error updateCachedRenderTarget(const gl::Context *context,
+                                       const gl::FramebufferAttachment *attachment,
+                                       RenderTargetT **cachedRenderTarget);
 
-    void updateColorRenderTarget(const gl::Context *context,
-                                 const gl::FramebufferState &state,
-                                 size_t colorIndex);
-    void updateDepthStencilRenderTarget(const gl::Context *context,
-                                        const gl::FramebufferState &state);
+    gl::Error updateColorRenderTarget(const gl::Context *context,
+                                      const gl::FramebufferState &state,
+                                      size_t colorIndex);
+    gl::Error updateDepthStencilRenderTarget(const gl::Context *context,
+                                             const gl::FramebufferState &state);
 
     gl::AttachmentArray<RenderTargetT *> mColorRenderTargets;
     // We only support a single Depth/Stencil RenderTarget currently.
@@ -65,9 +65,9 @@
 }
 
 template <typename RenderTargetT>
-void RenderTargetCache<RenderTargetT>::update(const gl::Context *context,
-                                              const gl::FramebufferState &state,
-                                              const gl::Framebuffer::DirtyBits &dirtyBits)
+gl::Error RenderTargetCache<RenderTargetT>::update(const gl::Context *context,
+                                                   const gl::FramebufferState &state,
+                                                   const gl::Framebuffer::DirtyBits &dirtyBits)
 {
     for (auto dirtyBit : dirtyBits)
     {
@@ -75,7 +75,7 @@
         {
             case gl::Framebuffer::DIRTY_BIT_DEPTH_ATTACHMENT:
             case gl::Framebuffer::DIRTY_BIT_STENCIL_ATTACHMENT:
-                updateDepthStencilRenderTarget(context, state);
+                ANGLE_TRY(updateDepthStencilRenderTarget(context, state));
                 break;
             case gl::Framebuffer::DIRTY_BIT_DRAW_BUFFERS:
             case gl::Framebuffer::DIRTY_BIT_READ_BUFFER:
@@ -90,11 +90,13 @@
                        dirtyBit < gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_MAX);
                 size_t colorIndex =
                     static_cast<size_t>(dirtyBit - gl::Framebuffer::DIRTY_BIT_COLOR_ATTACHMENT_0);
-                updateColorRenderTarget(context, state, colorIndex);
+                ANGLE_TRY(updateColorRenderTarget(context, state, colorIndex));
                 break;
             }
         }
     }
+
+    return gl::NoError();
 }
 
 template <typename RenderTargetT>
@@ -110,25 +112,26 @@
 }
 
 template <typename RenderTargetT>
-void RenderTargetCache<RenderTargetT>::updateColorRenderTarget(const gl::Context *context,
-                                                               const gl::FramebufferState &state,
-                                                               size_t colorIndex)
+gl::Error RenderTargetCache<RenderTargetT>::updateColorRenderTarget(
+    const gl::Context *context,
+    const gl::FramebufferState &state,
+    size_t colorIndex)
 {
-    updateCachedRenderTarget(context, state.getColorAttachment(colorIndex),
-                             &mColorRenderTargets[colorIndex]);
+    return updateCachedRenderTarget(context, state.getColorAttachment(colorIndex),
+                                    &mColorRenderTargets[colorIndex]);
 }
 
 template <typename RenderTargetT>
-void RenderTargetCache<RenderTargetT>::updateDepthStencilRenderTarget(
+gl::Error RenderTargetCache<RenderTargetT>::updateDepthStencilRenderTarget(
     const gl::Context *context,
     const gl::FramebufferState &state)
 {
-    updateCachedRenderTarget(context, state.getDepthOrStencilAttachment(),
-                             &mDepthStencilRenderTarget);
+    return updateCachedRenderTarget(context, state.getDepthOrStencilAttachment(),
+                                    &mDepthStencilRenderTarget);
 }
 
 template <typename RenderTargetT>
-void RenderTargetCache<RenderTargetT>::updateCachedRenderTarget(
+gl::Error RenderTargetCache<RenderTargetT>::updateCachedRenderTarget(
     const gl::Context *context,
     const gl::FramebufferAttachment *attachment,
     RenderTargetT **cachedRenderTarget)
@@ -137,11 +140,10 @@
     if (attachment)
     {
         ASSERT(attachment->isAttached());
-
-        // TODO(jmadill): Don't swallow this error.
-        ANGLE_SWALLOW_ERR(attachment->getRenderTarget(context, &newRenderTarget));
+        ANGLE_TRY(attachment->getRenderTarget(context, &newRenderTarget));
     }
     *cachedRenderTarget = newRenderTarget;
+    return gl::NoError();
 }
 
 template <typename RenderTargetT>
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
index ac518fc..5f117a6 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.cpp
@@ -319,12 +319,12 @@
     return true;
 }
 
-void FramebufferD3D::syncState(const gl::Context *context,
-                               const gl::Framebuffer::DirtyBits &dirtyBits)
+gl::Error FramebufferD3D::syncState(const gl::Context *context,
+                                    const gl::Framebuffer::DirtyBits &dirtyBits)
 {
     if (!mColorAttachmentsForRender.valid())
     {
-        return;
+        return gl::NoError();
     }
 
     for (auto dirtyBit : dirtyBits)
@@ -336,6 +336,8 @@
             mColorAttachmentsForRender.reset();
         }
     }
+
+    return gl::NoError();
 }
 
 const gl::AttachmentList &FramebufferD3D::getColorAttachmentsForRender(const gl::Context *context)
diff --git a/src/libANGLE/renderer/d3d/FramebufferD3D.h b/src/libANGLE/renderer/d3d/FramebufferD3D.h
index 58b0ee6..9e54e55 100644
--- a/src/libANGLE/renderer/d3d/FramebufferD3D.h
+++ b/src/libANGLE/renderer/d3d/FramebufferD3D.h
@@ -97,8 +97,8 @@
 
     bool checkStatus(const gl::Context *context) const override;
 
-    void syncState(const gl::Context *context,
-                   const gl::Framebuffer::DirtyBits &dirtyBits) override;
+    gl::Error syncState(const gl::Context *context,
+                        const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
     const gl::AttachmentList &getColorAttachmentsForRender(const gl::Context *context);
 
diff --git a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
index a665bee..1ee208a 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
+++ b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.cpp
@@ -357,12 +357,11 @@
     return renderTarget11->getFormatSet().format().fboImplementationInternalFormat;
 }
 
-void Framebuffer11::syncState(const gl::Context *context,
-                              const gl::Framebuffer::DirtyBits &dirtyBits)
+gl::Error Framebuffer11::syncState(const gl::Context *context,
+                                   const gl::Framebuffer::DirtyBits &dirtyBits)
 {
-    mRenderTargetCache.update(context, mState, dirtyBits);
-
-    FramebufferD3D::syncState(context, dirtyBits);
+    ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits));
+    ANGLE_TRY(FramebufferD3D::syncState(context, dirtyBits));
 
     // Call this last to allow the state manager to take advantage of the cached render targets.
     mRenderer->getStateManager()->invalidateRenderTarget();
@@ -372,6 +371,8 @@
     {
         mRenderer->getStateManager()->invalidateViewport(context);
     }
+
+    return gl::NoError();
 }
 
 gl::Error Framebuffer11::getSamplePosition(size_t index, GLfloat *xy) const
diff --git a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
index 6b4f975..d7b43b3 100644
--- a/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
+++ b/src/libANGLE/renderer/d3d/d3d11/Framebuffer11.h
@@ -36,8 +36,8 @@
     // Invalidate the cached swizzles of all bound texture attachments.
     gl::Error markAttachmentsDirty(const gl::Context *context) const;
 
-    void syncState(const gl::Context *context,
-                   const gl::Framebuffer::DirtyBits &dirtyBits) override;
+    gl::Error syncState(const gl::Context *context,
+                        const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
     const gl::AttachmentArray<RenderTarget11 *> &getCachedColorRenderTargets() const
     {
diff --git a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
index 5feed6a..992c65f 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
+++ b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp
@@ -408,10 +408,11 @@
     return gl::InternalError() << "getSamplePosition is unsupported to d3d9.";
 }
 
-void Framebuffer9::syncState(const gl::Context *context,
-                             const gl::Framebuffer::DirtyBits &dirtyBits)
+gl::Error Framebuffer9::syncState(const gl::Context *context,
+                                  const gl::Framebuffer::DirtyBits &dirtyBits)
 {
-    FramebufferD3D::syncState(context, dirtyBits);
-    mRenderTargetCache.update(context, mState, dirtyBits);
+    ANGLE_TRY(FramebufferD3D::syncState(context, dirtyBits));
+    ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits));
+    return gl::NoError();
 }
 }  // namespace rx
diff --git a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
index cc0f18f..2cca4c0 100644
--- a/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
+++ b/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h
@@ -34,8 +34,8 @@
 
     gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
 
-    void syncState(const gl::Context *context,
-                   const gl::Framebuffer::DirtyBits &dirtyBits) override;
+    gl::Error syncState(const gl::Context *context,
+                        const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
     const gl::AttachmentArray<RenderTarget9 *> &getCachedColorRenderTargets() const
     {
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.cpp b/src/libANGLE/renderer/gl/FramebufferGL.cpp
index c4be5ec..914902a 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.cpp
+++ b/src/libANGLE/renderer/gl/FramebufferGL.cpp
@@ -606,12 +606,13 @@
     return (status == GL_FRAMEBUFFER_COMPLETE);
 }
 
-void FramebufferGL::syncState(const gl::Context *context, const Framebuffer::DirtyBits &dirtyBits)
+gl::Error FramebufferGL::syncState(const gl::Context *context,
+                                   const Framebuffer::DirtyBits &dirtyBits)
 {
     // Don't need to sync state for the default FBO.
     if (mIsDefault)
     {
-        return;
+        return gl::NoError();
     }
 
     mStateManager->bindFramebuffer(GL_FRAMEBUFFER, mFramebufferID);
@@ -698,6 +699,8 @@
         mStateManager->updateMultiviewBaseViewLayerIndexUniform(context->getGLState().getProgram(),
                                                                 getState());
     }
+
+    return gl::NoError();
 }
 
 GLuint FramebufferGL::getFramebufferID() const
diff --git a/src/libANGLE/renderer/gl/FramebufferGL.h b/src/libANGLE/renderer/gl/FramebufferGL.h
index 1400279..e489609 100644
--- a/src/libANGLE/renderer/gl/FramebufferGL.h
+++ b/src/libANGLE/renderer/gl/FramebufferGL.h
@@ -89,8 +89,8 @@
 
     bool checkStatus(const gl::Context *context) const override;
 
-    void syncState(const gl::Context *context,
-                   const gl::Framebuffer::DirtyBits &dirtyBits) override;
+    gl::Error syncState(const gl::Context *context,
+                        const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
     GLuint getFramebufferID() const;
     bool isDefault() const;
diff --git a/src/libANGLE/renderer/null/FramebufferNULL.cpp b/src/libANGLE/renderer/null/FramebufferNULL.cpp
index 71d3cdc..30dba62 100644
--- a/src/libANGLE/renderer/null/FramebufferNULL.cpp
+++ b/src/libANGLE/renderer/null/FramebufferNULL.cpp
@@ -185,9 +185,10 @@
     return true;
 }
 
-void FramebufferNULL::syncState(const gl::Context *context,
-                                const gl::Framebuffer::DirtyBits &dirtyBits)
+gl::Error FramebufferNULL::syncState(const gl::Context *context,
+                                     const gl::Framebuffer::DirtyBits &dirtyBits)
 {
+    return gl::NoError();
 }
 
 gl::Error FramebufferNULL::getSamplePosition(size_t index, GLfloat *xy) const
diff --git a/src/libANGLE/renderer/null/FramebufferNULL.h b/src/libANGLE/renderer/null/FramebufferNULL.h
index 7aeefa4..cc3235b 100644
--- a/src/libANGLE/renderer/null/FramebufferNULL.h
+++ b/src/libANGLE/renderer/null/FramebufferNULL.h
@@ -65,8 +65,8 @@
 
     bool checkStatus(const gl::Context *context) const override;
 
-    void syncState(const gl::Context *context,
-                   const gl::Framebuffer::DirtyBits &dirtyBits) override;
+    gl::Error syncState(const gl::Context *context,
+                        const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
     gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;
 };
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
index 2bd6920..b65d3f7 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.cpp
@@ -319,15 +319,14 @@
     return true;
 }
 
-void FramebufferVk::syncState(const gl::Context *context,
-                              const gl::Framebuffer::DirtyBits &dirtyBits)
+gl::Error FramebufferVk::syncState(const gl::Context *context,
+                                   const gl::Framebuffer::DirtyBits &dirtyBits)
 {
     ContextVk *contextVk = vk::GetImpl(context);
     RendererVk *renderer = contextVk->getRenderer();
 
     ASSERT(dirtyBits.any());
-
-    mRenderTargetCache.update(context, mState, dirtyBits);
+    ANGLE_TRY(mRenderTargetCache.update(context, mState, dirtyBits));
 
     mRenderPassDesc.reset();
     renderer->releaseResource(*this, &mFramebuffer);
@@ -336,6 +335,8 @@
     mLastRenderNodeSerial = Serial();
 
     contextVk->invalidateCurrentPipeline();
+
+    return gl::NoError();
 }
 
 const vk::RenderPassDesc &FramebufferVk::getRenderPassDesc(const gl::Context *context)
diff --git a/src/libANGLE/renderer/vulkan/FramebufferVk.h b/src/libANGLE/renderer/vulkan/FramebufferVk.h
index 125b79f..32935cf 100644
--- a/src/libANGLE/renderer/vulkan/FramebufferVk.h
+++ b/src/libANGLE/renderer/vulkan/FramebufferVk.h
@@ -80,8 +80,8 @@
 
     bool checkStatus(const gl::Context *context) const override;
 
-    void syncState(const gl::Context *context,
-                   const gl::Framebuffer::DirtyBits &dirtyBits) override;
+    gl::Error syncState(const gl::Context *context,
+                        const gl::Framebuffer::DirtyBits &dirtyBits) override;
 
     gl::Error getSamplePosition(size_t index, GLfloat *xy) const override;