Title: [208981] trunk
Revision
208981
Author
[email protected]
Date
2016-11-26 18:06:59 -0800 (Sat, 26 Nov 2016)

Log Message

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 <body> falls into the "directly composited background color" 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 <html> 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.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (208980 => 208981)


--- trunk/LayoutTests/ChangeLog	2016-11-26 23:35:11 UTC (rev 208980)
+++ trunk/LayoutTests/ChangeLog	2016-11-27 02:06:59 UTC (rev 208981)
@@ -1,5 +1,18 @@
 2016-11-26  Simon Fraser  <[email protected]>
 
+        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  <[email protected]>
+
         Convert testharnessreport.js to LF linebreaks, from CRLF, which broke patches.
 
         * resources/testharnessreport.js:

Added: trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-expected.html (0 => 208981)


--- 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)
@@ -0,0 +1,9 @@
+<style>
+.green {
+    background-color: green;
+    width: 200px;
+    height: 200px;
+}
+</style>
+<body>
+<div class="green"></div>

Added: trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-non-propagated-expected.html (0 => 208981)


--- 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)
@@ -0,0 +1,21 @@
+<style>
+html {
+    background: gray;
+}
+body {
+    background: silver;
+}
+
+div {
+    position: absolute;
+    z-index: -1;
+}
+.green {
+    background-color: green;
+    width: 200px;
+    height: 200px;
+}
+</style>
+<body>
+<div class="green"></div>
+<div></div>

Added: trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body-non-propagated.html (0 => 208981)


--- 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)
@@ -0,0 +1,23 @@
+<style>
+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;
+}
+</style>
+<body>
+<div class="green"></div>
+<div></div>

Added: trunk/LayoutTests/compositing/backgrounds/negative-z-index-behind-body.html (0 => 208981)


--- 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)
@@ -0,0 +1,21 @@
+<style>
+body {
+    position: relative;
+    background: white;
+}
+
+div {
+    position: absolute;
+    z-index: -1;
+    transform: translateZ(0);
+}
+
+.green {
+    background-color: green;
+    width: 200px;
+    height: 200px;
+}
+</style>
+<body>
+<div class="green"></div>
+<div></div>

Modified: trunk/Source/WebCore/ChangeLog (208980 => 208981)


--- 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)
@@ -1,3 +1,33 @@
+2016-11-26  Simon Fraser  <[email protected]>
+
+        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 <body> falls into the "directly composited background color" 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 <html> 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):
+
 2016-11-25  Myles C. Maxfield  <[email protected]>
 
         [CSS Font Loading] FontFace.load() promises don't always fire

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (208980 => 208981)


--- 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)
@@ -130,17 +130,6 @@
 
 bool RenderBox::s_hadOverflowClip = false;
 
-static bool skipBodyBackground(const RenderBox* bodyElementRenderer)
-{
-    ASSERT(bodyElementRenderer->isBody());
-    // The <body> only paints its background if the root element has defined a background independent of the body,
-    // or if the <body>'s parent is not the document element's renderer (e.g. inside SVG foreignObject).
-    auto documentElementRenderer = bodyElementRenderer->document().documentElement()->renderer();
-    return documentElementRenderer
-        && !documentElementRenderer->hasBackground()
-        && (documentElementRenderer == bodyElementRenderer->parent());
-}
-
 RenderBox::RenderBox(Element& element, RenderStyle&& style, BaseTypeFlags baseTypeFlags)
     : RenderBoxModelObject(element, WTFMove(style), baseTypeFlags)
 {
@@ -1383,6 +1372,20 @@
         paintInfo.context().endTransparencyLayer();
 }
 
+bool RenderBox::paintsOwnBackground() const
+{
+    if (isBody()) {
+        // The <body> only paints its background if the root element has defined a background independent of the body,
+        // or if the <body>'s parent is not the document element's renderer (e.g. inside SVG foreignObject).
+        auto documentElementRenderer = document().documentElement()->renderer();
+        return !documentElementRenderer
+            || documentElementRenderer->hasBackground()
+            || (documentElementRenderer != parent());
+    }
+    
+    return true;
+}
+
 void RenderBox::paintBackground(const PaintInfo& paintInfo, const LayoutRect& paintRect, BackgroundBleedAvoidance bleedAvoidance)
 {
     if (isDocumentElementRenderer()) {
@@ -1389,10 +1392,13 @@
         paintRootBoxFillLayers(paintInfo);
         return;
     }
-    if (isBody() && skipBodyBackground(this))
+
+    if (!paintsOwnBackground())
         return;
+
     if (backgroundIsKnownToBeObscured(paintRect.location()) && !boxShadowShouldBeAppliedToBackground(paintRect.location(), bleedAvoidance))
         return;
+
     paintFillLayers(paintInfo, style().visitedDependentColor(CSSPropertyBackgroundColor), style().backgroundLayers(), paintRect, bleedAvoidance);
 }
 
@@ -1419,7 +1425,7 @@
 
 bool RenderBox::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
 {
-    if (isBody() && skipBodyBackground(this))
+    if (!paintsOwnBackground())
         return false;
 
     Color backgroundColor = style().visitedDependentColor(CSSPropertyBackgroundColor);

Modified: trunk/Source/WebCore/rendering/RenderBox.h (208980 => 208981)


--- 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)
@@ -56,6 +56,9 @@
     }
 
     bool backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const final;
+    
+    // Returns false for the body renderer if its background is propagated to the root.
+    bool paintsOwnBackground() const;
 
     // Use this with caution! No type checking is done!
     RenderBox* firstChildBox() const;

Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (208980 => 208981)


--- 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)
@@ -1809,7 +1809,7 @@
 
 void RenderLayerBacking::updateDirectlyCompositedBackgroundColor(bool isSimpleContainer, bool& didUpdateContentsRect)
 {
-    if (!isSimpleContainer) {
+    if (!isSimpleContainer || (is<RenderBox>(renderer()) && !downcast<RenderBox>(renderer()).paintsOwnBackground())) {
         m_graphicsLayer->setContentsToSolidColor(Color());
         return;
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to