[SCM] WebKit Debian packaging branch, debian/experimental, updated. debian/1.3.8-1-1049-g2e11a8e

zmo at google.com zmo at google.com
Fri Jan 21 14:44:40 UTC 2011


The following commit has been merged in the debian/experimental branch:
commit 5ae3f6839626b0e9c2e93ec69c1fd9ead8909b1e
Author: zmo at google.com <zmo at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Tue Dec 28 21:35:20 2010 +0000

    2010-12-23  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            Initialize to 0 for undefined values in CopyTexImage2D
            https://bugs.webkit.org/show_bug.cgi?id=51421
    
            * src/GraphicsContext3DChromium.cpp: Implement getInternalFramebufferSize().
            (WebCore::GraphicsContext3DInternal::getInternalFramebufferSize):
            * src/GraphicsContext3DInternal.h:
    2010-12-23  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            Initialize to 0 for undefined values in CopyTexImage2D
            https://bugs.webkit.org/show_bug.cgi?id=51421
    
            * html/canvas/WebGLFramebuffer.cpp: Track width/height/internalFormat of color buffer.
            (WebCore::WebGLFramebuffer::WebGLFramebuffer):
            (WebCore::WebGLFramebuffer::setAttachment):
            (WebCore::WebGLFramebuffer::getWidth):
            (WebCore::WebGLFramebuffer::getHeight):
            (WebCore::WebGLFramebuffer::getColorBufferFormat):
            * html/canvas/WebGLFramebuffer.h:
            * html/canvas/WebGLRenderingContext.cpp:
            (WebCore::WebGLRenderingContext::copyTexImage2D): Initialize undefined pixels to 0.
            (WebCore::WebGLRenderingContext::copyTexSubImage2D):
            (WebCore::WebGLRenderingContext::framebufferTexture2D):
            (WebCore::WebGLRenderingContext::renderbufferStorage):
            (WebCore::WebGLRenderingContext::getBoundFramebufferWidth):
            (WebCore::WebGLRenderingContext::getBoundFramebufferHeight):
            * html/canvas/WebGLRenderingContext.h:
            * html/canvas/WebGLTexture.cpp: Track width/height/internalFormat of a texture by target/level.
            (WebCore::WebGLTexture::getInternalFormat):
            (WebCore::WebGLTexture::getWidth):
            (WebCore::WebGLTexture::getHeight):
            (WebCore::WebGLTexture::mapTargetToIndex):
            (WebCore::WebGLTexture::getLevelInfo):
            * html/canvas/WebGLTexture.h:
            (WebCore::WebGLTexture::isTexture):
            * platform/graphics/GraphicsContext3D.h: Add getInternalFramebufferSize() function.
            * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
            (WebCore::GraphicsContext3D::getInternalFramebufferSize):
            * platform/graphics/qt/GraphicsContext3DQt.cpp:
            (WebCore::GraphicsContext3D::getInternalFramebufferSize):
    2010-12-23  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            Initialize to 0 for undefined values in CopyTexImage2D
            https://bugs.webkit.org/show_bug.cgi?id=51421
    
            * fast/canvas/webgl/uninitialized-test-expected.txt: Add test cases for copyTexImage2D.
            * fast/canvas/webgl/uninitialized-test.html: Ditto.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74720 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 17ad24c..f84ac8f 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-12-23  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Initialize to 0 for undefined values in CopyTexImage2D
+        https://bugs.webkit.org/show_bug.cgi?id=51421
+
+        * fast/canvas/webgl/uninitialized-test-expected.txt: Add test cases for copyTexImage2D.
+        * fast/canvas/webgl/uninitialized-test.html: Ditto.
+
 2010-12-28  Zhenyao Mo  <zmo at google.com>
 
         Reviewed by Kenneth Russell.
diff --git a/LayoutTests/fast/canvas/webgl/uninitialized-test-expected.txt b/LayoutTests/fast/canvas/webgl/uninitialized-test-expected.txt
index fba2b72..89d88a5 100644
--- a/LayoutTests/fast/canvas/webgl/uninitialized-test-expected.txt
+++ b/LayoutTests/fast/canvas/webgl/uninitialized-test-expected.txt
@@ -3,7 +3,29 @@ Tests to check user code cannot access uninitialized data from GL resources.
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 PASS Context created.
-Reading an uninitialized texture should succeed with all bytes set to 0.
+
+Reading an uninitialized texture (texImage2D) should succeed with all bytes set to 0.
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+PASS All data initialized
+PASS getError was expected value: NO_ERROR : 
+
+Reading an uninitialized portion of a texture (copyTexImage2D) should succeed with all bytes set to 0.
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+PASS getError was expected value: NO_ERROR : 
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+PASS All data initialized
+PASS getError was expected value: NO_ERROR : 
+
+Reading an uninitialized portion of a texture (copyTexImage2D with negative x and y) should succeed with all bytes set to 0.
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+PASS getError was expected value: NO_ERROR : 
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+PASS All data initialized
+PASS getError was expected value: NO_ERROR : 
+
+Reading an uninitialized portion of a texture (copyTexImage2D from WebGL internal fbo) should succeed with all bytes set to 0.
+PASS getError was expected value: NO_ERROR : 
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
 PASS All data initialized
 PASS getError was expected value: NO_ERROR : 
 
diff --git a/LayoutTests/fast/canvas/webgl/uninitialized-test.html b/LayoutTests/fast/canvas/webgl/uninitialized-test.html
index f353f93..0975006 100644
--- a/LayoutTests/fast/canvas/webgl/uninitialized-test.html
+++ b/LayoutTests/fast/canvas/webgl/uninitialized-test.html
@@ -21,52 +21,57 @@ if (!gl)
 else
   testPassed("Context created.");
 
-debug("Reading an uninitialized texture should succeed with all bytes set to 0.");
+function setupTexture(texWidth, texHeight) {
+    var texture = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, texture);
+    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texWidth, texHeight, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
 
-var width = 512;
-var height = 512;
-var bpp = 4;
-var expectedDataLength = width*height*bpp;
-
-var tex = gl.createTexture();
-gl.bindTexture(gl.TEXTURE_2D, tex);
-gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+    // this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
+    // into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
+    // with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
 
-// this can be quite undeterministic so to improve odds of seeing uninitialized data write bits
-// into tex then delete texture then re-create one with same characteristics (driver will likely reuse mem)
-// with this trick on r59046 WebKit/OSX I get FAIL 100% of the time instead of ~15% of the time.
+    var badData = new Uint8Array(texWidth * texHeight * 4);
+    for (var i = 0; i < badData.length; ++i)
+        badData[i] = i % 255;
 
-var badData = new Uint8Array(expectedDataLength);
-for (var i = 0; i < badData.length; ++i)
-    badData[i] = i % 255;
+    gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+    gl.finish(); // make sure it has been uploaded
 
-gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, badData);
-gl.finish(); // make sure it has been uploaded
+    gl.deleteTexture(texture);
+    gl.finish(); // make sure it has been deleted
 
-gl.deleteTexture(tex);
-gl.finish(); // make sure it has been deleted
-
-var tex = gl.createTexture();
-gl.bindTexture(gl.TEXTURE_2D, tex);
-gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+    var texture = gl.createTexture();
+    gl.bindTexture(gl.TEXTURE_2D, texture);
+    return texture;
+}
 
-var fb = gl.createFramebuffer();
-gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
-gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+function checkNonZeroPixels(texture, texWidth, texHeight, skipX, skipY, skipWidth, skipHeight, skipR, skipG, skipB, skipA) {
+    gl.bindTexture(gl.TEXTURE_2D, null);
+    var fb = gl.createFramebuffer();
+    gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+    gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
+    shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
 
-data = new Uint8Array(width * height * 4);
-gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, data);
+    var data = new Uint8Array(texWidth * texHeight * 4);
+    gl.readPixels(0, 0, texWidth, texHeight, gl.RGBA, gl.UNSIGNED_BYTE, data);
 
-if (data.length != expectedDataLength) {
-    testFailed("expected data length " + expectedDataLength + " but got " + data.length + " instead.");
-} else {
     var k = 0;
-    for (var i = 0; i < data.length; ++i) {
-        if (data[i] != 0) {
-            k++;
+    for (var y = 0; y < texHeight; ++y) {
+        for (var x = 0; x < texWidth; ++x) {
+            var index = (y * texWidth + x) * 4;
+            if (x >= skipX && x < skipX + skipWidth && y >= skipY && y < skipY + skipHeight) {
+                if (data[index] != skipR || data[index + 1] != skipG || data[index + 2] != skipB || data[index + 3] != skipA) {
+                    testFailed("non-zero pixel values are wrong");
+                    return;
+                }
+            } else {
+                for (var i = 0; i < 4; ++i) {
+                    if (data[index + i] != 0)
+                        k++;
+                }
+            }
         }
     }
-
     if (k) {
         testFailed("Found " + k + " non-zero bytes");
     } else {
@@ -74,6 +79,77 @@ if (data.length != expectedDataLength) {
     }
 }
 
+var width = 512;
+var height = 512;
+
+debug("");
+debug("Reading an uninitialized texture (texImage2D) should succeed with all bytes set to 0.");
+
+var tex = setupTexture(width, height);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+checkNonZeroPixels(tex, width, height, 0, 0, 0, 0, 0, 0, 0, 0);
+gl.deleteTexture(tex);
+gl.finish();
+glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+debug("Reading an uninitialized portion of a texture (copyTexImage2D) should succeed with all bytes set to 0.");
+
+var tex = setupTexture(width, height);
+var fbo = gl.createFramebuffer();
+gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+var rbo = gl.createRenderbuffer();
+gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+var fboWidth = 16;
+var fboHeight = 16;
+gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, fboWidth, fboHeight);
+gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
+shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+gl.clearColor(1.0, 0.0, 0.0, 1.0);
+gl.clear(gl.COLOR_BUFFER_BIT);
+glErrorShouldBe(gl, gl.NO_ERROR);
+gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, width, height, 0);
+checkNonZeroPixels(tex, width, height, 0, 0, fboWidth, fboHeight, 255, 0, 0, 255);
+gl.deleteTexture(tex);
+gl.finish();
+glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+debug("Reading an uninitialized portion of a texture (copyTexImage2D with negative x and y) should succeed with all bytes set to 0.");
+
+var tex = setupTexture(width, height);
+var fbo = gl.createFramebuffer();
+gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+var rbo = gl.createRenderbuffer();
+gl.bindRenderbuffer(gl.RENDERBUFFER, rbo);
+var fboWidth = 16;
+var fboHeight = 16;
+gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, fboWidth, fboHeight);
+gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, rbo);
+shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+gl.clearColor(1.0, 0.0, 0.0, 1.0);
+gl.clear(gl.COLOR_BUFFER_BIT);
+glErrorShouldBe(gl, gl.NO_ERROR);
+var x = -8;
+var y = -8;
+gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, x, y, width, height, 0);
+checkNonZeroPixels(tex, width, height, -x, -y, fboWidth, fboHeight, 255, 0, 0, 255);
+gl.deleteTexture(tex);
+gl.finish();
+glErrorShouldBe(gl, gl.NO_ERROR);
+
+debug("");
+debug("Reading an uninitialized portion of a texture (copyTexImage2D from WebGL internal fbo) should succeed with all bytes set to 0.");
+
+var tex = setupTexture(width, height);
+gl.bindFramebuffer(gl.FRAMEBUFFER, null);
+gl.clearColor(0.0, 1.0, 0.0, 0.0);
+gl.clear(gl.COLOR_BUFFER_BIT);
+glErrorShouldBe(gl, gl.NO_ERROR);
+gl.copyTexImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 0, 0, width, height, 0);
+checkNonZeroPixels(tex, width, height, 0, 0, canvas.width, canvas.height, 0, 255, 0, 0);
+gl.deleteTexture(tex);
+gl.finish();
 glErrorShouldBe(gl, gl.NO_ERROR);
 
 //TODO: uninitialized vertex array buffer
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 0bfc1e7..a8e327c 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -2,6 +2,42 @@
 
         Reviewed by Kenneth Russell.
 
+        Initialize to 0 for undefined values in CopyTexImage2D
+        https://bugs.webkit.org/show_bug.cgi?id=51421
+
+        * html/canvas/WebGLFramebuffer.cpp: Track width/height/internalFormat of color buffer.
+        (WebCore::WebGLFramebuffer::WebGLFramebuffer):
+        (WebCore::WebGLFramebuffer::setAttachment):
+        (WebCore::WebGLFramebuffer::getWidth):
+        (WebCore::WebGLFramebuffer::getHeight):
+        (WebCore::WebGLFramebuffer::getColorBufferFormat):
+        * html/canvas/WebGLFramebuffer.h:
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::copyTexImage2D): Initialize undefined pixels to 0.
+        (WebCore::WebGLRenderingContext::copyTexSubImage2D):
+        (WebCore::WebGLRenderingContext::framebufferTexture2D):
+        (WebCore::WebGLRenderingContext::renderbufferStorage):
+        (WebCore::WebGLRenderingContext::getBoundFramebufferWidth):
+        (WebCore::WebGLRenderingContext::getBoundFramebufferHeight):
+        * html/canvas/WebGLRenderingContext.h:
+        * html/canvas/WebGLTexture.cpp: Track width/height/internalFormat of a texture by target/level.
+        (WebCore::WebGLTexture::getInternalFormat):
+        (WebCore::WebGLTexture::getWidth):
+        (WebCore::WebGLTexture::getHeight):
+        (WebCore::WebGLTexture::mapTargetToIndex):
+        (WebCore::WebGLTexture::getLevelInfo):
+        * html/canvas/WebGLTexture.h:
+        (WebCore::WebGLTexture::isTexture):
+        * platform/graphics/GraphicsContext3D.h: Add getInternalFramebufferSize() function.
+        * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
+        (WebCore::GraphicsContext3D::getInternalFramebufferSize):
+        * platform/graphics/qt/GraphicsContext3DQt.cpp:
+        (WebCore::GraphicsContext3D::getInternalFramebufferSize):
+
+2010-12-23  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
         Map GLsizei to long instead of unsigned long in WebGLRenderingContext and GraphicsContext3D
         https://bugs.webkit.org/show_bug.cgi?id=39855
 
diff --git a/WebCore/html/canvas/WebGLFramebuffer.cpp b/WebCore/html/canvas/WebGLFramebuffer.cpp
index 8ce0d6c..a1c3a9a 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -76,28 +76,58 @@ PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx
 WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
     : WebGLObject(ctx)
     , m_hasEverBeenBound(false)
+    , m_texTarget(0)
+    , m_texLevel(-1)
 {
     setObject(context()->graphicsContext3D()->createFramebuffer());
 }
 
-void WebGLFramebuffer::setAttachment(unsigned long attachment, WebGLObject* attachedObject)
+void WebGLFramebuffer::setAttachment(unsigned long attachment, unsigned long texTarget, WebGLTexture* texture, int level)
 {
     if (!object())
         return;
-    if (attachedObject && !attachedObject->object())
-        attachedObject = 0;
+    if (texture && !texture->object())
+        texture = 0;
     switch (attachment) {
     case GraphicsContext3D::COLOR_ATTACHMENT0:
-        m_colorAttachment = attachedObject;
+        m_colorAttachment = texture;
+        if (texture) {
+            m_texTarget = texTarget;
+            m_texLevel = level;
+        }
         break;
     case GraphicsContext3D::DEPTH_ATTACHMENT:
-        m_depthAttachment = attachedObject;
+        m_depthAttachment = texture;
         break;
     case GraphicsContext3D::STENCIL_ATTACHMENT:
-        m_stencilAttachment = attachedObject;
+        m_stencilAttachment = texture;
         break;
     case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
-        m_depthStencilAttachment = attachedObject;
+        m_depthStencilAttachment = texture;
+        break;
+    default:
+        return;
+    }
+}
+
+void WebGLFramebuffer::setAttachment(unsigned long attachment, WebGLRenderbuffer* renderbuffer)
+{
+    if (!object())
+        return;
+    if (renderbuffer && !renderbuffer->object())
+        renderbuffer = 0;
+    switch (attachment) {
+    case GraphicsContext3D::COLOR_ATTACHMENT0:
+        m_colorAttachment = renderbuffer;
+        break;
+    case GraphicsContext3D::DEPTH_ATTACHMENT:
+        m_depthAttachment = renderbuffer;
+        break;
+    case GraphicsContext3D::STENCIL_ATTACHMENT:
+        m_stencilAttachment = renderbuffer;
+        break;
+    case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
+        m_depthStencilAttachment = renderbuffer;
         break;
     default:
         return;
@@ -138,21 +168,48 @@ void WebGLFramebuffer::removeAttachment(WebGLObject* attachment)
         return;
 }
 
+int WebGLFramebuffer::getWidth() const
+{
+    if (!object() || !isColorAttached())
+        return 0;
+    if (m_colorAttachment->isRenderbuffer())
+        return (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getWidth();
+    if (m_colorAttachment->isTexture())
+        return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getWidth(m_texTarget, m_texLevel);
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+int WebGLFramebuffer::getHeight() const
+{
+    if (!object() || !isColorAttached())
+        return 0;
+    if (m_colorAttachment->isRenderbuffer())
+        return (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getHeight();
+    if (m_colorAttachment->isTexture())
+        return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getHeight(m_texTarget, m_texLevel);
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
 unsigned long WebGLFramebuffer::getColorBufferFormat() const
 {
-    if (object() && m_colorAttachment && m_colorAttachment->object()) {
-        if (m_colorAttachment->isRenderbuffer()) {
-            unsigned long format = (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getInternalFormat();
-            switch (format) {
-            case GraphicsContext3D::RGBA4:
-            case GraphicsContext3D::RGB5_A1:
-                return GraphicsContext3D::RGBA;
-            case GraphicsContext3D::RGB565:
-                return GraphicsContext3D::RGB;
-            }
-        } else if (m_colorAttachment->isTexture())
-            return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getInternalFormat(0);
+    if (!object() || !isColorAttached())
+        return 0;
+    if (m_colorAttachment->isRenderbuffer()) {
+        unsigned long format = (reinterpret_cast<WebGLRenderbuffer*>(m_colorAttachment.get()))->getInternalFormat();
+        switch (format) {
+        case GraphicsContext3D::RGBA4:
+        case GraphicsContext3D::RGB5_A1:
+            return GraphicsContext3D::RGBA;
+        case GraphicsContext3D::RGB565:
+            return GraphicsContext3D::RGB;
+        }
+        return 0;
     }
+    if (m_colorAttachment->isTexture())
+        return (reinterpret_cast<WebGLTexture*>(m_colorAttachment.get()))->getInternalFormat(m_texTarget, m_texLevel);
+    ASSERT_NOT_REACHED();
     return 0;
 }
 
diff --git a/WebCore/html/canvas/WebGLFramebuffer.h b/WebCore/html/canvas/WebGLFramebuffer.h
index cb565ae..d801904 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/WebCore/html/canvas/WebGLFramebuffer.h
@@ -33,18 +33,24 @@
 
 namespace WebCore {
 
+class WebGLRenderbuffer;
+class WebGLTexture;
+
 class WebGLFramebuffer : public WebGLObject {
 public:
     virtual ~WebGLFramebuffer() { deleteObject(); }
 
     static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
 
-    void setAttachment(unsigned long, WebGLObject*);
+    void setAttachment(unsigned long attachment, unsigned long texTarget, WebGLTexture*, int level);
+    void setAttachment(unsigned long attachment, WebGLRenderbuffer*);
     // If an object is attached to the framebuffer, remove it.
     void removeAttachment(WebGLObject*);
     WebGLObject* getAttachment(unsigned long) const;
 
     unsigned long getColorBufferFormat() const;
+    int getWidth() const;
+    int getHeight() const;
 
     // This should always be called before drawArray, drawElements, clear,
     // readPixels, copyTexImage2D, copyTexSubImage2D if this framebuffer is
@@ -83,6 +89,9 @@ private:
     RefPtr<WebGLObject> m_depthStencilAttachment;
 
     bool m_hasEverBeenBound;
+
+    unsigned long m_texTarget;
+    int m_texLevel;
 };
 
 } // namespace WebCore
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index 90ba6ee..f138ca5 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -65,10 +65,28 @@ namespace WebCore {
 
 const double secondsBetweenRestoreAttempts = 1.0;
 
-static inline Platform3DObject objectOrZero(WebGLObject* object)
-{
-    return object ? object->object() : 0;
-}
+namespace {
+
+    Platform3DObject objectOrZero(WebGLObject* object)
+    {
+        return object ? object->object() : 0;
+    }
+
+    void clip(long start, long range, long sourceRange, long* clippedStart, long* clippedRange)
+    {
+        ASSERT(clippedStart && clippedRange);
+        if (start < 0) {
+            range += start;
+            start = 0;
+        }
+        long end = start + range;
+        if (end > sourceRange)
+            range -= end - sourceRange;
+        *clippedStart = start;
+        *clippedRange = range;
+    }
+
+} // namespace anonymous
 
 class WebGLStateRestorer {
 public:
@@ -650,7 +668,22 @@ void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, uns
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
         return;
     }
-    m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+    if (isResourceSafe())
+        m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+    else {
+        long clippedX, clippedY, clippedWidth, clippedHeight;
+        clip(x, width, getBoundFramebufferWidth(), &clippedX, &clippedWidth);
+        clip(y, height, getBoundFramebufferHeight(), &clippedY, &clippedHeight);
+        if (clippedX != x || clippedY != y || clippedWidth != static_cast<long>(width) || clippedHeight != static_cast<long>(height)) {
+            m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border,
+                                              internalformat, GraphicsContext3D::UNSIGNED_BYTE);
+            if (clippedWidth > 0 && clippedHeight > 0) {
+                m_context->copyTexSubImage2D(target, level, clippedX - x, clippedY - y,
+                                             clippedX, clippedY, clippedWidth, clippedHeight);
+            }
+        } else
+            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);
     cleanupAfterGraphicsCall(false);
@@ -665,7 +698,7 @@ void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level,
         return;
     if (!validateSize(xoffset, yoffset) || !validateSize(width, height))
         return;
-    if (!isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(level), getBoundFramebufferColorFormat())) {
+    if (!isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(target, level), getBoundFramebufferColorFormat())) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
@@ -1321,7 +1354,7 @@ void WebGLRenderingContext::framebufferTexture2D(unsigned long target, unsigned
         return;
     }
     m_context->framebufferTexture2D(target, attachment, textarget, objectOrZero(texture), level);
-    m_framebufferBinding->setAttachment(attachment, texture);
+    m_framebufferBinding->setAttachment(attachment, textarget, texture, level);
     cleanupAfterGraphicsCall(false);
 }
 
@@ -2387,14 +2420,15 @@ void WebGLRenderingContext::renderbufferStorage(unsigned long target, unsigned l
         m_context->renderbufferStorage(target, internalformat, width, height);
         m_renderbufferBinding->setInternalFormat(internalformat);
         m_renderbufferBinding->setIsValid(true);
+        m_renderbufferBinding->setSize(width, height);
         cleanupAfterGraphicsCall(false);
         break;
     case GraphicsContext3D::DEPTH_STENCIL:
         if (isDepthStencilSupported()) {
             m_context->renderbufferStorage(target, Extensions3D::DEPTH24_STENCIL8, width, height);
             cleanupAfterGraphicsCall(false);
-        } else
-            m_renderbufferBinding->setSize(width, height);
+        }
+        m_renderbufferBinding->setSize(width, height);
         m_renderbufferBinding->setIsValid(isDepthStencilSupported());
         m_renderbufferBinding->setInternalFormat(internalformat);
         break;
@@ -3583,6 +3617,20 @@ unsigned long WebGLRenderingContext::getBoundFramebufferColorFormat()
     return GraphicsContext3D::RGB;
 }
 
+int WebGLRenderingContext::getBoundFramebufferWidth()
+{
+    if (m_framebufferBinding && m_framebufferBinding->object())
+        return m_framebufferBinding->getWidth();
+    return m_context->getInternalFramebufferSize().width();
+}
+
+int WebGLRenderingContext::getBoundFramebufferHeight()
+{
+    if (m_framebufferBinding && m_framebufferBinding->object())
+        return m_framebufferBinding->getHeight();
+    return m_context->getInternalFramebufferSize().height();
+}
+
 WebGLTexture* WebGLRenderingContext::validateTextureBinding(unsigned long target, bool useSixEnumsForCubeMap)
 {
     WebGLTexture* tex = 0;
diff --git a/WebCore/html/canvas/WebGLRenderingContext.h b/WebCore/html/canvas/WebGLRenderingContext.h
index c8c4bdb..959d818 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/WebCore/html/canvas/WebGLRenderingContext.h
@@ -505,6 +505,12 @@ public:
     // Helper function to get the bound framebuffer's color buffer format.
     unsigned long getBoundFramebufferColorFormat();
 
+    // Helper function to get the bound framebuffer's width.
+    int getBoundFramebufferWidth();
+
+    // Helper function to get the bound framebuffer's height.
+    int getBoundFramebufferHeight();
+
     // Helper function to check if size is non-negative.
     // Generate GL error and return false for negative inputs; otherwise, return true.
     bool validateSize(long x, long y);
diff --git a/WebCore/html/canvas/WebGLTexture.cpp b/WebCore/html/canvas/WebGLTexture.cpp
index 4fedaf0..5d06c3f 100644
--- a/WebCore/html/canvas/WebGLTexture.cpp
+++ b/WebCore/html/canvas/WebGLTexture.cpp
@@ -169,12 +169,28 @@ void WebGLTexture::generateMipmapLevelInfo()
     m_needToUseBlackTexture = false;
 }
 
-unsigned long WebGLTexture::getInternalFormat(int level) const
+unsigned long WebGLTexture::getInternalFormat(unsigned long target, int level) const
 {
-    if (!object() || !m_target)
+    const LevelInfo* info = getLevelInfo(target, level);
+    if (!info)
+        return 0;
+    return info->internalFormat;
+}
+
+int WebGLTexture::getWidth(unsigned long target, int level) const
+{
+    const LevelInfo* info = getLevelInfo(target, level);
+    if (!info)
+        return 0;
+    return info->width;
+}
+
+int WebGLTexture::getHeight(unsigned long target, int level) const
+{
+    const LevelInfo* info = getLevelInfo(target, level);
+    if (!info)
         return 0;
-    // We assume level has been validated already.
-    return m_info[0][level].internalFormat;
+    return info->height;
 }
 
 bool WebGLTexture::isNPOT(unsigned width, unsigned height)
@@ -205,7 +221,7 @@ void WebGLTexture::deleteObjectImpl(Platform3DObject object)
     context()->graphicsContext3D()->deleteTexture(object);
 }
 
-int WebGLTexture::mapTargetToIndex(unsigned long target)
+int WebGLTexture::mapTargetToIndex(unsigned long target) const
 {
     if (m_target == GraphicsContext3D::TEXTURE_2D) {
         if (target == GraphicsContext3D::TEXTURE_2D)
@@ -314,6 +330,18 @@ void WebGLTexture::update()
         m_needToUseBlackTexture = true;
 }
 
+const WebGLTexture::LevelInfo* WebGLTexture::getLevelInfo(unsigned long target, int level) const
+{
+    if (!object() || !m_target)
+        return 0;
+    int targetIndex = mapTargetToIndex(target);
+    if (targetIndex < 0 || targetIndex >= static_cast<int>(m_info.size()))
+        return 0;
+    if (level < 0 || level >= static_cast<int>(m_info[targetIndex].size()))
+        return 0;
+    return &(m_info[targetIndex][level]);
+}
+
 }
 
 #endif // ENABLE(3D_CANVAS)
diff --git a/WebCore/html/canvas/WebGLTexture.h b/WebCore/html/canvas/WebGLTexture.h
index 493ef7e..12b89aa 100644
--- a/WebCore/html/canvas/WebGLTexture.h
+++ b/WebCore/html/canvas/WebGLTexture.h
@@ -52,7 +52,9 @@ public:
     // Generate all level information.
     void generateMipmapLevelInfo();
 
-    unsigned long getInternalFormat(int level) const;
+    unsigned long getInternalFormat(unsigned long target, int level) const;
+    int getWidth(unsigned long target, int level) const;
+    int getHeight(unsigned long target, int level) const;
 
     // Whether width/height is NotPowerOfTwo.
     static bool isNPOT(unsigned, unsigned);
@@ -71,19 +73,6 @@ protected:
     virtual void deleteObjectImpl(Platform3DObject);
 
 private:
-    virtual bool isTexture() const { return true; }
-
-    void update();
-
-    int mapTargetToIndex(unsigned long);
-
-    unsigned long m_target;
-
-    int m_minFilter;
-    int m_magFilter;
-    int m_wrapS;
-    int m_wrapT;
-
     class LevelInfo {
     public:
         LevelInfo()
@@ -111,6 +100,21 @@ private:
         unsigned long type;
     };
 
+    virtual bool isTexture() const { return true; }
+
+    void update();
+
+    int mapTargetToIndex(unsigned long) const;
+
+    const LevelInfo* getLevelInfo(unsigned long target, int level) const;
+
+    unsigned long m_target;
+
+    int m_minFilter;
+    int m_magFilter;
+    int m_wrapS;
+    int m_wrapT;
+
     Vector<Vector<LevelInfo> > m_info;
 
     bool m_isNPOT;
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index f9540be..edce5e5 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -796,6 +796,8 @@ public:
     // determine this.
     Extensions3D* getExtensions();
 
+    IntSize getInternalFramebufferSize();
+
   private:
     GraphicsContext3D(Attributes attrs, HostWindow* hostWindow, bool renderDirectlyToHostWindow);
 
diff --git a/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
index aa3b60e..0e72aea 100644
--- a/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
+++ b/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
@@ -271,6 +271,11 @@ void GraphicsContext3D::reshape(int width, int height)
     ::glFlush();
 }
 
+IntSize GraphicsContext3D::getInternalFramebufferSize()
+{
+    return IntSize(m_currentWidth, m_currentHeight);
+}
+
 void GraphicsContext3D::prepareTexture()
 {
     makeContextCurrent();
diff --git a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
index 2ba358f..70fc46c 100644
--- a/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
+++ b/WebCore/platform/graphics/qt/GraphicsContext3DQt.cpp
@@ -598,6 +598,11 @@ void GraphicsContext3D::reshape(int width, int height)
     glFlush();
 }
 
+IntSize GraphicsContext3D::getInternalFramebufferSize()
+{
+    return IntSize(m_currentWidth, m_currentHeight);
+}
+
 void GraphicsContext3D::activeTexture(unsigned long texture)
 {
     m_internal->m_glWidget->makeCurrent();
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index f0e5784..70b7184 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,14 @@
+2010-12-23  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        Initialize to 0 for undefined values in CopyTexImage2D
+        https://bugs.webkit.org/show_bug.cgi?id=51421
+
+        * src/GraphicsContext3DChromium.cpp: Implement getInternalFramebufferSize().
+        (WebCore::GraphicsContext3DInternal::getInternalFramebufferSize):
+        * src/GraphicsContext3DInternal.h:
+
 2010-12-23  Sheriff Bot  <webkit.review.bot at gmail.com>
 
         Unreviewed, rolling out r74561.
diff --git a/WebKit/chromium/src/GraphicsContext3DChromium.cpp b/WebKit/chromium/src/GraphicsContext3DChromium.cpp
index 2dff52b..08b50c2 100644
--- a/WebKit/chromium/src/GraphicsContext3DChromium.cpp
+++ b/WebKit/chromium/src/GraphicsContext3DChromium.cpp
@@ -246,6 +246,11 @@ void GraphicsContext3DInternal::reshape(int width, int height)
 #endif // PLATFORM(CG)
 }
 
+IntSize GraphicsContext3DInternal::getInternalFramebufferSize()
+{
+    return IntSize(m_impl->width(), m_impl->height());
+}
+
 bool GraphicsContext3DInternal::isContextLost()
 {
     return m_impl->isContextLost();
@@ -892,6 +897,7 @@ PlatformLayer* GraphicsContext3D::platformLayer() const
 DELEGATE_TO_INTERNAL(makeContextCurrent)
 DELEGATE_TO_INTERNAL_1R(sizeInBytes, int, int)
 DELEGATE_TO_INTERNAL_2(reshape, int, int)
+DELEGATE_TO_INTERNAL_R(getInternalFramebufferSize, IntSize)
 
 DELEGATE_TO_INTERNAL_1(activeTexture, unsigned long)
 DELEGATE_TO_INTERNAL_2(attachShader, Platform3DObject, Platform3DObject)
diff --git a/WebKit/chromium/src/GraphicsContext3DInternal.h b/WebKit/chromium/src/GraphicsContext3DInternal.h
index ad54a4f..05165a3 100644
--- a/WebKit/chromium/src/GraphicsContext3DInternal.h
+++ b/WebKit/chromium/src/GraphicsContext3DInternal.h
@@ -65,6 +65,7 @@ public:
     int sizeInBytes(int type);
 
     void reshape(int width, int height);
+    IntSize getInternalFramebufferSize();
 
     void paintRenderingResultsToCanvas(CanvasRenderingContext*);
     bool paintsIntoCanvasBuffer() const;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list