- 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;
}