[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

zmo at google.com zmo at google.com
Wed Dec 22 13:49:03 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 1527cf239341accc980308a255db0ae01d8f086d
Author: zmo at google.com <zmo at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Mon Sep 27 21:27:54 2010 +0000

    2010-09-14  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            Textures and renderbuffers should be detached first before deletion if they are attached to framebuffers
            https://bugs.webkit.org/show_bug.cgi?id=43942
    
            Test: fast/canvas/webgl/object-deletion-behaviour.html
    
            * html/canvas/WebGLBuffer.cpp:
            (WebCore::WebGLBuffer::deleteObjectImpl): Delete the object only once.
            * html/canvas/WebGLFramebuffer.cpp: Use RefPtr for attachment WebGLObjects.
            (WebCore::WebGLFramebuffer::WebGLFramebuffer):
            (WebCore::WebGLFramebuffer::removeAttachment): Remove an attachment data ref.
            (WebCore::WebGLFramebuffer::onAttachedObjectChange):
            (WebCore::WebGLFramebuffer::getColorBufferFormat):
            (WebCore::WebGLFramebuffer::deleteObjectImpl):
            (WebCore::WebGLFramebuffer::initializeRenderbuffers):
            * html/canvas/WebGLFramebuffer.h: Declare removeAttachment().
            * html/canvas/WebGLObject.cpp:
            (WebCore::WebGLObject::setObject): Make it protected and can only be called when initializing.
            * html/canvas/WebGLObject.h:
            (WebCore::WebGLObject::onDetached): Fix a bug.
            (WebCore::WebGLObject::isDeleted): Expose the delete flag.
            * html/canvas/WebGLProgram.cpp:
            (WebCore::WebGLProgram::deleteObjectImpl): Detach shaders when deleting a program.
            * html/canvas/WebGLRenderbuffer.cpp:
            (WebCore::WebGLRenderbuffer::deleteObjectImpl): Delete the object only once.
            * html/canvas/WebGLRenderingContext.cpp:
            (WebCore::WebGLRenderingContext::deleteFramebuffer): Bind to internal fbo when deleting the currently-bound fbo.
            (WebCore::WebGLRenderingContext::deleteRenderbuffer): Remove renderbuffer from currently-bound fbo upon deletion.
            (WebCore::WebGLRenderingContext::deleteTexture): Remove texture from currently-bound fbo upon deletion.
            (WebCore::WebGLRenderingContext::useProgram): Fix a condition.
            * html/canvas/WebGLShader.cpp:
            (WebCore::WebGLShader::deleteObjectImpl): Delete the object only once.
            * html/canvas/WebGLTexture.cpp:
            (WebCore::WebGLTexture::deleteObjectImpl): Ditto.
    2010-09-14  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            Textures and renderbuffers should be detached first before deletion if they are attached to framebuffers
            https://bugs.webkit.org/show_bug.cgi?id=43942
    
            * fast/canvas/webgl/object-deletion-behaviour-expected.txt: Added.
            * fast/canvas/webgl/object-deletion-behaviour.html: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@68424 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 312a74b..696505f 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-09-14  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Textures and renderbuffers should be detached first before deletion if they are attached to framebuffers
+        https://bugs.webkit.org/show_bug.cgi?id=43942
+
+        * fast/canvas/webgl/object-deletion-behaviour-expected.txt: Added.
+        * fast/canvas/webgl/object-deletion-behaviour.html: Added.
+
 2010-09-27  Ryosuke Niwa  <rniwa at webkit.org>
 
         Reviewed by Antonio Gomes.
diff --git a/LayoutTests/fast/canvas/webgl/object-deletion-behaviour-expected.txt b/LayoutTests/fast/canvas/webgl/object-deletion-behaviour-expected.txt
new file mode 100644
index 0000000..8a6a2c8
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/object-deletion-behaviour-expected.txt
@@ -0,0 +1,48 @@
+Tests deletion behavior for texture, renderbuffer, shader, and program
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+shader and program deletion
+PASS vertex shader loaded
+PASS fragment shader loaded
+PASS gl.attachShader(program, vertexShader) was expected value: NO_ERROR.
+PASS gl.attachShader(program, fragmentShader) was expected value: NO_ERROR.
+PASS gl.linkProgram(program) was expected value: NO_ERROR.
+PASS gl.getProgramParameter(program, gl.LINK_STATUS) is true
+PASS gl.useProgram(program) was expected value: NO_ERROR.
+PASS gl.deleteShader(vertexShader) was expected value: NO_ERROR.
+PASS gl.isShader(vertexShader) is true
+PASS gl.getShaderParameter(vertexShader, gl.DELETE_STATUS) is true
+PASS gl.detachShader(program, vertexShader) was expected value: NO_ERROR.
+PASS gl.isShader(vertexShader) is false
+PASS gl.deleteShader(fragmentShader) was expected value: NO_ERROR.
+PASS gl.isShader(fragmentShader) is true
+PASS gl.getShaderParameter(fragmentShader, gl.DELETE_STATUS) is true
+PASS gl.deleteProgram(program) was expected value: NO_ERROR.
+PASS gl.isProgram(program) is true
+PASS gl.getProgramParameter(program, gl.DELETE_STATUS) is true
+PASS gl.useProgram(null) was expected value: NO_ERROR.
+PASS gl.isProgram(program) is false
+PASS gl.isShader(fragmentShader) is false
+
+texture deletion
+PASS gl.bindFramebuffer(gl.FRAMEBUFFER, fbo) was expected value: NO_ERROR.
+PASS gl.bindTexture(gl.TEXTURE_2D, tex) was expected value: NO_ERROR.
+PASS gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0) was expected value: NO_ERROR.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) is tex
+PASS gl.deleteTexture(tex) was expected value: NO_ERROR.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) is null
+PASS gl.isTexture(tex) is false
+
+renderbuffer deletion
+PASS gl.bindRenderbuffer(gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo) was expected value: NO_ERROR.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) is rbo
+PASS gl.deleteRenderbuffer(rbo) was expected value: NO_ERROR.
+PASS gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME) is null
+PASS gl.isRenderbuffer(rbo) is false
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/object-deletion-behaviour.html b/LayoutTests/fast/canvas/webgl/object-deletion-behaviour.html
new file mode 100644
index 0000000..72f872f
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/object-deletion-behaviour.html
@@ -0,0 +1,82 @@
+<html>
+<head>
+<link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/webgl-test.js"></script>
+<script src="resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+
+<script>
+description("Tests deletion behavior for texture, renderbuffer, shader, and program");
+
+var wtu = WebGLTestUtils;
+var gl = wtu.create3DContext();
+var shouldGenerateGLError = wtu.shouldGenerateGLError;
+
+debug("");
+debug("shader and program deletion");
+
+var vertexShader = wtu.loadStandardVertexShader(gl);
+assertMsg(vertexShader, "vertex shader loaded");
+var fragmentShader = wtu.loadStandardFragmentShader(gl);
+assertMsg(fragmentShader, "fragment shader loaded");
+
+var program = gl.createProgram();
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, vertexShader)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.attachShader(program, fragmentShader)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.linkProgram(program)");
+shouldBeTrue("gl.getProgramParameter(program, gl.LINK_STATUS)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.useProgram(program)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteShader(vertexShader)");
+shouldBeTrue("gl.isShader(vertexShader)");
+shouldBeTrue("gl.getShaderParameter(vertexShader, gl.DELETE_STATUS)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.detachShader(program, vertexShader)");
+shouldBeFalse("gl.isShader(vertexShader)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteShader(fragmentShader)");
+shouldBeTrue("gl.isShader(fragmentShader)");
+shouldBeTrue("gl.getShaderParameter(fragmentShader, gl.DELETE_STATUS)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteProgram(program)");
+shouldBeTrue("gl.isProgram(program)");
+shouldBeTrue("gl.getProgramParameter(program, gl.DELETE_STATUS)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.useProgram(null)");
+shouldBeFalse("gl.isProgram(program)");
+shouldBeFalse("gl.isShader(fragmentShader)");
+
+debug("");
+debug("texture deletion");
+
+var fbo = gl.createFramebuffer();
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindFramebuffer(gl.FRAMEBUFFER, fbo)");
+
+var tex = gl.createTexture();
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindTexture(gl.TEXTURE_2D, tex)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0)");
+shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "tex");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteTexture(tex)");
+// Deleting a texture bound to the currently-bound fbo is the same as
+// detaching the textue from fbo first, then delete the texture.
+shouldBeNull("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
+shouldBeFalse("gl.isTexture(tex)");
+
+debug("");
+debug("renderbuffer deletion");
+
+var rbo = gl.createRenderbuffer();
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.bindRenderbuffer(gl.RENDERBUFFER, rbo)");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo)");
+shouldBe("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)", "rbo");
+shouldGenerateGLError(gl, gl.NO_ERROR, "gl.deleteRenderbuffer(rbo)");
+// Deleting a renderbuffer bound to the currently-bound fbo is the same as
+// detaching the renderbuffer from fbo first, then delete the renderbuffer.
+shouldBeNull("gl.getFramebufferAttachmentParameter(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME)");
+shouldBeFalse("gl.isRenderbuffer(rbo)");
+
+successfullyParsed = true;
+</script>
+
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 05c4bc9..2aca7f8 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,41 @@
+2010-09-14  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Textures and renderbuffers should be detached first before deletion if they are attached to framebuffers
+        https://bugs.webkit.org/show_bug.cgi?id=43942
+
+        Test: fast/canvas/webgl/object-deletion-behaviour.html
+
+        * html/canvas/WebGLBuffer.cpp:
+        (WebCore::WebGLBuffer::deleteObjectImpl): Delete the object only once.
+        * html/canvas/WebGLFramebuffer.cpp: Use RefPtr for attachment WebGLObjects.
+        (WebCore::WebGLFramebuffer::WebGLFramebuffer):
+        (WebCore::WebGLFramebuffer::removeAttachment): Remove an attachment data ref.
+        (WebCore::WebGLFramebuffer::onAttachedObjectChange):
+        (WebCore::WebGLFramebuffer::getColorBufferFormat):
+        (WebCore::WebGLFramebuffer::deleteObjectImpl):
+        (WebCore::WebGLFramebuffer::initializeRenderbuffers):
+        * html/canvas/WebGLFramebuffer.h: Declare removeAttachment().
+        * html/canvas/WebGLObject.cpp:
+        (WebCore::WebGLObject::setObject): Make it protected and can only be called when initializing.
+        * html/canvas/WebGLObject.h:
+        (WebCore::WebGLObject::onDetached): Fix a bug.
+        (WebCore::WebGLObject::isDeleted): Expose the delete flag.
+        * html/canvas/WebGLProgram.cpp:
+        (WebCore::WebGLProgram::deleteObjectImpl): Detach shaders when deleting a program.
+        * html/canvas/WebGLRenderbuffer.cpp:
+        (WebCore::WebGLRenderbuffer::deleteObjectImpl): Delete the object only once.
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::deleteFramebuffer): Bind to internal fbo when deleting the currently-bound fbo.
+        (WebCore::WebGLRenderingContext::deleteRenderbuffer): Remove renderbuffer from currently-bound fbo upon deletion.
+        (WebCore::WebGLRenderingContext::deleteTexture): Remove texture from currently-bound fbo upon deletion.
+        (WebCore::WebGLRenderingContext::useProgram): Fix a condition.
+        * html/canvas/WebGLShader.cpp:
+        (WebCore::WebGLShader::deleteObjectImpl): Delete the object only once.
+        * html/canvas/WebGLTexture.cpp:
+        (WebCore::WebGLTexture::deleteObjectImpl): Ditto.
+
 2010-09-27  Ryosuke Niwa  <rniwa at webkit.org>
 
         Reviewed by Antonio Gomes.
diff --git a/WebCore/html/canvas/WebGLBuffer.cpp b/WebCore/html/canvas/WebGLBuffer.cpp
index d43868d..99d9cad 100644
--- a/WebCore/html/canvas/WebGLBuffer.cpp
+++ b/WebCore/html/canvas/WebGLBuffer.cpp
@@ -52,7 +52,8 @@ WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
 
 void WebGLBuffer::deleteObjectImpl(Platform3DObject object)
 {
-    context()->graphicsContext3D()->deleteBuffer(object);
+    if (!isDeleted())
+        context()->graphicsContext3D()->deleteBuffer(object);
 }
 
 bool WebGLBuffer::associateBufferDataImpl(ArrayBuffer* array, unsigned byteOffset, unsigned byteLength)
diff --git a/WebCore/html/canvas/WebGLFramebuffer.cpp b/WebCore/html/canvas/WebGLFramebuffer.cpp
index 6291705..a709341 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -40,10 +40,6 @@ PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx
 
 WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
     : WebGLObject(ctx)
-    , m_colorAttachment(0)
-    , m_depthAttachment(0)
-    , m_stencilAttachment(0)
-    , m_depthStencilAttachment(0)
 {
     setObject(context()->graphicsContext3D()->createFramebuffer());
 }
@@ -73,6 +69,23 @@ void WebGLFramebuffer::setAttachment(unsigned long attachment, WebGLObject* atta
     initializeRenderbuffers();
 }
 
+void WebGLFramebuffer::removeAttachment(WebGLObject* attachment)
+{
+    if (!object())
+        return;
+    if (attachment == m_colorAttachment.get())
+        m_colorAttachment = 0;
+    else if (attachment == m_depthAttachment.get())
+        m_depthAttachment = 0;
+    else if (attachment == m_stencilAttachment.get())
+        m_stencilAttachment = 0;
+    else if (attachment == m_depthStencilAttachment.get())
+        m_depthStencilAttachment = 0;
+    else
+        return;
+    initializeRenderbuffers();
+}
+
 void WebGLFramebuffer::onBind()
 {
     initializeRenderbuffers();
@@ -83,8 +96,8 @@ void WebGLFramebuffer::onAttachedObjectChange(WebGLObject* object)
     // Currently object == 0 is not considered, but this might change if the
     // lifespan of WebGLObject changes.
     if (object
-        && (object == m_colorAttachment || object == m_depthAttachment
-            || object == m_stencilAttachment || object == m_depthStencilAttachment))
+        && (object == m_colorAttachment.get() || object == m_depthAttachment.get()
+            || object == m_stencilAttachment.get() || object == m_depthStencilAttachment.get()))
         initializeRenderbuffers();
 }
 
@@ -92,7 +105,7 @@ unsigned long WebGLFramebuffer::getColorBufferFormat()
 {
     if (object() && m_colorAttachment && m_colorAttachment->object()) {
         if (m_colorAttachment->isRenderbuffer()) {
-            unsigned long format = (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment))->getInternalFormat();
+            unsigned long format = (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getInternalFormat();
             switch (format) {
             case GraphicsContext3D::RGBA4:
             case GraphicsContext3D::RGB5_A1:
@@ -101,14 +114,19 @@ unsigned long WebGLFramebuffer::getColorBufferFormat()
                 return GraphicsContext3D::RGB;
             }
         } else if (m_colorAttachment->isTexture())
-            return (reinterpret_cast<WebGLTexture*>(m_colorAttachment))->getInternalFormat(0);
+            return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getInternalFormat(0);
     }
     return 0;
 }
 
 void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
 {
-    context()->graphicsContext3D()->deleteFramebuffer(object);
+    if (!isDeleted())
+        context()->graphicsContext3D()->deleteFramebuffer(object);
+    m_colorAttachment = 0;
+    m_depthAttachment = 0;
+    m_stencilAttachment = 0;
+    m_depthStencilAttachment = 0;
 }
 
 bool WebGLFramebuffer::isUninitialized(WebGLObject* attachedObject)
@@ -131,19 +149,19 @@ void WebGLFramebuffer::initializeRenderbuffers()
         return;
     bool initColor = false, initDepth = false, initStencil = false;
     unsigned long mask = 0;
-    if (isUninitialized(m_colorAttachment)) {
+    if (isUninitialized(m_colorAttachment.get())) {
         initColor = true;
         mask |= GraphicsContext3D::COLOR_BUFFER_BIT;
     }
-    if (isUninitialized(m_depthAttachment)) {
+    if (isUninitialized(m_depthAttachment.get())) {
         initDepth = true;
         mask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
     }
-    if (isUninitialized(m_stencilAttachment)) {
+    if (isUninitialized(m_stencilAttachment.get())) {
         initStencil = true;
         mask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
     }
-    if (isUninitialized(m_depthStencilAttachment)) {
+    if (isUninitialized(m_depthStencilAttachment.get())) {
         initDepth = true;
         initStencil = true;
         mask |= (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT);
@@ -209,14 +227,14 @@ void WebGLFramebuffer::initializeRenderbuffers()
         g3d->disable(GraphicsContext3D::DITHER);
 
     if (initColor)
-        setInitialized(m_colorAttachment);
+        setInitialized(m_colorAttachment.get());
     if (initDepth && initStencil && m_depthStencilAttachment)
-        setInitialized(m_depthStencilAttachment);
+        setInitialized(m_depthStencilAttachment.get());
     else {
         if (initDepth)
-            setInitialized(m_depthAttachment);
+            setInitialized(m_depthAttachment.get());
         if (initStencil)
-            setInitialized(m_stencilAttachment);
+            setInitialized(m_stencilAttachment.get());
     }
 }
 
diff --git a/WebCore/html/canvas/WebGLFramebuffer.h b/WebCore/html/canvas/WebGLFramebuffer.h
index ac945dd..1892694 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/WebCore/html/canvas/WebGLFramebuffer.h
@@ -44,6 +44,8 @@ public:
     bool isDepthStencilAttached() const { return (m_depthStencilAttachment && m_depthStencilAttachment->object()); }
 
     void setAttachment(unsigned long, WebGLObject*);
+    // If an object is attached to the framebuffer, remove it.
+    void removeAttachment(WebGLObject*);
 
     // This function is called right after a framebuffer is bound.
     // Because renderbuffers and textures attached to the framebuffer might
@@ -71,12 +73,10 @@ private:
     void setInitialized(WebGLObject*);
     void initializeRenderbuffers();
 
-    // These objects are kept alive by the global table in
-    // WebGLRenderingContext.
-    WebGLObject* m_colorAttachment;
-    WebGLObject* m_depthAttachment;
-    WebGLObject* m_stencilAttachment;
-    WebGLObject* m_depthStencilAttachment;
+    RefPtr<WebGLObject> m_colorAttachment;
+    RefPtr<WebGLObject> m_depthAttachment;
+    RefPtr<WebGLObject> m_stencilAttachment;
+    RefPtr<WebGLObject> m_depthStencilAttachment;
 };
 
 } // namespace WebCore
diff --git a/WebCore/html/canvas/WebGLObject.cpp b/WebCore/html/canvas/WebGLObject.cpp
index 5fd5534..8aa4663 100644
--- a/WebCore/html/canvas/WebGLObject.cpp
+++ b/WebCore/html/canvas/WebGLObject.cpp
@@ -49,10 +49,8 @@ WebGLObject::~WebGLObject()
 
 void WebGLObject::setObject(Platform3DObject object)
 {
-    if (object == m_object)
-        return;
-        
-    deleteObject();
+    // object==0 && m_deleted==false indicating an uninitialized state;
+    ASSERT(!m_object && !m_deleted);
     m_object = object;
 }
 
diff --git a/WebCore/html/canvas/WebGLObject.h b/WebCore/html/canvas/WebGLObject.h
index 18d4cf9..82b8079 100644
--- a/WebCore/html/canvas/WebGLObject.h
+++ b/WebCore/html/canvas/WebGLObject.h
@@ -40,7 +40,6 @@ public:
     virtual ~WebGLObject();
 
     Platform3DObject object() const { return m_object; }
-    void setObject(Platform3DObject);
     void deleteObject();
 
     void detachContext()
@@ -64,13 +63,22 @@ public:
         if (m_attachmentCount)
             --m_attachmentCount;
         if (!m_attachmentCount && m_deleted)
-            m_object = 0;
+            deleteObject();
     }
     unsigned getAttachmentCount() { return m_attachmentCount; }
 
 protected:
     WebGLObject(WebGLRenderingContext*);
+
+    // setObject should be only called once right after creating a WebGLObject.
+    void setObject(Platform3DObject);
+
+    // deleteObjectImpl() may be called multiple times for the same object;
+    // isDeleted() needs to be tested in implementations when deciding whether
+    // to delete the OpenGL resource.
     virtual void deleteObjectImpl(Platform3DObject) = 0;
+    bool isDeleted() { return m_deleted; }
+    void setDeteled() { m_deleted = true; }
 
 private:
     Platform3DObject m_object;
diff --git a/WebCore/html/canvas/WebGLProgram.cpp b/WebCore/html/canvas/WebGLProgram.cpp
index 8cf3c42..0853b67 100644
--- a/WebCore/html/canvas/WebGLProgram.cpp
+++ b/WebCore/html/canvas/WebGLProgram.cpp
@@ -47,12 +47,17 @@ WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
 
 void WebGLProgram::deleteObjectImpl(Platform3DObject obj)
 {
-    context()->graphicsContext3D()->deleteProgram(obj);
-    if (!object()) {
-        if (m_vertexShader)
+    if (!isDeleted())
+        context()->graphicsContext3D()->deleteProgram(obj);
+    if (!getAttachmentCount()) {
+        if (m_vertexShader) {
             m_vertexShader->onDetached();
-        if (m_fragmentShader)
+            m_vertexShader = 0;
+        }
+        if (m_fragmentShader) {
             m_fragmentShader->onDetached();
+            m_fragmentShader = 0;
+        }
     }
 }
 
diff --git a/WebCore/html/canvas/WebGLRenderbuffer.cpp b/WebCore/html/canvas/WebGLRenderbuffer.cpp
index 7bc2eec..4772873 100644
--- a/WebCore/html/canvas/WebGLRenderbuffer.cpp
+++ b/WebCore/html/canvas/WebGLRenderbuffer.cpp
@@ -48,7 +48,8 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
 
 void WebGLRenderbuffer::deleteObjectImpl(Platform3DObject object)
 {
-    context()->graphicsContext3D()->deleteRenderbuffer(object);
+    if (!isDeleted())
+        context()->graphicsContext3D()->deleteRenderbuffer(object);
 }
 
 }
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index ff64c95..80800b0 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -635,7 +635,11 @@ void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
 {
     if (!framebuffer)
         return;
-    
+    if (framebuffer == m_framebufferBinding) {
+        m_framebufferBinding = 0;
+        // Have to call bindFramebuffer here to bind back to internal fbo.
+        m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
+    }
     framebuffer->deleteObject();
 }
 
@@ -656,10 +660,11 @@ void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
 {
     if (!renderbuffer)
         return;
-    
+    if (renderbuffer == m_renderbufferBinding)
+        m_renderbufferBinding = 0;
     renderbuffer->deleteObject();
     if (m_framebufferBinding)
-        m_framebufferBinding->onAttachedObjectChange(renderbuffer);
+        m_framebufferBinding->removeAttachment(renderbuffer);
 }
 
 void WebGLRenderingContext::deleteShader(WebGLShader* shader)
@@ -677,7 +682,7 @@ void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
     
     texture->deleteObject();
     if (m_framebufferBinding)
-        m_framebufferBinding->onAttachedObjectChange(texture);
+        m_framebufferBinding->removeAttachment(texture);
 }
 
 void WebGLRenderingContext::depthFunc(unsigned long func)
@@ -2716,7 +2721,7 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
             m_currentProgram->onDetached();
         m_currentProgram = program;
         m_context->useProgram(objectOrZero(program));
-        if (program)
+        if (program && program->object())
             program->onAttached();
     }
     cleanupAfterGraphicsCall(false);
diff --git a/WebCore/html/canvas/WebGLShader.cpp b/WebCore/html/canvas/WebGLShader.cpp
index 4f8bf68..1ccaad8 100644
--- a/WebCore/html/canvas/WebGLShader.cpp
+++ b/WebCore/html/canvas/WebGLShader.cpp
@@ -47,7 +47,8 @@ WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GraphicsContext3D::WebGLEnu
 
 void WebGLShader::deleteObjectImpl(Platform3DObject object)
 {
-    context()->graphicsContext3D()->deleteShader(object);
+    if (!isDeleted())
+        context()->graphicsContext3D()->deleteShader(object);
 }
 
 }
diff --git a/WebCore/html/canvas/WebGLTexture.cpp b/WebCore/html/canvas/WebGLTexture.cpp
index 7fc84ad..c2b1c10 100644
--- a/WebCore/html/canvas/WebGLTexture.cpp
+++ b/WebCore/html/canvas/WebGLTexture.cpp
@@ -29,6 +29,7 @@
 
 #include "WebGLTexture.h"
 
+#include "WebGLFramebuffer.h"
 #include "WebGLRenderingContext.h"
 
 namespace WebCore {
@@ -201,7 +202,8 @@ bool WebGLTexture::needToUseBlackTexture() const
 
 void WebGLTexture::deleteObjectImpl(Platform3DObject object)
 {
-    context()->graphicsContext3D()->deleteTexture(object);
+    if (!isDeleted())
+        context()->graphicsContext3D()->deleteTexture(object);
 }
 
 int WebGLTexture::mapTargetToIndex(unsigned long target)

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list