<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[208981] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/208981">208981</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2016-11-26 18:06:59 -0800 (Sat, 26 Nov 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Composited negative z-index elements are hidden behind the body sometimes
https://bugs.webkit.org/show_bug.cgi?id=165080
rdar://problem/22260229

Reviewed by Zalan Bujtas.

Source/WebCore:

If the &lt;body&gt; falls into the &quot;directly composited background color&quot; code path
(say, because it's composited because of composited negative z-index children,
and has content of its own), then we failed to take root background propagation
into account, and put the opaque root background color on the body's layer.

Fix by sharing some code from RenderBox related to whether the body's renderer
paints its background.

Tests cover the buggy case, and the case where the &lt;html&gt; has its own background color.

Tests: compositing/backgrounds/negative-z-index-behind-body-non-propagated.html
       compositing/backgrounds/negative-z-index-behind-body.html

* rendering/RenderBox.cpp:
(WebCore::RenderBox::paintsOwnBackground):
(WebCore::RenderBox::paintBackground):
(WebCore::RenderBox::backgroundIsKnownToBeOpaqueInRect):
(WebCore::skipBodyBackground): Deleted.
* rendering/RenderBox.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateDirectlyCompositedBackgroundColor):

LayoutTests:

* compositing/backgrounds/negative-z-index-behind-body-expected.html: Added.
* compositing/backgrounds/negative-z-index-behind-body-non-propagated-expected.html: Added.
* compositing/backgrounds/negative-z-index-behind-body-non-propagated.html: Added.
* compositing/backgrounds/negative-z-index-behind-body.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBoxcpp">trunk/Source/WebCore/rendering/RenderBox.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderBoxh">trunk/Source/WebCore/rendering/RenderBox.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerBackingcpp">trunk/Source/WebCore/rendering/RenderLayerBacking.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscompositingbackgroundsnegativezindexbehindbodyexpectedhtml">trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-expected.html</a></li>
<li><a href="#trunkLayoutTestscompositingbackgroundsnegativezindexbehindbodynonpropagatedexpectedhtml">trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-non-propagated-expected.html</a></li>
<li><a href="#trunkLayoutTestscompositingbackgroundsnegativezindexbehindbodynonpropagatedhtml">trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-non-propagated.html</a></li>
<li><a href="#trunkLayoutTestscompositingbackgroundsnegativezindexbehindbodyhtml">trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (208980 => 208981)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-11-26 23:35:11 UTC (rev 208980)
+++ trunk/LayoutTests/ChangeLog        2016-11-27 02:06:59 UTC (rev 208981)
</span><span class="lines">@@ -1,5 +1,18 @@
</span><span class="cx"> 2016-11-26  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Composited negative z-index elements are hidden behind the body sometimes
+        https://bugs.webkit.org/show_bug.cgi?id=165080
+        rdar://problem/22260229
+
+        Reviewed by Zalan Bujtas.
+
+        * compositing/backgrounds/negative-z-index-behind-body-expected.html: Added.
+        * compositing/backgrounds/negative-z-index-behind-body-non-propagated-expected.html: Added.
+        * compositing/backgrounds/negative-z-index-behind-body-non-propagated.html: Added.
+        * compositing/backgrounds/negative-z-index-behind-body.html: Added.
+
+2016-11-26  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
</ins><span class="cx">         Convert testharnessreport.js to LF linebreaks, from CRLF, which broke patches.
</span><span class="cx"> 
</span><span class="cx">         * resources/testharnessreport.js:
</span></span></pre></div>
<a id="trunkLayoutTestscompositingbackgroundsnegativezindexbehindbodyexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-expected.html (0 => 208981)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-expected.html                                (rev 0)
+++ trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-expected.html        2016-11-27 02:06:59 UTC (rev 208981)
</span><span class="lines">@@ -0,0 +1,9 @@
</span><ins>+&lt;style&gt;
+.green {
+    background-color: green;
+    width: 200px;
+    height: 200px;
+}
+&lt;/style&gt;
+&lt;body&gt;
+&lt;div class=&quot;green&quot;&gt;&lt;/div&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscompositingbackgroundsnegativezindexbehindbodynonpropagatedexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-non-propagated-expected.html (0 => 208981)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-non-propagated-expected.html                                (rev 0)
+++ trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-non-propagated-expected.html        2016-11-27 02:06:59 UTC (rev 208981)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+&lt;style&gt;
+html {
+    background: gray;
+}
+body {
+    background: silver;
+}
+
+div {
+    position: absolute;
+    z-index: -1;
+}
+.green {
+    background-color: green;
+    width: 200px;
+    height: 200px;
+}
+&lt;/style&gt;
+&lt;body&gt;
+&lt;div class=&quot;green&quot;&gt;&lt;/div&gt;
+&lt;div&gt;&lt;/div&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscompositingbackgroundsnegativezindexbehindbodynonpropagatedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-non-propagated.html (0 => 208981)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-non-propagated.html                                (rev 0)
+++ trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-non-propagated.html        2016-11-27 02:06:59 UTC (rev 208981)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+&lt;style&gt;
+html {
+    background: gray;
+}
+body {
+    position: relative;
+    background: silver;
+}
+
+div {
+    position: absolute;
+    z-index: -1;
+    transform: translateZ(0);
+}
+.green {
+    background-color: green;
+    width: 200px;
+    height: 200px;
+}
+&lt;/style&gt;
+&lt;body&gt;
+&lt;div class=&quot;green&quot;&gt;&lt;/div&gt;
+&lt;div&gt;&lt;/div&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscompositingbackgroundsnegativezindexbehindbodyhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body.html (0 => 208981)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body.html                                (rev 0)
+++ trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body.html        2016-11-27 02:06:59 UTC (rev 208981)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+&lt;style&gt;
+body {
+    position: relative;
+    background: white;
+}
+
+div {
+    position: absolute;
+    z-index: -1;
+    transform: translateZ(0);
+}
+
+.green {
+    background-color: green;
+    width: 200px;
+    height: 200px;
+}
+&lt;/style&gt;
+&lt;body&gt;
+&lt;div class=&quot;green&quot;&gt;&lt;/div&gt;
+&lt;div&gt;&lt;/div&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (208980 => 208981)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-11-26 23:35:11 UTC (rev 208980)
+++ trunk/Source/WebCore/ChangeLog        2016-11-27 02:06:59 UTC (rev 208981)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2016-11-26  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Composited negative z-index elements are hidden behind the body sometimes
+        https://bugs.webkit.org/show_bug.cgi?id=165080
+        rdar://problem/22260229
+
+        Reviewed by Zalan Bujtas.
+
+        If the &lt;body&gt; falls into the &quot;directly composited background color&quot; code path
+        (say, because it's composited because of composited negative z-index children,
+        and has content of its own), then we failed to take root background propagation
+        into account, and put the opaque root background color on the body's layer.
+
+        Fix by sharing some code from RenderBox related to whether the body's renderer
+        paints its background.
+        
+        Tests cover the buggy case, and the case where the &lt;html&gt; has its own background color.
+
+        Tests: compositing/backgrounds/negative-z-index-behind-body-non-propagated.html
+               compositing/backgrounds/negative-z-index-behind-body.html
+
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::paintsOwnBackground):
+        (WebCore::RenderBox::paintBackground):
+        (WebCore::RenderBox::backgroundIsKnownToBeOpaqueInRect):
+        (WebCore::skipBodyBackground): Deleted.
+        * rendering/RenderBox.h:
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateDirectlyCompositedBackgroundColor):
+
</ins><span class="cx"> 2016-11-25  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSS Font Loading] FontFace.load() promises don't always fire
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (208980 => 208981)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.cpp        2016-11-26 23:35:11 UTC (rev 208980)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp        2016-11-27 02:06:59 UTC (rev 208981)
</span><span class="lines">@@ -130,17 +130,6 @@
</span><span class="cx"> 
</span><span class="cx"> bool RenderBox::s_hadOverflowClip = false;
</span><span class="cx"> 
</span><del>-static bool skipBodyBackground(const RenderBox* bodyElementRenderer)
-{
-    ASSERT(bodyElementRenderer-&gt;isBody());
-    // The &lt;body&gt; only paints its background if the root element has defined a background independent of the body,
-    // or if the &lt;body&gt;'s parent is not the document element's renderer (e.g. inside SVG foreignObject).
-    auto documentElementRenderer = bodyElementRenderer-&gt;document().documentElement()-&gt;renderer();
-    return documentElementRenderer
-        &amp;&amp; !documentElementRenderer-&gt;hasBackground()
-        &amp;&amp; (documentElementRenderer == bodyElementRenderer-&gt;parent());
-}
-
</del><span class="cx"> RenderBox::RenderBox(Element&amp; element, RenderStyle&amp;&amp; style, BaseTypeFlags baseTypeFlags)
</span><span class="cx">     : RenderBoxModelObject(element, WTFMove(style), baseTypeFlags)
</span><span class="cx"> {
</span><span class="lines">@@ -1383,6 +1372,20 @@
</span><span class="cx">         paintInfo.context().endTransparencyLayer();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool RenderBox::paintsOwnBackground() const
+{
+    if (isBody()) {
+        // The &lt;body&gt; only paints its background if the root element has defined a background independent of the body,
+        // or if the &lt;body&gt;'s parent is not the document element's renderer (e.g. inside SVG foreignObject).
+        auto documentElementRenderer = document().documentElement()-&gt;renderer();
+        return !documentElementRenderer
+            || documentElementRenderer-&gt;hasBackground()
+            || (documentElementRenderer != parent());
+    }
+    
+    return true;
+}
+
</ins><span class="cx"> void RenderBox::paintBackground(const PaintInfo&amp; paintInfo, const LayoutRect&amp; paintRect, BackgroundBleedAvoidance bleedAvoidance)
</span><span class="cx"> {
</span><span class="cx">     if (isDocumentElementRenderer()) {
</span><span class="lines">@@ -1389,10 +1392,13 @@
</span><span class="cx">         paintRootBoxFillLayers(paintInfo);
</span><span class="cx">         return;
</span><span class="cx">     }
</span><del>-    if (isBody() &amp;&amp; skipBodyBackground(this))
</del><ins>+
+    if (!paintsOwnBackground())
</ins><span class="cx">         return;
</span><ins>+
</ins><span class="cx">     if (backgroundIsKnownToBeObscured(paintRect.location()) &amp;&amp; !boxShadowShouldBeAppliedToBackground(paintRect.location(), bleedAvoidance))
</span><span class="cx">         return;
</span><ins>+
</ins><span class="cx">     paintFillLayers(paintInfo, style().visitedDependentColor(CSSPropertyBackgroundColor), style().backgroundLayers(), paintRect, bleedAvoidance);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -1419,7 +1425,7 @@
</span><span class="cx"> 
</span><span class="cx"> bool RenderBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect&amp; localRect) const
</span><span class="cx"> {
</span><del>-    if (isBody() &amp;&amp; skipBodyBackground(this))
</del><ins>+    if (!paintsOwnBackground())
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     Color backgroundColor = style().visitedDependentColor(CSSPropertyBackgroundColor);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderBoxh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderBox.h (208980 => 208981)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderBox.h        2016-11-26 23:35:11 UTC (rev 208980)
+++ trunk/Source/WebCore/rendering/RenderBox.h        2016-11-27 02:06:59 UTC (rev 208981)
</span><span class="lines">@@ -56,6 +56,9 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect&amp; localRect) const final;
</span><ins>+    
+    // Returns false for the body renderer if its background is propagated to the root.
+    bool paintsOwnBackground() const;
</ins><span class="cx"> 
</span><span class="cx">     // Use this with caution! No type checking is done!
</span><span class="cx">     RenderBox* firstChildBox() const;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerBackingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (208980 => 208981)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2016-11-26 23:35:11 UTC (rev 208980)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2016-11-27 02:06:59 UTC (rev 208981)
</span><span class="lines">@@ -1809,7 +1809,7 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(bool isSimpleContainer, bool&amp; didUpdateContentsRect)
</span><span class="cx"> {
</span><del>-    if (!isSimpleContainer) {
</del><ins>+    if (!isSimpleContainer || (is&lt;RenderBox&gt;(renderer()) &amp;&amp; !downcast&lt;RenderBox&gt;(renderer()).paintsOwnBackground())) {
</ins><span class="cx">         m_graphicsLayer-&gt;setContentsToSolidColor(Color());
</span><span class="cx">         return;
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>