WebGL should not flip textures on presentation if contents are unchanged
authorjamesr@google.com <jamesr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Aug 2012 22:42:30 +0000 (22:42 +0000)
committerjamesr@google.com <jamesr@google.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Aug 2012 22:42:30 +0000 (22:42 +0000)
https://bugs.webkit.org/show_bug.cgi?id=94961

Reviewed by Kenneth Russell.

Source/WebCore:

For WebGL contexts where antialias and preserveDrawingBuffer are false, chromium implements DrawingBuffer using
two textures and flips them on presentation. If the page hasn't actually rendered anything into the WebGL
context since the last presentation, this makes an old frame available. This fixes the bug by marking the
DrawingBuffer when its contents change.

Test: compositing/webgl/webgl-repaint.html

* html/canvas/WebGLRenderingContext.cpp:
(WebCore):
(WebCore::WebGLRenderingContext::markContextChanged):
* platform/graphics/chromium/DrawingBufferChromium.cpp:
(WebCore::DrawingBuffer::DrawingBuffer):
(WebCore::DrawingBuffer::prepareBackBuffer):
* platform/graphics/gpu/DrawingBuffer.h:
(WebCore::DrawingBuffer::markContentsChanged):
(DrawingBuffer):

Tools:

Run some compositing webgl tests in threaded mode to catch regressions specific to that mode.

* Scripts/webkitpy/layout_tests/port/chromium.py:
(ChromiumPort.virtual_test_suites):

LayoutTests:

Adds a test to make sure multiple displays without any WebGL draw calls leave the WebGL output alone.

* compositing/webgl/webgl-repaint-expected.png: Added.
* compositing/webgl/webgl-repaint-expected.txt: Added.
* compositing/webgl/webgl-repaint.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/compositing/webgl/webgl-repaint-expected.png [new file with mode: 0644]
LayoutTests/compositing/webgl/webgl-repaint-expected.txt [new file with mode: 0644]
LayoutTests/compositing/webgl/webgl-repaint.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/html/canvas/WebGLRenderingContext.cpp
Source/WebCore/platform/graphics/chromium/DrawingBufferChromium.cpp
Source/WebCore/platform/graphics/gpu/DrawingBuffer.h
Tools/ChangeLog
Tools/Scripts/webkitpy/layout_tests/port/chromium.py

index c59653f..dfbda56 100644 (file)
@@ -1,3 +1,16 @@
+2012-08-24  James Robinson  <jamesr@chromium.org>
+
+        WebGL should not flip textures on presentation if contents are unchanged
+        https://bugs.webkit.org/show_bug.cgi?id=94961
+
+        Reviewed by Kenneth Russell.
+
+        Adds a test to make sure multiple displays without any WebGL draw calls leave the WebGL output alone.
+
+        * compositing/webgl/webgl-repaint-expected.png: Added.
+        * compositing/webgl/webgl-repaint-expected.txt: Added.
+        * compositing/webgl/webgl-repaint.html: Added.
+
 2012-08-27  Leo Yang  <leoyang@rim.com>
 
         [BlackBerry] Test expectation for fast/js/constructor-length.html
diff --git a/LayoutTests/compositing/webgl/webgl-repaint-expected.png b/LayoutTests/compositing/webgl/webgl-repaint-expected.png
new file mode 100644 (file)
index 0000000..babbb59
Binary files /dev/null and b/LayoutTests/compositing/webgl/webgl-repaint-expected.png differ
diff --git a/LayoutTests/compositing/webgl/webgl-repaint-expected.txt b/LayoutTests/compositing/webgl/webgl-repaint-expected.txt
new file mode 100644 (file)
index 0000000..8b13789
--- /dev/null
@@ -0,0 +1 @@
+
diff --git a/LayoutTests/compositing/webgl/webgl-repaint.html b/LayoutTests/compositing/webgl/webgl-repaint.html
new file mode 100644 (file)
index 0000000..7c9e852
--- /dev/null
@@ -0,0 +1,65 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style type="text/css" media="screen">
+canvas {
+    margin: 20px;
+    width: 200px;
+    height: 200px;
+    padding: 0 0;
+}
+.border {
+    border: 1px solid black;
+}
+</style>
+<script>
+if (window.testRunner)
+    testRunner.overridePreference("WebKitWebGLEnabled", "1");
+
+function initWebGL()
+{
+    var canvas = document.getElementById('canvas');
+    var gl = canvas.getContext("experimental-webgl", {'antialias': false});
+    if (!gl) {
+        alert("No WebGL context found");
+        return null;
+    }
+
+    return gl;
+}
+
+var gl = null;
+
+function init()
+{
+  gl = initWebGL();
+  gl.viewport(0, 0, 200, 200);
+  gl.clearColor(1, 0, 0, 1); // red
+  gl.clear(gl.COLOR_BUFFER_BIT);
+  if (window.testRunner) {
+      testRunner.display();
+      testRunner.dumpAsText(true);
+      drawGreen();
+  } else
+      window.setTimeout(drawGreen, 50);
+}
+
+function drawGreen()
+{
+  gl.clearColor(0, 1, 0, 1); // green
+  gl.clear(gl.COLOR_BUFFER_BIT);
+  if (window.testRunner) {
+      testRunner.display();
+      testRunner.display();
+  } else
+      window.setInterval(function() {
+        document.getElementById('canvas').classList.toggle('border');
+      }, 50);
+}
+
+</script>
+</head>
+<body onload="init()">
+<canvas id="canvas" width="200" height="200"></canvas>
+</body>
+</html>
index 7240f72..06c9249 100644 (file)
@@ -1,3 +1,27 @@
+2012-08-24  James Robinson  <jamesr@chromium.org>
+
+        WebGL should not flip textures on presentation if contents are unchanged
+        https://bugs.webkit.org/show_bug.cgi?id=94961
+
+        Reviewed by Kenneth Russell.
+
+        For WebGL contexts where antialias and preserveDrawingBuffer are false, chromium implements DrawingBuffer using
+        two textures and flips them on presentation. If the page hasn't actually rendered anything into the WebGL
+        context since the last presentation, this makes an old frame available. This fixes the bug by marking the
+        DrawingBuffer when its contents change.
+
+        Test: compositing/webgl/webgl-repaint.html
+
+        * html/canvas/WebGLRenderingContext.cpp:
+        (WebCore):
+        (WebCore::WebGLRenderingContext::markContextChanged):
+        * platform/graphics/chromium/DrawingBufferChromium.cpp:
+        (WebCore::DrawingBuffer::DrawingBuffer):
+        (WebCore::DrawingBuffer::prepareBackBuffer):
+        * platform/graphics/gpu/DrawingBuffer.h:
+        (WebCore::DrawingBuffer::markContentsChanged):
+        (DrawingBuffer):
+
 2012-08-27  Adam Barth  <abarth@webkit.org>
 
         [V8] Clean up V8DOMWindowShell's findFrame
index fe0fe6d..f056570 100644 (file)
@@ -602,6 +602,9 @@ void WebGLRenderingContext::markContextChanged()
 
     m_context->markContextChanged();
 
+    if (m_drawingBuffer)
+        m_drawingBuffer->markContentsChanged();
+
     m_layerCleared = false;
 #if USE(ACCELERATED_COMPOSITING)
     RenderBox* renderBox = canvas()->renderBox();
index 6102a3e..06839c9 100644 (file)
@@ -87,6 +87,7 @@ DrawingBuffer::DrawingBuffer(GraphicsContext3D* context,
     , m_stencilBuffer(0)
     , m_multisampleFBO(0)
     , m_multisampleColorBuffer(0)
+    , m_contentsChanged(true)
 {
     initialize(size);
 }
@@ -119,6 +120,9 @@ void DrawingBuffer::initialize(const IntSize& size)
 #if USE(ACCELERATED_COMPOSITING)
 void DrawingBuffer::prepareBackBuffer()
 {
+    if (!m_contentsChanged)
+        return;
+
     m_context->makeContextCurrent();
 
     if (multisample())
@@ -138,6 +142,8 @@ void DrawingBuffer::prepareBackBuffer()
         bind();
     else
         restoreFramebufferBinding();
+
+    m_contentsChanged = false;
 }
 
 bool DrawingBuffer::requiresCopyFromBackToFrontBuffer() const
index 3419ff5..5b3302b 100644 (file)
@@ -124,6 +124,7 @@ public:
 #if USE(ACCELERATED_COMPOSITING)
     PlatformLayer* platformLayer();
     void prepareBackBuffer();
+    void markContentsChanged() { m_contentsChanged = true; }
     bool requiresCopyFromBackToFrontBuffer() const;
     unsigned frontColorBuffer() const;
     void paintCompositedResultsToCanvas(ImageBuffer*);
@@ -164,6 +165,9 @@ private:
     Platform3DObject m_multisampleFBO;
     Platform3DObject m_multisampleColorBuffer;
 
+    // True if our contents have been modified since the last presentation of this buffer.
+    bool m_contentsChanged;
+
 #if PLATFORM(CHROMIUM)
     OwnPtr<DrawingBufferPrivate> m_private;
 #endif
index 81b0a3d..d5bb473 100644 (file)
@@ -1,3 +1,15 @@
+2012-08-24  James Robinson  <jamesr@chromium.org>
+
+        WebGL should not flip textures on presentation if contents are unchanged
+        https://bugs.webkit.org/show_bug.cgi?id=94961
+
+        Reviewed by Kenneth Russell.
+
+        Run some compositing webgl tests in threaded mode to catch regressions specific to that mode.
+
+        * Scripts/webkitpy/layout_tests/port/chromium.py:
+        (ChromiumPort.virtual_test_suites):
+
 2012-08-27  Gavin Peters  <gavinp@chromium.org>
 
         [webkit-patch] Don't crash chrome-channels command when a previously unknown platform shows up.
index 2ff21cc..e66b0a2 100755 (executable)
@@ -367,6 +367,9 @@ class ChromiumPort(Port):
             VirtualTestSuite('platform/chromium/virtual/threaded/compositing/visibility',
                              'compositing/visibility',
                              ['--enable-threaded-compositing']),
+            VirtualTestSuite('platform/chromium/virtual/threaded/compositing/webgl',
+                             'compositing/webgl',
+                             ['--enable-threaded-compositing']),
         ]
 
     #