Bug 981240 - Finalize null attachments back to zero. - r=kamidphish
authorJeff Gilbert <jgilbert@mozilla.com>
Tue, 11 Mar 2014 16:10:59 -0700
changeset 173097 a6fc178ac9a1f56149ad43c961db598770efcc35
parent 173096 716ba77a9d0a8d72fe8c4e3273bdcf0d5b57fe47
child 173098 a1a9976d954e0b088a86c302773dfe0e528b0932
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerskamidphish
bugs981240
milestone30.0a1
Bug 981240 - Finalize null attachments back to zero. - r=kamidphish
content/canvas/src/WebGLFramebuffer.cpp
content/canvas/src/WebGLFramebuffer.h
--- a/content/canvas/src/WebGLFramebuffer.cpp
+++ b/content/canvas/src/WebGLFramebuffer.cpp
@@ -91,16 +91,27 @@ WebGLFramebuffer::Attachment::IsReadable
 
 void
 WebGLFramebuffer::Attachment::SetTexImage(WebGLTexture* tex, GLenum target, GLint level)
 {
     mTexturePtr = tex;
     mRenderbufferPtr = nullptr;
     mTexImageTarget = target;
     mTexImageLevel = level;
+
+    mNeedsFinalize = true;
+}
+
+void
+WebGLFramebuffer::Attachment::SetRenderbuffer(WebGLRenderbuffer* rb)
+{
+    mTexturePtr = nullptr;
+    mRenderbufferPtr = rb;
+
+    mNeedsFinalize = true;
 }
 
 bool
 WebGLFramebuffer::Attachment::HasUninitializedImageData() const
 {
     if (!HasImage())
         return false;
 
@@ -310,22 +321,41 @@ WebGLFramebuffer::Attachment::IsComplete
         return false;
     }
 
     MOZ_ASSERT(false, "Should not get here.");
     return false;
 }
 
 void
-WebGLFramebuffer::Attachment::FinalizeAttachment(GLenum attachmentLoc) const
+WebGLFramebuffer::Attachment::FinalizeAttachment(GLContext* gl, GLenum attachmentLoc) const
 {
+    if (!mNeedsFinalize)
+        return;
+
+    mNeedsFinalize = false;
+
+    if (!HasImage()) {
+        if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
+            gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
+                                         LOCAL_GL_RENDERBUFFER, 0);
+            gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
+                                         LOCAL_GL_RENDERBUFFER, 0);
+        } else {
+            gl->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
+                                         LOCAL_GL_RENDERBUFFER, 0);
+        }
+
+        return;
+    }
     MOZ_ASSERT(HasImage());
 
     if (Texture()) {
-        GLContext* gl = Texture()->Context()->gl;
+        MOZ_ASSERT(gl == Texture()->Context()->gl);
+
         if (attachmentLoc == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
             gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT,
                                       TexImageTarget(), Texture()->GLName(), TexImageLevel());
             gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT,
                                       TexImageTarget(), Texture()->GLName(), TexImageLevel());
         } else {
             gl->fFramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, attachmentLoc,
                                       TexImageTarget(), Texture()->GLName(), TexImageLevel());
@@ -827,32 +857,28 @@ FinalizeDrawAndReadBuffers(GLContext* aG
     GLenum colorBufferSource = aColorBufferDefined ? LOCAL_GL_COLOR_ATTACHMENT0 : LOCAL_GL_NONE;
     aGL->fDrawBuffer(colorBufferSource);
     aGL->fReadBuffer(colorBufferSource);
 }
 
 void
 WebGLFramebuffer::FinalizeAttachments() const
 {
+    GLContext* gl = mContext->gl;
+
     size_t count = ColorAttachmentCount();
     for (size_t i = 0; i < count; i++) {
-        if (ColorAttachment(i).IsDefined())
-            ColorAttachment(i).FinalizeAttachment(LOCAL_GL_COLOR_ATTACHMENT0 + i);
+        ColorAttachment(i).FinalizeAttachment(gl, LOCAL_GL_COLOR_ATTACHMENT0 + i);
     }
 
-    if (DepthAttachment().IsDefined())
-        DepthAttachment().FinalizeAttachment(LOCAL_GL_DEPTH_ATTACHMENT);
+    DepthAttachment().FinalizeAttachment(gl, LOCAL_GL_DEPTH_ATTACHMENT);
+    StencilAttachment().FinalizeAttachment(gl, LOCAL_GL_STENCIL_ATTACHMENT);
+    DepthStencilAttachment().FinalizeAttachment(gl, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
 
-    if (StencilAttachment().IsDefined())
-        StencilAttachment().FinalizeAttachment(LOCAL_GL_STENCIL_ATTACHMENT);
-
-    if (DepthStencilAttachment().IsDefined())
-        DepthStencilAttachment().FinalizeAttachment(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT);
-
-    FinalizeDrawAndReadBuffers(mContext->gl, ColorAttachment(0).IsDefined());
+    FinalizeDrawAndReadBuffers(gl, ColorAttachment(0).IsDefined());
 }
 
 inline void
 ImplCycleCollectionUnlink(mozilla::WebGLFramebuffer::Attachment& aField)
 {
     aField.mTexturePtr = nullptr;
     aField.mRenderbufferPtr = nullptr;
 }
--- a/content/canvas/src/WebGLFramebuffer.h
+++ b/content/canvas/src/WebGLFramebuffer.h
@@ -36,35 +36,35 @@ public:
     struct Attachment
     {
         // deleting a texture or renderbuffer immediately detaches it
         WebGLRefPtr<WebGLTexture> mTexturePtr;
         WebGLRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
         GLenum mAttachmentPoint;
         GLenum mTexImageTarget;
         GLint mTexImageLevel;
+        mutable bool mNeedsFinalize;
 
         Attachment(GLenum aAttachmentPoint = LOCAL_GL_COLOR_ATTACHMENT0)
             : mAttachmentPoint(aAttachmentPoint)
+            , mNeedsFinalize(false)
         {}
 
         bool IsDefined() const {
             return Texture() || Renderbuffer();
         }
 
         bool IsDeleteRequested() const;
 
         bool HasAlpha() const;
         bool IsReadableFloat() const;
 
         void SetTexImage(WebGLTexture* tex, GLenum target, GLint level);
-        void SetRenderbuffer(WebGLRenderbuffer* rb) {
-            mTexturePtr = nullptr;
-            mRenderbufferPtr = rb;
-        }
+        void SetRenderbuffer(WebGLRenderbuffer* rb);
+
         const WebGLTexture* Texture() const {
             return mTexturePtr;
         }
         WebGLTexture* Texture() {
             return mTexturePtr;
         }
         const WebGLRenderbuffer* Renderbuffer() const {
             return mRenderbufferPtr;
@@ -87,17 +87,17 @@ public:
             mRenderbufferPtr = nullptr;
         }
 
         const WebGLRectangleObject& RectangleObject() const;
 
         bool HasImage() const;
         bool IsComplete() const;
 
-        void FinalizeAttachment(GLenum attachmentLoc) const;
+        void FinalizeAttachment(gl::GLContext* gl, GLenum attachmentLoc) const;
     };
 
     void Delete();
 
     bool HasEverBeenBound() { return mHasEverBeenBound; }
     void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
     GLuint GLName() { return mGLName; }