[Chromium] Prevent DrawingBuffer instances from corrupting the active
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Nov 2011 06:06:31 +0000 (06:06 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Nov 2011 06:06:31 +0000 (06:06 +0000)
texture state of the WebGL contexts. The DrawingBuffer now tracks the
state of texture unit 0, and the active texture unit, so that state can
be restored.
https://bugs.webkit.org/show_bug.cgi?id=73033

Patch by Jeff Timanus <twiz@chromium.org> on 2011-11-23
Reviewed by Kenneth Russell.

Test: fast/canvas/webgl/webgl-texture-binding-preserved.html

Source/WebCore:

* html/canvas/WebGLRenderingContext.cpp:
(WebCore::WebGLRenderingContext::activeTexture):
(WebCore::WebGLRenderingContext::bindTexture):
* platform/graphics/chromium/DrawingBufferChromium.cpp:
(WebCore::DrawingBuffer::DrawingBuffer):
(WebCore::DrawingBuffer::publishToPlatformLayer):
* platform/graphics/gpu/DrawingBuffer.h:
(WebCore::DrawingBuffer::setTexture2DBinding):
(WebCore::DrawingBuffer::setActiveTextureUnit):
* platform/graphics/gpu/mac/DrawingBufferMac.mm:
(WebCore::DrawingBuffer::DrawingBuffer):
* platform/graphics/gpu/qt/DrawingBufferQt.cpp:
(WebCore::DrawingBuffer::DrawingBuffer):
* platform/graphics/gtk/DrawingBufferGtk.cpp:
(WebCore::DrawingBuffer::DrawingBuffer):

LayoutTests:

* fast/canvas/webgl/webgl-texture-binding-preserved-expected.txt: Added.
* fast/canvas/webgl/webgl-texture-binding-preserved.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@101120 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved-expected.txt [new file with mode: 0755]
LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved.html [new file with mode: 0755]
Source/WebCore/ChangeLog
Source/WebCore/html/canvas/WebGLRenderingContext.cpp
Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm
Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp
Source/WebCore/platform/graphics/gtk/DrawingBufferGtk.cpp

index 096de7c..5b1df40 100644 (file)
@@ -1,3 +1,18 @@
+2011-11-23  Jeff Timanus  <twiz@chromium.org>
+
+        [Chromium]  Prevent DrawingBuffer instances from corrupting the active
+        texture state of the WebGL contexts. The DrawingBuffer now tracks the
+        state of texture unit 0, and the active texture unit, so that state can
+        be restored.
+        https://bugs.webkit.org/show_bug.cgi?id=73033
+
+        Reviewed by Kenneth Russell.
+
+        Test: fast/canvas/webgl/webgl-texture-binding-preserved.html
+
+        * fast/canvas/webgl/webgl-texture-binding-preserved-expected.txt: Added.
+        * fast/canvas/webgl/webgl-texture-binding-preserved.html: Added.
+
 2011-11-23  Dmitry Lomov  <dslomov@google.com>
 
         https://bugs.webkit.org/show_bug.cgi?id=73054
diff --git a/LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved-expected.txt b/LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved-expected.txt
new file mode 100755 (executable)
index 0000000..8b621ad
--- /dev/null
@@ -0,0 +1,9 @@
+Checks that painting WebGL contents doesn't pollute the context state.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS successfullyParsed is true
+
+TEST COMPLETE
+PASS Should have rendered blue.
+
diff --git a/LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved.html b/LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved.html
new file mode 100755 (executable)
index 0000000..06a1b7b
--- /dev/null
@@ -0,0 +1,69 @@
+<html>
+<head>
+<script src="../../js/resources/js-test-pre.js"></script>
+<script src="resources/webgl-test.js"></script>
+<script src="resources/webgl-test-utils.js"> </script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("Checks that painting WebGL contents doesn't pollute the context state.");
+
+var wtu = WebGLTestUtils;
+
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    layoutTestController.waitUntilDone();
+}
+
+var canvas;
+var context;
+var requestAnimationFrame;
+
+function draw() {
+  // Draw a blue quad to the screen.  The compositor should have executed
+  // before reaching this point.  If the texture state was corruted, then 
+  // a red quad will be drawn.  See crbug.com/105045.
+  wtu.drawQuad(context);
+
+  wtu.checkCanvasRect(context, 0, 0, 1, 1, [0, 0, 255, 255], "Should have rendered blue.", 1);
+  if (window.layoutTestController)
+      layoutTestController.notifyDone();
+}
+
+window.onload = function()
+{
+  if (window.initNonKhronosFramework) {
+    window.initNonKhronosFramework(false);
+  }
+
+  canvas = document.getElementById("webgl-canvas");
+  canvas.width = 50; canvas.height = 50;
+  context = create3DContext(canvas);
+
+  requestAnimationFrame = window.webkitRequestAnimationFrame
+
+  var program = wtu.setupTexturedQuad(context);
+  var bufferObjects = wtu.setupUnitQuad(context);
+  var texture = wtu.createColoredTexture(context, 1, 1, [0, 0, 255, 255]);
+
+  context.uniform1i(context.getUniformLocation(program, "tex"), 0);
+
+  context.activeTexture(context.TEXTURE_0 + 5);
+  context.bindTexture(context.TEXTURE_2D, texture);
+
+  context.viewport(0, 0, canvas.width, canvas.height);
+
+  context.clearColor(255, 0, 0, 255);
+  context.clear(context.COLOR_BUFFER_BIT | context.DEPTH_BUFFER_BIT);
+
+  // We need to ensure that the compositor has run before the drawing
+  // takes place.
+  setTimeout(draw, 100);
+}
+</script>
+<script src="../../js/resources/js-test-post.js"></script>
+<canvas id="webgl-canvas" width="32px" height="32px"></canvas>
+</body>
+</html>
index 45b31e0..6b24aef 100644 (file)
@@ -1,3 +1,31 @@
+2011-11-23  Jeff Timanus  <twiz@chromium.org>
+
+        [Chromium]  Prevent DrawingBuffer instances from corrupting the active
+        texture state of the WebGL contexts. The DrawingBuffer now tracks the
+        state of texture unit 0, and the active texture unit, so that state can
+        be restored.
+        https://bugs.webkit.org/show_bug.cgi?id=73033
+
+        Reviewed by Kenneth Russell.
+
+        Test: fast/canvas/webgl/webgl-texture-binding-preserved.html
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore::WebGLRenderingContext::activeTexture):
+        (WebCore::WebGLRenderingContext::bindTexture):
+        * platform/graphics/chromium/DrawingBufferChromium.cpp:
+        (WebCore::DrawingBuffer::DrawingBuffer):
+        (WebCore::DrawingBuffer::publishToPlatformLayer):
+        * platform/graphics/gpu/DrawingBuffer.h:
+        (WebCore::DrawingBuffer::setTexture2DBinding):
+        (WebCore::DrawingBuffer::setActiveTextureUnit):
+        * platform/graphics/gpu/mac/DrawingBufferMac.mm:
+        (WebCore::DrawingBuffer::DrawingBuffer):
+        * platform/graphics/gpu/qt/DrawingBufferQt.cpp:
+        (WebCore::DrawingBuffer::DrawingBuffer):
+        * platform/graphics/gtk/DrawingBufferGtk.cpp:
+        (WebCore::DrawingBuffer::DrawingBuffer):
+
 2011-11-23  Luke Macpherson   <macpherson@chromium.org>
 
         CSSValue: reorder ClassType enum to allow faster comparisons, add COMPILE_ASSERT on class size.
index dd7d419..30b8ff6 100644 (file)
@@ -758,6 +758,10 @@ void WebGLRenderingContext::activeTexture(GC3Denum texture, ExceptionCode& ec)
     }
     m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
     m_context->activeTexture(texture);
+
+    if (m_drawingBuffer)
+        m_drawingBuffer->setActiveTextureUnit(texture);
+
     cleanupAfterGraphicsCall(false);
 }
 
@@ -888,6 +892,10 @@ void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture,
     if (target == GraphicsContext3D::TEXTURE_2D) {
         m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
         maxLevel = m_maxTextureLevel;
+
+        if (m_drawingBuffer && !m_activeTextureUnit)
+            m_drawingBuffer->setTexture2DBinding(objectOrZero(texture));
+
     } else if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) {
         m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
         maxLevel = m_maxCubeMapTextureLevel;
index c5bebaa..bf37bbc 100644 (file)
@@ -62,6 +62,8 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
                              bool separateBackingTexture)
     : m_separateBackingTexture(separateBackingTexture)
     , m_scissorEnabled(false)
+    , m_texture2DBinding(0)
+    , m_activeTextureUnit(GraphicsContext3D::TEXTURE0)
     , m_context(context)
     , m_size(-1, -1)
     , m_multisampleExtensionSupported(multisampleExtensionSupported)
@@ -118,9 +120,16 @@ void DrawingBuffer::publishToPlatformLayer()
 
     if (m_separateBackingTexture) {
         m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
+
+        // This path always uses TEXTURE0, and restores its state below.
+        m_context->activeTexture(GraphicsContext3D::TEXTURE0);
         m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_backingColorBuffer);
+
         unsigned colorFormat = m_context->getContextAttributes().alpha ? GraphicsContext3D::RGBA : GraphicsContext3D::RGB;
         m_context->copyTexImage2D(GraphicsContext3D::TEXTURE_2D, 0, colorFormat, 0, 0, size().width(), size().height(), 0);
+
+        m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, m_texture2DBinding);
+        m_context->activeTexture(m_activeTextureUnit);
     }
 
     if (multisample())
index a139f72..039af5c 100644 (file)
@@ -85,6 +85,14 @@ public:
     // can be disabled during calls to commit.
     void setScissorEnabled(bool scissorEnabled) { m_scissorEnabled = scissorEnabled; }
 
+    // The DrawingBuffer needs to track the texture bound to texture unit 0.
+    // The bound texture is tracked to avoid costly queries during rendering.
+    void setTexture2DBinding(GC3Dint texture) { m_texture2DBinding = texture; }
+
+    // Track the currently active texture unit. Texture unit 0 is used as host for a scratch
+    // texture.
+    void setActiveTextureUnit(GC3Dint textureUnit) { m_activeTextureUnit = textureUnit; }
+
     bool multisample() const;
 
     Platform3DObject platformColorBuffer() const;
@@ -112,6 +120,8 @@ private:
 
     bool m_separateBackingTexture;
     bool m_scissorEnabled;
+    Platform3DObject m_texture2DBinding;
+    GC3Denum m_activeTextureUnit;
 
     RefPtr<GraphicsContext3D> m_context;
     IntSize m_size;
index 7c25d97..3fda6a3 100644 (file)
@@ -43,6 +43,8 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
                              bool separateBackingTexture)
     : m_separateBackingTexture(separateBackingTexture)
     , m_scissorEnabled(false)
+    , m_texture2DBinding(0)
+    , m_activeTextureUnit(GraphicsContext3D::TEXTURE0)
     , m_context(context)
     , m_size(-1, -1)
     , m_multisampleExtensionSupported(multisampleExtensionSupported)
index ef67afe..a592edc 100644 (file)
@@ -38,6 +38,8 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
                              bool separateBackingTexture)
     : m_separateBackingTexture(separateBackingTexture)
     , m_scissorEnabled(false)
+    , m_texture2DBinding(0)
+    , m_activeTextureUnit(GraphicsContext3D::TEXTURE0)
     , m_context(context)
     , m_size(-1, -1)
     , m_multisampleExtensionSupported(multisampleExtensionSupported)
index f9a248b..067b9c7 100644 (file)
@@ -40,6 +40,8 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
                              bool separateBackingTexture)
     : m_separateBackingTexture(separateBackingTexture)
     , m_scissorEnabled(false)
+    , m_texture2DBinding(0)
+    , m_activeTextureUnit(GraphicsContext3D::TEXTURE0)
     , m_context(context)
     , m_size(-1, -1)
     , m_multisampleExtensionSupported(multisampleExtensionSupported)