[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

simon.fraser at apple.com simon.fraser at apple.com
Thu Apr 8 00:59:09 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit aafddd81183931c6db985764edd608b0f8bba9ad
Author: simon.fraser at apple.com <simon.fraser at apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Sat Jan 9 04:07:52 2010 +0000

    2010-01-08  Simon Fraser  <simon.fraser at apple.com>
    
            Reviewed by Dan Bernstein.
    
            WebGL canvas paints background color twice
            https://bugs.webkit.org/show_bug.cgi?id=33361
    
            Clean up some logic around "directly composited" content: some images, video, and WebGL.
    
            We previously set the GraphicsLayer background color to the CSS background color
            in some cases where the box has no other decorations. However, the content
            layer's bounds do not correspond with the background box in many cases,
            and we could end up both painting the background color, and setting it on the layer.
    
            Simplify this logic to never use layer background colors, and thus skip allocating
            backing store only when the element has no visible box decorations.
    
            Tests: compositing/images/direct-image-background-color.html
                   compositing/reflections/simple-composited-reflections.html
                   compositing/video/video-background-color.html
                   compositing/webgl/webgl-background-color.html
                   compositing/webgl/webgl-blending.html
    
            * rendering/RenderLayerBacking.h:
            * rendering/RenderLayerBacking.cpp:
            (WebCore::is3DCanvas): Utility to determine if a RenderObject is a canvas with WebGL
            (WebCore::RenderLayerBacking::RenderLayerBacking): Remove m_hasDirectlyCompositedContent.
            (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): canUseDirectCompositing()
            is renamed to isDirectlyCompositedImage() and only applies to images now.
            No longer set layer background color.
            (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Just use hasPaintedContent()
            as the argument to setDrawsContent().
            (WebCore::hasBoxDecorationsOrBackground): Renamed.
            (WebCore::RenderLayerBacking::hasNonCompositingContent):
            (WebCore::hasBoxDecorationsOrBackgroundImage): Renamed from hasBoxDecorations().
            (WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer): Moved test for
            hasOverflowControls() into hasNonCompositingContent() and removed the FIXME comment.
            (WebCore::RenderLayerBacking::containsPaintedContent): New method that decides
            if the layer (and its non-composited children) has any content that must be painted into backing store.
            (WebCore::RenderLayerBacking::isDirectlyCompositedImage): Renamed from canUseDirectCompositing()
            and reduced to only apply to images.
            (WebCore::RenderLayerBacking::rendererContentChanged): 3D canvas no longer falls under the
            canUseDirectCompositing() scope.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@53034 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 3e48332..2bfe17d 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,22 @@
+2010-01-08  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        WebGL canvas paints background color twice
+        https://bugs.webkit.org/show_bug.cgi?id=33361
+        
+        New testcases for various kinds of "directly composited" elements: images, video, WebGL,
+        with background colors.
+
+        * compositing/images/direct-image-background-color.html: Added.
+        * compositing/reflections/simple-composited-reflections.html: Added.
+        * compositing/video/video-background-color.html: Added.
+        * compositing/webgl/webgl-background-color.html: Added.
+        * compositing/webgl/webgl-blending.html: Added.
+        * platform/mac/compositing/images/direct-image-background-color-expected.txt: Added.
+        * platform/mac/compositing/video/video-background-color-expected.txt: Added.
+        * platform/mac/compositing/webgl/webgl-background-color-expected.txt: Added.
+
 2010-01-08  Kenneth Russell  <kbr at google.com>
 
         Reviewed by Dimitri Glazkov.
diff --git a/LayoutTests/compositing/images/direct-image-background-color.html b/LayoutTests/compositing/images/direct-image-background-color.html
new file mode 100644
index 0000000..d4bafcb
--- /dev/null
+++ b/LayoutTests/compositing/images/direct-image-background-color.html
@@ -0,0 +1,33 @@
+<!DOCTYPE>
+
+<html>
+<head>
+  <title>Directly composited images with background color</title>
+  <style type="text/css" media="screen">
+    body {
+      outline: 10px solid transparent; /* affects layer sizes */
+    }
+
+    img {
+      display: block;
+      margin: 20px;
+      height: 180px;
+      width: 260px;
+      padding: 10px;
+      background-color: rgba(0, 0, 128, 0.5);
+    }
+    
+    .composited {
+      -webkit-transform: translateZ(0);
+    }
+  </style>
+</head>
+<body>
+
+  <img src="../resources/alpha-gradient-small.png">
+  <img class="composited" src="../resources/alpha-gradient-small.png">
+
+  <p>Top and bottom should look the same.</p>
+
+</body>
+</html>
diff --git a/LayoutTests/compositing/reflections/simple-composited-reflections.html b/LayoutTests/compositing/reflections/simple-composited-reflections.html
new file mode 100644
index 0000000..d00e157
--- /dev/null
+++ b/LayoutTests/compositing/reflections/simple-composited-reflections.html
@@ -0,0 +1,29 @@
+<!DOCTYPE>
+
+<html>
+<head>
+  <title>Simple composited reflections</title>
+  <style type="text/css" media="screen">
+
+      img {
+        margin: 20px;
+      }
+
+      .compositing {
+        -webkit-transform: translateZ(0);
+      }
+
+      .reflected {
+        -webkit-box-reflect: below 10px;
+      }
+
+  </style>
+</head>
+<body>
+
+  <p>Testing reflections on directly composited images. Left and right sides should look the same.</p>
+  <img class="reflected" src="../resources/thiswayup.png" width="184" height="124">
+  <img class="compositing reflected" src="../resources/thiswayup.png" width="184" height="124">
+
+</body>
+</html>
diff --git a/LayoutTests/compositing/resources/alpha-gradient-small.mov b/LayoutTests/compositing/resources/alpha-gradient-small.mov
new file mode 100644
index 0000000..ab453a4
Binary files /dev/null and b/LayoutTests/compositing/resources/alpha-gradient-small.mov differ
diff --git a/LayoutTests/compositing/resources/alpha-gradient-small.png b/LayoutTests/compositing/resources/alpha-gradient-small.png
new file mode 100644
index 0000000..c54942f
Binary files /dev/null and b/LayoutTests/compositing/resources/alpha-gradient-small.png differ
diff --git a/LayoutTests/compositing/resources/thiswayup.png b/LayoutTests/compositing/resources/thiswayup.png
new file mode 100644
index 0000000..cf735f1
Binary files /dev/null and b/LayoutTests/compositing/resources/thiswayup.png differ
diff --git a/LayoutTests/compositing/video/video-background-color.html b/LayoutTests/compositing/video/video-background-color.html
new file mode 100644
index 0000000..43f0a19
--- /dev/null
+++ b/LayoutTests/compositing/video/video-background-color.html
@@ -0,0 +1,46 @@
+<!DOCTYPE>
+
+<html>
+<head>
+  <title>Video with background color</title>
+  <style type="text/css" media="screen">
+    body {
+      outline: 10px solid transparent; /* affects layer sizes */
+    }
+    video, .wrapper {
+      display: block;
+      margin: 20px;
+      height: 180px;
+      width: 260px;
+      background-color: rgba(0, 0, 128, 0.5);
+    }
+  
+    .wrapper > img {
+      position: relative;
+      left: 30px;
+    }
+  </style>
+  <script type="text/javascript" charset="utf-8">
+    if (window.layoutTestController)
+      layoutTestController.waitUntilDone();
+  </script>
+</head>
+<body>
+
+  <div class="wrapper">
+    <img src="../resources/alpha-gradient-small.png">
+  </div>
+  <video src="../resources/alpha-gradient-small.mov" autoplay loop></video>
+
+  <p>Top and bottom should look the same.</p>
+
+  <script type="text/javascript" charset="utf-8">
+    var video = document.getElementsByTagName('video')[0];
+    video.addEventListener('canplaythrough', function() {
+      if (window.layoutTestController)
+        layoutTestController.notifyDone();
+    }, false);
+  </script>
+
+</body>
+</html>
diff --git a/LayoutTests/compositing/webgl/webgl-background-color.html b/LayoutTests/compositing/webgl/webgl-background-color.html
new file mode 100644
index 0000000..3c63a0b
--- /dev/null
+++ b/LayoutTests/compositing/webgl/webgl-background-color.html
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <style type="text/css" media="screen">
+      body {
+        outline: 10px solid transparent; /* affects layer sizes */
+      }
+      canvas {
+        margin: 20px;
+        width: 200px;
+        height: 200px;
+        padding: 0 20px;
+        background-color: rgba(0, 0, 128, 0.5);
+      }
+    
+      .compare {
+        margin: 20px;
+        width: 200px;
+        height: 200px;
+        padding: 0 20px;
+        background-color: rgba(0, 0, 128, 0.5);
+      }
+    </style>
+    <script>
+        function initWebGL(canvasName, vshader, fshader, attribs, clearColor, clearDepth)
+        {
+            var canvas = document.getElementById(canvasName);
+            var gl = canvas.getContext("experimental-webgl");
+            if (!gl) {
+                alert("No WebGL context found");
+                return null;
+            }
+
+            gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
+            gl.clearDepth(clearDepth);
+
+            gl.enable(gl.DEPTH_TEST);
+            gl.enable(gl.BLEND);
+            gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
+
+            return gl;
+        }
+
+        function drawCanvas(canvasID)
+        {
+          var gl = initWebGL(canvasID, "", "", [], [ 0, 0, 0, 0 ], 1);
+          gl.viewport(0, 0, 200, 200);
+          gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+        }
+
+        function init()
+        {
+          drawCanvas('canvas');
+       }
+    </script>
+  </head>
+  <body onload="init()">
+   
+    <div class="compare"></div>
+    <canvas id="canvas" style="left: 20px" width="200" height="200"></canvas>
+
+    <p>Top and bottom should look the same.</p>
+  </body>
+</html>
diff --git a/LayoutTests/compositing/webgl/webgl-blending.html b/LayoutTests/compositing/webgl/webgl-blending.html
new file mode 100644
index 0000000..ea716cc
--- /dev/null
+++ b/LayoutTests/compositing/webgl/webgl-blending.html
@@ -0,0 +1,193 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <script id="vshader" type="x-shader/x-vertex">
+        attribute vec4 vPosition;
+        void main()
+        {
+            gl_Position = vPosition;
+        }
+    </script>
+
+    <script id="fshader" type="x-shader/x-fragment">
+        void main()
+        {
+            gl_FragColor = vec4(1.0, 0.0, 0.0, 0.5);
+        }
+    </script>
+
+    <script>
+        function initWebGL(canvasName, vshader, fshader, attribs, clearColor, clearDepth)
+        {
+            var canvas = document.getElementById(canvasName);
+            var gl = canvas.getContext("experimental-webgl");
+            if (!gl) {
+                alert("No WebGL context found");
+                return null;
+            }
+
+            // Add a console
+            gl.console = ("console" in window) ? window.console : { log: function() { } };
+
+            // create our shaders
+            var vertexShader = loadShader(gl, vshader);
+            var fragmentShader = loadShader(gl, fshader);
+
+            if (!vertexShader || !fragmentShader)
+                return null;
+
+            // Create the program object
+            gl.program = gl.createProgram();
+
+            if (!gl.program)
+                return null;
+
+            // Attach our two shaders to the program
+            gl.attachShader (gl.program, vertexShader);
+            gl.attachShader (gl.program, fragmentShader);
+
+            // Bind attributes
+            for (var i in attribs)
+                gl.bindAttribLocation (gl.program, i, attribs[i]);
+
+            // Link the program
+            gl.linkProgram(gl.program);
+
+            // Check the link status
+            var linked = gl.getProgramParameter(gl.program, gl.LINK_STATUS);
+            if (!linked) {
+                // something went wrong with the link
+                var error = gl.getProgramInfoLog (gl.program);
+                gl.console.log("Error in program linking:"+error);
+
+                gl.deleteProgram(gl.program);
+                gl.deleteProgram(fragmentShader);
+                gl.deleteProgram(vertexShader);
+
+                return null;
+            }
+
+            gl.useProgram(gl.program);
+
+            gl.clearColor(clearColor[0], clearColor[1], clearColor[2], clearColor[3]);
+            gl.clearDepth(clearDepth);
+
+            gl.enable(gl.DEPTH_TEST);
+            gl.enable(gl.BLEND);
+            gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
+
+            return gl;
+        }
+
+        //
+        // loadShader
+        //
+        // 'shaderId' is the id of a <script> element containing the shader source string.
+        // Load this shader and return the WebGLShader object corresponding to it.
+        //
+        function loadShader(ctx, shaderId)
+        {
+            var shaderScript = document.getElementById(shaderId);
+            if (!shaderScript) {
+                ctx.console.log("*** Error: shader script '"+shaderId+"' not found");
+                return null;
+            }
+
+            if (shaderScript.type == "x-shader/x-vertex")
+                var shaderType = ctx.VERTEX_SHADER;
+            else if (shaderScript.type == "x-shader/x-fragment")
+                var shaderType = ctx.FRAGMENT_SHADER;
+            else {
+                ctx.console.log("*** Error: shader script '"+shaderId+"' of undefined type '"+shaderScript.type+"'");
+                return null;
+            }
+
+            // Create the shader object
+            var shader = ctx.createShader(shaderType);
+            if (shader == null) {
+                ctx.console.log("*** Error: unable to create shader '"+shaderId+"'");       
+                return null;
+            }
+
+            // Load the shader source
+            ctx.shaderSource(shader, shaderScript.text);
+
+            // Compile the shader
+            ctx.compileShader(shader);
+
+            // Check the compile status
+            var compiled = ctx.getShaderParameter(shader, ctx.COMPILE_STATUS);
+            if (!compiled) {
+                // Something went wrong during compilation; get the error
+                var error = ctx.getShaderInfoLog(shader);
+                ctx.console.log("*** Error compiling shader '"+shaderId+"':"+error);
+                ctx.deleteShader(shader);
+                return null;
+            }
+
+            return shader;
+        }
+    
+        function init()
+        {
+            var gl = initWebGL("canvas", "vshader", "fshader", [ "vPosition"], [ 1, 0, 0, 0.5 ], 1);
+            gl.viewport(0, 0, 200, 200);
+            gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+            
+            // var vertexObject = gl.createBuffer();
+            // gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+            // gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);
+            // gl.enableVertexAttribArray(0);
+            // gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+            // 
+            // gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+            // gl.drawArrays(gl.TRIANGLES, 0, 3);
+
+            // gl = initWebGL("right", "vshader", "fshader", [ "vPosition"], [ 0, 0, 1, 0.5 ], 1);
+            // gl.viewport(0, 0, 200, 200);
+            // 
+            // var vertexObject = gl.createBuffer();
+            // gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
+            // gl.bufferData(gl.ARRAY_BUFFER, new WebGLFloatArray([ 0,0.5,0, -0.5,-0.5,0, 0.5,-0.5,0 ]), gl.STATIC_DRAW);
+            // gl.enableVertexAttribArray(0);
+            // gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
+            // 
+            // gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
+            // gl.drawArrays(gl.TRIANGLES, 0, 3);
+       }
+    </script>
+    <style type="text/css" media="screen">
+      .box {
+        display: inline-block;
+        margin: 20px;
+        width: 200px;
+        height: 200px;
+      }
+
+      .indicator {
+        position: absolute;
+        z-index: -1;
+        width: 100%;
+        height: 75px;
+        background-color: green;
+        border-top: 75px solid blue;
+        border-bottom: 75px solid yellow;
+      }
+      
+      canvas {
+        background-color: rgba(255, 0, 0, 0.5);
+      }
+      
+      .compare {
+        background-color: rgba(255, 0, 0, 0.5);
+      }
+    </style>
+  </head>
+  <body onload="init()">
+   
+    <div class="indicator"></div>
+
+    <canvas class="box" id="canvas" style="left: 20px" width="200" height="200"></canvas>
+    <div class="box compare"></div>
+  </body>
+</html>
diff --git a/LayoutTests/platform/mac/compositing/images/direct-image-background-color-expected.checksum b/LayoutTests/platform/mac/compositing/images/direct-image-background-color-expected.checksum
new file mode 100644
index 0000000..c443503
--- /dev/null
+++ b/LayoutTests/platform/mac/compositing/images/direct-image-background-color-expected.checksum
@@ -0,0 +1 @@
+f8c00bc140562cb9ba7f315c60ca00e4
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/compositing/images/direct-image-background-color-expected.png b/LayoutTests/platform/mac/compositing/images/direct-image-background-color-expected.png
new file mode 100644
index 0000000..d87c38d
Binary files /dev/null and b/LayoutTests/platform/mac/compositing/images/direct-image-background-color-expected.png differ
diff --git a/LayoutTests/platform/mac/compositing/images/direct-image-background-color-expected.txt b/LayoutTests/platform/mac/compositing/images/direct-image-background-color-expected.txt
new file mode 100644
index 0000000..85ce308
--- /dev/null
+++ b/LayoutTests/platform/mac/compositing/images/direct-image-background-color-expected.txt
@@ -0,0 +1,11 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,20) size 784x564
+      RenderImage {IMG} at (20,0) size 280x200 [bgcolor=#0000807F]
+      RenderBlock {P} at (0,440) size 784x18
+        RenderText {#text} at (0,0) size 242x18
+          text run at (0,0) width 242: "Top and bottom should look the same."
+layer at (28,240) size 280x200
+  RenderImage {IMG} at (20,220) size 280x200 [bgcolor=#0000807F]
diff --git a/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.checksum b/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.checksum
new file mode 100644
index 0000000..db3bf66
--- /dev/null
+++ b/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.checksum
@@ -0,0 +1 @@
+a25fcf2080fe3639a05a8e2df7bbf261
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.png b/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.png
new file mode 100644
index 0000000..b8bb60c
Binary files /dev/null and b/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.png differ
diff --git a/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.txt b/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.txt
new file mode 100644
index 0000000..b540d2b
--- /dev/null
+++ b/LayoutTests/platform/mac/compositing/reflections/simple-composited-reflections-expected.txt
@@ -0,0 +1,18 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,8) size 784x584
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 581x18
+          text run at (0,0) width 581: "Testing reflections on directly composited images. Left and right sides should look the same."
+      RenderBlock (anonymous) at (0,34) size 784x168
+        RenderText {#text} at (224,150) size 4x18
+          text run at (224,150) width 4: " "
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+        RenderText {#text} at (0,0) size 0x0
+layer at (28,62) size 184x124
+  RenderImage {IMG} at (20,20) size 184x124
+layer at (256,62) size 184x124
+  RenderImage {IMG} at (248,20) size 184x124
diff --git a/LayoutTests/platform/mac/compositing/video/video-background-color-expected.checksum b/LayoutTests/platform/mac/compositing/video/video-background-color-expected.checksum
new file mode 100644
index 0000000..090b409
--- /dev/null
+++ b/LayoutTests/platform/mac/compositing/video/video-background-color-expected.checksum
@@ -0,0 +1 @@
+1d4471782bc32ff3631d407e47a93808
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/compositing/video/video-background-color-expected.png b/LayoutTests/platform/mac/compositing/video/video-background-color-expected.png
new file mode 100644
index 0000000..838ffa1
Binary files /dev/null and b/LayoutTests/platform/mac/compositing/video/video-background-color-expected.png differ
diff --git a/LayoutTests/platform/mac/compositing/video/video-background-color-expected.txt b/LayoutTests/platform/mac/compositing/video/video-background-color-expected.txt
new file mode 100644
index 0000000..10573a6
--- /dev/null
+++ b/LayoutTests/platform/mac/compositing/video/video-background-color-expected.txt
@@ -0,0 +1,14 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x600
+  RenderBlock {HTML} at (0,0) size 800x600
+    RenderBody {BODY} at (8,20) size 784x564
+      RenderBlock {DIV} at (20,0) size 260x180 [bgcolor=#0000807F]
+        RenderText {#text} at (0,0) size 0x0
+      RenderBlock {P} at (0,400) size 784x18
+        RenderText {#text} at (0,0) size 242x18
+          text run at (0,0) width 242: "Top and bottom should look the same."
+layer at (28,220) size 260x180
+  RenderVideo {VIDEO} at (20,200) size 260x180 [bgcolor=#0000807F]
+layer at (58,20) size 200x180
+  RenderImage {IMG} at (0,0) size 200x180
diff --git a/LayoutTests/platform/mac/compositing/webgl/webgl-background-color-expected.checksum b/LayoutTests/platform/mac/compositing/webgl/webgl-background-color-expected.checksum
new file mode 100644
index 0000000..d1d8f88
--- /dev/null
+++ b/LayoutTests/platform/mac/compositing/webgl/webgl-background-color-expected.checksum
@@ -0,0 +1 @@
+418036c081491969e6944be3a802ad2a
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/compositing/webgl/webgl-background-color-expected.png b/LayoutTests/platform/mac/compositing/webgl/webgl-background-color-expected.png
new file mode 100644
index 0000000..b260503
Binary files /dev/null and b/LayoutTests/platform/mac/compositing/webgl/webgl-background-color-expected.png differ
diff --git a/LayoutTests/platform/mac/compositing/webgl/webgl-background-color-expected.txt b/LayoutTests/platform/mac/compositing/webgl/webgl-background-color-expected.txt
new file mode 100644
index 0000000..f8a2d66
--- /dev/null
+++ b/LayoutTests/platform/mac/compositing/webgl/webgl-background-color-expected.txt
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x534
+  RenderBlock {HTML} at (0,0) size 800x534
+    RenderBody {BODY} at (8,20) size 784x498
+      RenderBlock {DIV} at (20,0) size 240x200 [bgcolor=#0000807F]
+      RenderBlock (anonymous) at (0,220) size 784x244
+        RenderText {#text} at (0,0) size 0x0
+      RenderBlock {P} at (0,480) size 784x18
+        RenderText {#text} at (0,0) size 242x18
+          text run at (0,0) width 242: "Top and bottom should look the same."
+layer at (28,260) size 240x200
+  RenderHTMLCanvas {CANVAS} at (20,20) size 240x200 [bgcolor=#0000807F]
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 1015b13..a463090 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,47 @@
+2010-01-08  Simon Fraser  <simon.fraser at apple.com>
+
+        Reviewed by Dan Bernstein.
+
+        WebGL canvas paints background color twice
+        https://bugs.webkit.org/show_bug.cgi?id=33361
+
+        Clean up some logic around "directly composited" content: some images, video, and WebGL.
+
+        We previously set the GraphicsLayer background color to the CSS background color
+        in some cases where the box has no other decorations. However, the content 
+        layer's bounds do not correspond with the background box in many cases,
+        and we could end up both painting the background color, and setting it on the layer.
+        
+        Simplify this logic to never use layer background colors, and thus skip allocating
+        backing store only when the element has no visible box decorations.
+
+        Tests: compositing/images/direct-image-background-color.html
+               compositing/reflections/simple-composited-reflections.html
+               compositing/video/video-background-color.html
+               compositing/webgl/webgl-background-color.html
+               compositing/webgl/webgl-blending.html
+
+        * rendering/RenderLayerBacking.h:
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::is3DCanvas): Utility to determine if a RenderObject is a canvas with WebGL
+        (WebCore::RenderLayerBacking::RenderLayerBacking): Remove m_hasDirectlyCompositedContent.
+        (WebCore::RenderLayerBacking::updateGraphicsLayerConfiguration): canUseDirectCompositing()
+        is renamed to isDirectlyCompositedImage() and only applies to images now. 
+        No longer set layer background color.
+        (WebCore::RenderLayerBacking::updateGraphicsLayerGeometry): Just use hasPaintedContent()
+        as the argument to setDrawsContent().
+        (WebCore::hasBoxDecorationsOrBackground): Renamed.
+        (WebCore::RenderLayerBacking::hasNonCompositingContent):
+        (WebCore::hasBoxDecorationsOrBackgroundImage): Renamed from hasBoxDecorations().
+        (WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer): Moved test for
+        hasOverflowControls() into hasNonCompositingContent() and removed the FIXME comment.
+        (WebCore::RenderLayerBacking::containsPaintedContent): New method that decides
+        if the layer (and its non-composited children) has any content that must be painted into backing store.
+        (WebCore::RenderLayerBacking::isDirectlyCompositedImage): Renamed from canUseDirectCompositing()
+        and reduced to only apply to images.
+        (WebCore::RenderLayerBacking::rendererContentChanged): 3D canvas no longer falls under the
+        canUseDirectCompositing() scope.
+
 2010-01-08  Steve Block  <steveblock at google.com>
 
         Reviewed by Darin Adler.
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index f022d67..d38294b 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -57,12 +57,20 @@ namespace WebCore {
 using namespace HTMLNames;
 
 static bool hasBorderOutlineOrShadow(const RenderStyle*);
-static bool hasBoxDecorations(const RenderStyle*);
-static bool hasBoxDecorationsWithBackgroundImage(const RenderStyle*);
+static bool hasBoxDecorationsOrBackground(const RenderStyle*);
+static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle*);
+
+static inline bool is3DCanvas(RenderObject* renderer)
+{
+#if ENABLE(3D_CANVAS)    
+    if (renderer->isCanvas())
+        return static_cast<HTMLCanvasElement*>(renderer->node())->is3D();
+#endif
+    return false;
+}
 
 RenderLayerBacking::RenderLayerBacking(RenderLayer* layer)
     : m_owningLayer(layer)
-    , m_hasDirectlyCompositedContent(false)
     , m_artificiallyInflatedBounds(false)
 {
     createGraphicsLayer();
@@ -186,29 +194,17 @@ bool RenderLayerBacking::updateGraphicsLayerConfiguration()
     if (updateMaskLayer(m_owningLayer->renderer()->hasMask()))
         m_graphicsLayer->setMaskLayer(m_maskLayer.get());
 
-    m_hasDirectlyCompositedContent = false;
-    if (canUseDirectCompositing()) {
-        if (renderer()->isImage()) {
-            updateImageContents();
-            m_hasDirectlyCompositedContent = true;
-            m_graphicsLayer->setDrawsContent(false);
-        }
-#if ENABLE(3D_CANVAS)    
-        else if (renderer()->isCanvas()) {
-            HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
-            if (canvas->is3D()) {
-                WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(canvas->renderingContext());
-                if (context->graphicsContext3D()->platformGraphicsContext3D())
-                    m_graphicsLayer->setContentsToGraphicsContext3D(context->graphicsContext3D());
-            }
-        }
-#endif
+    if (isDirectlyCompositedImage())
+        updateImageContents();
 
-        if (rendererHasBackground())
-            m_graphicsLayer->setBackgroundColor(rendererBackgroundColor());
-        else
-            m_graphicsLayer->clearBackgroundColor();
+#if ENABLE(3D_CANVAS)    
+    if (is3DCanvas(renderer())) {
+        HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
+        WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(canvas->renderingContext());
+        if (context->graphicsContext3D()->platformGraphicsContext3D())
+            m_graphicsLayer->setContentsToGraphicsContext3D(context->graphicsContext3D());
     }
+#endif
 
     return layerConfigChanged;
 }
@@ -351,8 +347,7 @@ void RenderLayerBacking::updateGraphicsLayerGeometry()
     }
 
     m_graphicsLayer->setContentsRect(contentsBox());
-    if (!m_hasDirectlyCompositedContent)
-        m_graphicsLayer->setDrawsContent(!isSimpleContainerCompositingLayer() && !paintingGoesToWindow() && !m_artificiallyInflatedBounds);
+    m_graphicsLayer->setDrawsContent(containsPaintedContent());
 }
 
 void RenderLayerBacking::updateInternalHierarchy()
@@ -498,12 +493,12 @@ static bool hasBorderOutlineOrShadow(const RenderStyle* style)
     return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow();
 }
 
-static bool hasBoxDecorations(const RenderStyle* style)
+static bool hasBoxDecorationsOrBackground(const RenderStyle* style)
 {
     return hasBorderOutlineOrShadow(style) || style->hasBackground();
 }
 
-static bool hasBoxDecorationsWithBackgroundImage(const RenderStyle* style)
+static bool hasBoxDecorationsOrBackgroundImage(const RenderStyle* style)
 {
     return hasBorderOutlineOrShadow(style) || style->hasBackgroundImage();
 }
@@ -563,13 +558,9 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
     // Reject anything that has a border, a border-radius or outline,
     // or any background (color or image).
     // FIXME: we could optimize layers for simple backgrounds.
-    if (hasBoxDecorations(style))
+    if (hasBoxDecorationsOrBackground(style))
         return false;
 
-    // If we have scrollbars or a resizer, need backing store to paint them into.
-    if (m_owningLayer->hasOverflowControls())
-        return false;
-    
     // If we have got this far and the renderer has no children, then we're ok.
     if (!renderObject->firstChild())
         return true;
@@ -584,7 +575,7 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
         
         // Reject anything that has a border, a border-radius or outline,
         // or is not a simple background (no background, or solid color).
-        if (hasBoxDecorationsWithBackgroundImage(style))
+        if (hasBoxDecorationsOrBackgroundImage(style))
             return false;
         
         // Now look at the body's renderer.
@@ -595,7 +586,7 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
         
         style = bodyObject->style();
         
-        if (hasBoxDecorationsWithBackgroundImage(style))
+        if (hasBoxDecorationsOrBackgroundImage(style))
             return false;
 
         // Ceck to see if all the body's children are compositing layers.
@@ -612,9 +603,11 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
     return true;
 }
 
+// Conservative test for having no rendered children.
 bool RenderLayerBacking::hasNonCompositingContent() const
 {
-    // Conservative test for having no rendered children.
+    if (m_owningLayer->hasOverflowControls())
+        return true;
     
     // Some HTML can cause whitespace text nodes to have renderers, like:
     // <div>
@@ -631,7 +624,6 @@ bool RenderLayerBacking::hasNonCompositingContent() const
         }
     }
 
-    // FIXME: test for overflow controls.
     if (m_owningLayer->isStackingContext()) {
         // Use the m_hasCompositingDescendant bit to optimize?
         if (Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList()) {
@@ -665,51 +657,45 @@ bool RenderLayerBacking::hasNonCompositingContent() const
     return false;
 }
 
-// A layer can use direct compositing if the render layer's object is a replaced object and has no children.
-// This allows the GraphicsLayer to display the RenderLayer contents directly; it's used for images.
-bool RenderLayerBacking::canUseDirectCompositing() const
+bool RenderLayerBacking::containsPaintedContent() const
 {
-    RenderObject* renderObject = renderer();
-    
-    // Canvas3D is always direct composited
-#if ENABLE(3D_CANVAS)    
-    if (renderer()->isCanvas()) {
-        HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
-        return canvas->is3D();
-    }
-#endif
-
-    // Reject anything that isn't an image
-    if (!renderObject->isImage() && !renderObject->isVideo())
+    if (isSimpleContainerCompositingLayer() || paintingGoesToWindow() || m_artificiallyInflatedBounds)
         return false;
-    
-    if (renderObject->hasMask() || renderObject->hasReflection())
+
+    if (isDirectlyCompositedImage())
         return false;
 
-    // Video can use an inner layer even if it has box decorations; we draw those into another layer.
-    if (renderObject->isVideo())
-        return true;
-    
-    // Reject anything that would require the image to be drawn via the GraphicsContext,
-    // like border, shadows etc. Solid background color is OK.
-    return !hasBoxDecorationsWithBackgroundImage(renderObject->style());
+    // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
+    // and set background color on the layer in that case, instead of allocating backing store and painting.
+    if (renderer()->isVideo() || is3DCanvas(renderer()))
+        return hasBoxDecorationsOrBackground(renderer()->style());
+
+    return true;
 }
-    
+
+// An image can be directly compositing if it's the sole content of the layer, and has no box decorations
+// that require painting. Direct compositing saves backing store.
+bool RenderLayerBacking::isDirectlyCompositedImage() const
+{
+    RenderObject* renderObject = renderer();
+    return renderObject->isImage()
+            && !renderObject->hasMask() && !renderObject->hasReflection()
+            && !hasBoxDecorationsOrBackground(renderObject->style());
+}
+
 void RenderLayerBacking::rendererContentChanged()
 {
-    if (canUseDirectCompositing()) {
-        if (renderer()->isImage())
-            updateImageContents();
-        else {
+    if (isDirectlyCompositedImage()) {
+        updateImageContents();
+        return;
+    }
+
 #if ENABLE(3D_CANVAS)    
-            if (renderer()->isCanvas()) {
-                HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer()->node());
-                if (canvas->is3D())
-                    m_graphicsLayer->setGraphicsContext3DNeedsDisplay();
-            }
-#endif
-        }
+    if (is3DCanvas(renderer())) {
+        m_graphicsLayer->setGraphicsContext3DNeedsDisplay();
+        return;
     }
+#endif
 }
 
 void RenderLayerBacking::updateImageContents()
diff --git a/WebCore/rendering/RenderLayerBacking.h b/WebCore/rendering/RenderLayerBacking.h
index cb80255..7aea926 100644
--- a/WebCore/rendering/RenderLayerBacking.h
+++ b/WebCore/rendering/RenderLayerBacking.h
@@ -149,12 +149,12 @@ private:
     // Return the opacity value that this layer should use for compositing.
     float compositingOpacity(float rendererOpacity) const;
     
-    // Returns true if this RenderLayer only has content that can be rendered directly
-    // by the compositing layer, without drawing (e.g. solid background color).
+    // Returns true if this compositing layer has no visible content.
     bool isSimpleContainerCompositingLayer() const;
-    // Returns true if we can optimize the RenderLayer to draw the replaced content
-    // directly into a compositing buffer
-    bool canUseDirectCompositing() const;
+    // Returns true if this layer has content that needs to be rendered by painting into the backing store.
+    bool containsPaintedContent() const;
+    // Returns true if the RenderLayer just contains an image that we can composite directly.
+    bool isDirectlyCompositedImage() const;
     void updateImageContents();
 
     bool rendererHasBackground() const;
@@ -179,7 +179,6 @@ private:
 
     IntRect m_compositedBounds;
 
-    bool m_hasDirectlyCompositedContent;
     bool m_artificiallyInflatedBounds;      // bounds had to be made non-zero to make transform-origin work
 };
 

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list