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

zmo at google.com zmo at google.com
Mon Dec 27 16:28:32 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit bc8eb1a4d75d96efab6799ef703b462b7ebba6a1
Author: zmo at google.com <zmo at google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Dec 22 01:08:31 2010 +0000

    2010-12-21  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            WebGLRenderingContext needs to zero textures and renderbuffers
            https://bugs.webkit.org/show_bug.cgi?id=49355
    
            * src/WebGraphicsContext3DDefaultImpl.cpp:
            (WebKit::WebGraphicsContext3DDefaultImpl::texImage2D): Generate an INVALID_VALUE if pixels==null is passed in.
    2010-12-21  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            WebGLRenderingContext needs to zero textures and renderbuffers
            https://bugs.webkit.org/show_bug.cgi?id=49355
    
            Test: fast/canvas/webgl/uninitialized-test.html
    
            * html/canvas/WebGLFramebuffer.cpp:
            (WebCore::WebGLFramebuffer::onAccess): Use a parameter to decide if renderbuffer initialization is needed.
            (WebCore::WebGLFramebuffer::initializeRenderbuffers): Don't return false if color buffer doesn't exist.
            * html/canvas/WebGLFramebuffer.h: Modify onAccess with an added parameter.
            * html/canvas/WebGLRenderingContext.cpp:
            (WebCore::WebGLRenderingContext::clear): Call onAccess with an added parameter.
            (WebCore::WebGLRenderingContext::copyTexImage2D): Ditto.
            (WebCore::WebGLRenderingContext::copyTexSubImage2D): Ditto.
            (WebCore::WebGLRenderingContext::drawArrays): Ditto.
            (WebCore::WebGLRenderingContext::drawElements): Ditto.
            (WebCore::WebGLRenderingContext::readPixels): Ditto.
            (WebCore::WebGLRenderingContext::texImage2DBase): Create buffer data of 0s if input is null to initialize textures.
            * platform/graphics/GraphicsContext3D.cpp:
            (WebCore::GraphicsContext3D::texImage2DResourceSafe): Helper function that initialize all pixels to 0.
            * platform/graphics/GraphicsContext3D.h:
            * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
            (WebCore::Canvas2DLayerChromium::updateContentsIfDirty): Use texImage2DResourceSafe.
            * platform/graphics/chromium/DrawingBufferChromium.cpp:
            (WebCore::generateColorTexture): Ditto.
            * platform/graphics/chromium/LayerRendererChromium.cpp:
            (WebCore::LayerRendererChromium::prepareToDrawLayers): Ditto.
            * platform/graphics/chromium/TextureManager.cpp:
            (WebCore::TextureManager::requestTexture): Ditto.
            * platform/graphics/chromium/VideoLayerChromium.cpp:
            (WebCore::VideoLayerChromium::allocateTexture): Ditto.
            * platform/graphics/gpu/DrawingBuffer.cpp:
            (WebCore::DrawingBuffer::reset): Use texImage2DResourceSafe; also, only initialize depth/stencil buffer.
            * platform/graphics/gpu/SharedGraphicsContext3D.cpp:
            (WebCore::SharedGraphicsContext3D::texImage2D): Use texImage2DResourceSafe.
            * platform/graphics/gpu/Texture.cpp:
            (WebCore::Texture::create): Ditto.
            * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
            (WebCore::GraphicsContext3D::texImage2D): Generate an INVALID_VALUE if pixels==null is passed in.
    2010-12-21  Zhenyao Mo  <zmo at google.com>
    
            Reviewed by Kenneth Russell.
    
            WebGLRenderingContext needs to zero textures and renderbuffers
            https://bugs.webkit.org/show_bug.cgi?id=49355
    
            * fast/canvas/webgl/uninitialized-test-expected.txt: Added.
            * fast/canvas/webgl/uninitialized-test.html: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@74440 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index fb604d1..70b9860 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,13 @@
+2010-12-21  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        WebGLRenderingContext needs to zero textures and renderbuffers
+        https://bugs.webkit.org/show_bug.cgi?id=49355
+
+        * fast/canvas/webgl/uninitialized-test-expected.txt: Added.
+        * fast/canvas/webgl/uninitialized-test.html: Added.
+
 2010-12-21  Kenneth Russell  <kbr at google.com>
 
         Unreviewed test expectations update. Remove the following five
diff --git a/LayoutTests/fast/canvas/webgl/uninitialized-test-expected.txt b/LayoutTests/fast/canvas/webgl/uninitialized-test-expected.txt
new file mode 100644
index 0000000..fba2b72
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/uninitialized-test-expected.txt
@@ -0,0 +1,13 @@
+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.
+PASS All data initialized
+PASS getError was expected value: NO_ERROR : 
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/fast/canvas/webgl/uninitialized-test.html b/LayoutTests/fast/canvas/webgl/uninitialized-test.html
new file mode 100644
index 0000000..f353f93
--- /dev/null
+++ b/LayoutTests/fast/canvas/webgl/uninitialized-test.html
@@ -0,0 +1,91 @@
+<!doctype html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+<title>WebGL Uninitialized GL Resources Tests</title>
+<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>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<canvas id="canvas" width="2" height="2"> </canvas>
+<script>
+description("Tests to check user code cannot access uninitialized data from GL resources.");
+
+var canvas = document.getElementById("canvas");
+var gl = create3DContext(canvas);
+if (!gl)
+  testFailed("Context created.");
+else
+  testPassed("Context created.");
+
+debug("Reading an uninitialized texture should succeed with all bytes set to 0.");
+
+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.
+
+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, width, height, gl.RGBA, gl.UNSIGNED_BYTE, badData);
+gl.finish(); // make sure it has been uploaded
+
+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 fb = gl.createFramebuffer();
+gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
+gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);
+
+data = new Uint8Array(width * height * 4);
+gl.readPixels(0, 0, width, height, 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++;
+        }
+    }
+
+    if (k) {
+        testFailed("Found " + k + " non-zero bytes");
+    } else {
+        testPassed("All data initialized");
+    }
+}
+
+glErrorShouldBe(gl, gl.NO_ERROR);
+
+//TODO: uninitialized vertex array buffer
+//TODO: uninitialized vertex elements buffer
+//TODO: uninitialized framebuffer? (implementations would need to do a GL clear at first binding?)
+//TODO: uninitialized renderbuffer? (implementations would need to do a GL clear at first binding?)
+//TODO: uninitialized uniform arrays?
+
+debug("");
+successfullyParsed = true;
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+</body>
+</html>
+
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 2c958ae..b2234f9 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,46 @@
+2010-12-21  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        WebGLRenderingContext needs to zero textures and renderbuffers
+        https://bugs.webkit.org/show_bug.cgi?id=49355
+
+        Test: fast/canvas/webgl/uninitialized-test.html
+
+        * html/canvas/WebGLFramebuffer.cpp:
+        (WebCore::WebGLFramebuffer::onAccess): Use a parameter to decide if renderbuffer initialization is needed.
+        (WebCore::WebGLFramebuffer::initializeRenderbuffers): Don't return false if color buffer doesn't exist.
+        * html/canvas/WebGLFramebuffer.h: Modify onAccess with an added parameter.
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::clear): Call onAccess with an added parameter.
+        (WebCore::WebGLRenderingContext::copyTexImage2D): Ditto.
+        (WebCore::WebGLRenderingContext::copyTexSubImage2D): Ditto.
+        (WebCore::WebGLRenderingContext::drawArrays): Ditto.
+        (WebCore::WebGLRenderingContext::drawElements): Ditto.
+        (WebCore::WebGLRenderingContext::readPixels): Ditto.
+        (WebCore::WebGLRenderingContext::texImage2DBase): Create buffer data of 0s if input is null to initialize textures.
+        * platform/graphics/GraphicsContext3D.cpp:
+        (WebCore::GraphicsContext3D::texImage2DResourceSafe): Helper function that initialize all pixels to 0.
+        * platform/graphics/GraphicsContext3D.h:
+        * platform/graphics/chromium/Canvas2DLayerChromium.cpp:
+        (WebCore::Canvas2DLayerChromium::updateContentsIfDirty): Use texImage2DResourceSafe.
+        * platform/graphics/chromium/DrawingBufferChromium.cpp:
+        (WebCore::generateColorTexture): Ditto.
+        * platform/graphics/chromium/LayerRendererChromium.cpp:
+        (WebCore::LayerRendererChromium::prepareToDrawLayers): Ditto.
+        * platform/graphics/chromium/TextureManager.cpp:
+        (WebCore::TextureManager::requestTexture): Ditto.
+        * platform/graphics/chromium/VideoLayerChromium.cpp:
+        (WebCore::VideoLayerChromium::allocateTexture): Ditto.
+        * platform/graphics/gpu/DrawingBuffer.cpp:
+        (WebCore::DrawingBuffer::reset): Use texImage2DResourceSafe; also, only initialize depth/stencil buffer.
+        * platform/graphics/gpu/SharedGraphicsContext3D.cpp:
+        (WebCore::SharedGraphicsContext3D::texImage2D): Use texImage2DResourceSafe.
+        * platform/graphics/gpu/Texture.cpp:
+        (WebCore::Texture::create): Ditto.
+        * platform/graphics/opengl/GraphicsContext3DOpenGL.cpp:
+        (WebCore::GraphicsContext3D::texImage2D): Generate an INVALID_VALUE if pixels==null is passed in.
+
 2010-12-21  Chris Rogers  <crogers at google.com>
 
         Reviewed by Kenneth Russell.
diff --git a/WebCore/html/canvas/WebGLFramebuffer.cpp b/WebCore/html/canvas/WebGLFramebuffer.cpp
index 838876b..8ce0d6c 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -181,11 +181,13 @@ bool WebGLFramebuffer::isIncomplete(bool checkInternalFormat) const
     return false;
 }
 
-bool WebGLFramebuffer::onAccess()
+bool WebGLFramebuffer::onAccess(bool needToInitializeRenderbuffers)
 {
     if (isIncomplete(true))
         return false;
-    return initializeRenderbuffers();
+    if (needToInitializeRenderbuffers)
+        return initializeRenderbuffers();
+    return true;
 }
 
 void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
@@ -200,8 +202,6 @@ void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
 bool WebGLFramebuffer::initializeRenderbuffers()
 {
     ASSERT(object());
-    if (!isColorAttached())
-        return false;
     bool initColor = false, initDepth = false, initStencil = false;
     unsigned long mask = 0;
     if (isUninitialized(m_colorAttachment.get())) {
diff --git a/WebCore/html/canvas/WebGLFramebuffer.h b/WebCore/html/canvas/WebGLFramebuffer.h
index b86417d..cb565ae 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/WebCore/html/canvas/WebGLFramebuffer.h
@@ -50,8 +50,9 @@ public:
     // 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();
+    // the buffers if they haven't been initialized and
+    // needToInitializeRenderbuffers is true.
+    bool onAccess(bool needToInitializeRenderbuffers);
 
     // Return false does not mean COMPLETE, might still be INCOMPLETE.
     bool isIncomplete(bool checkInternalFormat) const;
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index 51894fe..65769e1 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -571,7 +571,7 @@ void WebGLRenderingContext::clear(unsigned long mask)
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
         return;
     }
@@ -649,7 +649,7 @@ void WebGLRenderingContext::copyTexImage2D(unsigned long target, long level, uns
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
         return;
     }
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
         return;
     }
@@ -674,7 +674,7 @@ void WebGLRenderingContext::copyTexSubImage2D(unsigned long target, long level,
             return;
         }
     }
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
         return;
     }
@@ -1105,7 +1105,7 @@ void WebGLRenderingContext::drawArrays(unsigned long mode, long first, long coun
         }
     }
 
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
         return;
     }
@@ -1169,7 +1169,7 @@ void WebGLRenderingContext::drawElements(unsigned long mode, long count, unsigne
         }
     }
 
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
         return;
     }
@@ -2320,7 +2320,7 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height,
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
         return;
     }
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess()) {
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
         m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
         return;
     }
@@ -2520,8 +2520,15 @@ void WebGLRenderingContext::texImage2DBase(unsigned target, unsigned level, unsi
             return;
         }
     }
-    m_context->texImage2D(target, level, internalformat, width, height,
-                          border, format, type, pixels);
+    if (!pixels && !isResourceSafe()) {
+        bool succeed = m_context->texImage2DResourceSafe(target, level, internalformat, width, height,
+                                                         border, format, type);
+        if (!succeed)
+            return;
+    } else {
+        m_context->texImage2D(target, level, internalformat, width, height,
+                              border, format, type, pixels);
+    }
     tex->setLevelInfo(target, level, internalformat, width, height, type);
     cleanupAfterGraphicsCall(false);
 }
diff --git a/WebCore/platform/graphics/GraphicsContext3D.cpp b/WebCore/platform/graphics/GraphicsContext3D.cpp
index d6d1de7..7fae4a1 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.cpp
+++ b/WebCore/platform/graphics/GraphicsContext3D.cpp
@@ -31,27 +31,108 @@
 #include "GraphicsContext3D.h"
 
 #include "ArrayBufferView.h"
+#include "CheckedInt.h"
 #include "DrawingBuffer.h"
 #include "Image.h"
 #include "ImageData.h"
 
+#include <wtf/OwnArrayPtr.h>
+#include <wtf/PassOwnArrayPtr.h>
+
 namespace WebCore {
 
-static uint8_t convertColor16LittleTo8(uint16_t value)
-{
-    return value >> 8;
-}
+namespace {
+
+    unsigned bytesPerComponent(unsigned type)
+    {
+        switch (type) {
+        case GraphicsContext3D::UNSIGNED_BYTE:
+            return 1;
+        case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+        case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+        case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+            return 2;
+        case GraphicsContext3D::FLOAT:
+            return 4;
+        default:
+            return 1;
+        }
+    }
+
+    unsigned componentsPerPixel(unsigned format, unsigned type)
+    {
+        switch (type) {
+        case GraphicsContext3D::UNSIGNED_SHORT_5_6_5:
+        case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
+        case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
+        case GraphicsContext3D::FLOAT:
+            return 1;
+        default:
+            break;
+        }
+        switch (format) {
+        case GraphicsContext3D::ALPHA:
+        case GraphicsContext3D::LUMINANCE:
+            return 1;
+        case GraphicsContext3D::LUMINANCE_ALPHA:
+            return 2;
+        case GraphicsContext3D::RGB:
+            return 3;
+        case GraphicsContext3D::RGBA:
+            return 4;
+        default:
+            return 4;
+        }
+    }
+
+    // This function should only be called if width and height is non-zero and
+    // format/type are valid.  Return 0 if overflow happens.
+    size_t imageSizeInBytes(unsigned width, unsigned height, unsigned format, unsigned type)
+    {
+        ASSERT(width && height);
+        CheckedInt<uint32_t> checkedWidth(width);
+        CheckedInt<uint32_t> checkedHeight(height);
+        CheckedInt<uint32_t> checkedBytesPerPixel(bytesPerComponent(type) * componentsPerPixel(format, type));
+        CheckedInt<uint32_t> checkedSize = checkedWidth * checkedHeight * checkedBytesPerPixel;
+        if (checkedSize.valid())
+            return checkedSize.value();
+        return 0;
+    }
+
+    uint8_t convertColor16LittleTo8(uint16_t value)
+    {
+        return value >> 8;
+    }
+
+    uint8_t convertColor16BigTo8(uint16_t value)
+    {
+        return static_cast<uint8_t>(value & 0x00FF);
+    }
+
+} // anonymous namespace
 
-static uint8_t convertColor16BigTo8(uint16_t value)
-{
-    return static_cast<uint8_t>(value & 0x00FF);
-}
 
 PassRefPtr<DrawingBuffer> GraphicsContext3D::createDrawingBuffer(const IntSize& size)
 {
     return DrawingBuffer::create(this, size);
 }
 
+bool GraphicsContext3D::texImage2DResourceSafe(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type)
+{
+    OwnArrayPtr<unsigned char> zero;
+    if (width && height) {
+        size_t size = imageSizeInBytes(width, height, format, type);
+        if (!size) {
+            synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+            return false;
+        }
+        zero = adoptArrayPtr(new unsigned char[size]);
+        memset(zero.get(), 0, size);
+    }
+    texImage2D(target, level, internalformat, width, height, border, format, type, zero.get());
+    return true;
+}
+
 bool GraphicsContext3D::computeFormatAndTypeParameters(unsigned int format,
                                                        unsigned int type,
                                                        unsigned long* componentsPerPixel,
diff --git a/WebCore/platform/graphics/GraphicsContext3D.h b/WebCore/platform/graphics/GraphicsContext3D.h
index d455b65..f9540be 100644
--- a/WebCore/platform/graphics/GraphicsContext3D.h
+++ b/WebCore/platform/graphics/GraphicsContext3D.h
@@ -472,6 +472,10 @@ public:
     // like GL_FLOAT, GL_INT, etc.
     int sizeInBytes(int type);
 
+    // Helper to texImage2D with pixel==0 case: pixels are initialized to 0.
+    // Return true if no GL error is synthesized.
+    bool texImage2DResourceSafe(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type);
+
     bool isGLES2Compliant() const;
 
     //----------------------------------------------------------------------
diff --git a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
index adf84a9..ad961aa 100644
--- a/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/Canvas2DLayerChromium.cpp
@@ -68,7 +68,7 @@ void Canvas2DLayerChromium::updateContentsIfDirty()
         context->activeTexture(GraphicsContext3D::TEXTURE0);
         context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_textureId);
         IntSize size = m_drawingBuffer->size();
-        context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, size.width(), size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
+        context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, size.width(), size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE);
         // Set the min-mag filters to linear and wrap modes to GraphicsContext3D::CLAMP_TO_EDGE
         // to get around NPOT texture limitations of GLES.
         context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR);
diff --git a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
index 0395bc2..507c227 100644
--- a/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
+++ b/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
@@ -60,7 +60,7 @@ static unsigned generateColorTexture(GraphicsContext3D* context, const IntSize&
     context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::NEAREST);
     context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE);
     context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE);
-    context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, size.width(), size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0);
+    context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, size.width(), size.height(), 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE);
     context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, offscreenColorTexture, 0);
 
     return offscreenColorTexture;
diff --git a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
index 6d5f642..882baae 100644
--- a/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
+++ b/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
@@ -199,8 +199,7 @@ void LayerRendererChromium::prepareToDrawLayers(const IntRect& visibleRect, cons
     if (visibleRectWidth != m_rootLayerTextureWidth || visibleRectHeight != m_rootLayerTextureHeight) {
         m_rootLayerTextureWidth = visibleRectWidth;
         m_rootLayerTextureHeight = visibleRectHeight;
-
-        GLC(m_context.get(), m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, 0));
+        GLC(m_context.get(), m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, GraphicsContext3D::RGBA, m_rootLayerTextureWidth, m_rootLayerTextureHeight, 0, GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE));
 
         // Reset the current render surface to force an update of the viewport and
         // projection matrix next time useRenderSurface is called.
diff --git a/WebCore/platform/graphics/chromium/TextureManager.cpp b/WebCore/platform/graphics/chromium/TextureManager.cpp
index ac93aa3..9579ef9 100644
--- a/WebCore/platform/graphics/chromium/TextureManager.cpp
+++ b/WebCore/platform/graphics/chromium/TextureManager.cpp
@@ -156,7 +156,7 @@ unsigned TextureManager::requestTexture(TextureToken token, IntSize size, unsign
     // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE.
     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
-    GLC(m_context.get(), m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GraphicsContext3D::UNSIGNED_BYTE, 0));
+    GLC(m_context.get(), m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, format, size.width(), size.height(), 0, format, GraphicsContext3D::UNSIGNED_BYTE));
     TextureInfo info;
     info.size = size;
     info.format = format;
diff --git a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
index d6bd871..24fd732 100644
--- a/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
+++ b/WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
@@ -300,7 +300,7 @@ bool VideoLayerChromium::allocateTexturesIfNeeded(GraphicsContext3D* context, Vi
 void VideoLayerChromium::allocateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned textureFormat)
 {
     GLC(context, context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
-    GLC(context, context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, textureFormat, dimensions.width(), dimensions.height(), 0, textureFormat, GraphicsContext3D::UNSIGNED_BYTE, 0));
+    GLC(context, context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, textureFormat, dimensions.width(), dimensions.height(), 0, textureFormat, GraphicsContext3D::UNSIGNED_BYTE));
 }
 
 void VideoLayerChromium::updateTexture(GraphicsContext3D* context, unsigned textureId, const IntSize& dimensions, unsigned format, const void* data)
diff --git a/WebCore/platform/graphics/gpu/DrawingBuffer.cpp b/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
index c4c952b..0048bd3 100644
--- a/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/WebCore/platform/graphics/gpu/DrawingBuffer.cpp
@@ -117,9 +117,7 @@ void DrawingBuffer::reset(const IntSize& newSize)
         
         m_context->getIntegerv(Extensions3D::MAX_SAMPLES, &maxSampleCount);
         int sampleCount = std::min(8, maxSampleCount);
-        if (sampleCount > maxSampleCount)
-            sampleCount = maxSampleCount;
-        
+
         m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
 
         m_context->bindRenderbuffer(GraphicsContext3D::RENDERBUFFER, m_multisampleColorBuffer);
@@ -145,7 +143,7 @@ void DrawingBuffer::reset(const IntSize& newSize)
     m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
 
     m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_colorBuffer);
-    m_context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, internalColorFormat, m_size.width(), m_size.height(), 0, colorFormat, GraphicsContext3D::UNSIGNED_BYTE, 0);
+    m_context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, internalColorFormat, m_size.width(), m_size.height(), 0, colorFormat, GraphicsContext3D::UNSIGNED_BYTE);
     m_context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE, m_colorBuffer, 0);
     m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, 0);
     if (!multisample() && (attributes.stencil || attributes.depth)) {
@@ -166,57 +164,48 @@ void DrawingBuffer::reset(const IntSize& newSize)
     if (multisample())
         m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_multisampleFBO);
 
-    // Initialize renderbuffers to 0.
-    float clearColor[] = {0, 0, 0, 0}, clearDepth = 0;
-    int clearStencil = 0;
-    unsigned char colorMask[] = {true, true, true, true}, depthMask = true;
-    unsigned int stencilMask = 0xffffffff;
-    unsigned char isScissorEnabled = false;
-    unsigned char isDitherEnabled = false;
-    unsigned long clearMask = GraphicsContext3D::COLOR_BUFFER_BIT;
-    m_context->getFloatv(GraphicsContext3D::COLOR_CLEAR_VALUE, clearColor);
-    m_context->clearColor(0, 0, 0, 0);
-    m_context->getBooleanv(GraphicsContext3D::COLOR_WRITEMASK, colorMask);
-    m_context->colorMask(true, true, true, true);
-    if (attributes.depth) {
-        m_context->getFloatv(GraphicsContext3D::DEPTH_CLEAR_VALUE, &clearDepth);
-        m_context->clearDepth(1);
-        m_context->getBooleanv(GraphicsContext3D::DEPTH_WRITEMASK, &depthMask);
-        m_context->depthMask(true);
-        clearMask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
-    }
-    if (attributes.stencil) {
-        m_context->getIntegerv(GraphicsContext3D::STENCIL_CLEAR_VALUE, &clearStencil);
-        m_context->clearStencil(0);
-        m_context->getIntegerv(GraphicsContext3D::STENCIL_WRITEMASK, reinterpret_cast<int*>(&stencilMask));
-        m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, 0xffffffff);
-        clearMask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
-    }
-    isScissorEnabled = m_context->isEnabled(GraphicsContext3D::SCISSOR_TEST);
-    m_context->disable(GraphicsContext3D::SCISSOR_TEST);
-    isDitherEnabled = m_context->isEnabled(GraphicsContext3D::DITHER);
-    m_context->disable(GraphicsContext3D::DITHER);
-
-    m_context->clear(clearMask);
-
-    m_context->clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
-    m_context->colorMask(colorMask[0], colorMask[1], colorMask[2], colorMask[3]);
-    if (attributes.depth) {
-        m_context->clearDepth(clearDepth);
-        m_context->depthMask(depthMask);
-    }
-    if (attributes.stencil) {
-        m_context->clearStencil(clearStencil);
-        m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, stencilMask);
+    if (!m_context->getExtensions()->supports("GL_CHROMIUM_resource_safe")) {
+        // Initialize renderbuffers (depth/stencil).
+        float clearDepth = 0;
+        int clearStencil = 0;
+        unsigned char depthMask = true;
+        unsigned int stencilMask = 0xffffffff;
+        unsigned char isScissorEnabled = false;
+        unsigned long clearMask = 0;
+        if (attributes.depth) {
+            m_context->getFloatv(GraphicsContext3D::DEPTH_CLEAR_VALUE, &clearDepth);
+            m_context->clearDepth(1);
+            m_context->getBooleanv(GraphicsContext3D::DEPTH_WRITEMASK, &depthMask);
+            m_context->depthMask(true);
+            clearMask |= GraphicsContext3D::DEPTH_BUFFER_BIT;
+        }
+        if (attributes.stencil) {
+            m_context->getIntegerv(GraphicsContext3D::STENCIL_CLEAR_VALUE, &clearStencil);
+            m_context->clearStencil(0);
+            m_context->getIntegerv(GraphicsContext3D::STENCIL_WRITEMASK, reinterpret_cast<int*>(&stencilMask));
+            m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, 0xffffffff);
+            clearMask |= GraphicsContext3D::STENCIL_BUFFER_BIT;
+        }
+        if (clearMask) {
+            isScissorEnabled = m_context->isEnabled(GraphicsContext3D::SCISSOR_TEST);
+            m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+
+            m_context->clear(clearMask);
+
+            if (attributes.depth) {
+                m_context->clearDepth(clearDepth);
+                m_context->depthMask(depthMask);
+            }
+            if (attributes.stencil) {
+                m_context->clearStencil(clearStencil);
+                m_context->stencilMaskSeparate(GraphicsContext3D::FRONT, stencilMask);
+            }
+            if (isScissorEnabled)
+                m_context->enable(GraphicsContext3D::SCISSOR_TEST);
+            else
+                m_context->disable(GraphicsContext3D::SCISSOR_TEST);
+        }
     }
-    if (isScissorEnabled)
-        m_context->enable(GraphicsContext3D::SCISSOR_TEST);
-    else
-        m_context->disable(GraphicsContext3D::SCISSOR_TEST);
-    if (isDitherEnabled)
-        m_context->enable(GraphicsContext3D::DITHER);
-    else
-        m_context->disable(GraphicsContext3D::DITHER);
 
     m_context->flush();
     
diff --git a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
index a230384..d9764e6 100644
--- a/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
+++ b/WebCore/platform/graphics/gpu/SharedGraphicsContext3D.cpp
@@ -165,6 +165,10 @@ void SharedGraphicsContext3D::texParameteri(unsigned target, unsigned pname, int
 
 int SharedGraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels)
 {
+    if (!pixels) {
+        m_context->texImage2DResourceSafe(target, level, internalformat, width, height, border, format, type);
+        return 0;
+    }
     return m_context->texImage2D(target, level, internalformat, width, height, border, format, type, pixels);
 }
 
diff --git a/WebCore/platform/graphics/gpu/Texture.cpp b/WebCore/platform/graphics/gpu/Texture.cpp
index cfcaa63..e1f8114 100644
--- a/WebCore/platform/graphics/gpu/Texture.cpp
+++ b/WebCore/platform/graphics/gpu/Texture.cpp
@@ -106,15 +106,15 @@ PassRefPtr<Texture> Texture::create(GraphicsContext3D* context, Format format, i
 
         IntRect tileBoundsWithBorder = tiling.tileBoundsWithBorder(i);
 
-    unsigned int glFormat = 0;
-    unsigned int glType = 0;
-    bool swizzle;
-    convertFormat(context, format, &glFormat, &glType, &swizzle);
-    context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId);
-    context->texImage2D(GraphicsContext3D::TEXTURE_2D, 0, glFormat,
-            tileBoundsWithBorder.width(),
-            tileBoundsWithBorder.height(),
-            0, glFormat, glType, 0);
+        unsigned int glFormat = 0;
+        unsigned int glType = 0;
+        bool swizzle;
+        convertFormat(context, format, &glFormat, &glType, &swizzle);
+        context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId);
+        context->texImage2DResourceSafe(GraphicsContext3D::TEXTURE_2D, 0, glFormat,
+                                        tileBoundsWithBorder.width(),
+                                        tileBoundsWithBorder.height(),
+                                        0, glFormat, glType);
     }
     return adoptRef(new Texture(context, textureIds.leakPtr(), format, width, height, maxTextureSize));
 }
diff --git a/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp b/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
index 4cccd33..aa3b60e 100644
--- a/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
+++ b/WebCore/platform/graphics/opengl/GraphicsContext3DOpenGL.cpp
@@ -1327,8 +1327,11 @@ long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long
 
 int GraphicsContext3D::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels)
 {
+    if (width && height && !pixels) {
+        synthesizeGLError(INVALID_VALUE);
+        return 1;
+    }
     makeContextCurrent();
-
     unsigned openGLInternalFormat = internalformat;
     if (type == GL_FLOAT) {
         if (format == GL_RGBA)
diff --git a/WebKit/chromium/ChangeLog b/WebKit/chromium/ChangeLog
index ec97cbf..ffc8b90 100644
--- a/WebKit/chromium/ChangeLog
+++ b/WebKit/chromium/ChangeLog
@@ -1,3 +1,13 @@
+2010-12-21  Zhenyao Mo  <zmo at google.com>
+
+        Reviewed by Kenneth Russell.
+
+        WebGLRenderingContext needs to zero textures and renderbuffers
+        https://bugs.webkit.org/show_bug.cgi?id=49355
+
+        * src/WebGraphicsContext3DDefaultImpl.cpp:
+        (WebKit::WebGraphicsContext3DDefaultImpl::texImage2D): Generate an INVALID_VALUE if pixels==null is passed in.
+
 2010-12-20  Andrei Popescu  <andreip at google.com>
 
         Reviewed by Jeremy Orlow.
diff --git a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp
index d1ad1cc..9a4a362 100644
--- a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp
+++ b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp
@@ -1269,68 +1269,13 @@ DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, double, bool)
 
 DELEGATE_TO_GL_4(scissor, Scissor, long, long, unsigned long, unsigned long)
 
-unsigned bytesPerComponent(unsigned type)
-{
-    switch (type) {
-    case GL_BYTE:
-    case GL_UNSIGNED_BYTE:
-        return 1;
-    case GL_SHORT:
-    case GL_UNSIGNED_SHORT:
-    case GL_UNSIGNED_SHORT_5_6_5:
-    case GL_UNSIGNED_SHORT_4_4_4_4:
-    case GL_UNSIGNED_SHORT_5_5_5_1:
-        return 2;
-    case GL_FLOAT:
-        return 4;
-    default:
-        return 4;
-    }
-}
-
-unsigned componentsPerPixel(unsigned format, unsigned type)
-{
-    switch (type) {
-    case GL_UNSIGNED_SHORT_5_6_5:
-    case GL_UNSIGNED_SHORT_4_4_4_4:
-    case GL_UNSIGNED_SHORT_5_5_5_1:
-        return 1;
-    default:
-        break;
-    }
-    switch (format) {
-    case GL_LUMINANCE:
-        return 1;
-    case GL_LUMINANCE_ALPHA:
-        return 2;
-    case GL_RGB:
-        return 3;
-    case GL_RGBA:
-    case GL_BGRA_EXT:
-        return 4;
-    default:
-        return 4;
-    }
-}
-
-// N.B.:  This code does not protect against integer overflow (as the command
-// buffer implementation does), so it should not be considered robust enough
-// for use in the browser.  Since this implementation is only used for layout
-// tests, this should be ok for now.
-size_t imageSizeInBytes(unsigned width, unsigned height, unsigned format, unsigned type)
-{
-    return width * height * bytesPerComponent(type) * componentsPerPixel(format, type);
-}
-
 void WebGraphicsContext3DDefaultImpl::texImage2D(unsigned target, unsigned level, unsigned internalFormat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, const void* pixels)
 {
-    OwnArrayPtr<uint8> zero;
-    if (!pixels) {
-        size_t size = imageSizeInBytes(width, height, format, type);
-        zero.set(new uint8[size]);
-        memset(zero.get(), 0, size);
-        pixels = zero.get();
+    if (width && height && !pixels) {
+        synthesizeGLError(GL_INVALID_VALUE);
+        return;
     }
+    makeContextCurrent();
     glTexImage2D(target, level, internalFormat, width, height, border, format, type, pixels);
 }
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list