[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 15:24:55 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 1ba1ba7bd030290d0cb824764fc803929bed64c0
Author: zmo at google.com <zmo at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Nov 3 00:23:54 2010 +0000

    2010-10-28  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            Perform framebuffer attachment checking upon draw call rather than attachment
            https://bugs.webkit.org/show_bug.cgi?id=46318
    
            * html/canvas/WebGLFramebuffer.cpp:
            (WebCore::getInternalFormat): Helper function to get an attachment's internal format.
            (WebCore::isUninitialized): Helper function to decide if an attachment is initialized or not.
            (WebCore::setInitialized): Helper funtion to set an attachment as being initialized.
            (WebCore::WebGLFramebuffer::setAttachment): No longer perform buffer initialization at this point.
            (WebCore::WebGLFramebuffer::removeAttachment): Ditto.
            (WebCore::WebGLFramebuffer::getColorBufferFormat): Make it const.
            (WebCore::WebGLFramebuffer::isIncomplete): Attachments conflict check.
            (WebCore::WebGLFramebuffer::onAccess): Check atatchment conflicts and buffer initialization if necessary.
            (WebCore::WebGLFramebuffer::initializeRenderbuffers): Return a boolean whether the framebuffer is complete or not.
            * html/canvas/WebGLFramebuffer.h: Add new function declaration and remove some outdated functions.
            (WebCore::WebGLFramebuffer::isColorAttached):
            (WebCore::WebGLFramebuffer::isDepthAttached): Make this private.
            (WebCore::WebGLFramebuffer::isStencilAttached): Ditto.
            (WebCore::WebGLFramebuffer::isDepthStencilAttached): Ditto.
            * html/canvas/WebGLRenderbuffer.h:
            (WebCore::WebGLRenderbuffer::setInternalFormat): Also set the renderbuffer as uninitialized.
            * html/canvas/WebGLRenderingContext.cpp:
            (WebCore::WebGLRenderingContext::bindFramebuffer): No longer perform framebuffer initialization at this point.
            (WebCore::WebGLRenderingContext::checkFramebufferStatus): Check WebGL specific attachment conflicts.
            (WebCore::WebGLRenderingContext::clear): Call WebGLFramebuffer::onAccess.
            (WebCore::WebGLRenderingContext::copyTexImage2D): Ditto.
            (WebCore::WebGLRenderingContext::copyTexSubImage2D): Ditto.
            (WebCore::WebGLRenderingContext::drawArrays): Ditto.
            (WebCore::WebGLRenderingContext::drawElements): Ditto.
            (WebCore::WebGLRenderingContext::framebufferRenderbuffer): No longer perform framebuffer initialization at this point.
            (WebCore::WebGLRenderingContext::readPixels): Call WebGLFramebuffer::onAccess.
            (WebCore::WebGLRenderingContext::renderbufferStorage): No longer perform framebuffer initialization at this point.
            (WebCore::WebGLRenderingContext::texImage2DBase): Ditto.
    2010-10-28  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            Perform framebuffer attachment checking upon draw call rather than attachment
            https://bugs.webkit.org/show_bug.cgi?id=46318
    
            * fast/canvas/webgl/framebuffer-object-attachment-expected.txt:
            * fast/canvas/webgl/framebuffer-object-attachment.html:
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@71190 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 4680869..79f0ce6 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-10-28  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Perform framebuffer attachment checking upon draw call rather than attachment
+        https://bugs.webkit.org/show_bug.cgi?id=46318
+
+        * fast/canvas/webgl/framebuffer-object-attachment-expected.txt:
+        * fast/canvas/webgl/framebuffer-object-attachment.html:
+
 2010-11-02  Mihai Parparita  <mihaip at chromium.org>
         
         Update the pixel expectations for fast/flexbox, fast/frames, fast/invalid, fast/layers, and fast/lists for the Mac port.
diff --git a/LayoutTests/fast/canvas/webgl/framebuffer-object-attachment-expected.txt b/LayoutTests/fast/canvas/webgl/framebuffer-object-attachment-expected.txt
index 643dffd..96ffeba 100644
--- a/LayoutTests/fast/canvas/webgl/framebuffer-object-attachment-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/framebuffer-object-attachment-expected.txt
@@ -4,6 +4,8 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
 
 Create renderbuffers
 PASS gl = create3DContext() is non-null.
+PASS colorBuffer = gl.createRenderbuffer() is non-null.
+PASS gl.getError() is gl.NO_ERROR
 PASS depthBuffer = gl.createRenderbuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
 PASS stencilBuffer = gl.createRenderbuffer() is non-null.
@@ -15,64 +17,76 @@ PASS fbo = gl.createFramebuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
 Attach depth using STENCIL_ATTACHMENT
 PASS fbo = gl.createFramebuffer() is non-null.
-PASS gl.getError() is gl.INVALID_OPERATION
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
 Attach depth using DEPTH_STENCIL_ATTACHMENT
 PASS fbo = gl.createFramebuffer() is non-null.
-PASS gl.getError() is gl.INVALID_OPERATION
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
 Attach stencil using STENCIL_ATTACHMENT
 PASS fbo = gl.createFramebuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
 Attach stencil using DEPTH_ATTACHMENT
 PASS fbo = gl.createFramebuffer() is non-null.
-PASS gl.getError() is gl.INVALID_OPERATION
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
 Attach stencil using DEPTH_STENCIL_ATTACHMENT
 PASS fbo = gl.createFramebuffer() is non-null.
-PASS gl.getError() is gl.INVALID_OPERATION
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
 Attach depthStencil using DEPTH_STENCIL_ATTACHMENT
 PASS fbo = gl.createFramebuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
 Attach depthStencil using DEPTH_ATTACHMENT
 PASS fbo = gl.createFramebuffer() is non-null.
-PASS gl.getError() is gl.INVALID_OPERATION
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
 Attach depthStencil using STENCIL_ATTACHMENT
 PASS fbo = gl.createFramebuffer() is non-null.
-PASS gl.getError() is gl.INVALID_OPERATION
+PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
+PASS gl.getError() is gl.INVALID_FRAMEBUFFER_OPERATION
 Attach depth, then stencil, causing conflict
 PASS fbo = gl.createFramebuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
-PASS gl.getError() is gl.INVALID_OPERATION
-PASS gl.getError() is gl.NO_ERROR
 PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
 Attach stencil, then depth, causing conflict
 PASS fbo = gl.createFramebuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
-PASS gl.getError() is gl.INVALID_OPERATION
-PASS gl.getError() is gl.NO_ERROR
 PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
 Attach depth, then depthStencil, causing conflict
 PASS fbo = gl.createFramebuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
-PASS gl.getError() is gl.INVALID_OPERATION
-PASS gl.getError() is gl.NO_ERROR
 PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
 Attach depthStencil, then depth, causing conflict
 PASS fbo = gl.createFramebuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
-PASS gl.getError() is gl.INVALID_OPERATION
-PASS gl.getError() is gl.NO_ERROR
 PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
 Attach stencil, then depthStencil, causing conflict
 PASS fbo = gl.createFramebuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
-PASS gl.getError() is gl.INVALID_OPERATION
-PASS gl.getError() is gl.NO_ERROR
 PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
 Attach depthStencil, then stencil, causing conflict
 PASS fbo = gl.createFramebuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
-PASS gl.getError() is gl.INVALID_OPERATION
-PASS gl.getError() is gl.NO_ERROR
 PASS gl.getError() is gl.NO_ERROR
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_UNSUPPORTED
 Attach color renderbuffer with internalformat == RGBA4
 PASS colorBuffer = gl.createRenderbuffer() is non-null.
 PASS gl.getError() is gl.NO_ERROR
diff --git a/LayoutTests/fast/canvas/webgl/framebuffer-object-attachment.html b/LayoutTests/fast/canvas/webgl/framebuffer-object-attachment.html
index c56bb7f..a7da17e 100644
--- a/LayoutTests/fast/canvas/webgl/framebuffer-object-attachment.html
+++ b/LayoutTests/fast/canvas/webgl/framebuffer-object-attachment.html
@@ -23,25 +23,29 @@ function testAttachment(attachment, buffer, isConflicted)
 {
     shouldBeNonNull("fbo = gl.createFramebuffer()");
     gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
     gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment, gl.RENDERBUFFER, buffer);
-    shouldBe("gl.getError()", isConflicted ? "gl.INVALID_OPERATION" : "gl.NO_ERROR");
+    shouldBe("gl.getError()", "gl.NO_ERROR");
+    if (isConflicted) {
+        shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_UNSUPPORTED");
+        gl.clear(gl.COLOR_BUFFER_BIT);
+        shouldBe("gl.getError()", "gl.INVALID_FRAMEBUFFER_OPERATION");
+        gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(width * height * 4));
+        shouldBe("gl.getError()", "gl.INVALID_FRAMEBUFFER_OPERATION");
+    }
 }
 
 function testAttachments(attachment0, buffer0, attachment1, buffer1, isConflicted)
 {
     shouldBeNonNull("fbo = gl.createFramebuffer()");
     gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+    gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, colorBuffer);
     gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, buffer0);
     shouldBe("gl.getError()", "gl.NO_ERROR");
     gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1);
-    shouldBe("gl.getError()", isConflicted ? "gl.INVALID_OPERATION" : "gl.NO_ERROR");
-    if (isConflicted) {
-        // Detach buffer0 first using a null object, then attaching buffer1 should succeed.
-        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment0, gl.RENDERBUFFER, null);
-        shouldBe("gl.getError()", "gl.NO_ERROR");
-        gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachment1, gl.RENDERBUFFER, buffer1);
-        shouldBe("gl.getError()", "gl.NO_ERROR");
-    }
+    shouldBe("gl.getError()", "gl.NO_ERROR");
+    if (isConflicted)
+        shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_UNSUPPORTED");
 }
 
 function testColorRenderbuffer(internalformat)
@@ -57,6 +61,10 @@ description("Test framebuffer object attachment behaviors");
 
 debug("Create renderbuffers");
 shouldBeNonNull("gl = create3DContext()");
+shouldBeNonNull("colorBuffer = gl.createRenderbuffer()");
+gl.bindRenderbuffer(gl.RENDERBUFFER, colorBuffer);
+gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, width, height);
+shouldBe("gl.getError()", "gl.NO_ERROR");
 shouldBeNonNull("depthBuffer = gl.createRenderbuffer()");
 gl.bindRenderbuffer(gl.RENDERBUFFER, depthBuffer);
 gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 7e09ce6..d1e8bb8 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,40 @@
+2010-10-28  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Perform framebuffer attachment checking upon draw call rather than attachment
+        https://bugs.webkit.org/show_bug.cgi?id=46318
+
+        * html/canvas/WebGLFramebuffer.cpp:
+        (WebCore::getInternalFormat): Helper function to get an attachment's internal format.
+        (WebCore::isUninitialized): Helper function to decide if an attachment is initialized or not.
+        (WebCore::setInitialized): Helper funtion to set an attachment as being initialized.
+        (WebCore::WebGLFramebuffer::setAttachment): No longer perform buffer initialization at this point.
+        (WebCore::WebGLFramebuffer::removeAttachment): Ditto.
+        (WebCore::WebGLFramebuffer::getColorBufferFormat): Make it const.
+        (WebCore::WebGLFramebuffer::isIncomplete): Attachments conflict check.
+        (WebCore::WebGLFramebuffer::onAccess): Check atatchment conflicts and buffer initialization if necessary.
+        (WebCore::WebGLFramebuffer::initializeRenderbuffers): Return a boolean whether the framebuffer is complete or not.
+        * html/canvas/WebGLFramebuffer.h: Add new function declaration and remove some outdated functions.
+        (WebCore::WebGLFramebuffer::isColorAttached):
+        (WebCore::WebGLFramebuffer::isDepthAttached): Make this private.
+        (WebCore::WebGLFramebuffer::isStencilAttached): Ditto.
+        (WebCore::WebGLFramebuffer::isDepthStencilAttached): Ditto.
+        * html/canvas/WebGLRenderbuffer.h:
+        (WebCore::WebGLRenderbuffer::setInternalFormat): Also set the renderbuffer as uninitialized.
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::bindFramebuffer): No longer perform framebuffer initialization at this point.
+        (WebCore::WebGLRenderingContext::checkFramebufferStatus): Check WebGL specific attachment conflicts.
+        (WebCore::WebGLRenderingContext::clear): Call WebGLFramebuffer::onAccess.
+        (WebCore::WebGLRenderingContext::copyTexImage2D): Ditto.
+        (WebCore::WebGLRenderingContext::copyTexSubImage2D): Ditto.
+        (WebCore::WebGLRenderingContext::drawArrays): Ditto.
+        (WebCore::WebGLRenderingContext::drawElements): Ditto.
+        (WebCore::WebGLRenderingContext::framebufferRenderbuffer): No longer perform framebuffer initialization at this point.
+        (WebCore::WebGLRenderingContext::readPixels): Call WebGLFramebuffer::onAccess.
+        (WebCore::WebGLRenderingContext::renderbufferStorage): No longer perform framebuffer initialization at this point.
+        (WebCore::WebGLRenderingContext::texImage2DBase): Ditto.
+
 2010-11-01  Zhenyao Mo  <zmo at google.com>
 
         Reviewed by Kenneth Russell.
diff --git a/WebCore/html/canvas/WebGLFramebuffer.cpp b/WebCore/html/canvas/WebGLFramebuffer.cpp
index 0fdcb99..787b181 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -32,7 +32,33 @@
 #include "WebGLRenderingContext.h"
 
 namespace WebCore {
-    
+
+namespace {
+
+    // This function is only for depth/stencil/depth_stencil attachment.
+    // Currently we assume these attachments are all renderbuffers.
+    unsigned long getInternalFormat(WebGLObject* buffer)
+    {
+        ASSERT(buffer && buffer->isRenderbuffer());
+        return (reinterpret_cast<WebGLRenderbuffer*>(buffer))->getInternalFormat();
+    }
+
+    bool isUninitialized(WebGLObject* attachedObject)
+    {
+        if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()
+            && !(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isInitialized())
+            return true;
+        return false;
+    }
+
+    void setInitialized(WebGLObject* attachedObject)
+    {
+        if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer())
+            (reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->setInitialized();
+    }
+
+} // anonymous namespace
+
 PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx)
 {
     return adoptRef(new WebGLFramebuffer(ctx));
@@ -66,7 +92,6 @@ void WebGLFramebuffer::setAttachment(unsigned long attachment, WebGLObject* atta
     default:
         return;
     }
-    initializeRenderbuffers();
 }
 
 void WebGLFramebuffer::removeAttachment(WebGLObject* attachment)
@@ -83,25 +108,9 @@ void WebGLFramebuffer::removeAttachment(WebGLObject* attachment)
         m_depthStencilAttachment = 0;
     else
         return;
-    initializeRenderbuffers();
-}
-
-void WebGLFramebuffer::onBind()
-{
-    initializeRenderbuffers();
-}
-
-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.get() || object == m_depthAttachment.get()
-            || object == m_stencilAttachment.get() || object == m_depthStencilAttachment.get()))
-        initializeRenderbuffers();
 }
 
-unsigned long WebGLFramebuffer::getColorBufferFormat()
+unsigned long WebGLFramebuffer::getColorBufferFormat() const
 {
     if (object() && m_colorAttachment && m_colorAttachment->object()) {
         if (m_colorAttachment->isRenderbuffer()) {
@@ -119,6 +128,36 @@ unsigned long WebGLFramebuffer::getColorBufferFormat()
     return 0;
 }
 
+bool WebGLFramebuffer::isIncomplete() const
+{
+    unsigned int count = 0;
+    if (isDepthAttached()) {
+        if (getInternalFormat(m_depthAttachment.get()) != GraphicsContext3D::DEPTH_COMPONENT16)
+            return true;
+        count++;
+    }
+    if (isStencilAttached()) {
+        if (getInternalFormat(m_stencilAttachment.get()) != GraphicsContext3D::STENCIL_INDEX8)
+            return true;
+        count++;
+    }
+    if (isDepthStencilAttached()) {
+        if (getInternalFormat(m_depthStencilAttachment.get()) != GraphicsContext3D::DEPTH_STENCIL)
+            return true;
+        count++;
+    }
+    if (count > 1)
+        return true;
+    return false;
+}
+
+bool WebGLFramebuffer::onAccess()
+{
+    if (isIncomplete())
+        return false;
+    return initializeRenderbuffers();
+}
+
 void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
 {
     if (!isDeleted())
@@ -129,24 +168,11 @@ void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
     m_depthStencilAttachment = 0;
 }
 
-bool WebGLFramebuffer::isUninitialized(WebGLObject* attachedObject)
+bool WebGLFramebuffer::initializeRenderbuffers()
 {
-    if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()
-        && !(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isInitialized())
-        return true;
-    return false;
-}
-
-void WebGLFramebuffer::setInitialized(WebGLObject* attachedObject)
-{
-    if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer())
-        (reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->setInitialized();
-}
-
-void WebGLFramebuffer::initializeRenderbuffers()
-{
-    if (!object())
-        return;
+    ASSERT(object());
+    if (!isColorAttached())
+        return false;
     bool initColor = false, initDepth = false, initStencil = false;
     unsigned long mask = 0;
     if (isUninitialized(m_colorAttachment.get())) {
@@ -167,13 +193,13 @@ void WebGLFramebuffer::initializeRenderbuffers()
         mask |= (GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT);
     }
     if (!initColor && !initDepth && !initStencil)
-        return;
+        return true;
 
     // We only clear un-initialized renderbuffers when they are ready to be
     // read, i.e., when the framebuffer is complete.
     GraphicsContext3D* g3d = context()->graphicsContext3D();
     if (g3d->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
-        return;
+        return false;
 
     float colorClearValue[] = {0, 0, 0, 0}, depthClearValue = 0;
     int stencilClearValue = 0;
@@ -237,6 +263,7 @@ void WebGLFramebuffer::initializeRenderbuffers()
         if (initStencil)
             setInitialized(m_stencilAttachment.get());
     }
+    return true;
 }
 
 }
diff --git a/WebCore/html/canvas/WebGLFramebuffer.h b/WebCore/html/canvas/WebGLFramebuffer.h
index 1892694..d455891 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/WebCore/html/canvas/WebGLFramebuffer.h
@@ -39,27 +39,21 @@ public:
 
     static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
 
-    bool isDepthAttached() const { return (m_depthAttachment && m_depthAttachment->object()); }
-    bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); }
-    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
-    // have changed and the framebuffer might have become complete when it
-    // isn't bound, so we need to clear un-initialized renderbuffers.
-    void onBind();
+    unsigned long getColorBufferFormat() const;
 
-    // When a texture or a renderbuffer changes, we need to check the
-    // current bound framebuffer; if the newly changed object is attached
-    // to the framebuffer and the framebuffer becomes complete, we need to
-    // clear un-initialized renderbuffers.
-    void onAttachedObjectChange(WebGLObject*);
+    // This should always be called before drawArray, drawElements, clear,
+    // readPixels, copyTexImage2D, copyTexSubImage2D if this framebuffer is
+    // currently bound.
+    // Return false if the framebuffer is incomplete; otherwise initialize
+    // the buffers if they haven't been initialized.
+    bool onAccess();
 
-    unsigned long getColorBufferFormat();
+    // Return false does not mean COMPLETE, might still be INCOMPLETE.
+    bool isIncomplete() const;
 
 protected:
     WebGLFramebuffer(WebGLRenderingContext*);
@@ -69,9 +63,13 @@ protected:
 private:
     virtual bool isFramebuffer() const { return true; }
 
-    bool isUninitialized(WebGLObject*);
-    void setInitialized(WebGLObject*);
-    void initializeRenderbuffers();
+    // Return false if framebuffer is incomplete.
+    bool initializeRenderbuffers();
+
+    bool isColorAttached() const { return (m_colorAttachment && m_colorAttachment->object()); }
+    bool isDepthAttached() const { return (m_depthAttachment && m_depthAttachment->object()); }
+    bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); }
+    bool isDepthStencilAttached() const { return (m_depthStencilAttachment && m_depthStencilAttachment->object()); }
 
     RefPtr<WebGLObject> m_colorAttachment;
     RefPtr<WebGLObject> m_depthAttachment;
diff --git a/WebCore/html/canvas/WebGLRenderbuffer.h b/WebCore/html/canvas/WebGLRenderbuffer.h
index 5765061..cfa26d3 100644
--- a/WebCore/html/canvas/WebGLRenderbuffer.h
+++ b/WebCore/html/canvas/WebGLRenderbuffer.h
@@ -39,7 +39,12 @@ public:
 
     static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*);
 
-    void setInternalFormat(unsigned long internalformat) { m_internalFormat = internalformat; }
+    void setInternalFormat(unsigned long internalformat)
+    {
+        m_internalFormat = internalformat;
+        m_initialized = false;
+    }
+
     unsigned long getInternalFormat() const { return m_internalFormat; }
 
     bool isInitialized() const { return m_initialized; }
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index 2a59e89..d75ca5e 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -272,8 +272,6 @@ void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuff
     }
     m_framebufferBinding = buffer;
     m_context->bindFramebuffer(target, objectOrZero(buffer));
-    if (m_framebufferBinding)
-        m_framebufferBinding->onBind();
     cleanupAfterGraphicsCall(false);
 }
 
@@ -460,6 +458,8 @@ unsigned long WebGLRenderingContext::checkFramebufferStatus(unsigned long target
     }
     if (!m_framebufferBinding || !m_framebufferBinding->object())
         return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
+    if (m_framebufferBinding->isIncomplete())
+        return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
     return m_context->checkFramebufferStatus(target);
     cleanupAfterGraphicsCall(false);
 }
@@ -470,6 +470,10 @@ void WebGLRenderingContext::clear(unsigned long mask)
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+        return;
+    }
     m_context->clear(mask);
     cleanupAfterGraphicsCall(true);
 }
@@ -534,11 +538,13 @@ void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, uns
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+        return;
+    }
     m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
     // FIXME: if the framebuffer is not complete, none of the below should be executed.
     tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
-    if (m_framebufferBinding)
-        m_framebufferBinding->onAttachedObjectChange(tex);
     cleanupAfterGraphicsCall(false);
 }
 
@@ -555,6 +561,10 @@ void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level,
             return;
         }
     }
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+        return;
+    }
     m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
     cleanupAfterGraphicsCall(false);
 }
@@ -956,6 +966,11 @@ void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long coun
         }
     }
 
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+        return;
+    }
+
     bool vertexAttrib0Simulated = false;
     if (!isGLES2Compliant())
         vertexAttrib0Simulated = simulateVertexAttrib0(first + count - 1);
@@ -1015,6 +1030,11 @@ void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigne
         }
     }
 
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+        return;
+    }
+
     bool vertexAttrib0Simulated = false;
     if (!isGLES2Compliant()) {
         if (!numElements)
@@ -1089,33 +1109,6 @@ void WebGLRenderingContext::framebufferRenderbuffer(unsigned long target, unsign
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    if (buffer && buffer->object()) {
-        bool isConflicted = false;
-        switch (attachment) {
-        case GraphicsContext3D::DEPTH_ATTACHMENT:
-            if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isStencilAttached())
-                isConflicted = true;
-            if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_COMPONENT16)
-                isConflicted = true;
-            break;
-        case GraphicsContext3D::STENCIL_ATTACHMENT:
-            if (m_framebufferBinding->isDepthStencilAttached() || m_framebufferBinding->isDepthAttached())
-                isConflicted = true;
-            if (buffer->getInternalFormat() != GraphicsContext3D::STENCIL_INDEX8)
-                isConflicted = true;
-            break;
-        case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
-            if (m_framebufferBinding->isDepthAttached() || m_framebufferBinding->isStencilAttached())
-                isConflicted = true;
-            if (buffer->getInternalFormat() != GraphicsContext3D::DEPTH_STENCIL)
-                isConflicted = true;
-            break;
-        }
-        if (isConflicted) {
-            m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
-            return;
-        }
-    }
     m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, objectOrZero(buffer));
     m_framebufferBinding->setAttachment(attachment, buffer);
     cleanupAfterGraphicsCall(false);
@@ -2008,6 +2001,10 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height,
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+        m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+        return;
+    }
     // Calculate array size, taking into consideration of PACK_ALIGNMENT.
     unsigned long bytesPerRow = componentsPerPixel * bytesPerComponent * width;
     unsigned long padding = 0;
@@ -2061,11 +2058,8 @@ void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned l
     case GraphicsContext3D::STENCIL_INDEX8:
     case GraphicsContext3D::DEPTH_STENCIL:
         m_context->renderbufferStorage(target, internalformat, width, height);
-        if (m_renderbufferBinding) {
+        if (m_renderbufferBinding)
             m_renderbufferBinding->setInternalFormat(internalformat);
-            if (m_framebufferBinding)
-                m_framebufferBinding->onAttachedObjectChange(m_renderbufferBinding.get());
-        }
         cleanupAfterGraphicsCall(false);
         break;
     default:
@@ -2150,8 +2144,6 @@ void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsi
     m_context->texImage2D(target, level, internalformat, width, height,
                           border, format, type, pixels);
     tex->setLevelInfo(target, level, internalformat, width, height, type);
-    if (m_framebufferBinding)
-        m_framebufferBinding->onAttachedObjectChange(tex);
     cleanupAfterGraphicsCall(false);
 }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list