<!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>[238357] trunk/Source/WebCore</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/238357">238357</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2018-11-17 16:51:42 -0800 (Sat, 17 Nov 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>Avoid triggering compositing updates when only the root layer is composited
https://bugs.webkit.org/show_bug.cgi?id=191813

Reviewed by Zalan Bujtas.

If we know that the only composited layer is the root, we can avoid triggering deep
compositing updates sometimes, for example when layout changes size or position,
or when z-order lists change.

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::addChild):
(WebCore::RenderLayer::removeChild):
(WebCore::RenderLayer::updateLayerPosition):
(WebCore::RenderLayer::scrollTo):
(WebCore::RenderLayer::updateCompositingLayersAfterScroll):
(WebCore::outputPaintOrderTreeRecursive):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::updateBackingAndHierarchy): Consult the layer.hasCompositingDescendant()
flag to cut off descendants traversal when possible.
(WebCore::RenderLayerCompositor::layerStyleChanged):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayercpp">trunk/Source/WebCore/rendering/RenderLayer.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerCompositorcpp">trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (238356 => 238357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2018-11-18 00:25:20 UTC (rev 238356)
+++ trunk/Source/WebCore/ChangeLog      2018-11-18 00:51:42 UTC (rev 238357)
</span><span class="lines">@@ -1,5 +1,28 @@
</span><span class="cx"> 2018-11-17  Simon Fraser  <simon.fraser@apple.com>
</span><span class="cx"> 
</span><ins>+        Avoid triggering compositing updates when only the root layer is composited
+        https://bugs.webkit.org/show_bug.cgi?id=191813
+
+        Reviewed by Zalan Bujtas.
+
+        If we know that the only composited layer is the root, we can avoid triggering deep
+        compositing updates sometimes, for example when layout changes size or position,
+        or when z-order lists change.
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::addChild):
+        (WebCore::RenderLayer::removeChild):
+        (WebCore::RenderLayer::updateLayerPosition):
+        (WebCore::RenderLayer::scrollTo):
+        (WebCore::RenderLayer::updateCompositingLayersAfterScroll):
+        (WebCore::outputPaintOrderTreeRecursive):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::updateBackingAndHierarchy): Consult the layer.hasCompositingDescendant()
+        flag to cut off descendants traversal when possible.
+        (WebCore::RenderLayerCompositor::layerStyleChanged):
+
+2018-11-17  Simon Fraser  <simon.fraser@apple.com>
+
</ins><span class="cx">         Fix an error in 238354 - !=, not ==.
</span><span class="cx">         
</span><span class="cx">         Fixes test failures.
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (238356 => 238357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.cpp   2018-11-18 00:25:20 UTC (rev 238356)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp      2018-11-18 00:51:42 UTC (rev 238357)
</span><span class="lines">@@ -405,7 +405,7 @@
</span><span class="cx">     if (child.isSelfPaintingLayer() || child.hasSelfPaintingLayerDescendant())
</span><span class="cx">         setAncestorChainHasSelfPaintingLayerDescendant();
</span><span class="cx"> 
</span><del>-    if (compositor().usesCompositing())
</del><ins>+    if (compositor().hasContentCompositingLayers())
</ins><span class="cx">         setDescendantsNeedCompositingRequirementsTraversal();
</span><span class="cx"> 
</span><span class="cx">     if (child.hasDescendantNeedingCompositingRequirementsTraversal() || child.needsCompositingRequirementsTraversal())
</span><span class="lines">@@ -451,7 +451,7 @@
</span><span class="cx">     if (oldChild.isSelfPaintingLayer() || oldChild.hasSelfPaintingLayerDescendant())
</span><span class="cx">         dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
</span><span class="cx"> 
</span><del>-    if (compositor().usesCompositing())
</del><ins>+    if (compositor().hasContentCompositingLayers())
</ins><span class="cx">         setDescendantsNeedCompositingRequirementsTraversal();
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(CSS_COMPOSITING)
</span><span class="lines">@@ -1577,7 +1577,7 @@
</span><span class="cx">     positionOrOffsetChanged |= location() != localPoint;
</span><span class="cx">     setLocation(localPoint);
</span><span class="cx">     
</span><del>-    if (positionOrOffsetChanged && compositor().usesCompositing()) {
</del><ins>+    if (positionOrOffsetChanged && compositor().hasContentCompositingLayers()) {
</ins><span class="cx">         if (isComposited())
</span><span class="cx">             setNeedsCompositingGeometryUpdate();
</span><span class="cx">         // This layer's position can affect the location of a composited descendant (which may be a sibling in z-order),
</span><span class="lines">@@ -2430,7 +2430,7 @@
</span><span class="cx">     frame.eventHandler().dispatchFakeMouseMoveEventSoonInQuad(quadForFakeMouseMoveEvent);
</span><span class="cx"> 
</span><span class="cx">     bool requiresRepaint = true;
</span><del>-    if (compositor().usesCompositing() && usesCompositedScrolling()) {
</del><ins>+    if (usesCompositedScrolling()) {
</ins><span class="cx">         setNeedsCompositingGeometryUpdate();
</span><span class="cx">         setDescendantsNeedUpdateBackingAndHierarchyTraversal();
</span><span class="cx">         requiresRepaint = false;
</span><span class="lines">@@ -2580,7 +2580,7 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderLayer::updateCompositingLayersAfterScroll()
</span><span class="cx"> {
</span><del>-    if (compositor().usesCompositing()) {
</del><ins>+    if (compositor().hasContentCompositingLayers()) {
</ins><span class="cx">         // Our stacking container is guaranteed to contain all of our descendants that may need
</span><span class="cx">         // repositioning, so update compositing layers from there.
</span><span class="cx">         if (RenderLayer* compositingAncestor = stackingContext()->enclosingCompositingLayer()) {
</span><span class="lines">@@ -6643,7 +6643,7 @@
</span><span class="cx"> static void outputPaintOrderTreeLegend(TextStream& stream)
</span><span class="cx"> {
</span><span class="cx">     stream.nextLine();
</span><del>-    stream << "(S)tacking Context, (N)ormal flow only, (O)verflow clip, (A)lpha (opacity or mask), has (B)lend mode, (I)solates blending, (T)ransform-ish, (F)ilter, Fi(X)ed position, (C)omposited\n"
</del><ins>+    stream << "(S)tacking Context, (N)ormal flow only, (O)verflow clip, (A)lpha (opacity or mask), has (B)lend mode, (I)solates blending, (T)ransform-ish, (F)ilter, Fi(X)ed position, (C)omposited, (c)omposited descendant\n"
</ins><span class="cx">         "Dirty (z)-lists, Dirty (n)ormal flow lists\n"
</span><span class="cx">         "Descendant needs overlap (t)raversal, Descendant needs (b)acking or hierarchy update, All descendants need (r)equirements traversal, All (s)ubsequent layers need requirements traversal, All descendants need (h)ierarchy traversal\n"
</span><span class="cx">         "Needs compositing paint order update on (s)ubsequent layers, Needs compositing paint (o)rder children update, "
</span><span class="lines">@@ -6670,6 +6670,7 @@
</span><span class="cx">     stream << (layer.hasFilter() ? "F" : "-");
</span><span class="cx">     stream << (layer.renderer().isFixedPositioned() ? "X" : "-");
</span><span class="cx">     stream << (layer.isComposited() ? "C" : "-");
</span><ins>+    stream << (layer.hasCompositingDescendant() ? "c" : "-");
</ins><span class="cx"> 
</span><span class="cx">     stream << " ";
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerCompositorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (238356 => 238357)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp 2018-11-18 00:25:20 UTC (rev 238356)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp    2018-11-18 00:51:42 UTC (rev 238357)
</span><span class="lines">@@ -1170,29 +1170,35 @@
</span><span class="cx">     // to the compositing child list of an enclosing layer.
</span><span class="cx">     Vector<Ref<GraphicsLayer>> layerChildren;
</span><span class="cx">     auto& childList = layerBacking ? layerChildren : childLayersOfEnclosingLayer;
</span><del>-    // FIXME: why the !layerBacking check?
-    bool requireDescendantTraversal = !layerBacking || layer.needsCompositingLayerConnection() || layer.hasDescendantNeedingUpdateBackingOrHierarchyTraversal() || !updateLevel.isEmpty();
</del><span class="cx"> 
</span><ins>+    bool requireDescendantTraversal = layer.hasDescendantNeedingUpdateBackingOrHierarchyTraversal()
+        || (layer.hasCompositingDescendant() && (!layerBacking || layer.needsCompositingLayerConnection() || !updateLevel.isEmpty()));
+
</ins><span class="cx"> #if !ASSERT_DISABLED
</span><span class="cx">     LayerListMutationDetector mutationChecker(layer);
</span><span class="cx"> #endif
</span><span class="cx">     
</span><del>-    if (requireDescendantTraversal) {
-        for (auto* renderLayer : layer.negativeZOrderLayers())
-            updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
-
-            // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
</del><ins>+    auto appendForegroundLayerIfNecessary = [&] {
+        // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
</ins><span class="cx">         if (layer.negativeZOrderLayers().size()) {
</span><span class="cx">             if (layerBacking && layerBacking->foregroundLayer())
</span><span class="cx">                 childList.append(*layerBacking->foregroundLayer());
</span><span class="cx">         }
</span><ins>+    };
</ins><span class="cx"> 
</span><ins>+    if (requireDescendantTraversal) {
+        for (auto* renderLayer : layer.negativeZOrderLayers())
+            updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
+
+        appendForegroundLayerIfNecessary();
+
</ins><span class="cx">         for (auto* renderLayer : layer.normalFlowLayers())
</span><span class="cx">             updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
</span><span class="cx">         
</span><span class="cx">         for (auto* renderLayer : layer.positiveZOrderLayers())
</span><span class="cx">             updateBackingAndHierarchy(*renderLayer, childList, updateLevel, depth + 1);
</span><del>-    }
</del><ins>+    } else
+        appendForegroundLayerIfNecessary();
</ins><span class="cx"> 
</span><span class="cx">     if (layerBacking) {
</span><span class="cx">         if (requireDescendantTraversal) {
</span><span class="lines">@@ -1370,7 +1376,7 @@
</span><span class="cx">     if (queryData.reevaluateAfterLayout)
</span><span class="cx">         layer.setNeedsPostLayoutCompositingUpdate();
</span><span class="cx"> 
</span><del>-    if (diff >= StyleDifference::LayoutPositionedMovementOnly && usesCompositing()) {
</del><ins>+    if (diff >= StyleDifference::LayoutPositionedMovementOnly && hasContentCompositingLayers()) {
</ins><span class="cx">         layer.setNeedsPostLayoutCompositingUpdate();
</span><span class="cx">         layer.setNeedsCompositingGeometryUpdate();
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>