[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