Garbage at the top of http://www.technologyreview.com after scrolling
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Apr 2013 01:27:20 +0000 (01:27 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 25 Apr 2013 01:27:20 +0000 (01:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=114825

Source/WebCore:

Reviewed by Tim Horton.

Garbage pixels are caused by GraphicsLayerCA setting a layer to be opaque,
but then not painting anything into it. On this page, the element is
toggled to be visibility:hidden on scrolling, but RenderLayer::backgroundIsKnownToBeOpaqueInRect()
failed to consider that as something that can cause backgrounds not to be opaque.

For the bug to happen, some subtle interactions with r142012 come into play
for the layer to remain visible, hence the slightly complex testcase.

Test: compositing/contents-opaque/visibility-hidden.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::backgroundIsKnownToBeOpaqueInRect):

LayoutTests:

Reviewed by Tim Horton.

Test that sets visibility:hidden on an element with some complex
configuration of layer children, and dumps the layer tree to check
that the contents are not marked as opaque.

* compositing/contents-opaque/visibility-hidden-expected.txt: Added.
* compositing/contents-opaque/visibility-hidden.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/compositing/contents-opaque/visibility-hidden-expected.txt [new file with mode: 0644]
LayoutTests/compositing/contents-opaque/visibility-hidden.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp

index df88191..20b0c61 100644 (file)
@@ -1,3 +1,17 @@
+2013-04-24  Simon Fraser  <simon.fraser@apple.com>
+
+        Garbage at the top of http://www.technologyreview.com after scrolling
+        https://bugs.webkit.org/show_bug.cgi?id=114825
+
+        Reviewed by Tim Horton.
+        
+        Test that sets visibility:hidden on an element with some complex
+        configuration of layer children, and dumps the layer tree to check
+        that the contents are not marked as opaque.
+
+        * compositing/contents-opaque/visibility-hidden-expected.txt: Added.
+        * compositing/contents-opaque/visibility-hidden.html: Added.
+
 2013-04-24  David Kilzer  <ddkilzer@apple.com>
 
         Fix invalid test names in jsc-test-list
diff --git a/LayoutTests/compositing/contents-opaque/visibility-hidden-expected.txt b/LayoutTests/compositing/contents-opaque/visibility-hidden-expected.txt
new file mode 100644 (file)
index 0000000..100d7d0
--- /dev/null
@@ -0,0 +1,17 @@
+(GraphicsLayer
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 20.00)
+          (bounds 200.00 50.00)
+          (drawsContent 1)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/contents-opaque/visibility-hidden.html b/LayoutTests/compositing/contents-opaque/visibility-hidden.html
new file mode 100644 (file)
index 0000000..3bd90e7
--- /dev/null
@@ -0,0 +1,54 @@
+<html>
+    <head>
+        <style type="text/css">
+            header {
+                position: absolute;
+                top: 20px;
+                width: 200px;
+                height: 50px;
+                background-color: silver;
+                -webkit-transform: translateZ(0);
+            }
+            
+            header.hidden {
+                visibility: hidden;
+            }
+            
+            nav {
+                height: 37px;
+                overflow: hidden;
+            }
+            
+            nav ul li {
+                height: 50px;
+                float: left;
+                overflow: hidden;
+            }
+            
+        </style>
+        <script type="text/javascript">
+            if (window.testRunner)
+                testRunner.dumpAsText();
+
+            function doTest() {
+                var header = document.getElementsByTagName('header')[0];
+                header.classList.toggle('hidden');
+                if (window.testRunner && window.internals)
+                    document.getElementById('layertree').innerText = window.internals.layerTreeAsText(document);
+            }
+            window.addEventListener('load', doTest, false);
+        </script>
+    </head>
+
+<body>
+    <header> 
+        <nav> 
+            <ul>
+                <li>Some text here</li>
+            </ul>
+        </nav> 
+    </header>
+    
+    <pre id="layertree"></pre> 
+</body>
+</html>
index 41e3997..6251ad3 100644 (file)
@@ -1,5 +1,25 @@
 2013-04-24  Simon Fraser  <simon.fraser@apple.com>
 
+        Garbage at the top of http://www.technologyreview.com after scrolling
+        https://bugs.webkit.org/show_bug.cgi?id=114825
+
+        Reviewed by Tim Horton.
+
+        Garbage pixels are caused by GraphicsLayerCA setting a layer to be opaque,
+        but then not painting anything into it. On this page, the element is
+        toggled to be visibility:hidden on scrolling, but RenderLayer::backgroundIsKnownToBeOpaqueInRect()
+        failed to consider that as something that can cause backgrounds not to be opaque.
+        
+        For the bug to happen, some subtle interactions with r142012 come into play
+        for the layer to remain visible, hence the slightly complex testcase.
+        
+        Test: compositing/contents-opaque/visibility-hidden.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::backgroundIsKnownToBeOpaqueInRect):
+
+2013-04-24  Simon Fraser  <simon.fraser@apple.com>
+
         Dump layer opaqueness in the Compositing log output
         https://bugs.webkit.org/show_bug.cgi?id=115132
 
index 0605675..2374647 100644 (file)
@@ -5564,6 +5564,10 @@ bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect)
     if (paintsWithTransparency(PaintBehaviorNormal))
         return false;
 
+    ASSERT(!m_visibleContentStatusDirty);
+    if (!hasVisibleContent())
+        return false;
+
 #if ENABLE(CSS_FILTERS)
     if (paintsWithFilters() && renderer()->style()->filter().hasFilterThatAffectsOpacity())
         return false;