Title: [114961] trunk
Revision
114961
Author
z...@google.com
Date
2012-04-23 16:22:03 -0700 (Mon, 23 Apr 2012)

Log Message

framebuffer binding should not be changed after canvas resize or compositing
https://bugs.webkit.org/show_bug.cgi?id=84609

Reviewed by Kenneth Russell.

Source/WebCore: 

Test: fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize.html

* html/canvas/WebGLRenderingContext.cpp: set framebuffer binding to DrawingBuffer.
(WebCore):
(WebCore::WebGLRenderingContext::bindFramebuffer):
(WebCore::WebGLRenderingContext::deleteFramebuffer):
(WebCore::WebGLRenderingContext::loseContextImpl):
* platform/graphics/cairo/DrawingBufferCairo.cpp: initialize m_framebufferBinding.
(WebCore::DrawingBuffer::DrawingBuffer):
* platform/graphics/chromium/DrawingBufferChromium.cpp: Ditto.
(WebCore::DrawingBuffer::DrawingBuffer):
* platform/graphics/chromium/WebGLLayerChromium.cpp: Recover framebuffer binding after update().
(WebCore::WebGLLayerChromium::update):
* platform/graphics/gpu/DrawingBuffer.cpp: Add a function to restore framebuffer binding.
(WebCore::DrawingBuffer::restoreFramebufferBinding):
(WebCore):
* platform/graphics/gpu/DrawingBuffer.h: Ditto.
(WebCore::DrawingBuffer::setTexture2DBinding):
(DrawingBuffer):
(WebCore::DrawingBuffer::setFramebufferBinding):
* platform/graphics/gpu/mac/DrawingBufferMac.mm: initialize m_framebufferBinding.
(WebCore::DrawingBuffer::DrawingBuffer):
* platform/graphics/gpu/qt/DrawingBufferQt.cpp: initialize m_framebufferBinding.
(WebCore::DrawingBuffer::DrawingBuffer):

LayoutTests: 

* fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize-expected.txt: Added.
* fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize.html: Added.
* fast/canvas/webgl/resources/webgl-test-utils.js: Sync with khronos side (partial)
(WebGLTestUtils.):
(WebGLTestUtils):

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (114960 => 114961)


--- trunk/LayoutTests/ChangeLog	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/LayoutTests/ChangeLog	2012-04-23 23:22:03 UTC (rev 114961)
@@ -1,3 +1,16 @@
+2012-04-23  Zhenyao Mo  <z...@google.com>
+
+        framebuffer binding should not be changed after canvas resize or compositing
+        https://bugs.webkit.org/show_bug.cgi?id=84609
+
+        Reviewed by Kenneth Russell.
+
+        * fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize-expected.txt: Added.
+        * fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize.html: Added.
+        * fast/canvas/webgl/resources/webgl-test-utils.js: Sync with khronos side (partial)
+        (WebGLTestUtils.):
+        (WebGLTestUtils):
+
 2012-04-23  Oliver Hunt  <oli...@apple.com>
 
         Call instruction for the baseline JIT stores origin info in wrong callframe

Added: trunk/LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize-expected.txt (0 => 114961)


--- trunk/LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize-expected.txt	2012-04-23 23:22:03 UTC (rev 114961)
@@ -0,0 +1,26 @@
+Verifies that GL framebuffer bindings do not change when canvas is resized
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS fboSize < canvas.width is true
+PASS gl.checkFramebufferStatus(gl.FRAMEBUFFER) is gl.FRAMEBUFFER_COMPLETE
+test before resizing canvas
+PASS should be blue
+PASS area outside fbo should be transparent black
+PASS should be green
+PASS area outside fbo should be transparent black
+test after resizing canvas
+PASS should be blue
+PASS area outside fbo should be transparent black
+PASS should be green
+PASS area outside fbo should be transparent black
+test after resizing canvas and waiting for compositing
+PASS should be blue
+PASS area outside fbo should be transparent black
+PASS should be green
+PASS area outside fbo should be transparent black
+PASS getError was expected value: NO_ERROR : Should be no errors.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Property changes on: trunk/LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize-expected.txt
___________________________________________________________________

Added: svn:eol-style

Added: trunk/LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize.html (0 => 114961)


--- trunk/LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize.html	                        (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize.html	2012-04-23 23:22:03 UTC (rev 114961)
@@ -0,0 +1,83 @@
+
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>Verifies that GL framebuffer bindings do not change when canvas is resized</title>
+<link rel="stylesheet" href=""
+<script src=""
+<script src=""
+<script src=""
+</head>
+<body>
+<canvas id="example" width="4px" height="4px"></canvas>
+<div id="description"></div>
+<div id="console"></div>
+<script>
+description("Verifies that GL framebuffer bindings do not change when canvas is resized");
+
+if (window.initNonKhronosFramework) {
+  window.initNonKhronosFramework(true);
+}
+
+var err;
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("example");
+var gl = wtu.create3DContext(canvas);
+var green = [0, 255, 0, 255];
+var blue = [0, 0, 255, 255];
+var fboSize = 2;
+shouldBeTrue("fboSize < canvas.width");
+var fbo = gl.createFramebuffer();
+gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
+var fboTex = gl.createTexture();
+gl.activeTexture(gl.TEXTURE1);
+gl.bindTexture(gl.TEXTURE_2D, fboTex);
+gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, fboTex, 0);
+gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, fboSize, fboSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
+gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
+shouldBe("gl.checkFramebufferStatus(gl.FRAMEBUFFER)", "gl.FRAMEBUFFER_COMPLETE");
+
+function checkFBO(color, msg) {
+  wtu.checkCanvasRect(gl, 0, 0, fboSize, fboSize, color, msg);
+  wtu.checkCanvasRect(gl, fboSize, fboSize, fboSize, fboSize, [0, 0, 0, 0], "area outside fbo should be transparent black");
+}
+
+// The FBO is 2x2 and it's bound so clearing should clear a 2x2 area
+// and calling read pixels should read the clear color in that 2x2 area
+// and 0,0,0,0 outside that area.
+//
+// If the FBO is no longer bound because of a WebGL implementation error
+// then likely the clear will clear the backbuffer and reading outside
+// the 2x2 area will not be 0,0,0,0
+
+function test() {
+  gl.clearColor(0, 0, 1, 1);
+  gl.clear(gl.COLOR_BUFFER_BIT);
+  checkFBO(blue, "should be blue");
+  gl.clearColor(0, 1, 0, 1);
+  gl.clear(gl.COLOR_BUFFER_BIT);
+  checkFBO(green, "should be green");
+}
+
+debug("test before resizing canvas");
+test();
+debug("test after resizing canvas");
+canvas.width = 8;
+test();
+debug("test after resizing canvas and waiting for compositing");
+canvas.width = 16;
+wtu.waitFrames(5, function() {
+  test();
+  finishTest();
+  glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors.");
+});
+
+successfullyParsed = true;
+</script>
+</body>
+</html>
+
Property changes on: trunk/LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize.html
___________________________________________________________________

Added: svn:eol-style

Modified: trunk/LayoutTests/fast/canvas/webgl/resources/webgl-test-utils.js (114960 => 114961)


--- trunk/LayoutTests/fast/canvas/webgl/resources/webgl-test-utils.js	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/LayoutTests/fast/canvas/webgl/resources/webgl-test-utils.js	2012-04-23 23:22:03 UTC (rev 114961)
@@ -1104,7 +1104,66 @@
   return args;
 };
 
+/**
+ * Provides requestAnimationFrame in a cross browser way.
+ */
+var requestAnimFrameImpl_;
+
+var requestAnimFrame = function(callback, element) {
+  if (!requestAnimFrameImpl_) {
+    requestAnimFrameImpl_ = function() {
+      var functionNames = [
+        "requestAnimationFrame",
+        "webkitRequestAnimationFrame",
+        "mozRequestAnimationFrame",
+        "oRequestAnimationFrame",
+        "msRequestAnimationFrame"
+      ];
+      for (var jj = 0; jj < functionNames.length; ++jj) {
+        var functionName = functionNames[jj];
+        if (window[functionName]) {
+          return function(name) {
+            return function(callback, element) {
+              return window[name].call(window, callback, element);
+            };
+          }(functionName);
+        }
+      }
+      return function(callback, element) {
+           return window.setTimeout(callback, 1000 / 70);
+        };
+    }();
+  }
+
+  return requestAnimFrameImpl_(callback, element);
+};
+
+/**
+ * Provides cancelAnimationFrame in a cross browser way.
+ */
+var cancelAnimFrame = (function() {
+  return window.cancelAnimationFrame ||
+         window.webkitCancelAnimationFrame ||
+         window.mozCancelAnimationFrame ||
+         window.oCancelAnimationFrame ||
+         window.msCancelAnimationFrame ||
+         window.clearTimeout;
+})();
+
+var waitFrames = function(frames, callback) {
+  var countDown = function() {
+    if (frames == 0) {
+      callback();
+    } else {
+      --frames;
+      requestAnimFrame(countDown);
+    }
+  };
+  countDown();
+};
+
 return {
+  cancelAnimFrame: cancelAnimFrame,
   create3DContext: create3DContext,
   create3DContextWithWrapperThatThrowsOnGLError:
     create3DContextWithWrapperThatThrowsOnGLError,
@@ -1147,6 +1206,8 @@
   shouldGenerateGLError: shouldGenerateGLError,
   readFile: readFile,
   readFileList: readFileList,
+  requestAnimFrame: requestAnimFrame,
+  waitFrames: waitFrames,
 
   none: false
 };

Modified: trunk/Source/WebCore/ChangeLog (114960 => 114961)


--- trunk/Source/WebCore/ChangeLog	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/Source/WebCore/ChangeLog	2012-04-23 23:22:03 UTC (rev 114961)
@@ -1,3 +1,35 @@
+2012-04-23  Zhenyao Mo  <z...@google.com>
+
+        framebuffer binding should not be changed after canvas resize or compositing
+        https://bugs.webkit.org/show_bug.cgi?id=84609
+
+        Reviewed by Kenneth Russell.
+
+        Test: fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize.html
+
+        * html/canvas/WebGLRenderingContext.cpp: set framebuffer binding to DrawingBuffer.
+        (WebCore):
+        (WebCore::WebGLRenderingContext::bindFramebuffer):
+        (WebCore::WebGLRenderingContext::deleteFramebuffer):
+        (WebCore::WebGLRenderingContext::loseContextImpl):
+        * platform/graphics/cairo/DrawingBufferCairo.cpp: initialize m_framebufferBinding.
+        (WebCore::DrawingBuffer::DrawingBuffer):
+        * platform/graphics/chromium/DrawingBufferChromium.cpp: Ditto.
+        (WebCore::DrawingBuffer::DrawingBuffer):
+        * platform/graphics/chromium/WebGLLayerChromium.cpp: Recover framebuffer binding after update().
+        (WebCore::WebGLLayerChromium::update):
+        * platform/graphics/gpu/DrawingBuffer.cpp: Add a function to restore framebuffer binding.
+        (WebCore::DrawingBuffer::restoreFramebufferBinding):
+        (WebCore):
+        * platform/graphics/gpu/DrawingBuffer.h: Ditto.
+        (WebCore::DrawingBuffer::setTexture2DBinding):
+        (DrawingBuffer):
+        (WebCore::DrawingBuffer::setFramebufferBinding):
+        * platform/graphics/gpu/mac/DrawingBufferMac.mm: initialize m_framebufferBinding.
+        (WebCore::DrawingBuffer::DrawingBuffer):
+        * platform/graphics/gpu/qt/DrawingBufferQt.cpp: initialize m_framebufferBinding.
+        (WebCore::DrawingBuffer::DrawingBuffer):
+
 2012-04-23  Victor Carbune  <vcarb...@adobe.com>
 
         Simplify volume slider rendering

Modified: trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp (114960 => 114961)


--- trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/Source/WebCore/html/canvas/WebGLRenderingContext.cpp	2012-04-23 23:22:03 UTC (rev 114961)
@@ -920,6 +920,8 @@
         return;
     }
     m_framebufferBinding = buffer;
+    if (m_drawingBuffer)
+        m_drawingBuffer->setFramebufferBinding(objectOrZero(m_framebufferBinding.get()));
     if (!m_framebufferBinding && m_drawingBuffer) {
         // Instead of binding fb 0, bind the drawing buffer.
         m_drawingBuffer->bind();
@@ -1533,10 +1535,11 @@
         return;
     if (framebuffer == m_framebufferBinding) {
         m_framebufferBinding = 0;
-        // Have to call bindFramebuffer here to bind back to internal fbo.
-        if (m_drawingBuffer)
+        if (m_drawingBuffer) {
+            m_drawingBuffer->setFramebufferBinding(0);
+            // Have to call bindFramebuffer here to bind back to internal fbo.
             m_drawingBuffer->bind();
-        else
+        } else
             m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0);
     }
 }
@@ -4307,8 +4310,9 @@
     detachAndRemoveAllObjects();
 
     if (m_drawingBuffer) {
-        // Make absolutely sure we do not refer to an already-deleted texture.
+        // Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
         m_drawingBuffer->setTexture2DBinding(0);
+        m_drawingBuffer->setFramebufferBinding(0);
     }
 
     // There is no direct way to clear errors from a GL implementation and

Modified: trunk/Source/WebCore/platform/graphics/cairo/DrawingBufferCairo.cpp (114960 => 114961)


--- trunk/Source/WebCore/platform/graphics/cairo/DrawingBufferCairo.cpp	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/Source/WebCore/platform/graphics/cairo/DrawingBufferCairo.cpp	2012-04-23 23:22:03 UTC (rev 114961)
@@ -43,6 +43,7 @@
     , m_alpha(alpha)
     , m_scissorEnabled(false)
     , m_texture2DBinding(0)
+    , m_framebufferBinding(0)
     , m_activeTextureUnit(GraphicsContext3D::TEXTURE0)
     , m_context(context)
     , m_size(-1, -1)

Modified: trunk/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp (114960 => 114961)


--- trunk/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp	2012-04-23 23:22:03 UTC (rev 114961)
@@ -69,6 +69,7 @@
     , m_alpha(alpha)
     , m_scissorEnabled(false)
     , m_texture2DBinding(0)
+    , m_framebufferBinding(0)
     , m_activeTextureUnit(GraphicsContext3D::TEXTURE0)
     , m_context(context)
     , m_size(-1, -1)

Modified: trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp (114960 => 114961)


--- trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/Source/WebCore/platform/graphics/chromium/WebGLLayerChromium.cpp	2012-04-23 23:22:03 UTC (rev 114961)
@@ -86,6 +86,8 @@
     m_textureId = m_drawingBuffer->frontColorBuffer();
     if (m_drawingBuffer->requiresCopyFromBackToFrontBuffer())
         updater.appendCopy(m_drawingBuffer->colorBuffer(), m_textureId, bounds());
+
+    m_drawingBuffer->restoreFramebufferBinding();
 }
 
 void WebGLLayerChromium::pushPropertiesTo(CCLayerImpl* layer)

Modified: trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp (114960 => 114961)


--- trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.cpp	2012-04-23 23:22:03 UTC (rev 114961)
@@ -336,6 +336,14 @@
     m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo);
 }
 
+void DrawingBuffer::restoreFramebufferBinding()
+{
+    if (!m_context || !m_framebufferBinding)
+        return;
+
+    m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_framebufferBinding);
+}
+
 bool DrawingBuffer::multisample() const
 {
     return m_context && m_context->getContextAttributes().antialias && m_multisampleExtensionSupported;

Modified: trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h (114960 => 114961)


--- trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/Source/WebCore/platform/graphics/gpu/DrawingBuffer.h	2012-04-23 23:22:03 UTC (rev 114961)
@@ -99,8 +99,15 @@
 
     // 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; }
+    void setTexture2DBinding(Platform3DObject texture) { m_texture2DBinding = texture; }
 
+    // The DrawingBuffer needs to track the currently bound framebuffer so it
+    // restore the binding when needed.
+    void setFramebufferBinding(Platform3DObject fbo) { m_framebufferBinding = fbo; }
+
+    // Bind to the m_framebufferBinding if it's not 0.
+    void restoreFramebufferBinding();
+
     // Track the currently active texture unit. Texture unit 0 is used as host for a scratch
     // texture.
     void setActiveTextureUnit(GC3Dint textureUnit) { m_activeTextureUnit = textureUnit; }
@@ -135,6 +142,7 @@
     AlphaRequirement m_alpha;
     bool m_scissorEnabled;
     Platform3DObject m_texture2DBinding;
+    Platform3DObject m_framebufferBinding;
     GC3Denum m_activeTextureUnit;
 
     RefPtr<GraphicsContext3D> m_context;

Modified: trunk/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm (114960 => 114961)


--- trunk/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/Source/WebCore/platform/graphics/gpu/mac/DrawingBufferMac.mm	2012-04-23 23:22:03 UTC (rev 114961)
@@ -46,6 +46,7 @@
     , m_alpha(alpha)
     , m_scissorEnabled(false)
     , m_texture2DBinding(0)
+    , m_framebufferBinding(0)
     , m_activeTextureUnit(GraphicsContext3D::TEXTURE0)
     , m_context(context)
     , m_size(-1, -1)

Modified: trunk/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp (114960 => 114961)


--- trunk/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp	2012-04-23 23:13:13 UTC (rev 114960)
+++ trunk/Source/WebCore/platform/graphics/gpu/qt/DrawingBufferQt.cpp	2012-04-23 23:22:03 UTC (rev 114961)
@@ -41,6 +41,7 @@
     , m_alpha(alpha)
     , m_scissorEnabled(false)
     , m_texture2DBinding(0)
+    , m_framebufferBinding(0)
     , m_activeTextureUnit(GraphicsContext3D::TEXTURE0)
     , m_context(context)
     , m_size(-1, -1)
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to