Adding a mask on a simple color compositing layer removes the content
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Jun 2014 19:00:32 +0000 (19:00 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 23 Jun 2014 19:00:32 +0000 (19:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134127

Reviewed by Dean Jackson.

Source/WebCore:

In r169053 I moved some updateDrawsContent() into updateAfterDescendents(),
but this isn't called when a composited layer gains or loses a mask (which
doesn't cause a layout). This caused us to fail to allocate backing store
when gaining a mask, resulting in missing content.

Fix by calling updateAfterDescendents() from RenderLayer::styleChange()
when the layer config isn't changing.

Also remove a condition in isSimpleContainerCompositingLayer() that caused us
to fall off the simple layer path for masked layers, since this works just
fine.

Test: compositing/masks/solid-color-masked.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::calculateClipRects):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer):

LayoutTests:

* compositing/masks/mask-layer-size-expected.txt:
* compositing/masks/solid-color-masked-expected.html: Added.
* compositing/masks/solid-color-masked.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/compositing/masks/mask-layer-size-expected.txt
LayoutTests/compositing/masks/solid-color-masked-expected.html [new file with mode: 0644]
LayoutTests/compositing/masks/solid-color-masked.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayerBacking.cpp

index 870b258..01e0a15 100644 (file)
@@ -1,3 +1,14 @@
+2014-06-23  Simon Fraser  <simon.fraser@apple.com>
+
+        Adding a mask on a simple color compositing layer removes the content
+        https://bugs.webkit.org/show_bug.cgi?id=134127
+
+        Reviewed by Dean Jackson.
+
+        * compositing/masks/mask-layer-size-expected.txt:
+        * compositing/masks/solid-color-masked-expected.html: Added.
+        * compositing/masks/solid-color-masked.html: Added.
+
 2014-06-23  David Hyatt  <hyatt@apple.com>
 
         [New Multicolumn] Writing mode changes on the <html> and RenderView need to
index 96cc620..e64409a 100644 (file)
@@ -10,7 +10,6 @@
           (position 10.00 10.00)
           (bounds 400.00 200.00)
           (contentsOpaque 1)
-          (drawsContent 1)
         )
       )
     )
diff --git a/LayoutTests/compositing/masks/solid-color-masked-expected.html b/LayoutTests/compositing/masks/solid-color-masked-expected.html
new file mode 100644 (file)
index 0000000..9b6d9b3
--- /dev/null
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+          width: 100px;
+          height: 100px;
+          background-color: blue;
+        }
+        
+        .composited {
+          -webkit-transform: translateZ(0);
+        }
+
+        .masked {
+            -webkit-mask-image: linear-gradient(black, transparent);
+        }
+    </style>
+</head>
+<body>
+<div id="box" class="masked composited box">
+</div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/masks/solid-color-masked.html b/LayoutTests/compositing/masks/solid-color-masked.html
new file mode 100644 (file)
index 0000000..86834aa
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <style>
+        .box {
+          width: 100px;
+          height: 100px;
+          background-color: blue;
+        }
+        
+        .composited {
+          -webkit-transform: translateZ(0);
+        }
+
+        .masked {
+            -webkit-mask-image: linear-gradient(black, transparent);
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+        function doTest()
+        {
+            window.setTimeout(function() {
+                document.getElementById('box').classList.add('masked');
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+<div id="box" class="composited box">
+</div>
+</body>
+</html>
index 61cd74f..1da55d8 100644 (file)
@@ -1,3 +1,29 @@
+2014-06-23  Simon Fraser  <simon.fraser@apple.com>
+
+        Adding a mask on a simple color compositing layer removes the content
+        https://bugs.webkit.org/show_bug.cgi?id=134127
+
+        Reviewed by Dean Jackson.
+        
+        In r169053 I moved some updateDrawsContent() into updateAfterDescendents(),
+        but this isn't called when a composited layer gains or loses a mask (which
+        doesn't cause a layout). This caused us to fail to allocate backing store
+        when gaining a mask, resulting in missing content.
+        
+        Fix by calling updateAfterDescendents() from RenderLayer::styleChange()
+        when the layer config isn't changing.
+        
+        Also remove a condition in isSimpleContainerCompositingLayer() that caused us
+        to fall off the simple layer path for masked layers, since this works just
+        fine.
+
+        Test: compositing/masks/solid-color-masked.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::calculateClipRects):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer):
+
 2014-06-23  David Hyatt  <hyatt@apple.com>
 
         [New Multicolumn] Writing mode changes on the <html> and RenderView need to
index 0c0a923..6c36338 100644 (file)
@@ -6395,8 +6395,11 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle
         || needsCompositingLayersRebuiltForClip(oldStyle, &newStyle)
         || needsCompositingLayersRebuiltForOverflow(oldStyle, &newStyle))
         compositor().setCompositingLayersNeedRebuild();
-    else if (isComposited())
+    else if (isComposited()) {
+        // FIXME: updating geometry here is potentially harmful, because layout is not up-to-date.
         backing()->updateGeometry();
+        backing()->updateAfterDescendents();
+    }
 
     if (oldStyle) {
         // Compositing layers keep track of whether they are clipped by any of the ancestors.
index 45cc8a5..656af19 100644 (file)
@@ -1703,9 +1703,6 @@ static bool isCompositedPlugin(RenderObject* renderer)
 // This is a useful optimization, because it allows us to avoid allocating backing store.
 bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
 {
-    if (renderer().hasMask()) // masks require special treatment
-        return false;
-
     if (renderer().isReplaced() && (!isCompositedPlugin(&renderer()) || isRestartedPlugin(&renderer())))
         return false;