<!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>[213600] 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/213600">213600</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2017-03-08 14:53:20 -0800 (Wed, 08 Mar 2017)</dd>
</dl>

<h3>Log Message</h3>
<pre>Change determineNonLayerDescendantsPaintedContent to max out based on renderers traversed
https://bugs.webkit.org/show_bug.cgi?id=169384

Reviewed by Zalan Bujtas.

Source/WebCore:

determineNonLayerDescendantsPaintedContent() would bail after depth 3, sibling count 20. However,
empirical testing shows that it would run to completion more often if the limit was based on the
number of nodes traversed (in particular, it's common to see fairly deep subtrees with few siblings).
Running to completion has huge memory advantages, because we can then be sure to have checked all the
renderers for smoothed text, allowing us, on some pages, to avoid the extra memory cost of using
layers that support subpixel-antialiased text.

Performance measurement shows that mean runtime of this function goes up from 0.30us to 0.34us
with a 200 renderer limit, which seems worthwhile.

Test: compositing/contents-format/subpixel-antialiased-text-traversal.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::calculateClipRects):

LayoutTests:

Rebaseline an existing test which changes behavior, and add a new test that generates divs
on both sides of the threshold, in depth and breadth.

* compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt: Added.
* compositing/contents-format/subpixel-antialiased-text-traversal.html: Added.
* platform/mac/compositing/contents-format/subpixel-antialiased-text-configs-antialiasing-style-expected.txt:
* platform/mac/compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsplatformmaccompositingcontentsformatsubpixelantialiasedtextconfigsantialiasingstyleexpectedtxt">trunk/LayoutTests/platform/mac/compositing/contents-format/subpixel-antialiased-text-configs-antialiasing-style-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayercpp">trunk/Source/WebCore/rendering/RenderLayer.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscompositingcontentsformatsubpixelantialiasedtexttraversalexpectedtxt">trunk/LayoutTests/compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt</a></li>
<li><a href="#trunkLayoutTestscompositingcontentsformatsubpixelantialiasedtexttraversalhtml">trunk/LayoutTests/compositing/contents-format/subpixel-antialiased-text-traversal.html</a></li>
<li><a href="#trunkLayoutTestsplatformmaccompositingcontentsformatsubpixelantialiasedtexttraversalexpectedtxt">trunk/LayoutTests/platform/mac/compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (213599 => 213600)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2017-03-08 22:50:51 UTC (rev 213599)
+++ trunk/LayoutTests/ChangeLog        2017-03-08 22:53:20 UTC (rev 213600)
</span><span class="lines">@@ -1,3 +1,18 @@
</span><ins>+2017-03-08  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Change determineNonLayerDescendantsPaintedContent to max out based on renderers traversed
+        https://bugs.webkit.org/show_bug.cgi?id=169384
+
+        Reviewed by Zalan Bujtas.
+
+        Rebaseline an existing test which changes behavior, and add a new test that generates divs
+        on both sides of the threshold, in depth and breadth.
+
+        * compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt: Added.
+        * compositing/contents-format/subpixel-antialiased-text-traversal.html: Added.
+        * platform/mac/compositing/contents-format/subpixel-antialiased-text-configs-antialiasing-style-expected.txt:
+        * platform/mac/compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt: Added.
+
</ins><span class="cx"> 2017-03-08  Youenn Fablet  &lt;youenn@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Support canvas captureStream
</span></span></pre></div>
<a id="trunkLayoutTestscompositingcontentsformatsubpixelantialiasedtexttraversalexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt (0 => 213600)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt                                (rev 0)
+++ trunk/LayoutTests/compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt        2017-03-08 22:53:20 UTC (rev 213600)
</span><span class="lines">@@ -0,0 +1,36 @@
</span><ins>+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 1163.00 1244.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 1163.00 1244.00)
+      (contentsOpaque 1)
+      (children 4
+        (GraphicsLayer
+          (position 12.00 17.00)
+          (bounds 162.00 606.00)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 182.00 17.00)
+          (bounds 162.00 606.00)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 352.00 17.00)
+          (bounds 635.00 1215.00)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 522.00 17.00)
+          (bounds 641.00 1227.00)
+          (drawsContent 1)
+        )
+      )
+    )
+  )
+)
+01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
+0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
+0
+0
</ins></span></pre></div>
<a id="trunkLayoutTestscompositingcontentsformatsubpixelantialiasedtexttraversalhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/contents-format/subpixel-antialiased-text-traversal.html (0 => 213600)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/contents-format/subpixel-antialiased-text-traversal.html                                (rev 0)
+++ trunk/LayoutTests/compositing/contents-format/subpixel-antialiased-text-traversal.html        2017-03-08 22:53:20 UTC (rev 213600)
</span><span class="lines">@@ -0,0 +1,91 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+    &lt;style&gt;
+        .container {
+            height: 150px;
+            width: 150px;
+            float: left;
+            position: relative;
+            border: 1px solid black;
+            padding: 20px;
+            margin: 10px;
+            box-sizing: border-box;
+            box-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
+        }
+        
+        .container div {
+            border: 1px solid rgba(0, 0, 0, 0.5);
+            padding: 2px;
+        }
+        
+        .inner {
+            float: left;
+        }
+
+        .composited {
+            will-change: transform;
+        }
+
+        .antialiased {
+            -webkit-font-smoothing: antialiased;
+        }
+    &lt;/style&gt;
+    &lt;script&gt;
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        if (window.internals) {
+            internals.setFontSmoothingEnabled(true);
+            internals.settings.setSubpixelAntialiasedLayerTextEnabled(true)
+        }
+
+        function createContainer(maxDepth, leafSiblings)
+        {
+            var container = document.createElement('div');
+            container.className = 'composited antialiased container';
+            
+            var parent = container;
+
+            for (var depth = 0; depth &lt; maxDepth; ++depth) {
+                var innerDiv = document.createElement('div');
+                parent.appendChild(innerDiv);
+                parent = innerDiv;
+            }
+
+            for (var breadth = 0; breadth &lt; leafSiblings; ++breadth) {
+                var child = document.createElement('div');
+                child.className = 'inner';
+                child.textContent = breadth;
+                parent.appendChild(child);
+            }
+            
+            return container;
+        }
+
+        function createContainers()
+        {
+            document.body.appendChild(createContainer(1, 99));
+            document.body.appendChild(createContainer(1, 100));
+            document.body.appendChild(createContainer(198, 1));
+            document.body.appendChild(createContainer(200, 1));
+        }
+
+        function doTest()
+        {
+            createContainers();
+
+            if (window.internals)
+                document.getElementById('layers').innerText = internals.layerTreeAsText(document);
+        }
+
+        window.addEventListener('load', doTest, false);
+    &lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+
+&lt;pre id=&quot;layers&quot;&gt;&lt;/pre&gt;
+
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformmaccompositingcontentsformatsubpixelantialiasedtextconfigsantialiasingstyleexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/compositing/contents-format/subpixel-antialiased-text-configs-antialiasing-style-expected.txt (213599 => 213600)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/compositing/contents-format/subpixel-antialiased-text-configs-antialiasing-style-expected.txt        2017-03-08 22:50:51 UTC (rev 213599)
+++ trunk/LayoutTests/platform/mac/compositing/contents-format/subpixel-antialiased-text-configs-antialiasing-style-expected.txt        2017-03-08 22:53:20 UTC (rev 213600)
</span><span class="lines">@@ -111,7 +111,6 @@
</span><span class="cx">         (GraphicsLayer
</span><span class="cx">           (position 352.00 357.00)
</span><span class="cx">           (bounds 162.00 162.00)
</span><del>-          (supports subpixel antialiased text 1)
</del><span class="cx">           (drawsContent 1)
</span><span class="cx">         )
</span><span class="cx">         (GraphicsLayer
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmaccompositingcontentsformatsubpixelantialiasedtexttraversalexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/mac/compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt (0 => 213600)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt                                (rev 0)
+++ trunk/LayoutTests/platform/mac/compositing/contents-format/subpixel-antialiased-text-traversal-expected.txt        2017-03-08 22:53:20 UTC (rev 213600)
</span><span class="lines">@@ -0,0 +1,38 @@
</span><ins>+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 1163.00 1244.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 1163.00 1244.00)
+      (contentsOpaque 1)
+      (children 4
+        (GraphicsLayer
+          (position 12.00 17.00)
+          (bounds 162.00 606.00)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 182.00 17.00)
+          (bounds 162.00 606.00)
+          (supports subpixel antialiased text 1)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 352.00 17.00)
+          (bounds 635.00 1215.00)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 522.00 17.00)
+          (bounds 641.00 1227.00)
+          (supports subpixel antialiased text 1)
+          (drawsContent 1)
+        )
+      )
+    )
+  )
+)
+01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
+0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
+0
+0
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (213599 => 213600)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2017-03-08 22:50:51 UTC (rev 213599)
+++ trunk/Source/WebCore/ChangeLog        2017-03-08 22:53:20 UTC (rev 213600)
</span><span class="lines">@@ -1,3 +1,25 @@
</span><ins>+2017-03-08  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Change determineNonLayerDescendantsPaintedContent to max out based on renderers traversed
+        https://bugs.webkit.org/show_bug.cgi?id=169384
+
+        Reviewed by Zalan Bujtas.
+
+        determineNonLayerDescendantsPaintedContent() would bail after depth 3, sibling count 20. However,
+        empirical testing shows that it would run to completion more often if the limit was based on the
+        number of nodes traversed (in particular, it's common to see fairly deep subtrees with few siblings).
+        Running to completion has huge memory advantages, because we can then be sure to have checked all the
+        renderers for smoothed text, allowing us, on some pages, to avoid the extra memory cost of using
+        layers that support subpixel-antialiased text.
+
+        Performance measurement shows that mean runtime of this function goes up from 0.30us to 0.34us
+        with a 200 renderer limit, which seems worthwhile.
+
+        Test: compositing/contents-format/subpixel-antialiased-text-traversal.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::calculateClipRects):
+
</ins><span class="cx"> 2017-03-08  Youenn Fablet  &lt;youenn@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Support canvas captureStream
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (213599 => 213600)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.cpp        2017-03-08 22:50:51 UTC (rev 213599)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp        2017-03-08 22:53:20 UTC (rev 213600)
</span><span class="lines">@@ -6587,19 +6587,12 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Constrain the depth and breadth of the search for performance.
</span><del>-static const int maxDescendentDepth = 3;
-static const int maxSiblingCount = 20;
</del><ins>+static const unsigned maxRendererTraversalCount = 200;
</ins><span class="cx"> 
</span><del>-static void determineNonLayerDescendantsPaintedContent(const RenderElement&amp; renderer, int depth, RenderLayer::PaintedContentRequest&amp; request)
</del><ins>+static void determineNonLayerDescendantsPaintedContent(const RenderElement&amp; renderer, unsigned&amp; renderersTraversed, RenderLayer::PaintedContentRequest&amp; request)
</ins><span class="cx"> {
</span><del>-    if (depth &gt; maxDescendentDepth) {
-        request.makeStatesUndetermined();
-        return;
-    }
-    
-    int siblingCount = 0;
</del><span class="cx">     for (const auto&amp; child : childrenOfType&lt;RenderObject&gt;(renderer)) {
</span><del>-        if (++siblingCount &gt; maxSiblingCount) {
</del><ins>+        if (++renderersTraversed &gt; maxRendererTraversalCount) {
</ins><span class="cx">             request.makeStatesUndetermined();
</span><span class="cx">             return;
</span><span class="cx">         }
</span><span class="lines">@@ -6651,7 +6644,7 @@
</span><span class="cx">                 return;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        determineNonLayerDescendantsPaintedContent(renderElementChild, depth + 1, request);
</del><ins>+        determineNonLayerDescendantsPaintedContent(renderElementChild, renderersTraversed, request);
</ins><span class="cx">         if (request.isSatisfied())
</span><span class="cx">             return;
</span><span class="cx">     }
</span><span class="lines">@@ -6659,7 +6652,8 @@
</span><span class="cx"> 
</span><span class="cx"> bool RenderLayer::hasNonEmptyChildRenderers(PaintedContentRequest&amp; request) const
</span><span class="cx"> {
</span><del>-    determineNonLayerDescendantsPaintedContent(renderer(), 0, request);
</del><ins>+    unsigned renderersTraversed = 0;
+    determineNonLayerDescendantsPaintedContent(renderer(), renderersTraversed, request);
</ins><span class="cx">     return request.probablyHasPaintedContent();
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>