Title: [269025] trunk
Revision
269025
Author
[email protected]
Date
2020-10-27 01:01:43 -0700 (Tue, 27 Oct 2020)

Log Message

REGRESSION (r268386): Flashes of inverted color when zooming the map on windy.com
https://bugs.webkit.org/show_bug.cgi?id=218177
<rdar://problem/70676037>

Patch by Kimmo Kinnunen <[email protected]> on 2020-10-27
Reviewed by Dean Jackson.

Source/WebCore:

Refactoring r268386 changed the behavior so that a new WebGL drawing
buffer would be created when CA would be using the oldest IOSurface
display buffer of the WebGL layer. Before r268386 the WebGL would just
draw on top of the IOSurface even if CA was using it.

This change made the existing bug of using uninitialized IOSurfaces
visible, since IOSurfaces seem to be initialized with red. The existing
bug was probably in r262366.

The fix in this commit fixes the case where WebGL context is drawn to
but the CA does not display the contents. Draw would cause preparation
of the drawing buffer for display, along with the contract that drawing
buffer might be uninitialized. However, the clear of the drawing buffer
was marked needed only during display.

Case that failed at the time of writing was the case where after draw,
the element would be removed by setting display:none. This would return
red contents, e.g. uninitialized IOSurface contents. Before r268386 this
would first return red until 3 buffers had passed and then it would
start recycling old display buffer contents.

The naming is not fixed in this commit due to just fixing the
regression. Other ports contain code that makes renaming or
restructuring the callbacks more confusing for the other ports.

Test: fast/canvas/webgl/webgl-clear-composited-notshowing.html

* WebCore.xcodeproj/project.pbxproj:
* platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm:
(WebCore::GraphicsContextGLOpenGL::GraphicsContextGLOpenGL):
(WebCore::GraphicsContextGLOpenGL::prepareForDisplay):
* platform/graphics/cocoa/WebGLLayer.h:
* platform/graphics/cocoa/WebGLLayer.mm:
(-[WebGLLayer initWithDevicePixelRatio:contentsOpaque:]):
(-[WebGLLayer display]):
(-[WebGLLayer detachClient]):
* platform/graphics/cocoa/WebGLLayerClient.h: Removed.
* platform/graphics/opengl/GraphicsContextGLOpenGL.h:

LayoutTests:

Test case for WebGL which is drawn to a canvas that is not visible. This should still
adhere to preserveDrawingBuffer == false contract of clearing the drawing buffer
correctly.

Case that failed at the time of writing was the case where after draw, the element
would be removed by setting display:none.

* fast/canvas/webgl/webgl-clear-composited-notshowing-expected.txt: Added.
* fast/canvas/webgl/webgl-clear-composited-notshowing.html: Added.

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (269024 => 269025)


--- trunk/LayoutTests/ChangeLog	2020-10-27 07:28:46 UTC (rev 269024)
+++ trunk/LayoutTests/ChangeLog	2020-10-27 08:01:43 UTC (rev 269025)
@@ -1,3 +1,21 @@
+2020-10-27  Kimmo Kinnunen  <[email protected]>
+
+        REGRESSION (r268386): Flashes of inverted color when zooming the map on windy.com
+        https://bugs.webkit.org/show_bug.cgi?id=218177
+        <rdar://problem/70676037>
+
+        Reviewed by Dean Jackson.
+
+        Test case for WebGL which is drawn to a canvas that is not visible. This should still
+        adhere to preserveDrawingBuffer == false contract of clearing the drawing buffer
+        correctly.
+
+        Case that failed at the time of writing was the case where after draw, the element
+        would be removed by setting display:none.
+
+        * fast/canvas/webgl/webgl-clear-composited-notshowing-expected.txt: Added.
+        * fast/canvas/webgl/webgl-clear-composited-notshowing.html: Added.
+
 2020-10-27  Fujii Hironori  <[email protected]>
 
         [WinCairo] Unreviewed test gardening

Added: trunk/LayoutTests/fast/canvas/webgl/webgl-clear-composited-notshowing-expected.txt (0 => 269025)


--- trunk/LayoutTests/fast/canvas/webgl/webgl-clear-composited-notshowing-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/webgl-clear-composited-notshowing-expected.txt	2020-10-27 08:01:43 UTC (rev 269025)
@@ -0,0 +1,165 @@
+Test that test that WebGL canvas preserveDrawingBuffer = false clear behavior on cases where compositor does not neccessarily display the element. You should see no failures and some of the canvases as green on screen.
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 0
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 1
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 2
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 3
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 4
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 5
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 6
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 7
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 8
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: ref attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: ref attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: clipped attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: clipped attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: notOnScreen attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: notOnScreen attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: displayToNone attrs: {"alpha":false,"antialias":false} is initialized to zero on iteration: 9
+PASS canvas: displayToNone attrs: {"alpha":true,"antialias":false} is initialized to zero on iteration: 9
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/fast/canvas/webgl/webgl-clear-composited-notshowing.html (0 => 269025)


--- trunk/LayoutTests/fast/canvas/webgl/webgl-clear-composited-notshowing.html	                        (rev 0)
+++ trunk/LayoutTests/fast/canvas/webgl/webgl-clear-composited-notshowing.html	2020-10-27 08:01:43 UTC (rev 269025)
@@ -0,0 +1,116 @@
+
+<html>
+<head>
+<script src=""
+<script src="" </script>
+<script src=""
+<style type="text/css">
+#cases {
+    width: 300px;
+    height: 50px;
+}
+#cases canvas {
+    width: 20px;
+    height: 20px;
+    background: purple;
+}
+#cases > span {
+   display: block;
+   margin: 1px;
+   float: left;
+}
+#cases > span.clipped {
+    position: relative;
+    overflow: hidden;
+    height: 0px;
+    width: 0px;
+}
+#cases canvas.notOnScreen {
+    position: relative;
+    top: -1000px;
+}
+</style>
+</head>
+<body>
+<div id="cases"></div>
+<div id="description">
+    Test that test that WebGL canvas preserveDrawingBuffer = false clear behavior on
+    cases where compositor does not neccessarily display the element.
+    You should see no failures and some of the canvases as green on screen.
+</div>
+<div id="console"></div>
+
+<script type="text/_javascript_">
+
+var wtu = WebGLTestUtils;
+window.jsTestIsAsync = true;
+
+if (window.testRunner) {
+    testRunner.dumpAsText(true);
+    testRunner.waitUntilDone();
+}
+
+var gls = [];
+var cases = [
+    "ref", // Normal canvas for reference.
+    "clipped", // Case where canvas is clipped by its parent.
+    "notOnScreen", // Case where canvas is not on screen.
+    "displayToNone" // Case where canvas is drawn to and then made not visible
+                    // by display:none, then drawn to, then made visible again, ...
+];
+for (let c of cases)
+{
+    for (let i = 0; i < 4; ++i)
+    {
+        let attrs = {
+            'alpha': (i & 1) == 1,
+            'antialias': (i & 2) == 1
+        };
+
+        let s = document.createElement("span");
+        s.className = c;
+        let canvas = document.createElement("canvas");
+        canvas.className = c;
+        s.appendChild(canvas);
+        document.getElementById("cases").appendChild(s);
+        gl = canvas.getContext("webgl", attrs);
+        gl.attrs = attrs;
+        gls.push(gl);
+    }
+}
+
+// All cases are currently expected to prepare a new drawing buffer on each composite that is preceeded with a
+// drawing command. This is not the only allowed behavior especially for elements that are not on screen, but
+// it's the mode of operation.
+async function composite(gl)
+{
+    return new Promise(resolve => wtu.waitForComposite(gl, resolve ));
+}
+
+async function runTests()
+{
+    let iterations = 10;
+    for (let i = 0; i < iterations; ++i)
+    {
+        for (let gl of gls)
+        {
+            let alpha = gl.getContextAttributes().alpha == true ? 0 : 255;
+            wtu.checkCanvasRect(gl, 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight, [0, 0, 0, alpha],
+                `canvas: ${gl.canvas.className} attrs: ${JSON.stringify(gl.attrs)} is initialized to zero on iteration: ${i}`);
+            // Clear marker is selected so that uninitialized IOSurface contents of 1,0,0,1 is also seen.
+            gl.clearColor(1.0, 0.7, 0.5, 1.0);
+            if (i == (iterations - 1))
+                gl.clearColor(0.0, 1.0, 0.0, 1.0);
+            gl.clear(gl.COLOR_BUFFER_BIT);
+            if (gl.canvas.className == "displayToNone")
+                gl.canvas.style = "display:" + ((i % 2) == 0 ? "none" : "");
+        }
+        await composite(gls[0]);
+    }
+    finishTest();
+}
+runTests();
+
+var successfullyParsed = true;
+</script>
+</body>

Modified: trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations (269024 => 269025)


--- trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations	2020-10-27 07:28:46 UTC (rev 269024)
+++ trunk/LayoutTests/platform/ios-simulator-wk2/TestExpectations	2020-10-27 08:01:43 UTC (rev 269025)
@@ -163,3 +163,5 @@
 
 webkit.org/b/217268 imported/w3c/web-platform-tests/mathml/relations/css-styling/padding-border-margin/border-002.html [ Failure ]
 webkit.org/b/217268 imported/w3c/web-platform-tests/mathml/relations/html5-tree/dynamic-childlist-001.html [ Failure ]
+
+webkit.org/b/209139 fast/canvas/webgl/webgl-clear-composited-notshowing.html [ Failure ]

Modified: trunk/Source/WebCore/ChangeLog (269024 => 269025)


--- trunk/Source/WebCore/ChangeLog	2020-10-27 07:28:46 UTC (rev 269024)
+++ trunk/Source/WebCore/ChangeLog	2020-10-27 08:01:43 UTC (rev 269025)
@@ -1,3 +1,50 @@
+2020-10-27  Kimmo Kinnunen  <[email protected]>
+
+        REGRESSION (r268386): Flashes of inverted color when zooming the map on windy.com
+        https://bugs.webkit.org/show_bug.cgi?id=218177
+        <rdar://problem/70676037>
+
+        Reviewed by Dean Jackson.
+
+        Refactoring r268386 changed the behavior so that a new WebGL drawing
+        buffer would be created when CA would be using the oldest IOSurface
+        display buffer of the WebGL layer. Before r268386 the WebGL would just
+        draw on top of the IOSurface even if CA was using it.
+
+        This change made the existing bug of using uninitialized IOSurfaces
+        visible, since IOSurfaces seem to be initialized with red. The existing
+        bug was probably in r262366.
+
+        The fix in this commit fixes the case where WebGL context is drawn to
+        but the CA does not display the contents. Draw would cause preparation
+        of the drawing buffer for display, along with the contract that drawing
+        buffer might be uninitialized. However, the clear of the drawing buffer
+        was marked needed only during display.
+
+        Case that failed at the time of writing was the case where after draw,
+        the element would be removed by setting display:none. This would return
+        red contents, e.g. uninitialized IOSurface contents. Before r268386 this
+        would first return red until 3 buffers had passed and then it would
+        start recycling old display buffer contents.
+
+        The naming is not fixed in this commit due to just fixing the
+        regression. Other ports contain code that makes renaming or
+        restructuring the callbacks more confusing for the other ports.
+
+        Test: fast/canvas/webgl/webgl-clear-composited-notshowing.html
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm:
+        (WebCore::GraphicsContextGLOpenGL::GraphicsContextGLOpenGL):
+        (WebCore::GraphicsContextGLOpenGL::prepareForDisplay):
+        * platform/graphics/cocoa/WebGLLayer.h:
+        * platform/graphics/cocoa/WebGLLayer.mm:
+        (-[WebGLLayer initWithDevicePixelRatio:contentsOpaque:]):
+        (-[WebGLLayer display]):
+        (-[WebGLLayer detachClient]):
+        * platform/graphics/cocoa/WebGLLayerClient.h: Removed.
+        * platform/graphics/opengl/GraphicsContextGLOpenGL.h:
+
 2020-10-26  Said Abou-Hallawa  <[email protected]>
 
         [GPU Process]: Introduce RemoteResourceCacheProxy to manage the remote resources in Web Process

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (269024 => 269025)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-10-27 07:28:46 UTC (rev 269024)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2020-10-27 08:01:43 UTC (rev 269025)
@@ -2217,7 +2217,6 @@
 		7AF9B20618CFB2DF00C64BEF /* VTTRegionList.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AF9B20018CFB2DF00C64BEF /* VTTRegionList.h */; };
 		7AF9B20D18CFB5F400C64BEF /* JSVTTRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AF9B20918CFB5F200C64BEF /* JSVTTRegion.h */; };
 		7AF9B20F18CFB5F400C64BEF /* JSVTTRegionList.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AF9B20B18CFB5F300C64BEF /* JSVTTRegionList.h */; };
-		7BB34A152534579100029D08 /* WebGLLayerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB34A132534579100029D08 /* WebGLLayerClient.h */; };
 		7BB34A1725345CB200029D08 /* GraphicsContextGLANGLEUtilities.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB34A1625345CB200029D08 /* GraphicsContextGLANGLEUtilities.h */; };
 		7BB34A48253776CA00029D08 /* GraphicsContextGLImageExtractor.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BB34A45253776C600029D08 /* GraphicsContextGLImageExtractor.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		7BE7427381FA906FBB4F0F2C /* JSSVGGraphicsElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 950C4C02BED8936F818E2F99 /* JSSVGGraphicsElement.h */; };
@@ -10087,7 +10086,6 @@
 		7AF9B20918CFB5F200C64BEF /* JSVTTRegion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVTTRegion.h; sourceTree = "<group>"; };
 		7AF9B20A18CFB5F300C64BEF /* JSVTTRegionList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSVTTRegionList.cpp; sourceTree = "<group>"; };
 		7AF9B20B18CFB5F300C64BEF /* JSVTTRegionList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSVTTRegionList.h; sourceTree = "<group>"; };
-		7BB34A132534579100029D08 /* WebGLLayerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebGLLayerClient.h; sourceTree = "<group>"; };
 		7BB34A1625345CB200029D08 /* GraphicsContextGLANGLEUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GraphicsContextGLANGLEUtilities.h; sourceTree = "<group>"; };
 		7BB34A45253776C600029D08 /* GraphicsContextGLImageExtractor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GraphicsContextGLImageExtractor.h; sourceTree = "<group>"; };
 		7BB34A47253776C700029D08 /* GraphicsContextGLImageExtractor.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = GraphicsContextGLImageExtractor.cpp; sourceTree = "<group>"; };
@@ -26561,7 +26559,6 @@
 				CD5D27751E8318E000D80A3D /* WebCoreDecompressionSession.mm */,
 				49FFBF3D11C93EE3006A7118 /* WebGLLayer.h */,
 				49FFBF3E11C93EE3006A7118 /* WebGLLayer.mm */,
-				7BB34A132534579100029D08 /* WebGLLayerClient.h */,
 				318436DB21B9DAA000ED383E /* WebGPULayer.h */,
 				318436DD21B9DAA000ED383E /* WebGPULayer.mm */,
 			);
@@ -34824,7 +34821,6 @@
 				6EBF0E5512A8929800DB1709 /* WebGLExtension.h in Headers */,
 				49C7B9CF1042D32F0009D447 /* WebGLFramebuffer.h in Headers */,
 				49FFBF3F11C93EE3006A7118 /* WebGLLayer.h in Headers */,
-				7BB34A152534579100029D08 /* WebGLLayerClient.h in Headers */,
 				93F1D5BB12D532C400832BEC /* WebGLLoseContext.h in Headers */,
 				49C7B9D51042D32F0009D447 /* WebGLObject.h in Headers */,
 				49C7B9D71042D32F0009D447 /* WebGLProgram.h in Headers */,

Modified: trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm (269024 => 269025)


--- trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm	2020-10-27 07:28:46 UTC (rev 269024)
+++ trunk/Source/WebCore/platform/graphics/cocoa/GraphicsContextGLOpenGLCocoa.mm	2020-10-27 08:01:43 UTC (rev 269025)
@@ -334,7 +334,7 @@
 
     // Create the WebGLLayer
     BEGIN_BLOCK_OBJC_EXCEPTIONS
-        m_webGLLayer = adoptNS([[WebGLLayer alloc] initWithClient:this devicePixelRatio:attrs.devicePixelRatio contentsOpaque:!attrs.alpha]);
+        m_webGLLayer = adoptNS([[WebGLLayer alloc] initWithDevicePixelRatio:attrs.devicePixelRatio contentsOpaque:!attrs.alpha]);
 #ifndef NDEBUG
         [m_webGLLayer setName:@"WebGL Layer"];
 #endif
@@ -694,19 +694,19 @@
     [m_webGLLayer prepareForDisplayWithContents: {WTFMove(m_displayBufferBacking), m_displayBufferPbuffer}];
     m_displayBufferPbuffer = EGL_NO_SURFACE;
 
+    bool hasNewBacking = false;
     if (recycledBuffer.surface && recycledBuffer.surface->size() == getInternalFramebufferSize()) {
-        if (bindDisplayBufferBacking(WTFMove(recycledBuffer.surface), recycledBuffer.handle))
-            return;
+        hasNewBacking = bindDisplayBufferBacking(WTFMove(recycledBuffer.surface), recycledBuffer.handle);
+        recycledBuffer.handle = nullptr;
     }
     recycledBuffer.surface.reset();
     if (recycledBuffer.handle)
         EGL_DestroySurface(m_displayObj, recycledBuffer.handle);
+
     // Error will be handled by next call to makeContextCurrent() which will notice lack of display buffer.
-    reshapeDisplayBufferBacking();
-}
+    if (!hasNewBacking)
+        reshapeDisplayBufferBacking();
 
-void GraphicsContextGLOpenGL::didDisplay()
-{
     markLayerComposited();
 }
 

Modified: trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayer.h (269024 => 269025)


--- trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayer.h	2020-10-27 07:28:46 UTC (rev 269024)
+++ trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayer.h	2020-10-27 08:01:43 UTC (rev 269025)
@@ -28,7 +28,6 @@
 #import <wtf/NakedPtr.h>
 
 namespace WebCore {
-class WebGLLayerClient;
 struct WebGLLayerBuffer {
     std::unique_ptr<WebCore::IOSurface> surface; // The actual contents.
     void* handle { nullptr }; // Client specific metadata handle (such as EGLSurface).
@@ -48,7 +47,7 @@
 // the existing binding obtained through the buffer recycle logic.
 @interface WebGLLayer : CALayer
 
-- (id)initWithClient:(NakedPtr<WebCore::WebGLLayerClient>)client devicePixelRatio:(float)devicePixelRatio contentsOpaque:(bool)contentsOpaque;
+- (id)initWithDevicePixelRatio:(float)devicePixelRatio contentsOpaque:(bool)contentsOpaque;
 
 - (CGImageRef)copyImageSnapshotWithColorSpace:(CGColorSpaceRef)colorSpace;
 
@@ -69,7 +68,6 @@
 // Detaches the client and returns the current contents buffer metadata handle.
 // The if multiple buffers have been submitted, recycleBuffer must have been called before calling
 // this.
-// The client will not receive `WebGLLayerClient` notifications after calling this.
 - (void*)detachClient;
 
 @end

Modified: trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayer.mm (269024 => 269025)


--- trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayer.mm	2020-10-27 07:28:46 UTC (rev 269024)
+++ trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayer.mm	2020-10-27 08:01:43 UTC (rev 269025)
@@ -31,12 +31,10 @@
 #import "GraphicsLayer.h"
 #import "GraphicsLayerCA.h"
 #import "PlatformCALayer.h"
-#import "WebGLLayerClient.h"
 #import <pal/spi/cocoa/QuartzCoreSPI.h>
 #import <wtf/RetainPtr.h>
 
 @implementation WebGLLayer {
-    NakedPtr<WebCore::WebGLLayerClient> _client;
     WebCore::WebGLLayerBuffer _contentsBuffer;
     WebCore::WebGLLayerBuffer _spareBuffer;
 
@@ -43,9 +41,8 @@
     BOOL _preparedForDisplay;
 }
 
-- (id)initWithClient:(NakedPtr<WebCore::WebGLLayerClient>)client devicePixelRatio:(float)devicePixelRatio contentsOpaque:(bool)contentsOpaque
+- (id)initWithDevicePixelRatio:(float)devicePixelRatio contentsOpaque:(bool)contentsOpaque
 {
-    _client = client;
     self = [super init];
     self.transform = CATransform3DIdentity;
     self.contentsOpaque = contentsOpaque;
@@ -102,8 +99,6 @@
         self.contents = _contentsBuffer.surface->asLayerContents();
         [self reloadValueForKeyPath:@"contents"];
     }
-    if (_client)
-        _client->didDisplay();
     auto layer = WebCore::PlatformCALayer::platformCALayerForLayer((__bridge void*)self);
     if (layer && layer->owner())
         layer->owner()->platformCALayerLayerDidDisplay(layer.get());
@@ -114,7 +109,6 @@
 - (void*) detachClient
 {
     ASSERT(!_spareBuffer.surface);
-    _client = nil;
     void* result = _contentsBuffer.handle;
     _contentsBuffer.handle = nullptr;
     return result;

Deleted: trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayerClient.h (269024 => 269025)


--- trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayerClient.h	2020-10-27 07:28:46 UTC (rev 269024)
+++ trunk/Source/WebCore/platform/graphics/cocoa/WebGLLayerClient.h	2020-10-27 08:01:43 UTC (rev 269025)
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2020 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#pragma once
-
-namespace WebCore {
-
-class WebGLLayerClient {
-public:
-    virtual ~WebGLLayerClient() { }
-    virtual void didDisplay() = 0;
-};
-
-}

Modified: trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h (269024 => 269025)


--- trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h	2020-10-27 07:28:46 UTC (rev 269024)
+++ trunk/Source/WebCore/platform/graphics/opengl/GraphicsContextGLOpenGL.h	2020-10-27 08:01:43 UTC (rev 269025)
@@ -37,7 +37,6 @@
 
 #if PLATFORM(COCOA)
 #include "IOSurface.h"
-#include "WebGLLayerClient.h"
 #endif
 
 #if USE(CA)
@@ -88,9 +87,6 @@
 class GraphicsContextGLOpenGLPrivate;
 
 class GraphicsContextGLOpenGL final : public GraphicsContextGL
-#if PLATFORM(COCOA)
-    , private WebGLLayerClient
-#endif
 {
 public:
     static RefPtr<GraphicsContextGLOpenGL> create(GraphicsContextGLAttributes, HostWindow*, Destination = Destination::Offscreen);
@@ -546,8 +542,6 @@
     bool allowOfflineRenderers() const;
     bool reshapeDisplayBufferBacking();
     bool bindDisplayBufferBacking(std::unique_ptr<IOSurface> backing, void* pbuffer);
-    // WebGLLayerClient overrides.
-    void didDisplay() final;
 #endif
 
 #if PLATFORM(COCOA)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to