Title: [199536] trunk
Revision
199536
Author
[email protected]
Date
2016-04-14 04:09:37 -0700 (Thu, 14 Apr 2016)

Log Message

WebGL based canvases composite incorrectly after changing size
https://bugs.webkit.org/show_bug.cgi?id=152556
<rdar://problem/24012678>

Patch by Antoine Quint <[email protected]> on 2016-04-14
Reviewed by Dean Jackson.

Source/WebCore:

On iOS, we use the CAEAGLLayer's bounds to set the size of the backing store.
However, that layer's bounds is also used to size the layer during layout. If
the canvas backing store is resized after layout has been performed, the call
to setBounds loses the layout value and the <canvas> element is incorrectly
sized on screen.

To address this, when updating the backing store, we keep track of the previous
layer bounds so we can reset it after we sized the backing store.

Test: webgl/webgl-backing-store-size-update.html

* platform/graphics/GraphicsContext3D.h:
* platform/graphics/mac/GraphicsContext3DMac.mm:
(WebCore::GraphicsContext3D::setRenderbufferStorageFromDrawable):

LayoutTests:

Adding a new test that sets the size of the backing store to a different
size than the layout size after the layout size of the <canvas> element
has been applied to ensure that the implementation correctly retains the
layout size as the canvas backing store is resized.

* webgl/webgl-backing-store-size-update-expected.html: Added.
* webgl/webgl-backing-store-size-update.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (199535 => 199536)


--- trunk/LayoutTests/ChangeLog	2016-04-14 10:12:12 UTC (rev 199535)
+++ trunk/LayoutTests/ChangeLog	2016-04-14 11:09:37 UTC (rev 199536)
@@ -1,3 +1,19 @@
+2016-04-14  Antoine Quint  <[email protected]>
+
+        WebGL based canvases composite incorrectly after changing size
+        https://bugs.webkit.org/show_bug.cgi?id=152556
+        <rdar://problem/24012678>
+
+        Reviewed by Dean Jackson.
+
+        Adding a new test that sets the size of the backing store to a different
+        size than the layout size after the layout size of the <canvas> element
+        has been applied to ensure that the implementation correctly retains the
+        layout size as the canvas backing store is resized.
+
+        * webgl/webgl-backing-store-size-update-expected.html: Added.
+        * webgl/webgl-backing-store-size-update.html: Added.
+
 2016-04-13  Joseph Pecoraro  <[email protected]>
 
         JSContext Inspector: Improve Class instances and JSC API Exported Values view in Console / ObjectTree

Added: trunk/LayoutTests/webgl/webgl-backing-store-size-update-expected.html (0 => 199536)


--- trunk/LayoutTests/webgl/webgl-backing-store-size-update-expected.html	                        (rev 0)
+++ trunk/LayoutTests/webgl/webgl-backing-store-size-update-expected.html	2016-04-14 11:09:37 UTC (rev 199536)
@@ -0,0 +1 @@
+<div style="width: 50px; height: 50px; background-color: black;"></div>

Added: trunk/LayoutTests/webgl/webgl-backing-store-size-update.html (0 => 199536)


--- trunk/LayoutTests/webgl/webgl-backing-store-size-update.html	                        (rev 0)
+++ trunk/LayoutTests/webgl/webgl-backing-store-size-update.html	2016-04-14 11:09:37 UTC (rev 199536)
@@ -0,0 +1,35 @@
+<canvas style="width:100px; height:100px;">
+<script type="text/_javascript_">
+    if (window.testRunner)
+        testRunner.waitUntilDone();
+
+    var canvas = document.querySelector("canvas");
+
+    function draw() {
+        // For the purpose of this test, we want the backing store metrics to
+        // not match the layout metrics.
+        var scaleFactor = 2;
+        canvas.width = canvas.clientWidth * scaleFactor;
+        canvas.height = canvas.clientHeight * scaleFactor;
+
+        var gl = canvas.getContext("webgl");
+        gl.clearColor(0, 0, 0, 1);
+        gl.clear(gl.COLOR_BUFFER_BIT);
+    }
+
+    // Size the canvas once at the initial 100px by 100px size.
+    draw();
+
+    // Now change the layout size of the canvas and in the next animation
+    // frame, after we know the layout size has taken effect, change the
+    // size of the backing store.
+    canvas.style.width = "50px";
+    canvas.style.height = "50px";
+    window.requestAnimationFrame(function() {
+        draw();
+        if (window.testRunner)
+            testRunner.notifyDone();
+    });
+
+</script>
+</canvas>

Modified: trunk/Source/WebCore/ChangeLog (199535 => 199536)


--- trunk/Source/WebCore/ChangeLog	2016-04-14 10:12:12 UTC (rev 199535)
+++ trunk/Source/WebCore/ChangeLog	2016-04-14 11:09:37 UTC (rev 199536)
@@ -1,3 +1,26 @@
+2016-04-14  Antoine Quint  <[email protected]>
+
+        WebGL based canvases composite incorrectly after changing size
+        https://bugs.webkit.org/show_bug.cgi?id=152556
+        <rdar://problem/24012678>
+
+        Reviewed by Dean Jackson.
+
+        On iOS, we use the CAEAGLLayer's bounds to set the size of the backing store.
+        However, that layer's bounds is also used to size the layer during layout. If
+        the canvas backing store is resized after layout has been performed, the call
+        to setBounds loses the layout value and the <canvas> element is incorrectly
+        sized on screen.
+
+        To address this, when updating the backing store, we keep track of the previous
+        layer bounds so we can reset it after we sized the backing store.
+
+        Test: webgl/webgl-backing-store-size-update.html
+
+        * platform/graphics/GraphicsContext3D.h:
+        * platform/graphics/mac/GraphicsContext3DMac.mm:
+        (WebCore::GraphicsContext3D::setRenderbufferStorageFromDrawable):
+
 2016-04-13  Carlos Garcia Campos  <[email protected]>
 
         Unreviewed. Fix GObject DOM bindings API break after r199392.

Modified: trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h (199535 => 199536)


--- trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2016-04-14 10:12:12 UTC (rev 199535)
+++ trunk/Source/WebCore/platform/graphics/GraphicsContext3D.h	2016-04-14 11:09:37 UTC (rev 199536)
@@ -1291,7 +1291,7 @@
     void readPixelsAndConvertToBGRAIfNecessary(int x, int y, int width, int height, unsigned char* pixels);
 
 #if PLATFORM(IOS)
-    bool setRenderbufferStorageFromDrawable(GC3Dsizei width, GC3Dsizei height);
+    void setRenderbufferStorageFromDrawable(GC3Dsizei width, GC3Dsizei height);
 #endif
 
     bool reshapeFBOs(const IntSize&);

Modified: trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm (199535 => 199536)


--- trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm	2016-04-14 10:12:12 UTC (rev 199535)
+++ trunk/Source/WebCore/platform/graphics/mac/GraphicsContext3DMac.mm	2016-04-14 11:09:37 UTC (rev 199536)
@@ -340,12 +340,18 @@
 }
 
 #if PLATFORM(IOS)
-bool GraphicsContext3D::setRenderbufferStorageFromDrawable(GC3Dsizei width, GC3Dsizei height)
+void GraphicsContext3D::setRenderbufferStorageFromDrawable(GC3Dsizei width, GC3Dsizei height)
 {
+    // We need to make a call to setBounds below to update the backing store size but we also
+    // do not want to clobber the bounds set during layout.
+    CGRect previousBounds = [m_webGLLayer.get() bounds];
+
     [m_webGLLayer setBounds:CGRectMake(0, 0, width, height)];
     [m_webGLLayer setOpaque:(m_internalColorFormat != GL_RGBA8)];
 
-    return [m_contextObj renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast<id<EAGLDrawable>>(m_webGLLayer.get())];
+    [m_contextObj renderbufferStorage:GL_RENDERBUFFER fromDrawable:static_cast<id<EAGLDrawable>>(m_webGLLayer.get())];
+
+    [m_webGLLayer setBounds:previousBounds];
 }
 #endif
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to