Bug 704839 - [7/9] - Refactor mutual ownership of WebGL objects - r=jgilbert
authorBenoit Jacob <bjacob@mozilla.com>
Sun, 04 Dec 2011 14:15:43 -0500
changeset 81408 1a4f061c4f2d5a174fec2f7b87179561cc6ca4ff
parent 81407 c1de92ddbedfcc6f18e0f22d27fb003d844af535
child 81409 2facd7e6fd7c78644c9d5e25efc0c190c97dfb35
push id3801
push userbjacob@mozilla.com
push dateSun, 04 Dec 2011 19:18:01 +0000
treeherdermozilla-inbound@d75664a67e3b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjgilbert
bugs704839
milestone11.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 704839 - [7/9] - Refactor mutual ownership of WebGL objects - r=jgilbert This patch fixes framebuffer attachment deletion.
content/canvas/src/WebGLContext.h
content/canvas/src/WebGLContextGL.cpp
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -1944,25 +1944,31 @@ class WebGLFramebufferAttachment
     WebGLint mTextureLevel;
     WebGLenum mTextureCubeMapFace;
 
 public:
     WebGLFramebufferAttachment(WebGLenum aAttachmentPoint)
         : mAttachmentPoint(aAttachmentPoint)
     {}
 
-    bool IsNull() const {
-        return !mTexturePtr && !mRenderbufferPtr;
+    bool IsDefined() const {
+        return Texture() || Renderbuffer();
+    }
+
+    bool IsDeleteRequested() const {
+        return Texture() ? Texture()->IsDeleteRequested()
+             : Renderbuffer() ? Renderbuffer()->IsDeleteRequested()
+             : false;
     }
 
     bool HasAlpha() const {
         WebGLenum format = 0;
-        if (mTexturePtr)
+        if (Texture() && Texture()->HasImageInfoAt(0,0))
             format = mTexturePtr->ImageInfoAt(0,0).mFormat;
-        if (mRenderbufferPtr)
+        else if (Renderbuffer())
             format = mRenderbufferPtr->InternalFormat();
         return format == LOCAL_GL_RGBA ||
                format == LOCAL_GL_LUMINANCE_ALPHA ||
                format == LOCAL_GL_ALPHA ||
                format == LOCAL_GL_RGBA4 ||
                format == LOCAL_GL_RGB5_A1;
     }
 
@@ -2019,16 +2025,21 @@ public:
         }
 
         return false; // no attachment at all, so no incompatibility
     }
 
     bool HasUninitializedRenderbuffer() const {
         return mRenderbufferPtr && !mRenderbufferPtr->Initialized();
     }
+
+    void Reset() {
+        mTexturePtr = nsnull;
+        mRenderbufferPtr = nsnull;
+    }
 };
 
 class WebGLFramebuffer
     : public nsIWebGLFramebuffer
     , public WebGLRefCountedObject<WebGLFramebuffer>
     , public WebGLContextBoundObject
 {
 public:
@@ -2195,33 +2206,33 @@ public:
         if (mColorAttachment.IsIncompatibleWithAttachmentPoint() ||
             mDepthAttachment.IsIncompatibleWithAttachmentPoint() ||
             mStencilAttachment.IsIncompatibleWithAttachmentPoint() ||
             mDepthStencilAttachment.IsIncompatibleWithAttachmentPoint())
         {
             // some attachment is incompatible with its attachment point
             return true;
         }
-        
-        if (int(mDepthAttachment.IsNull()) +
-            int(mStencilAttachment.IsNull()) +
-            int(mDepthStencilAttachment.IsNull()) <= 1)
+
+        if (int(mDepthAttachment.IsDefined()) +
+            int(mStencilAttachment.IsDefined()) +
+            int(mDepthStencilAttachment.IsDefined()) >= 2)
         {
             // has at least two among Depth, Stencil, DepthStencil
             return true;
         }
-        
-        if (!mDepthAttachment.IsNull() && !mDepthAttachment.HasSameDimensionsAs(mColorAttachment))
+
+        if (mDepthAttachment.IsDefined() && !mDepthAttachment.HasSameDimensionsAs(mColorAttachment))
             return true;
-        if (!mStencilAttachment.IsNull() && !mStencilAttachment.HasSameDimensionsAs(mColorAttachment))
+        if (mStencilAttachment.IsDefined() && !mStencilAttachment.HasSameDimensionsAs(mColorAttachment))
             return true;
-        if (!mDepthStencilAttachment.IsNull() && !mDepthStencilAttachment.HasSameDimensionsAs(mColorAttachment))
+        if (mDepthStencilAttachment.IsDefined() && !mDepthStencilAttachment.HasSameDimensionsAs(mColorAttachment))
             return true;
-        
-        else return false;
+
+        return false;
     }
 
     const WebGLFramebufferAttachment& ColorAttachment() const {
         return mColorAttachment;
     }
 
     const WebGLFramebufferAttachment& DepthAttachment() const {
         return mDepthAttachment;
@@ -2242,16 +2253,38 @@ public:
             return mDepthAttachment;
         if (attachment == LOCAL_GL_STENCIL_ATTACHMENT)
             return mStencilAttachment;
 
         NS_ASSERTION(attachment == LOCAL_GL_COLOR_ATTACHMENT0, "bad attachment!");
         return mColorAttachment;
     }
 
+    void DetachTexture(const WebGLTexture *tex) {
+        if (mColorAttachment.Texture() == tex)
+            FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_TEXTURE_2D, nsnull, 0);
+        if (mDepthAttachment.Texture() == tex)
+            FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nsnull, 0);
+        if (mStencilAttachment.Texture() == tex)
+            FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nsnull, 0);
+        if (mDepthStencilAttachment.Texture() == tex)
+            FramebufferTexture2D(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_TEXTURE_2D, nsnull, 0);
+    }
+
+    void DetachRenderbuffer(const WebGLRenderbuffer *rb) {
+        if (mColorAttachment.Renderbuffer() == rb)
+            FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0, LOCAL_GL_RENDERBUFFER, nsnull);
+        if (mDepthAttachment.Renderbuffer() == rb)
+            FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nsnull);
+        if (mStencilAttachment.Renderbuffer() == rb)
+            FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nsnull);
+        if (mDepthStencilAttachment.Renderbuffer() == rb)
+            FramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_DEPTH_STENCIL_ATTACHMENT, LOCAL_GL_RENDERBUFFER, nsnull);
+    }
+
     NS_DECL_ISUPPORTS
     NS_DECL_NSIWEBGLFRAMEBUFFER
 
 protected:
 
     // protected because WebGLContext should only call InitializeRenderbuffers
     void InitializeRenderbuffers()
     {
--- a/content/canvas/src/WebGLContextGL.cpp
+++ b/content/canvas/src/WebGLContextGL.cpp
@@ -145,17 +145,17 @@ WebGLProgram::GetUniformLocationObject(G
 
 /* void GlActiveTexture (in GLenum texture); */
 NS_IMETHODIMP
 WebGLContext::ActiveTexture(WebGLenum texture)
 {
     if (mContextLost)
         return NS_OK;
 
-    if (texture < LOCAL_GL_TEXTURE0 || texture >= LOCAL_GL_TEXTURE0+mBound2DTextures.Length())
+    if (texture < LOCAL_GL_TEXTURE0 || texture >= LOCAL_GL_TEXTURE0 + mBound2DTextures.Length())
         return ErrorInvalidEnum("ActiveTexture: texture unit %d out of range (0..%d)",
                                 texture, mBound2DTextures.Length()-1);
 
     MakeContextCurrent();
     mActiveTexture = texture - LOCAL_GL_TEXTURE0;
     gl->fActiveTexture(texture);
     return NS_OK;
 }
@@ -1190,16 +1190,19 @@ WebGLContext::DeleteRenderbuffer(nsIWebG
     WebGLuint rbufname;
     bool isNull, isDeleted;
     if (!GetConcreteObjectAndGLName("deleteRenderbuffer", rbobj, &rbuf, &rbufname, &isNull, &isDeleted))
         return NS_OK;
 
     if (isNull || isDeleted)
         return NS_OK;
 
+    if (mBoundFramebuffer)
+        mBoundFramebuffer->DetachRenderbuffer(rbuf);
+
     if (mBoundRenderbuffer == rbuf)
         BindRenderbuffer(LOCAL_GL_RENDERBUFFER, nsnull);
 
     rbuf->RequestDelete();
     mMapRenderbuffers.Remove(rbufname);
 
     return NS_OK;
 }
@@ -1214,16 +1217,19 @@ WebGLContext::DeleteTexture(nsIWebGLText
     WebGLuint texname;
     bool isNull, isDeleted;
     if (!GetConcreteObjectAndGLName("deleteTexture", tobj, &tex, &texname, &isNull, &isDeleted))
         return NS_OK;
 
     if (isNull || isDeleted)
         return NS_OK;
 
+    if (mBoundFramebuffer)
+        mBoundFramebuffer->DetachTexture(tex);
+
     for (int i = 0; i < mGLMaxTextureUnits; i++) {
         if ((tex->Target() == LOCAL_GL_TEXTURE_2D && mBound2DTextures[i] == tex) ||
             (tex->Target() == LOCAL_GL_TEXTURE_CUBE_MAP && mBoundCubeMapTextures[i] == tex))
         {
             ActiveTexture(LOCAL_GL_TEXTURE0 + i);
             BindTexture(tex->Target(), nsnull);
         }
     }