<!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>[200283] 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/200283">200283</a></dd>
<dt>Author</dt> <dd>simon.fraser@apple.com</dd>
<dt>Date</dt> <dd>2016-04-29 21:13:16 -0700 (Fri, 29 Apr 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Blur filter escapes an enclosing overflow:hidden
https://bugs.webkit.org/show_bug.cgi?id=155029

Reviewed by Zalan Bujtas.

Source/WebCore:

The clipping that was applied when drawing the results of filters was wrong for two reasons.

First, it used localPaintingInfo which has already been contaminated when setting up the filters.
When painting the result, we need to use the original paintingInfo, to get the right paintDirtyRect.

Secondly, when setting up the clip to paint the filter result, it was relying on layerFragments[0].backgroundRect.
However, that was also contaminated by filter setup, since calculateRects() intersects with paintDirtyRect to
compute that backgroundRect, and that paintDirtyRect came from filterPainter-&gt;repaintRect().

Fix this second issue by re-running collectFragments(), which computes a fragment backgroundRect using
the original paintDirtyRect.

Tests: css3/filters/blur-clipped-by-ancestor.html
       css3/filters/blur-clipped-with-overflow.html
       css3/filters/drop-shadow-with-overflow-hidden.html
       css3/filters/drop-shadow.html

* platform/graphics/filters/FilterEffect.cpp:
(WebCore::FilterEffect::clearResult): Unconditionally null these out.
* rendering/FilterEffectRenderer.cpp:
(WebCore::FilterEffectRendererHelper::beginFilterEffect): Typo fix.
* rendering/FilterEffectRenderer.h:
(WebCore::FilterEffectRendererHelper::FilterEffectRendererHelper): C++11 initialization.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::applyFilters):
(WebCore::RenderLayer::paintLayerContents):
* rendering/RenderLayer.h: const

LayoutTests:

* css3/filters/blur-clipped-by-ancestor-expected.html: Added.
* css3/filters/blur-clipped-by-ancestor.html: Added.
* css3/filters/blur-clipped-with-overflow-expected.html: Added.
* css3/filters/blur-clipped-with-overflow.html: Added.
* css3/filters/drop-shadow-expected.html: Added.
* css3/filters/drop-shadow-with-overflow-hidden-expected.html: Added.
* css3/filters/drop-shadow-with-overflow-hidden.html: Added.
* css3/filters/drop-shadow.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="#trunkSourceWebCoreplatformgraphicsfiltersFilterEffectcpp">trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingFilterEffectRenderercpp">trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingFilterEffectRendererh">trunk/Source/WebCore/rendering/FilterEffectRenderer.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayercpp">trunk/Source/WebCore/rendering/RenderLayer.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerh">trunk/Source/WebCore/rendering/RenderLayer.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscss3filtersblurclippedbyancestorexpectedhtml">trunk/LayoutTests/css3/filters/blur-clipped-by-ancestor-expected.html</a></li>
<li><a href="#trunkLayoutTestscss3filtersblurclippedbyancestorhtml">trunk/LayoutTests/css3/filters/blur-clipped-by-ancestor.html</a></li>
<li><a href="#trunkLayoutTestscss3filtersblurclippedwithoverflowexpectedhtml">trunk/LayoutTests/css3/filters/blur-clipped-with-overflow-expected.html</a></li>
<li><a href="#trunkLayoutTestscss3filtersblurclippedwithoverflowhtml">trunk/LayoutTests/css3/filters/blur-clipped-with-overflow.html</a></li>
<li><a href="#trunkLayoutTestscss3filtersdropshadowexpectedhtml">trunk/LayoutTests/css3/filters/drop-shadow-expected.html</a></li>
<li><a href="#trunkLayoutTestscss3filtersdropshadowwithoverflowhiddenexpectedhtml">trunk/LayoutTests/css3/filters/drop-shadow-with-overflow-hidden-expected.html</a></li>
<li><a href="#trunkLayoutTestscss3filtersdropshadowwithoverflowhiddenhtml">trunk/LayoutTests/css3/filters/drop-shadow-with-overflow-hidden.html</a></li>
<li><a href="#trunkLayoutTestscss3filtersdropshadowhtml">trunk/LayoutTests/css3/filters/drop-shadow.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (200282 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-04-30 03:54:41 UTC (rev 200282)
+++ trunk/LayoutTests/ChangeLog        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -1,3 +1,19 @@
</span><ins>+2016-04-29  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Blur filter escapes an enclosing overflow:hidden
+        https://bugs.webkit.org/show_bug.cgi?id=155029
+
+        Reviewed by Zalan Bujtas.
+
+        * css3/filters/blur-clipped-by-ancestor-expected.html: Added.
+        * css3/filters/blur-clipped-by-ancestor.html: Added.
+        * css3/filters/blur-clipped-with-overflow-expected.html: Added.
+        * css3/filters/blur-clipped-with-overflow.html: Added.
+        * css3/filters/drop-shadow-expected.html: Added.
+        * css3/filters/drop-shadow-with-overflow-hidden-expected.html: Added.
+        * css3/filters/drop-shadow-with-overflow-hidden.html: Added.
+        * css3/filters/drop-shadow.html: Added.
+
</ins><span class="cx"> 2016-04-29  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION(194502): overflow: scroll; direction: rtl; divs jump horizontally when scrolled vertically
</span></span></pre></div>
<a id="trunkLayoutTestscss3filtersblurclippedbyancestorexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/filters/blur-clipped-by-ancestor-expected.html (0 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/filters/blur-clipped-by-ancestor-expected.html                                (rev 0)
+++ trunk/LayoutTests/css3/filters/blur-clipped-by-ancestor-expected.html        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+    &lt;style&gt;
+        .wrapper {
+            height: 200px;
+            width: 200px;
+            margin: 50px;
+            border: 1px solid black;
+        }
+
+        .filtered {
+            -webkit-clip-path: inset(0px);
+            width: 100%;
+            height: 100%;
+            background-color: black;
+            filter: blur(10px);
+        }
+    &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div class=&quot;wrapper&quot;&gt;
+        &lt;div class=&quot;filtered&quot;&gt;
+        &lt;/div&gt;
+    &lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscss3filtersblurclippedbyancestorhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/filters/blur-clipped-by-ancestor.html (0 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/filters/blur-clipped-by-ancestor.html                                (rev 0)
+++ trunk/LayoutTests/css3/filters/blur-clipped-by-ancestor.html        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -0,0 +1,28 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+    &lt;style&gt;
+        .wrapper {
+            overflow: hidden;
+            height: 200px;
+            width: 200px;
+            margin: 50px;
+            border: 1px solid black;
+        }
+
+        .filtered {
+            width: 100%;
+            height: 100%;
+            background-color: black;
+            filter: blur(10px);
+        }
+    &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div class=&quot;wrapper&quot;&gt;
+        &lt;div class=&quot;filtered&quot;&gt;
+        &lt;/div&gt;
+    &lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscss3filtersblurclippedwithoverflowexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/filters/blur-clipped-with-overflow-expected.html (0 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/filters/blur-clipped-with-overflow-expected.html                                (rev 0)
+++ trunk/LayoutTests/css3/filters/blur-clipped-with-overflow-expected.html        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+    &lt;style&gt;
+        .filtered {
+            overflow: hidden;
+            margin: 40px;
+            padding: 20px;
+            height: 200px;
+            width: 200px;
+            background-color: silver;
+            border: 1px solid black;
+            filter: blur(1px);
+            box-shadow: 0 0 20px black;
+        }
+
+        .contents {
+            width: 100%;
+            height: 220px;
+            background-image: repeating-linear-gradient(blue, blue 50px, green 50px, green 100px);
+        }
+    &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div class=&quot;filtered&quot;&gt;
+        &lt;div class=&quot;contents&quot;&gt;&lt;/div&gt;
+    &lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscss3filtersblurclippedwithoverflowhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/filters/blur-clipped-with-overflow.html (0 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/filters/blur-clipped-with-overflow.html                                (rev 0)
+++ trunk/LayoutTests/css3/filters/blur-clipped-with-overflow.html        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -0,0 +1,30 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+    &lt;style&gt;
+        .filtered {
+            overflow: hidden;
+            margin: 40px;
+            padding: 20px;
+            height: 200px;
+            width: 200px;
+            background-color: silver;
+            border: 1px solid black;
+            filter: blur(1px);
+            box-shadow: 0 0 20px black;
+        }
+
+        .contents {
+            width: 100%;
+            height: 200%;
+            background-image: repeating-linear-gradient(blue, blue 50px, green 50px, green 100px);
+        }
+    &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div class=&quot;filtered&quot;&gt;
+        &lt;div class=&quot;contents&quot;&gt;&lt;/div&gt;
+    &lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscss3filtersdropshadowexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/filters/drop-shadow-expected.html (0 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/filters/drop-shadow-expected.html                                (rev 0)
+++ trunk/LayoutTests/css3/filters/drop-shadow-expected.html        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -0,0 +1,31 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;style&gt;
+        .filtered {
+            position: absolute;
+            top: 0;
+            left: 0;
+            margin: 40px;
+            padding: 20px;
+            height: 200px;
+            width: 200px;
+            background-color: silver;
+            border: 1px solid black;
+            box-shadow: 0 0 20px transparent; /* Make layers bigger */
+        }
+        
+        .shadow {
+            position: absolute;
+            top: 110px;
+            left: 110px;
+            border: 1px solid blue;
+            background-color: blue;
+        }
+    &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div class=&quot;filtered shadow&quot;&gt;&lt;/div&gt;
+    &lt;div class=&quot;filtered&quot;&gt;&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscss3filtersdropshadowwithoverflowhiddenexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/filters/drop-shadow-with-overflow-hidden-expected.html (0 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/filters/drop-shadow-with-overflow-hidden-expected.html                                (rev 0)
+++ trunk/LayoutTests/css3/filters/drop-shadow-with-overflow-hidden-expected.html        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+    &lt;style&gt;
+        .filtered {
+            overflow: hidden;
+            margin: 40px;
+            padding: 20px;
+            height: 200px;
+            width: 200px;
+            background-color: silver;
+            border: 1px solid black;
+            filter: drop-shadow(110px 110px 0 blue);
+            box-shadow: 0 0 20px black;
+        }
+    &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div class=&quot;filtered&quot;&gt;&lt;/div&gt;
+    &lt;!-- Fixme --&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscss3filtersdropshadowwithoverflowhiddenhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/filters/drop-shadow-with-overflow-hidden.html (0 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/filters/drop-shadow-with-overflow-hidden.html                                (rev 0)
+++ trunk/LayoutTests/css3/filters/drop-shadow-with-overflow-hidden.html        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -0,0 +1,22 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+
+&lt;html&gt;
+&lt;head&gt;
+    &lt;style&gt;
+        .filtered {
+            overflow: hidden;
+            margin: 40px;
+            padding: 20px;
+            height: 200px;
+            width: 200px;
+            background-color: silver;
+            border: 1px solid black;
+            filter: drop-shadow(110px 110px 0 blue);
+            box-shadow: 0 0 20px black;
+        }
+    &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div class=&quot;filtered&quot;&gt;&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscss3filtersdropshadowhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/filters/drop-shadow.html (0 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/filters/drop-shadow.html                                (rev 0)
+++ trunk/LayoutTests/css3/filters/drop-shadow.html        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -0,0 +1,23 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+    &lt;style&gt;
+        .filtered {
+            position: absolute;
+            top: 0;
+            left: 0;
+            margin: 40px;
+            padding: 20px;
+            height: 200px;
+            width: 200px;
+            background-color: silver;
+            border: 1px solid black;
+            filter: drop-shadow(110px 110px 0 blue);
+            box-shadow: 0 0 20px transparent; /* Make layers bigger */
+        }
+    &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+    &lt;div class=&quot;filtered&quot;&gt;&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (200282 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-04-30 03:54:41 UTC (rev 200282)
+++ trunk/Source/WebCore/ChangeLog        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -1,3 +1,38 @@
</span><ins>+2016-04-29  Simon Fraser  &lt;simon.fraser@apple.com&gt;
+
+        Blur filter escapes an enclosing overflow:hidden
+        https://bugs.webkit.org/show_bug.cgi?id=155029
+
+        Reviewed by Zalan Bujtas.
+
+        The clipping that was applied when drawing the results of filters was wrong for two reasons.
+
+        First, it used localPaintingInfo which has already been contaminated when setting up the filters.
+        When painting the result, we need to use the original paintingInfo, to get the right paintDirtyRect.
+
+        Secondly, when setting up the clip to paint the filter result, it was relying on layerFragments[0].backgroundRect.
+        However, that was also contaminated by filter setup, since calculateRects() intersects with paintDirtyRect to
+        compute that backgroundRect, and that paintDirtyRect came from filterPainter-&gt;repaintRect().
+        
+        Fix this second issue by re-running collectFragments(), which computes a fragment backgroundRect using
+        the original paintDirtyRect.
+
+        Tests: css3/filters/blur-clipped-by-ancestor.html
+               css3/filters/blur-clipped-with-overflow.html
+               css3/filters/drop-shadow-with-overflow-hidden.html
+               css3/filters/drop-shadow.html
+
+        * platform/graphics/filters/FilterEffect.cpp:
+        (WebCore::FilterEffect::clearResult): Unconditionally null these out.
+        * rendering/FilterEffectRenderer.cpp:
+        (WebCore::FilterEffectRendererHelper::beginFilterEffect): Typo fix.
+        * rendering/FilterEffectRenderer.h:
+        (WebCore::FilterEffectRendererHelper::FilterEffectRendererHelper): C++11 initialization.
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::applyFilters):
+        (WebCore::RenderLayer::paintLayerContents):
+        * rendering/RenderLayer.h: const
+
</ins><span class="cx"> 2016-04-29  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION(194502): overflow: scroll; direction: rtl; divs jump horizontally when scrolled vertically
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfiltersFilterEffectcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp (200282 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp        2016-04-30 03:54:41 UTC (rev 200282)
+++ trunk/Source/WebCore/platform/graphics/filters/FilterEffect.cpp        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -197,10 +197,9 @@
</span><span class="cx"> {
</span><span class="cx">     if (m_imageBufferResult)
</span><span class="cx">         m_imageBufferResult.reset();
</span><del>-    if (m_unmultipliedImageResult)
-        m_unmultipliedImageResult = nullptr;
-    if (m_premultipliedImageResult)
-        m_premultipliedImageResult = nullptr;
</del><ins>+
+    m_unmultipliedImageResult = nullptr;
+    m_premultipliedImageResult = nullptr;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void FilterEffect::clearResultsRecursive()
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingFilterEffectRenderercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp (200282 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp        2016-04-30 03:54:41 UTC (rev 200282)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.cpp        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -67,8 +67,6 @@
</span><span class="cx"> 
</span><span class="cx"> FilterEffectRenderer::FilterEffectRenderer()
</span><span class="cx">     : Filter(AffineTransform())
</span><del>-    , m_graphicsBufferAttached(false)
-    , m_hasFilterThatMovesPixels(false)
</del><span class="cx"> {
</span><span class="cx">     setFilterResolution(FloatSize(1, 1));
</span><span class="cx">     m_sourceGraphic = SourceGraphic::create(*this);
</span><span class="lines">@@ -407,7 +405,7 @@
</span><span class="cx">         return false;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    // Translate the context so that the contents of the layer is captuterd in the offscreen memory buffer.
</del><ins>+    // Translate the context so that the contents of the layer is captured in the offscreen memory buffer.
</ins><span class="cx">     sourceGraphicsContext-&gt;save();
</span><span class="cx">     sourceGraphicsContext-&gt;translate(-m_paintOffset.x(), -m_paintOffset.y());
</span><span class="cx">     sourceGraphicsContext-&gt;clearRect(m_repaintRect);
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingFilterEffectRendererh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/FilterEffectRenderer.h (200282 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/FilterEffectRenderer.h        2016-04-30 03:54:41 UTC (rev 200282)
+++ trunk/Source/WebCore/rendering/FilterEffectRenderer.h        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -58,9 +58,7 @@
</span><span class="cx">     WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx">     FilterEffectRendererHelper(bool haveFilterEffect)
</span><del>-        : m_renderLayer(0)
-        , m_haveFilterEffect(haveFilterEffect)
-        , m_startedFilterEffect(false)
</del><ins>+        : m_haveFilterEffect(haveFilterEffect)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="lines">@@ -76,11 +74,11 @@
</span><span class="cx">     const LayoutRect&amp; repaintRect() const { return m_repaintRect; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    RenderLayer* m_renderLayer; // FIXME: this is mainly used to get the FilterEffectRenderer. FilterEffectRendererHelper should be weaned off it.
</del><ins>+    RenderLayer* m_renderLayer { nullptr }; // FIXME: this is mainly used to get the FilterEffectRenderer. FilterEffectRendererHelper should be weaned off it.
</ins><span class="cx">     LayoutPoint m_paintOffset;
</span><span class="cx">     LayoutRect m_repaintRect;
</span><del>-    bool m_haveFilterEffect;
-    bool m_startedFilterEffect;
</del><ins>+    bool m_haveFilterEffect { false };
+    bool m_startedFilterEffect { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class FilterEffectRenderer final : public Filter {
</span><span class="lines">@@ -145,8 +143,8 @@
</span><span class="cx">     
</span><span class="cx">     IntRectExtent m_outsets;
</span><span class="cx"> 
</span><del>-    bool m_graphicsBufferAttached;
-    bool m_hasFilterThatMovesPixels;
</del><ins>+    bool m_graphicsBufferAttached { false };
+    bool m_hasFilterThatMovesPixels { false };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (200282 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.cpp        2016-04-30 03:54:41 UTC (rev 200282)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -4196,11 +4196,11 @@
</span><span class="cx">     return nullptr;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderLayer::applyFilters(FilterEffectRendererHelper* filterPainter, GraphicsContext&amp; originalContext, LayerPaintingInfo&amp; paintingInfo, LayerFragments&amp; layerFragments)
</del><ins>+void RenderLayer::applyFilters(FilterEffectRendererHelper* filterPainter, GraphicsContext&amp; originalContext, const LayerPaintingInfo&amp; paintingInfo, const LayerFragments&amp; layerFragments)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(filterPainter-&gt;hasStartedFilterEffect());
</span><del>-    // Apply the correct clipping (ie. overflow: hidden).
-    // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
</del><ins>+
+    // FIXME: Handle more than one fragment.
</ins><span class="cx">     ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
</span><span class="cx">     clipToRect(paintingInfo, originalContext, backgroundRect);
</span><span class="cx">     filterPainter-&gt;applyFilterEffect(originalContext);
</span><span class="lines">@@ -4291,14 +4291,13 @@
</span><span class="cx">     if (shouldApplyClipPath(paintingInfo.paintBehavior, localPaintFlags))
</span><span class="cx">         hasClipPath = setupClipPath(context, paintingInfo, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);
</span><span class="cx"> 
</span><del>-    LayerPaintingInfo localPaintingInfo(paintingInfo);
-
-    bool selectionAndBackgroundsOnly = localPaintingInfo.paintBehavior &amp; PaintBehaviorSelectionAndBackgroundsOnly;
-    bool selectionOnly = localPaintingInfo.paintBehavior &amp; PaintBehaviorSelectionOnly;
</del><ins>+    bool selectionAndBackgroundsOnly = paintingInfo.paintBehavior &amp; PaintBehaviorSelectionAndBackgroundsOnly;
+    bool selectionOnly = paintingInfo.paintBehavior &amp; PaintBehaviorSelectionOnly;
</ins><span class="cx">     LayerFragments layerFragments;
</span><span class="cx">     RenderObject* subtreePaintRootForRenderer = nullptr;
</span><span class="cx"> 
</span><del>-    { // Scope for currentContext.
</del><ins>+    { // Scope for filter-related state changes.
+        LayerPaintingInfo localPaintingInfo(paintingInfo);
</ins><span class="cx">         std::unique_ptr&lt;FilterEffectRendererHelper&gt; filterPainter = setupFilters(context, localPaintingInfo, paintFlags, columnAwareOffsetFromRoot, rootRelativeBounds, rootRelativeBoundsComputed);
</span><span class="cx"> 
</span><span class="cx">         GraphicsContext* filterContext = filterPainter ? filterPainter-&gt;filterContext() : nullptr;
</span><span class="lines">@@ -4329,7 +4328,7 @@
</span><span class="cx">             // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
</span><span class="cx">             // fragment should paint. If the parent's filter dictates full repaint to ensure proper filter effect,
</span><span class="cx">             // use the overflow clip as dirty rect, instead of no clipping. It maintains proper clipping for overflow::scroll.
</span><del>-            if (!paintingInfo.clipToDirtyRect &amp;&amp; renderer().hasOverflowClip()) {
</del><ins>+            if (!localPaintingInfo.clipToDirtyRect &amp;&amp; renderer().hasOverflowClip()) {
</ins><span class="cx">                 // We can turn clipping back by requesting full repaint for the overflow area.
</span><span class="cx">                 localPaintingInfo.clipToDirtyRect = true;
</span><span class="cx">                 paintDirtyRect = selfClipRect();
</span><span class="lines">@@ -4381,7 +4380,16 @@
</span><span class="cx">             paintOverflowControlsForFragments(layerFragments, currentContext, localPaintingInfo);
</span><span class="cx"> 
</span><span class="cx">         if (filterContext) {
</span><del>-            applyFilters(filterPainter.get(), context, localPaintingInfo, layerFragments);
</del><ins>+            // When we called collectFragments() last time, paintDirtyRect was reset to represent the filter bounds.
+            // Now we need to compute the backgroundRect uncontaminated by filters, in order to clip the filtered result.
+            // Note that we also use paintingInfo here, not localPaintingInfo which filters also contaminated.
+            LayerFragments layerFragments;
+            collectFragments(layerFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, ExcludeCompositedPaginatedLayers,
+                (localPaintFlags &amp; PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
+                (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, offsetFromRoot);
+            updatePaintingInfoForFragments(layerFragments, paintingInfo, localPaintFlags, shouldPaintContent, offsetFromRoot);
+
+            applyFilters(filterPainter.get(), context, paintingInfo, layerFragments);
</ins><span class="cx">             filterPainter = nullptr;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="lines">@@ -4389,17 +4397,17 @@
</span><span class="cx">     if (shouldPaintContent &amp;&amp; !(selectionOnly || selectionAndBackgroundsOnly)) {
</span><span class="cx">         if (shouldPaintMask(paintingInfo.paintBehavior, localPaintFlags)) {
</span><span class="cx">             // Paint the mask for the fragments.
</span><del>-            paintMaskForFragments(layerFragments, context, localPaintingInfo, subtreePaintRootForRenderer);
</del><ins>+            paintMaskForFragments(layerFragments, context, paintingInfo, subtreePaintRootForRenderer);
</ins><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         if (!(paintFlags &amp; PaintLayerPaintingCompositingMaskPhase) &amp;&amp; (paintFlags &amp; PaintLayerPaintingCompositingClipPathPhase)) {
</span><span class="cx">             // Re-use paintChildClippingMaskForFragments to paint black for the compositing clipping mask.
</span><del>-            paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, subtreePaintRootForRenderer);
</del><ins>+            paintChildClippingMaskForFragments(layerFragments, context, paintingInfo, subtreePaintRootForRenderer);
</ins><span class="cx">         }
</span><span class="cx">         
</span><span class="cx">         if ((localPaintFlags &amp; PaintLayerPaintingChildClippingMaskPhase)) {
</span><span class="cx">             // Paint the border radius mask for the fragments.
</span><del>-            paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, subtreePaintRootForRenderer);
</del><ins>+            paintChildClippingMaskForFragments(layerFragments, context, paintingInfo, subtreePaintRootForRenderer);
</ins><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.h (200282 => 200283)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.h        2016-04-30 03:54:41 UTC (rev 200282)
+++ trunk/Source/WebCore/rendering/RenderLayer.h        2016-04-30 04:13:16 UTC (rev 200283)
</span><span class="lines">@@ -786,7 +786,7 @@
</span><span class="cx"> 
</span><span class="cx">     bool hasFilterThatIsPainting(GraphicsContext&amp;, PaintLayerFlags) const;
</span><span class="cx">     std::unique_ptr&lt;FilterEffectRendererHelper&gt; setupFilters(GraphicsContext&amp;, LayerPaintingInfo&amp;, PaintLayerFlags, const LayoutSize&amp; offsetFromRoot, LayoutRect&amp; rootRelativeBounds, bool&amp; rootRelativeBoundsComputed);
</span><del>-    void applyFilters(FilterEffectRendererHelper*, GraphicsContext&amp; originalContext, LayerPaintingInfo&amp;, LayerFragments&amp;);
</del><ins>+    void applyFilters(FilterEffectRendererHelper*, GraphicsContext&amp; originalContext, const LayerPaintingInfo&amp;, const LayerFragments&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void paintLayer(GraphicsContext&amp;, const LayerPaintingInfo&amp;, PaintLayerFlags);
</span><span class="cx">     void paintFixedLayersInNamedFlows(GraphicsContext&amp;, const LayerPaintingInfo&amp;, PaintLayerFlags);
</span></span></pre>
</div>
</div>

</body>
</html>