Title: [142012] trunk
Revision
142012
Author
shawnsi...@chromium.org
Date
2013-02-06 11:35:21 -0800 (Wed, 06 Feb 2013)

Log Message

RenderLayer hasVisibleContent() has inconsistent semantics causing disappearing composited layers
https://bugs.webkit.org/show_bug.cgi?id=108118

Reviewed by Simon Fraser.

Source/WebCore:

RenderLayerBacking::hasVisibleNonCompositingDescendantLayers was
only checking whether direct children had visible content. As a
result, composited layers had wrong visibility status if only a
deeper descendant RenderLayer was visible.

Test: compositing/visibility/visibility-on-distant-descendant.html

* rendering/RenderLayerBacking.cpp:
(WebCore::hasVisibleNonCompositingDescendant): copied the original
implementation into this function; then added the RenderLayer
recursion as appropriate.
(WebCore):
(WebCore::RenderLayerBacking::hasVisibleNonCompositingDescendantLayers):
This is now just a wrapper to the private static recursive
function.

LayoutTests:

* compositing/visibility/visibility-on-distant-descendant-expected.png: Added.
* compositing/visibility/visibility-on-distant-descendant-expected.txt: Added.
* compositing/visibility/visibility-on-distant-descendant.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (142011 => 142012)


--- trunk/LayoutTests/ChangeLog	2013-02-06 19:07:27 UTC (rev 142011)
+++ trunk/LayoutTests/ChangeLog	2013-02-06 19:35:21 UTC (rev 142012)
@@ -1,3 +1,14 @@
+2013-02-06  Shawn Singh  <shawnsi...@chromium.org>
+
+        RenderLayer hasVisibleContent() has inconsistent semantics causing disappearing composited layers
+        https://bugs.webkit.org/show_bug.cgi?id=108118
+
+        Reviewed by Simon Fraser.
+
+        * compositing/visibility/visibility-on-distant-descendant-expected.png: Added.
+        * compositing/visibility/visibility-on-distant-descendant-expected.txt: Added.
+        * compositing/visibility/visibility-on-distant-descendant.html: Added.
+
 2013-02-06  Gregg Tavares  <g...@chromium.org>
 
         Adds the WebGL Conformance Test ogles support files.

Added: trunk/LayoutTests/compositing/visibility/visibility-on-distant-descendant-expected.png (0 => 142012)


--- trunk/LayoutTests/compositing/visibility/visibility-on-distant-descendant-expected.png	                        (rev 0)
+++ trunk/LayoutTests/compositing/visibility/visibility-on-distant-descendant-expected.png	2013-02-06 19:35:21 UTC (rev 142012)
@@ -0,0 +1,6 @@
+\x89PNG
+
+
+IHDR X\x9Av\x82p)tEXtchecksumd55c7583354eace2d81866730c07fabcKWJ:yIDATx\x9C\xED\xD9\xC1
+\x800\xC1@\xE3ะน\xE9b\xA3\x88\x99
+\xEEei\xE5k\xBDk\xC0\xE6q\xAE\xE0t\xF7\xEE\xC0 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\x8C2\xC8 #@\x80\xCC53\xB3{\xF0> @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d\x90 @F\x80d>	\xA71\xA1PIEND\xAEB`\x82
\ No newline at end of file

Added: trunk/LayoutTests/compositing/visibility/visibility-on-distant-descendant-expected.txt (0 => 142012)


--- trunk/LayoutTests/compositing/visibility/visibility-on-distant-descendant-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/compositing/visibility/visibility-on-distant-descendant-expected.txt	2013-02-06 19:35:21 UTC (rev 142012)
@@ -0,0 +1,13 @@
+layer at (0,0) size 800x600
+  RenderView at (0,0) size 800x600
+layer at (0,0) size 800x8
+  RenderBlock {HTML} at (0,0) size 800x8
+    RenderBody {BODY} at (8,8) size 784x0
+      RenderBlock {DIV} at (0,0) size 784x0
+layer at (0,0) size 300x300
+  RenderBlock (positioned) {DIV} at (0,0) size 300x300 [bgcolor=#FF0000]
+layer at (0,0) size 300x300
+  RenderBlock (positioned) {DIV} at (0,0) size 300x300
+layer at (0,0) size 300x300
+  RenderBlock (positioned) zI: 5 {DIV} at (0,0) size 300x300
+    RenderBlock {DIV} at (0,0) size 300x300 [bgcolor=#008000]

Added: trunk/LayoutTests/compositing/visibility/visibility-on-distant-descendant.html (0 => 142012)


--- trunk/LayoutTests/compositing/visibility/visibility-on-distant-descendant.html	                        (rev 0)
+++ trunk/LayoutTests/compositing/visibility/visibility-on-distant-descendant.html	2013-02-06 19:35:21 UTC (rev 142012)
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+  <style type="text/css" media="screen">
+    .hidden {
+        visibility: hidden;
+    }
+
+    .visible {
+        visibility: visible;
+    }
+
+    .box {
+        width: 300px;
+        height: 300px;
+    }
+
+    .composited {
+        -webkit-transform: translatez(0);
+    }
+
+    .topLeft {
+        position: absolute;
+        top: 0px;
+        left: 0px;
+    }
+
+    .stackingContext {
+        position: absolute;
+        z-index: 5;
+    }
+
+    .red {
+        background-color: red;
+    }
+
+    .green {
+        background-color: green;
+    }
+  </style>
+</head>
+<body>
+  <!--
+    https://bugs.webkit.org/show_bug.cgi?id=108118
+
+    The boolean check RenderLayerBacking::hasVisibleNonCompositingDescendant()
+    was actually not checking for visible content beyond children layers. As a
+    result, composited layers sometimes did not see that they actually have
+    visible content in a descendant RenderLayer. This test recreates that
+    scenario by using visibility:hidden stacking contexts to create a deeper
+    hierarchy of RenderLayers within on composited layer.
+
+    The green box should be visible, hiding the red box.
+  -->
+  <div>
+
+    <div class="topLeft red box">
+    </div>
+
+    <div class="composited topLeft hidden box">
+      <div class="hidden stackingContext">
+        <div class="hidden stackingContext">
+          <div class="visible green box">
+          </div>
+        </div>
+      </div>
+    </div>
+
+  </div>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (142011 => 142012)


--- trunk/Source/WebCore/ChangeLog	2013-02-06 19:07:27 UTC (rev 142011)
+++ trunk/Source/WebCore/ChangeLog	2013-02-06 19:35:21 UTC (rev 142012)
@@ -1,3 +1,26 @@
+2013-02-06  Shawn Singh  <shawnsi...@chromium.org>
+
+        RenderLayer hasVisibleContent() has inconsistent semantics causing disappearing composited layers
+        https://bugs.webkit.org/show_bug.cgi?id=108118
+
+        Reviewed by Simon Fraser.
+
+        RenderLayerBacking::hasVisibleNonCompositingDescendantLayers was
+        only checking whether direct children had visible content. As a
+        result, composited layers had wrong visibility status if only a
+        deeper descendant RenderLayer was visible.
+
+        Test: compositing/visibility/visibility-on-distant-descendant.html
+
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::hasVisibleNonCompositingDescendant): copied the original
+        implementation into this function; then added the RenderLayer
+        recursion as appropriate.
+        (WebCore):
+        (WebCore::RenderLayerBacking::hasVisibleNonCompositingDescendantLayers):
+        This is now just a wrapper to the private static recursive
+        function.
+
 2013-02-06  Jonathon Jongsma  <jonathon.jong...@collabora.com>
 
         [GStreamer] MediaPlayer's code is not easily reusable by other GStreamer-based players

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (142011 => 142012)


--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2013-02-06 19:07:27 UTC (rev 142011)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp	2013-02-06 19:35:21 UTC (rev 142012)
@@ -1429,44 +1429,39 @@
     return true;
 }
 
-// Conservative test for having no rendered children.
-bool RenderLayerBacking::hasVisibleNonCompositingDescendantLayers() const
+static bool hasVisibleNonCompositingDescendant(RenderLayer* parent)
 {
-    // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
-    m_owningLayer->updateLayerListsIfNeeded();
-
-#if !ASSERT_DISABLED
-    LayerListMutationDetector mutationChecker(m_owningLayer);
-#endif
-
-    if (Vector<RenderLayer*>* normalFlowList = m_owningLayer->normalFlowList()) {
+    if (Vector<RenderLayer*>* normalFlowList = parent->normalFlowList()) {
         size_t listSize = normalFlowList->size();
         for (size_t i = 0; i < listSize; ++i) {
             RenderLayer* curLayer = normalFlowList->at(i);
-            if (!curLayer->isComposited() && curLayer->hasVisibleContent())
+            if (!curLayer->isComposited()
+                && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
                 return true;
         }
     }
 
-    if (m_owningLayer->isStackingContainer()) {
-        if (!m_owningLayer->hasVisibleDescendant())
+    if (parent->isStackingContainer()) {
+        if (!parent->hasVisibleDescendant())
             return false;
 
         // Use the m_hasCompositingDescendant bit to optimize?
-        if (Vector<RenderLayer*>* negZOrderList = m_owningLayer->negZOrderList()) {
+        if (Vector<RenderLayer*>* negZOrderList = parent->negZOrderList()) {
             size_t listSize = negZOrderList->size();
             for (size_t i = 0; i < listSize; ++i) {
                 RenderLayer* curLayer = negZOrderList->at(i);
-                if (!curLayer->isComposited() && curLayer->hasVisibleContent())
+                if (!curLayer->isComposited()
+                    && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
                     return true;
             }
         }
 
-        if (Vector<RenderLayer*>* posZOrderList = m_owningLayer->posZOrderList()) {
+        if (Vector<RenderLayer*>* posZOrderList = parent->posZOrderList()) {
             size_t listSize = posZOrderList->size();
             for (size_t i = 0; i < listSize; ++i) {
                 RenderLayer* curLayer = posZOrderList->at(i);
-                if (!curLayer->isComposited() && curLayer->hasVisibleContent())
+                if (!curLayer->isComposited()
+                    && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
                     return true;
             }
         }
@@ -1475,6 +1470,19 @@
     return false;
 }
 
+// Conservative test for having no rendered children.
+bool RenderLayerBacking::hasVisibleNonCompositingDescendantLayers() const
+{
+    // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
+    m_owningLayer->updateLayerListsIfNeeded();
+
+#if !ASSERT_DISABLED
+    LayerListMutationDetector mutationChecker(m_owningLayer);
+#endif
+
+    return hasVisibleNonCompositingDescendant(m_owningLayer);
+}
+
 bool RenderLayerBacking::containsPaintedContent() const
 {
     if (isSimpleContainerCompositingLayer() || paintsIntoWindow() || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer->isReflection())
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to