<!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>[204552] 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/204552">204552</a></dd>
<dt>Author</dt> <dd>zalan@apple.com</dd>
<dt>Date</dt> <dd>2016-08-16 20:18:21 -0700 (Tue, 16 Aug 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Subpixel rendering: Cleanup RenderLayerBacking::updateGeometry.
https://bugs.webkit.org/show_bug.cgi?id=156860
&lt;rdar://problem/25432352&gt;

Reviewed by Simon Fraser.

Source/WebCore:

This patch cleans up the subpixel adjustment computation for the graphics layers
in RenderLayerBacking::updateGeometry.
It also fixes subpixel jiggling with clipping layers (both ancestor and child containment layers).

Tests: compositing/hidpi-ancestor-subpixel-clipping.html
       compositing/hidpi-sibling-composited-content-offset.html
       compositing/hidpi-subpixel-transform-origin.html
       fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::beginTransparencyLayers):
(WebCore::RenderLayer::paint):
(WebCore::RenderLayer::clipToRect):
(WebCore::RenderLayer::setupClipPath):
(WebCore::RenderLayer::paintLayerByApplyingTransform):
(WebCore::RenderLayer::paintBackgroundForFragments):
(WebCore::RenderLayer::paintForegroundForFragmentsWithPhase):
(WebCore::RenderLayer::paintOutlineForFragments):
(WebCore::RenderLayer::paintMaskForFragments):
(WebCore::RenderLayer::paintChildClippingMaskForFragments):
(WebCore::RenderLayer::paintOverflowControlsForFragments):
(WebCore::RenderLayer::calculateClipRects):
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::subpixelOffsetFromRendererChanged):
(WebCore::subpixelForLayerPainting):
(WebCore::computeOffsetFromRenderer):
(WebCore::snappedGraphicsLayerRect):
(WebCore::computeOffsetFromAncestorGraphicsLayer):
(WebCore::ComputedOffsets::ComputedOffsets): This is a helper class to hold offset values.
(WebCore::ComputedOffsets::fromAncestorGraphicsLayer):
(WebCore::ComputedOffsets::fromParentGraphicsLayer):
(WebCore::ComputedOffsets::fromPrimaryGraphicsLayer):
(WebCore::RenderLayerBacking::computePrimaryGraphicsLayerRect):
(WebCore::RenderLayerBacking::computeParentGraphicsLayerRect):
(WebCore::RenderLayerBacking::updateGeometry):
(WebCore::RenderLayerBacking::updateMaskingLayerGeometry):
(WebCore::RenderLayerBacking::contentOffsetInCompostingLayer):
(WebCore::RenderLayerBacking::setContentsNeedDisplayInRect):
(WebCore::RenderLayerBacking::paintIntoLayer):
(WebCore::RenderLayerBacking::paintContents):
(WebCore::devicePixelFractionGapFromRendererChanged): Deleted.
(WebCore::pixelFractionForLayerPainting): Deleted.
(WebCore::calculateDevicePixelOffsetFromRenderer): Deleted.
(WebCore::RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread): Deleted.
* rendering/RenderLayerBacking.h:

LayoutTests:

* compositing/hidpi-ancestor-subpixel-clipping-expected.html: Added.
* compositing/hidpi-ancestor-subpixel-clipping.html: Added.
* compositing/hidpi-sibling-composited-content-offset-expected.html: Added.
* compositing/hidpi-sibling-composited-content-offset.html: Added.
* compositing/hidpi-subpixel-transform-origin-expected.html: Added.
* compositing/hidpi-subpixel-transform-origin.html: Added.
* fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor-expected.txt: Added.
* fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.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="#trunkSourceWebCorerenderingRenderLayercpp">trunk/Source/WebCore/rendering/RenderLayer.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerh">trunk/Source/WebCore/rendering/RenderLayer.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerBackingcpp">trunk/Source/WebCore/rendering/RenderLayerBacking.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerBackingh">trunk/Source/WebCore/rendering/RenderLayerBacking.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscompositinghidpiancestorsubpixelclippingexpectedhtml">trunk/LayoutTests/compositing/hidpi-ancestor-subpixel-clipping-expected.html</a></li>
<li><a href="#trunkLayoutTestscompositinghidpiancestorsubpixelclippinghtml">trunk/LayoutTests/compositing/hidpi-ancestor-subpixel-clipping.html</a></li>
<li><a href="#trunkLayoutTestscompositinghidpisiblingcompositedcontentoffsetexpectedhtml">trunk/LayoutTests/compositing/hidpi-sibling-composited-content-offset-expected.html</a></li>
<li><a href="#trunkLayoutTestscompositinghidpisiblingcompositedcontentoffsethtml">trunk/LayoutTests/compositing/hidpi-sibling-composited-content-offset.html</a></li>
<li><a href="#trunkLayoutTestscompositinghidpisubpixeltransformoriginexpectedhtml">trunk/LayoutTests/compositing/hidpi-subpixel-transform-origin-expected.html</a></li>
<li><a href="#trunkLayoutTestscompositinghidpisubpixeltransformoriginhtml">trunk/LayoutTests/compositing/hidpi-subpixel-transform-origin.html</a></li>
<li><a href="#trunkLayoutTestsfastscrollingiossubpixeloverflowscrollingwithancestorexpectedtxt">trunk/LayoutTests/fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastscrollingiossubpixeloverflowscrollingwithancestorhtml">trunk/LayoutTests/fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (204551 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-08-17 03:17:04 UTC (rev 204551)
+++ trunk/LayoutTests/ChangeLog        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-08-16  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Subpixel rendering: Cleanup RenderLayerBacking::updateGeometry.
+        https://bugs.webkit.org/show_bug.cgi?id=156860
+        &lt;rdar://problem/25432352&gt;
+
+        Reviewed by Simon Fraser.
+
+        * compositing/hidpi-ancestor-subpixel-clipping-expected.html: Added.
+        * compositing/hidpi-ancestor-subpixel-clipping.html: Added.
+        * compositing/hidpi-sibling-composited-content-offset-expected.html: Added.
+        * compositing/hidpi-sibling-composited-content-offset.html: Added.
+        * compositing/hidpi-subpixel-transform-origin-expected.html: Added.
+        * compositing/hidpi-subpixel-transform-origin.html: Added.
+        * fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor-expected.txt: Added.
+        * fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html: Added.
+
</ins><span class="cx"> 2016-08-16  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r204540, r204545, and r204547.
</span></span></pre></div>
<a id="trunkLayoutTestscompositinghidpiancestorsubpixelclippingexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/hidpi-ancestor-subpixel-clipping-expected.html (0 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/hidpi-ancestor-subpixel-clipping-expected.html                                (rev 0)
+++ trunk/LayoutTests/compositing/hidpi-ancestor-subpixel-clipping-expected.html        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests ancestor clipping with subpixel positioning.&lt;/title&gt;
+&lt;style&gt;
+.container {
+  position: absolute;
+  background-color: green; 
+  width: 15px; 
+  height: 15px;
+}
+
+.clippingAncestor { 
+  width: 10px;
+  height: 10px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: red;
+  } 
+
+.jiggle {
+  height: 5px;
+  width: 5px; 
+  position: relative;
+  background-color: blue;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+var subpixelForContainer = 0;
+for (var i = 0; i &lt; 20; ++i) {
+  var borderWidth = 2;
+  var subpixelForJiggle = -2;
+  for (var j = 0; j &lt; 20; ++j) {
+    var container = document.createElement(&quot;div&quot;);
+    container.className = &quot;container&quot;;
+    container.style.left = i * 20 + subpixelForContainer + &quot;px&quot;;
+    container.style.top = j * 20 + subpixelForContainer + &quot;px&quot;;
+    document.body.appendChild(container);
+    subpixelForContainer += 0.05;
+
+    var clippingAncestor = document.createElement(&quot;div&quot;);
+    clippingAncestor.className = &quot;clippingAncestor&quot;;
+    clippingAncestor.style.borderWidth = borderWidth + &quot;px&quot;;
+    container.appendChild(clippingAncestor);
+    borderWidth += 0.1;
+
+    var jiggle = document.createElement(&quot;div&quot;);
+    jiggle.className = &quot;jiggle&quot;;
+    jiggle.style.top = subpixelForJiggle + &quot;px&quot;;
+    jiggle.style.left = subpixelForJiggle + &quot;px&quot;;
+    subpixelForJiggle += 0.1;
+    clippingAncestor.appendChild(jiggle);
+  }
+}
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscompositinghidpiancestorsubpixelclippinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/hidpi-ancestor-subpixel-clipping.html (0 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/hidpi-ancestor-subpixel-clipping.html                                (rev 0)
+++ trunk/LayoutTests/compositing/hidpi-ancestor-subpixel-clipping.html        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -0,0 +1,61 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests ancestor clipping with subpixel positioning.&lt;/title&gt;
+&lt;style&gt;
+.container {
+  position: absolute;
+  background-color: green; 
+  width: 15px; 
+  height: 15px;
+  transform: translateZ(0);
+}
+
+.clippingAncestor { 
+  width: 10px;
+  height: 10px;
+  overflow: hidden;
+  border-style: solid;
+  border-color: red;
+  } 
+
+.jiggle {
+  height: 5px;
+  width: 5px; 
+  position: relative;
+  background-color: blue;
+  transform: translateZ(0);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+var subpixelForContainer = 0;
+for (var i = 0; i &lt; 20; ++i) {
+  var borderWidth = 2;
+  var subpixelForJiggle = -2;
+  for (var j = 0; j &lt; 20; ++j) {
+    var container = document.createElement(&quot;div&quot;);
+    container.className = &quot;container&quot;;
+    container.style.left = i * 20 + subpixelForContainer + &quot;px&quot;;
+    container.style.top = j * 20 + subpixelForContainer + &quot;px&quot;;
+    document.body.appendChild(container);
+    subpixelForContainer += 0.05;
+
+    var clippingAncestor = document.createElement(&quot;div&quot;);
+    clippingAncestor.className = &quot;clippingAncestor&quot;;
+    clippingAncestor.style.borderWidth = borderWidth + &quot;px&quot;;
+    container.appendChild(clippingAncestor);
+    borderWidth += 0.1;
+
+    var jiggle = document.createElement(&quot;div&quot;);
+    jiggle.className = &quot;jiggle&quot;;
+    jiggle.style.top = subpixelForJiggle + &quot;px&quot;;
+    jiggle.style.left = subpixelForJiggle + &quot;px&quot;;
+    subpixelForJiggle += 0.1;
+    clippingAncestor.appendChild(jiggle);
+  }
+}
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscompositinghidpisiblingcompositedcontentoffsetexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/hidpi-sibling-composited-content-offset-expected.html (0 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/hidpi-sibling-composited-content-offset-expected.html                                (rev 0)
+++ trunk/LayoutTests/compositing/hidpi-sibling-composited-content-offset-expected.html        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests sibling composited content with subpixel positioning.&lt;/title&gt;
+&lt;style&gt;
+.container {
+  position: absolute;
+  background-color: green; 
+  transform: translateZ(0); 
+  width: 15px; 
+  height: 15px;
+}
+
+.offset { 
+  background-color: blue;
+  width: 5px;
+  height: 5px;
+  position: relative;
+  } 
+
+.jiggle {
+  height: 5px;
+  width: 5px; 
+  background-color: red;
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+var subpixelForContainer = 0;
+for (var i = 0; i &lt; 20; ++i) {
+  var subpixelForChild = -2;
+  for (var j = 0; j &lt; 20; ++j) {
+    var container = document.createElement(&quot;div&quot;);
+    container.className = &quot;container&quot;;
+    container.style.left = i * 20 + subpixelForContainer + &quot;px&quot;;
+    container.style.top = j * 20 + subpixelForContainer + &quot;px&quot;;
+    document.body.appendChild(container);
+    subpixelForContainer += 0.05;
+
+    var offset = document.createElement(&quot;div&quot;);
+    offset.className = &quot;offset&quot;;
+    offset.style.left = subpixelForChild + &quot;px&quot;;
+    container.appendChild(offset);
+    subpixelForChild += 0.05;
+
+    var jiggle = document.createElement(&quot;div&quot;);
+    jiggle.className = &quot;jiggle&quot;;
+    container.appendChild(jiggle);
+  }
+}
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscompositinghidpisiblingcompositedcontentoffsethtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/hidpi-sibling-composited-content-offset.html (0 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/hidpi-sibling-composited-content-offset.html                                (rev 0)
+++ trunk/LayoutTests/compositing/hidpi-sibling-composited-content-offset.html        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -0,0 +1,55 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests sibling composited content with subpixel positioning.&lt;/title&gt;
+&lt;style&gt;
+.container {
+  position: absolute;
+  background-color: green; 
+  transform: translateZ(0); 
+  width: 15px; 
+  height: 15px;
+}
+
+.offset { 
+  background-color: blue;
+  width: 5px;
+  height: 5px;
+  position: relative;
+  } 
+
+.jiggle {
+  height: 5px;
+  width: 5px; 
+  background-color: red;
+  transform: translateZ(0);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+var subpixelForContainer = 0;
+for (var i = 0; i &lt; 20; ++i) {
+  var subpixelForChild = -2;
+  for (var j = 0; j &lt; 20; ++j) {
+    var container = document.createElement(&quot;div&quot;);
+    container.className = &quot;container&quot;;
+    container.style.left = i * 20 + subpixelForContainer + &quot;px&quot;;
+    container.style.top = j * 20 + subpixelForContainer + &quot;px&quot;;
+    document.body.appendChild(container);
+    subpixelForContainer += 0.05;
+
+    var offset = document.createElement(&quot;div&quot;);
+    offset.className = &quot;offset&quot;;
+    offset.style.left = subpixelForChild + &quot;px&quot;;
+    container.appendChild(offset);
+    subpixelForChild += 0.05;
+
+    var jiggle = document.createElement(&quot;div&quot;);
+    jiggle.className = &quot;jiggle&quot;;
+    container.appendChild(jiggle);
+  }
+}
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscompositinghidpisubpixeltransformoriginexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/hidpi-subpixel-transform-origin-expected.html (0 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/hidpi-subpixel-transform-origin-expected.html                                (rev 0)
+++ trunk/LayoutTests/compositing/hidpi-subpixel-transform-origin-expected.html        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -0,0 +1,117 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests transform origin with subpixel values.&lt;/title&gt;
+&lt;style&gt;
+.container {
+  position: absolute;
+  background-color: green; 
+  width: 15px; 
+  height: 15px;
+  transform: rotate(90deg) translateZ(0);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 30px; top: 30px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 30px; top: 50px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 30px; top: 70px; transform-origin: 0px 1px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 30px; top: 90px; transform-origin: 0px 2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 30px; top: 110px; transform-origin: 0px 3px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 30.5px; top: 130.5px; transform-origin: 0px 5px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 30.5px; top: 150.5px; transform-origin: 0px 7px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 30.5px; top: 170.5px; transform-origin: 0px 10px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 30.5px; top: 190.5px; transform-origin: 0px 13px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 30.5px; top: 210.5px; transform-origin: 0px 16px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 50.5px; top: 30.5px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 50.5px; top: 50.5px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 50.5px; top: 70.5px; transform-origin: 0.5px 1px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 50.5px; top: 90.5px; transform-origin: 0.5px 2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 50.5px; top: 110.5px; transform-origin: 1px 3px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 51px; top: 131px; transform-origin: 1px 5px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 51px; top: 151px; transform-origin: 1px 7px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 51px; top: 171px; transform-origin: 1.5px 10px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 51px; top: 191px; transform-origin: 1.5px 13px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 51px; top: 211px; transform-origin: 2px 16px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 71px; top: 31px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 71px; top: 51px; transform-origin: 0.5px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 71px; top: 71px; transform-origin: 1px 1px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 71px; top: 91px; transform-origin: 1px 2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 71px; top: 111px; transform-origin: 1.5px 3px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 71.5px; top: 131.5px; transform-origin: 2px 5px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 71.5px; top: 151.5px; transform-origin: 2.5px 7px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 71.5px; top: 171.5px; transform-origin: 3px 10px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 71.5px; top: 191.5px; transform-origin: 3px 13px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 71.5px; top: 211.5px; transform-origin: 3.5px 16px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 91.5px; top: 31.5px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 91.5px; top: 51.5px; transform-origin: 0.5px 0.2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 91.5px; top: 71.5px; transform-origin: 1px 1px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 91.5px; top: 91.5px; transform-origin: 2px 2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 91.5px; top: 111.5px; transform-origin: 2.5px 3px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 92px; top: 132px; transform-origin: 3px 5px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 92px; top: 152px; transform-origin: 3.5px 7px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 92px; top: 172px; transform-origin: 4px 10px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 92px; top: 192px; transform-origin: 5px 13px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 92px; top: 212px; transform-origin: 5.5px 16px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 112px; top: 32px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 112px; top: 52px; transform-origin: 1px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 112px; top: 72px; transform-origin: 1.5px 1px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 112px; top: 92px; transform-origin: 2.5px 2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 112px; top: 112px; transform-origin: 3px 3px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 112.5px; top: 132.5px; transform-origin: 4px 5px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 112.5px; top: 152.5px; transform-origin: 5px 7px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 112.5px; top: 172.5px; transform-origin: 5.5px 10px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 112.5px; top: 192.5px; transform-origin: 6.5px 13px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 112.5px; top: 212.5px; transform-origin: 7px 16px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 132.5px; top: 32.5px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 132.5px; top: 52.5px; transform-origin: 1px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 132.5px; top: 72.5px; transform-origin: 2px 1px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 132.5px; top: 92.5px; transform-origin: 3px 2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 132.5px; top: 112.5px; transform-origin: 4px 3px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 133px; top: 133px; transform-origin: 5px 5px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 133px; top: 153px; transform-origin: 6px 7px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 133px; top: 173px; transform-origin: 7px 10px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 133px; top: 193px; transform-origin: 8px 13px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 133px; top: 213px; transform-origin: 9px 16px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 153px; top: 33px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 153px; top: 53px; transform-origin: 1px 0.2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 153px; top: 73px; transform-origin: 2.5px 1px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 153px; top: 93px; transform-origin: 3.5px 2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 153px; top: 113px; transform-origin: 5px 3px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 153.5px; top: 133.5px; transform-origin: 6px 5px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 153.5px; top: 153.5px; transform-origin: 7px 7px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 153.5px; top: 173.5px; transform-origin: 8.5px 10px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 153.5px; top: 193.5px; transform-origin: 9.5px 13px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 153.5px; top: 213.5px; transform-origin: 11px 16px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 173.5px; top: 33.5px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 173.5px; top: 53.5px; transform-origin: 1.5px 0.2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 173.5px; top: 73.5px; transform-origin: 3px 1px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 173.5px; top: 93.5px; transform-origin: 4px 2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 173.5px; top: 113.5px; transform-origin: 5.5px 3px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 174px; top: 134px; transform-origin: 7px 5px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 174px; top: 154px; transform-origin: 8.5px 7px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 174px; top: 174px; transform-origin: 10px 10px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 174px; top: 194px; transform-origin: 11px 13px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 174px; top: 214px; transform-origin: 12.5px 16px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 194px; top: 34px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 194px; top: 54px; transform-origin: 1.5px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 194px; top: 74px; transform-origin: 3px 1px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 194px; top: 94px; transform-origin: 5px 2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 194px; top: 114px; transform-origin: 6.5px 3px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 194.5px; top: 134.5px; transform-origin: 8px 5px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 194.5px; top: 154.5px; transform-origin: 9.5px 7px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 194.5px; top: 174.5px; transform-origin: 11px 10px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 194.5px; top: 194.5px; transform-origin: 13px 13px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 194.5px; top: 214.5px; transform-origin: 14.5px 16px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 214.5px; top: 34.5px; transform-origin: 0px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 214.5px; top: 54.5px; transform-origin: 2px 0px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 214.5px; top: 74.5px; transform-origin: 3.5px 1px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 214.5px; top: 94.5px; transform-origin: 5.5px 2px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 214.5px; top: 114.5px; transform-origin: 7px 3px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 215px; top: 135px; transform-origin: 9px 5px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 215px; top: 155px; transform-origin: 11px 7px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 215px; top: 175px; transform-origin: 12.5px 10px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 215px; top: 195px; transform-origin: 14.5px 13px;&quot;&gt;&lt;/div&gt;
+&lt;div class=&quot;container&quot; style=&quot;left: 215px; top: 215px; transform-origin: 16px 16px;&quot;&gt;&lt;/div&gt;
+
+&lt;/body&gt;&lt;/html&gt;
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestscompositinghidpisubpixeltransformoriginhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/compositing/hidpi-subpixel-transform-origin.html (0 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/compositing/hidpi-subpixel-transform-origin.html                                (rev 0)
+++ trunk/LayoutTests/compositing/hidpi-subpixel-transform-origin.html        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -0,0 +1,33 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;title&gt;This tests transform origin with subpixel values.&lt;/title&gt;
+&lt;style&gt;
+.container {
+  position: absolute;
+  background-color: green; 
+  width: 15px; 
+  height: 15px;
+  transform: rotate(90deg) translateZ(0);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+var subpixelForContainer = 30;
+for (var i = 0; i &lt; 10; ++i) {
+  var subpixelForOrigin = 0;
+  for (var j = 0; j &lt; 10; ++j) {
+    var container = document.createElement(&quot;div&quot;);
+    container.className = &quot;container&quot;;
+    container.style.left = i * 20 + subpixelForContainer + &quot;px&quot;;
+    container.style.top = j * 20 + subpixelForContainer + &quot;px&quot;;
+        container.style.transformOrigin = i * subpixelForOrigin +&quot;px &quot; + j * subpixelForOrigin + &quot;px&quot;;
+    document.body.appendChild(container);
+    subpixelForContainer += 0.05;
+    subpixelForOrigin += 0.2;
+  }
+}
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsfastscrollingiossubpixeloverflowscrollingwithancestorexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor-expected.txt (0 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor-expected.txt                                (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor-expected.txt        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -0,0 +1,41 @@
</span><ins>+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 320.00 568.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 320.00 568.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 300.00 400.00)
+          (children 1
+            (GraphicsLayer
+              (bounds origin 0.00 30.00)
+              (bounds 300.00 400.00)
+              (children 1
+                (GraphicsLayer
+                  (bounds 300.00 900.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (position 20.00 50.00)
+                      (bounds 260.00 800.00)
+                      (children 1
+                        (GraphicsLayer
+                          (bounds 260.00 800.00)
+                          (contentsOpaque 1)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
</ins></span></pre></div>
<a id="trunkLayoutTestsfastscrollingiossubpixeloverflowscrollingwithancestorhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html (0 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html                                (rev 0)
+++ trunk/LayoutTests/fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -0,0 +1,54 @@
</span><ins>+&lt;!DOCTYPE html&gt; &lt;!-- webkit-test-runner [ useFlexibleViewport=true ] --&gt;
+&lt;html&gt;
+&lt;head&gt;
+  &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width&quot;&gt;
+  &lt;script&gt;
+    if (window.testRunner)
+      testRunner.dumpAsText();
+
+    function doScroll()
+    {
+      var overflow = document.getElementById('scroller');
+      overflow.scrollTop = 30.5;
+
+      if (window.testRunner)
+        document.getElementById('layers').innerHTML = window.internals.layerTreeAsText(document);
+    }
+    
+    window.addEventListener('load', doScroll, false);
+  &lt;/script&gt;
+  &lt;style&gt;
+    #scroller {
+      overflow: scroll;
+      -webkit-overflow-scrolling: touch;
+      width: 300px;
+      height: 400px;
+    }
+    
+    .column {
+      overflow: hidden;
+      margin: 50px 20px;
+      width: 260px;
+      height: 800px;
+      background-color: red;
+    }
+
+    .contents {
+      -webkit-transform: translateZ(0);
+      width: 100%;
+      height: 100%;
+      background: green;
+    }
+  &lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+
+  &lt;div id=&quot;scroller&quot;&gt;
+    &lt;div class=&quot;column&quot;&gt;
+      &lt;div class=&quot;contents&quot;&gt;&lt;/div&gt;
+    &lt;/div&gt;
+  &lt;/div&gt;
+  &lt;pre id=&quot;layers&quot;&gt;Layer tree goes here in DRT.&lt;/pre&gt;
+
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (204551 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-08-17 03:17:04 UTC (rev 204551)
+++ trunk/Source/WebCore/ChangeLog        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -1,3 +1,58 @@
</span><ins>+2016-08-16  Zalan Bujtas  &lt;zalan@apple.com&gt;
+
+        Subpixel rendering: Cleanup RenderLayerBacking::updateGeometry.
+        https://bugs.webkit.org/show_bug.cgi?id=156860
+        &lt;rdar://problem/25432352&gt;
+
+        Reviewed by Simon Fraser.
+
+        This patch cleans up the subpixel adjustment computation for the graphics layers
+        in RenderLayerBacking::updateGeometry.
+        It also fixes subpixel jiggling with clipping layers (both ancestor and child containment layers). 
+
+        Tests: compositing/hidpi-ancestor-subpixel-clipping.html
+               compositing/hidpi-sibling-composited-content-offset.html
+               compositing/hidpi-subpixel-transform-origin.html
+               fast/scrolling/ios/subpixel-overflow-scrolling-with-ancestor.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::beginTransparencyLayers):
+        (WebCore::RenderLayer::paint):
+        (WebCore::RenderLayer::clipToRect):
+        (WebCore::RenderLayer::setupClipPath):
+        (WebCore::RenderLayer::paintLayerByApplyingTransform):
+        (WebCore::RenderLayer::paintBackgroundForFragments):
+        (WebCore::RenderLayer::paintForegroundForFragmentsWithPhase):
+        (WebCore::RenderLayer::paintOutlineForFragments):
+        (WebCore::RenderLayer::paintMaskForFragments):
+        (WebCore::RenderLayer::paintChildClippingMaskForFragments):
+        (WebCore::RenderLayer::paintOverflowControlsForFragments):
+        (WebCore::RenderLayer::calculateClipRects):
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::subpixelOffsetFromRendererChanged):
+        (WebCore::subpixelForLayerPainting):
+        (WebCore::computeOffsetFromRenderer):
+        (WebCore::snappedGraphicsLayerRect):
+        (WebCore::computeOffsetFromAncestorGraphicsLayer):
+        (WebCore::ComputedOffsets::ComputedOffsets): This is a helper class to hold offset values.
+        (WebCore::ComputedOffsets::fromAncestorGraphicsLayer):
+        (WebCore::ComputedOffsets::fromParentGraphicsLayer):
+        (WebCore::ComputedOffsets::fromPrimaryGraphicsLayer):
+        (WebCore::RenderLayerBacking::computePrimaryGraphicsLayerRect):
+        (WebCore::RenderLayerBacking::computeParentGraphicsLayerRect):
+        (WebCore::RenderLayerBacking::updateGeometry):
+        (WebCore::RenderLayerBacking::updateMaskingLayerGeometry):
+        (WebCore::RenderLayerBacking::contentOffsetInCompostingLayer):
+        (WebCore::RenderLayerBacking::setContentsNeedDisplayInRect):
+        (WebCore::RenderLayerBacking::paintIntoLayer):
+        (WebCore::RenderLayerBacking::paintContents):
+        (WebCore::devicePixelFractionGapFromRendererChanged): Deleted.
+        (WebCore::pixelFractionForLayerPainting): Deleted.
+        (WebCore::calculateDevicePixelOffsetFromRenderer): Deleted.
+        (WebCore::RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread): Deleted.
+        * rendering/RenderLayerBacking.h:
+
</ins><span class="cx"> 2016-08-16  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r204540, r204545, and r204547.
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.cpp (204551 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.cpp        2016-08-17 03:17:04 UTC (rev 204551)
+++ trunk/Source/WebCore/rendering/RenderLayer.cpp        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -1811,7 +1811,7 @@
</span><span class="cx">         m_usedTransparency = true;
</span><span class="cx">         context.save();
</span><span class="cx">         LayoutRect adjustedClipRect = paintingExtent(*this, paintingInfo.rootLayer, dirtyRect, paintingInfo.paintBehavior);
</span><del>-        adjustedClipRect.move(paintingInfo.subpixelAccumulation);
</del><ins>+        adjustedClipRect.move(paintingInfo.subpixelOffset);
</ins><span class="cx">         FloatRect pixelSnappedClipRect = snapRectToDevicePixels(adjustedClipRect, renderer().document().deviceScaleFactor());
</span><span class="cx">         context.clip(pixelSnappedClipRect);
</span><span class="cx"> 
</span><span class="lines">@@ -3808,11 +3808,11 @@
</span><span class="cx">     return ScrollableArea::scroll(direction, granularity, multiplier);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void RenderLayer::paint(GraphicsContext&amp; context, const LayoutRect&amp; damageRect, const LayoutSize&amp; subpixelAccumulation, PaintBehavior paintBehavior, RenderObject* subtreePaintRoot, PaintLayerFlags paintFlags)
</del><ins>+void RenderLayer::paint(GraphicsContext&amp; context, const LayoutRect&amp; damageRect, const LayoutSize&amp; subpixelOffset, PaintBehavior paintBehavior, RenderObject* subtreePaintRoot, PaintLayerFlags paintFlags)
</ins><span class="cx"> {
</span><span class="cx">     OverlapTestRequestMap overlapTestRequests;
</span><span class="cx"> 
</span><del>-    LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, subpixelAccumulation, subtreePaintRoot, &amp;overlapTestRequests);
</del><ins>+    LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, subpixelOffset, subtreePaintRoot, &amp;overlapTestRequests);
</ins><span class="cx">     paintLayer(context, paintingInfo, paintFlags);
</span><span class="cx"> 
</span><span class="cx">     for (auto&amp; widget : overlapTestRequests.keys())
</span><span class="lines">@@ -3851,7 +3851,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (needsClipping) {
</span><span class="cx">         LayoutRect adjustedClipRect = clipRect.rect();
</span><del>-        adjustedClipRect.move(paintingInfo.subpixelAccumulation);
</del><ins>+        adjustedClipRect.move(paintingInfo.subpixelOffset);
</ins><span class="cx">         context.clip(snapRectToDevicePixels(adjustedClipRect, deviceScaleFactor));
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -3862,7 +3862,7 @@
</span><span class="cx">         for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer-&gt;parent()) {
</span><span class="cx">             if (layer-&gt;renderer().hasOverflowClip() &amp;&amp; layer-&gt;renderer().style().hasBorderRadius() &amp;&amp; inContainingBlockChain(this, layer)) {
</span><span class="cx">                 LayoutRect adjustedClipRect = LayoutRect(toLayoutPoint(layer-&gt;offsetFromAncestor(paintingInfo.rootLayer, AdjustForColumns)), layer-&gt;size());
</span><del>-                adjustedClipRect.move(paintingInfo.subpixelAccumulation);
</del><ins>+                adjustedClipRect.move(paintingInfo.subpixelOffset);
</ins><span class="cx">                 FloatRoundedRect roundedRect = layer-&gt;renderer().style().getRoundedInnerBorderFor(adjustedClipRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor);
</span><span class="cx">                 if (roundedRect.intersectionIsRectangular(paintingInfo.paintDirtyRect))
</span><span class="cx">                     context.clip(snapRectToDevicePixels(intersection(paintingInfo.paintDirtyRect, adjustedClipRect), deviceScaleFactor));
</span><span class="lines">@@ -4134,7 +4134,7 @@
</span><span class="cx">     ASSERT(style.clipPath());
</span><span class="cx">     if (is&lt;ShapeClipPathOperation&gt;(*style.clipPath()) || (is&lt;BoxClipPathOperation&gt;(*style.clipPath()) &amp;&amp; is&lt;RenderBox&gt;(renderer()))) {
</span><span class="cx">         WindRule windRule;
</span><del>-        LayoutSize paintingOffsetFromRoot = LayoutSize(snapSizeToDevicePixel(offsetFromRoot + paintingInfo.subpixelAccumulation, LayoutPoint(), renderer().document().deviceScaleFactor()));
</del><ins>+        LayoutSize paintingOffsetFromRoot = LayoutSize(snapSizeToDevicePixel(offsetFromRoot + paintingInfo.subpixelOffset, LayoutPoint(), renderer().document().deviceScaleFactor()));
</ins><span class="cx">         Path path = computeClipPath(paintingOffsetFromRoot, rootRelativeBounds, windRule);
</span><span class="cx">         context.save();
</span><span class="cx">         context.clipPath(path, windRule);
</span><span class="lines">@@ -4450,7 +4450,7 @@
</span><span class="cx">     offsetFromParent += translationOffset;
</span><span class="cx">     TransformationMatrix transform(renderableTransform(paintingInfo.paintBehavior));
</span><span class="cx">     // Add the subpixel accumulation to the current layer's offset so that we can always snap the translateRight value to where the renderer() is supposed to be painting.
</span><del>-    LayoutSize offsetForThisLayer = offsetFromParent + paintingInfo.subpixelAccumulation;
</del><ins>+    LayoutSize offsetForThisLayer = offsetFromParent + paintingInfo.subpixelOffset;
</ins><span class="cx">     FloatSize devicePixelSnappedOffsetForThisLayer = toFloatSize(roundPointToDevicePixels(toLayoutPoint(offsetForThisLayer), deviceScaleFactor));
</span><span class="cx">     // We handle accumulated subpixels through nested layers here. Since the context gets translated to device pixels,
</span><span class="cx">     // all we need to do is add the delta to the accumulated pixels coming from ancestor layers.
</span><span class="lines">@@ -4461,9 +4461,9 @@
</span><span class="cx">     context.concatCTM(transform.toAffineTransform());
</span><span class="cx"> 
</span><span class="cx">     // Now do a paint with the root layer shifted to be us.
</span><del>-    LayoutSize adjustedSubpixelAccumulation = offsetForThisLayer - LayoutSize(devicePixelSnappedOffsetForThisLayer);
</del><ins>+    LayoutSize adjustedSubpixelOffset = offsetForThisLayer - LayoutSize(devicePixelSnappedOffsetForThisLayer);
</ins><span class="cx">     LayerPaintingInfo transformedPaintingInfo(this, LayoutRect(encloseRectToDevicePixels(transform.inverse().valueOr(AffineTransform()).mapRect(paintingInfo.paintDirtyRect), deviceScaleFactor)),
</span><del>-        paintingInfo.paintBehavior, adjustedSubpixelAccumulation, paintingInfo.subtreePaintRoot, paintingInfo.overlapTestRequests);
</del><ins>+        paintingInfo.paintBehavior, adjustedSubpixelOffset, paintingInfo.subtreePaintRoot, paintingInfo.overlapTestRequests);
</ins><span class="cx">     paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
</span><span class="cx">     context.setCTM(oldTransfrom);
</span><span class="cx"> }
</span><span class="lines">@@ -4705,7 +4705,7 @@
</span><span class="cx">         // Paint the background.
</span><span class="cx">         // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
</span><span class="cx">         PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseBlockBackground, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &amp;localPaintingInfo.rootLayer-&gt;renderer());
</span><del>-        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
</del><ins>+        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
</ins><span class="cx"> 
</span><span class="cx">         if (localPaintingInfo.clipToDirtyRect)
</span><span class="cx">             restoreClip(context, localPaintingInfo, fragment.backgroundRect);
</span><span class="lines">@@ -4772,7 +4772,7 @@
</span><span class="cx">         PaintInfo paintInfo(context, fragment.foregroundRect.rect(), phase, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &amp;localPaintingInfo.rootLayer-&gt;renderer());
</span><span class="cx">         if (phase == PaintPhaseForeground)
</span><span class="cx">             paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests;
</span><del>-        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
</del><ins>+        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
</ins><span class="cx">         
</span><span class="cx">         if (shouldClip)
</span><span class="cx">             restoreClip(context, localPaintingInfo, fragment.foregroundRect);
</span><span class="lines">@@ -4789,7 +4789,7 @@
</span><span class="cx">         // Paint our own outline
</span><span class="cx">         PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseSelfOutline, paintBehavior, subtreePaintRootForRenderer, nullptr, nullptr, &amp;localPaintingInfo.rootLayer-&gt;renderer());
</span><span class="cx">         clipToRect(context, localPaintingInfo, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius);
</span><del>-        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
</del><ins>+        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
</ins><span class="cx">         restoreClip(context, localPaintingInfo, fragment.backgroundRect);
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="lines">@@ -4807,7 +4807,7 @@
</span><span class="cx">         // Paint the mask.
</span><span class="cx">         // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
</span><span class="cx">         PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseMask, PaintBehaviorNormal, subtreePaintRootForRenderer, nullptr, nullptr, &amp;localPaintingInfo.rootLayer-&gt;renderer());
</span><del>-        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
</del><ins>+        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
</ins><span class="cx">         
</span><span class="cx">         if (localPaintingInfo.clipToDirtyRect)
</span><span class="cx">             restoreClip(context, localPaintingInfo, fragment.backgroundRect);
</span><span class="lines">@@ -4826,7 +4826,7 @@
</span><span class="cx"> 
</span><span class="cx">         // Paint the clipped mask.
</span><span class="cx">         PaintInfo paintInfo(context, fragment.backgroundRect.rect(), PaintPhaseClippingMask, PaintBehaviorNormal, subtreePaintRootForRenderer, nullptr, nullptr, &amp;localPaintingInfo.rootLayer-&gt;renderer());
</span><del>-        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation));
</del><ins>+        renderer().paint(paintInfo, toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset));
</ins><span class="cx"> 
</span><span class="cx">         if (localPaintingInfo.clipToDirtyRect)
</span><span class="cx">             restoreClip(context, localPaintingInfo, fragment.foregroundRect);
</span><span class="lines">@@ -4839,7 +4839,7 @@
</span><span class="cx">         if (fragment.backgroundRect.isEmpty())
</span><span class="cx">             continue;
</span><span class="cx">         clipToRect(context, localPaintingInfo, fragment.backgroundRect);
</span><del>-        paintOverflowControls(context, roundedIntPoint(toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelAccumulation)),
</del><ins>+        paintOverflowControls(context, roundedIntPoint(toLayoutPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subpixelOffset)),
</ins><span class="cx">             snappedIntRect(fragment.backgroundRect.rect()), true);
</span><span class="cx">         restoreClip(context, localPaintingInfo, fragment.backgroundRect);
</span><span class="cx">     }
</span><span class="lines">@@ -6981,9 +6981,9 @@
</span><span class="cx">     context.save();
</span><span class="cx">     context.translate(-adjustedPaintOffset.x(), -adjustedPaintOffset.y());
</span><span class="cx"> 
</span><del>-    LayoutSize subpixelAccumulation = moveOffset - toLayoutSize(LayoutPoint(adjustedPaintOffset));
</del><ins>+    LayoutSize subpixelOffset = moveOffset - toLayoutSize(LayoutPoint(adjustedPaintOffset));
</ins><span class="cx">     paintDirtyRect.move(moveOffset);
</span><del>-    paint(context, paintDirtyRect, LayoutSize(-subpixelAccumulation.width(), -subpixelAccumulation.height()), paintBehavior, nullptr, paintFlags | PaintLayerTemporaryClipRects);
</del><ins>+    paint(context, paintDirtyRect, LayoutSize(-subpixelOffset.width(), -subpixelOffset.height()), paintBehavior, nullptr, paintFlags | PaintLayerTemporaryClipRects);
</ins><span class="cx">     region-&gt;restoreRegionObjectsOriginalStyle();
</span><span class="cx">     context.restore();
</span><span class="cx"> }
</span><span class="lines">@@ -7024,7 +7024,7 @@
</span><span class="cx">         if (shouldClip)
</span><span class="cx">             clipToRect(context, paintingInfo, clipRect);
</span><span class="cx"> 
</span><del>-        flowThreadLayer-&gt;paintNamedFlowThreadInsideRegion(context, flowFragment, paintingInfo.paintDirtyRect, fragment.layerBounds.location() + paintingInfo.subpixelAccumulation,
</del><ins>+        flowThreadLayer-&gt;paintNamedFlowThreadInsideRegion(context, flowFragment, paintingInfo.paintDirtyRect, fragment.layerBounds.location() + paintingInfo.subpixelOffset,
</ins><span class="cx">             paintingInfo.paintBehavior, paintFlags);
</span><span class="cx"> 
</span><span class="cx">         if (shouldClip)
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayer.h (204551 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayer.h        2016-08-17 03:17:04 UTC (rev 204551)
+++ trunk/Source/WebCore/rendering/RenderLayer.h        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -466,7 +466,7 @@
</span><span class="cx">     // paints the layers that intersect the damage rect from back to
</span><span class="cx">     // front.  The hitTest method looks for mouse events by walking
</span><span class="cx">     // layers that intersect the point from front to back.
</span><del>-    void paint(GraphicsContext&amp;, const LayoutRect&amp; damageRect, const LayoutSize&amp; subpixelAccumulation = LayoutSize(), PaintBehavior = PaintBehaviorNormal,
</del><ins>+    void paint(GraphicsContext&amp;, const LayoutRect&amp; damageRect, const LayoutSize&amp; subpixelOffset = LayoutSize(), PaintBehavior = PaintBehaviorNormal,
</ins><span class="cx">         RenderObject* subtreePaintRoot = nullptr, PaintLayerFlags = 0);
</span><span class="cx">     bool hitTest(const HitTestRequest&amp;, HitTestResult&amp;);
</span><span class="cx">     bool hitTest(const HitTestRequest&amp;, const HitTestLocation&amp;, HitTestResult&amp;);
</span><span class="lines">@@ -678,11 +678,11 @@
</span><span class="cx">     enum CollectLayersBehavior { StopAtStackingContexts, StopAtStackingContainers };
</span><span class="cx"> 
</span><span class="cx">     struct LayerPaintingInfo {
</span><del>-        LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect&amp; inDirtyRect, PaintBehavior inPaintBehavior, const LayoutSize&amp; inSubpixelAccumulation, RenderObject* inSubtreePaintRoot = nullptr, OverlapTestRequestMap* inOverlapTestRequests = nullptr)
</del><ins>+        LayerPaintingInfo(RenderLayer* inRootLayer, const LayoutRect&amp; inDirtyRect, PaintBehavior inPaintBehavior, const LayoutSize&amp; inSupixelOffset, RenderObject* inSubtreePaintRoot = nullptr, OverlapTestRequestMap* inOverlapTestRequests = nullptr)
</ins><span class="cx">             : rootLayer(inRootLayer)
</span><span class="cx">             , subtreePaintRoot(inSubtreePaintRoot)
</span><span class="cx">             , paintDirtyRect(inDirtyRect)
</span><del>-            , subpixelAccumulation(inSubpixelAccumulation)
</del><ins>+            , subpixelOffset(inSupixelOffset)
</ins><span class="cx">             , overlapTestRequests(inOverlapTestRequests)
</span><span class="cx">             , paintBehavior(inPaintBehavior)
</span><span class="cx">             , clipToDirtyRect(true)
</span><span class="lines">@@ -690,7 +690,7 @@
</span><span class="cx">         RenderLayer* rootLayer;
</span><span class="cx">         RenderObject* subtreePaintRoot; // only paint descendants of this object
</span><span class="cx">         LayoutRect paintDirtyRect; // relative to rootLayer;
</span><del>-        LayoutSize subpixelAccumulation;
</del><ins>+        LayoutSize subpixelOffset;
</ins><span class="cx">         OverlapTestRequestMap* overlapTestRequests; // May be null.
</span><span class="cx">         PaintBehavior paintBehavior;
</span><span class="cx">         bool clipToDirtyRect;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerBackingcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.cpp (204551 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2016-08-17 03:17:04 UTC (rev 204551)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.cpp        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -696,14 +696,14 @@
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static bool devicePixelFractionGapFromRendererChanged(const LayoutSize&amp; previousDevicePixelFractionFromRenderer, const LayoutSize&amp; currentDevicePixelFractionFromRenderer, float deviceScaleFactor)
</del><ins>+static bool subpixelOffsetFromRendererChanged(const LayoutSize&amp; oldSubpixelOffsetFromRenderer, const LayoutSize&amp; newSubpixelOffsetFromRenderer, float deviceScaleFactor)
</ins><span class="cx"> {
</span><del>-    FloatSize previous = snapSizeToDevicePixel(previousDevicePixelFractionFromRenderer, LayoutPoint(), deviceScaleFactor);
-    FloatSize current = snapSizeToDevicePixel(currentDevicePixelFractionFromRenderer, LayoutPoint(), deviceScaleFactor);
</del><ins>+    FloatSize previous = snapSizeToDevicePixel(oldSubpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor);
+    FloatSize current = snapSizeToDevicePixel(newSubpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor);
</ins><span class="cx">     return previous != current;
</span><span class="cx"> }
</span><del>-
-static FloatSize pixelFractionForLayerPainting(const LayoutPoint&amp; point, float pixelSnappingFactor)
</del><ins>+    
+static FloatSize subpixelForLayerPainting(const LayoutPoint&amp; point, float pixelSnappingFactor)
</ins><span class="cx"> {
</span><span class="cx">     LayoutUnit x = point.x();
</span><span class="cx">     LayoutUnit y = point.y();
</span><span class="lines">@@ -712,13 +712,153 @@
</span><span class="cx">     return point - LayoutPoint(x, y);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void calculateDevicePixelOffsetFromRenderer(const LayoutSize&amp; rendererOffsetFromGraphicsLayer, FloatSize&amp; devicePixelOffsetFromRenderer,
-    LayoutSize&amp; devicePixelFractionFromRenderer, float deviceScaleFactor)
</del><ins>+struct OffsetFromRenderer {
+    // 1.2px - &gt; { m_devicePixelOffset = 1px m_subpixelOffset = 0.2px }
+    LayoutSize m_devicePixelOffset;
+    LayoutSize m_subpixelOffset;
+};
+
+static OffsetFromRenderer computeOffsetFromRenderer(const LayoutSize&amp; offset, float deviceScaleFactor)
</ins><span class="cx"> {
</span><del>-    devicePixelFractionFromRenderer = LayoutSize(pixelFractionForLayerPainting(toLayoutPoint(rendererOffsetFromGraphicsLayer), deviceScaleFactor));
-    devicePixelOffsetFromRenderer = rendererOffsetFromGraphicsLayer - devicePixelFractionFromRenderer;
</del><ins>+    OffsetFromRenderer offsetFromRenderer;
+    offsetFromRenderer.m_subpixelOffset = LayoutSize(subpixelForLayerPainting(toLayoutPoint(offset), deviceScaleFactor));
+    offsetFromRenderer.m_devicePixelOffset = offset - offsetFromRenderer.m_subpixelOffset;
+    return offsetFromRenderer;
</ins><span class="cx"> }
</span><ins>+    
+struct SnappedRectInfo {
+    LayoutRect m_snappedRect;
+    LayoutSize m_snapDelta;
+};
+    
+static SnappedRectInfo snappedGraphicsLayer(const LayoutSize&amp; offset, const LayoutSize&amp; size, float deviceScaleFactor)
+{
+    SnappedRectInfo snappedGraphicsLayer;
+    LayoutRect graphicsLayerRect = LayoutRect(toLayoutPoint(offset), size);
+    snappedGraphicsLayer.m_snappedRect = LayoutRect(snapRectToDevicePixels(graphicsLayerRect, deviceScaleFactor));
+    snappedGraphicsLayer.m_snapDelta = snappedGraphicsLayer.m_snappedRect.location() - toLayoutPoint(offset);
+    return snappedGraphicsLayer;
+}
</ins><span class="cx"> 
</span><ins>+static LayoutSize computeOffsetFromAncestorGraphicsLayer(RenderLayer* compositedAncestor, const LayoutPoint&amp; location)
+{
+    if (!compositedAncestor)
+        return toLayoutSize(location);
+
+    LayoutSize ancestorRenderLayerOffsetFromAncestorGraphicsLayer = -(LayoutSize(compositedAncestor-&gt;backing()-&gt;graphicsLayer()-&gt;offsetFromRenderer())
+        + compositedAncestor-&gt;backing()-&gt;subpixelOffsetFromRenderer());
+    return ancestorRenderLayerOffsetFromAncestorGraphicsLayer + toLayoutSize(location);
+}
+
+class ComputedOffsets {
+public:
+    ComputedOffsets(const RenderLayer&amp; renderLayer, const LayoutRect&amp; localRect, const LayoutRect&amp; parentGraphicsLayerRect, const LayoutRect&amp; primaryGraphicsLayerRect)
+        : m_renderLayer(renderLayer)
+        , m_location(localRect.location())
+        , m_parentGraphicsLayerOffset(toLayoutSize(parentGraphicsLayerRect.location()))
+        , m_primaryGraphicsLayerOffset(toLayoutSize(primaryGraphicsLayerRect.location()))
+    {
+    }
+
+    LayoutSize fromParentGraphicsLayer()
+    {
+        if (!m_fromParentGraphicsLayer)
+            m_fromParentGraphicsLayer = fromAncestorGraphicsLayer() - m_parentGraphicsLayerOffset;
+        return m_fromParentGraphicsLayer.value();
+    }
+    
+    LayoutSize fromPrimaryGraphicsLayer()
+    {
+        if (!m_fromPrimaryGraphicsLayer)
+            m_fromPrimaryGraphicsLayer = fromAncestorGraphicsLayer() - m_parentGraphicsLayerOffset - m_primaryGraphicsLayerOffset;
+        return m_fromPrimaryGraphicsLayer.value();
+    }
+    
+private:
+    LayoutSize fromAncestorGraphicsLayer()
+    {
+        if (!m_fromAncestorGraphicsLayer) {
+            RenderLayer* compositedAncestor = m_renderLayer.ancestorCompositingLayer();
+            LayoutPoint localPointInAncestorRenderLayerCoords = m_renderLayer.convertToLayerCoords(compositedAncestor, m_location, RenderLayer::AdjustForColumns);
+            m_fromAncestorGraphicsLayer = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, localPointInAncestorRenderLayerCoords);
+        }
+        return m_fromAncestorGraphicsLayer.value();
+    }
+
+    Optional&lt;LayoutSize&gt; m_fromAncestorGraphicsLayer;
+    Optional&lt;LayoutSize&gt; m_fromParentGraphicsLayer;
+    Optional&lt;LayoutSize&gt; m_fromPrimaryGraphicsLayer;
+    
+    const RenderLayer&amp; m_renderLayer;
+    // Location is relative to the renderer.
+    const LayoutPoint m_location;
+    const LayoutSize m_parentGraphicsLayerOffset;
+    const LayoutSize m_primaryGraphicsLayerOffset;
+};
+
+LayoutRect RenderLayerBacking::computePrimaryGraphicsLayerRect(const LayoutRect&amp; parentGraphicsLayerRect) const
+{
+    ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, LayoutRect());
+    return LayoutRect(encloseRectToDevicePixels(LayoutRect(toLayoutPoint(compositedBoundsOffset.fromParentGraphicsLayer()), compositedBounds().size()),
+        deviceScaleFactor()));
+}
+
+LayoutRect RenderLayerBacking::computeParentGraphicsLayerRect(RenderLayer* compositedAncestor, LayoutSize&amp; ancestorClippingLayerOffset) const
+{
+    if (!compositedAncestor || !compositedAncestor-&gt;backing())
+        return renderer().view().documentRect();
+
+    auto* ancestorBackingLayer = compositedAncestor-&gt;backing();
+    LayoutRect parentGraphicsLayerRect;
+    if (m_owningLayer.isInsideFlowThread()) {
+        /// FIXME: flows/columns need work.
+        LayoutRect ancestorCompositedBounds = ancestorBackingLayer-&gt;compositedBounds();
+        ancestorCompositedBounds.setLocation(LayoutPoint());
+        adjustAncestorCompositingBoundsForFlowThread(ancestorCompositedBounds, compositedAncestor);
+        parentGraphicsLayerRect = ancestorCompositedBounds;
+    }
+
+    if (ancestorBackingLayer-&gt;hasClippingLayer()) {
+        // If the compositing ancestor has a layer to clip children, we parent in that, and therefore position relative to it.
+        LayoutRect clippingBox = clipBox(downcast&lt;RenderBox&gt;(compositedAncestor-&gt;renderer()));
+        LayoutSize clippingBoxOffset = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, clippingBox.location());
+        parentGraphicsLayerRect = snappedGraphicsLayer(clippingBoxOffset, clippingBox.size(), deviceScaleFactor()).m_snappedRect;
+    }
+
+#if PLATFORM(IOS)
+    if (compositedAncestor-&gt;hasTouchScrollableOverflow()) {
+        auto&amp; renderBox = downcast&lt;RenderBox&gt;(compositedAncestor-&gt;renderer());
+        LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(),
+            renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(),
+            renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
+        ScrollOffset scrollOffset = compositedAncestor-&gt;scrollOffset();
+        parentGraphicsLayerRect = LayoutRect((paddingBox.location() - toLayoutSize(scrollOffset)), paddingBox.size());
+    }
+#else
+    if (compositedAncestor-&gt;needsCompositedScrolling()) {
+        auto&amp; renderBox = downcast&lt;RenderBox&gt;(compositedAncestor-&gt;renderer());
+        LayoutPoint scrollOrigin(renderBox.borderLeft(), renderBox.borderTop());
+        parentGraphicsLayerRect = LayoutRect(scrollOrigin - toLayoutSize(compositedAncestor-&gt;scrollOffset()), renderBox.borderBoxRect().size());
+    }
+#endif
+
+    if (m_ancestorClippingLayer) {
+        // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
+        // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
+        // for a compositing layer, rootLayer is the layer itself.
+        ShouldRespectOverflowClip shouldRespectOverflowClip = compositedAncestor-&gt;isolatesCompositedBlending() ? RespectOverflowClip : IgnoreOverflowClip;
+        RenderLayer::ClipRectsContext clipRectsContext(compositedAncestor, TemporaryClipRects, IgnoreOverlayScrollbarSize, shouldRespectOverflowClip);
+        LayoutRect parentClipRect = m_owningLayer.backgroundClipRect(clipRectsContext).rect(); // FIXME: Incorrect for CSS regions.
+        ASSERT(!parentClipRect.isInfinite());
+        LayoutSize clippingOffset = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, parentClipRect.location());
+        LayoutRect snappedClippingLayerRect = snappedGraphicsLayer(clippingOffset, parentClipRect.size(), deviceScaleFactor()).m_snappedRect;
+        // The primary layer is then parented in, and positioned relative to this clipping layer.
+        ancestorClippingLayerOffset = snappedClippingLayerRect.location() - parentGraphicsLayerRect.location();
+        parentGraphicsLayerRect = snappedClippingLayerRect;
+    }
+    return parentGraphicsLayerRect;
+}
+
</ins><span class="cx"> void RenderLayerBacking::updateGeometry()
</span><span class="cx"> {
</span><span class="cx">     // If we haven't built z-order lists yet, wait until later.
</span><span class="lines">@@ -726,7 +866,6 @@
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     const RenderStyle&amp; style = renderer().style();
</span><del>-
</del><span class="cx">     // Set transform property, if it is not animating. We have to do this here because the transform
</span><span class="cx">     // is affected by the layer dimensions.
</span><span class="cx">     if (!renderer().animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyTransform, AnimationBase::Running | AnimationBase::Paused))
</span><span class="lines">@@ -743,7 +882,6 @@
</span><span class="cx"> #if ENABLE(CSS_COMPOSITING)
</span><span class="cx">     updateBlendMode(style);
</span><span class="cx"> #endif
</span><del>-
</del><span class="cx">     m_owningLayer.updateDescendantDependentFlags();
</span><span class="cx"> 
</span><span class="cx">     // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
</span><span class="lines">@@ -750,123 +888,42 @@
</span><span class="cx">     bool preserves3D = style.transformStyle3D() == TransformStyle3DPreserve3D &amp;&amp; !renderer().hasReflection();
</span><span class="cx">     m_graphicsLayer-&gt;setPreserves3D(preserves3D);
</span><span class="cx">     m_graphicsLayer-&gt;setBackfaceVisibility(style.backfaceVisibility() == BackfaceVisibilityVisible);
</span><del>-    /*
-    * GraphicsLayer: device pixel positioned, enclosing rect.
-    * RenderLayer: subpixel positioned.
-    * Offset from renderer (GraphicsLayer &lt;-&gt; RenderLayer::renderer()): subpixel based offset.
-    *
-    *     relativeCompositingBounds
-    *      _______________________________________
-    *     |\          GraphicsLayer               |
-    *     | \                                     |
-    *     |  \ offset from renderer: (device pixel + subpixel)
-    *     |   \                                   |
-    *     |    \______________________________    |
-    *     |    | localCompositingBounds       |   |
-    *     |    |                              |   |
-    *     |    |   RenderLayer::renderer()    |   |
-    *     |    |                              |   |
-    *
-    * localCompositingBounds: this RenderLayer relative to its renderer().
-    * relativeCompositingBounds: this RenderLayer relative to its parent compositing layer.
-    * enclosingRelativeCompositingBounds: this RenderLayer relative to its parent, device pixel enclosing.
-    * rendererOffsetFromGraphicsLayer: RenderLayer::renderer()'s offset from its enclosing GraphicsLayer.
-    * devicePixelOffsetFromRenderer: rendererOffsetFromGraphicsLayer's device pixel part. (6.9px -&gt; 6.5px in case of 2x display)
-    * devicePixelFractionFromRenderer: rendererOffsetFromGraphicsLayer's fractional part (6.9px -&gt; 0.4px in case of 2x display)
-    */
-    float deviceScaleFactor = this-&gt;deviceScaleFactor();
-    RenderLayer* compAncestor = m_owningLayer.ancestorCompositingLayer();
-    // We compute everything relative to the enclosing compositing layer.
-    LayoutRect ancestorCompositingBounds;
-    if (compAncestor) {
-        ASSERT(compAncestor-&gt;backing());
-        ancestorCompositingBounds = compAncestor-&gt;backing()-&gt;compositedBounds();
-    }
-    LayoutRect localCompositingBounds = compositedBounds();
-    LayoutRect relativeCompositingBounds(localCompositingBounds);
</del><span class="cx"> 
</span><del>-    LayoutPoint offsetFromParent = m_owningLayer.convertToLayerCoords(compAncestor, LayoutPoint(), RenderLayer::AdjustForColumns);
-    // Device pixel fractions get accumulated through ancestor layers. Our painting offset is layout offset + parent's painting offset.
-    offsetFromParent = offsetFromParent + (compAncestor ? compAncestor-&gt;backing()-&gt;devicePixelFractionFromRenderer() : LayoutSize());
-    relativeCompositingBounds.moveBy(offsetFromParent);
</del><ins>+    RenderLayer* compositedAncestor = m_owningLayer.ancestorCompositingLayer();
+    LayoutSize ancestorClippingLayerOffset;
+    LayoutRect parentGraphicsLayerRect = computeParentGraphicsLayerRect(compositedAncestor, ancestorClippingLayerOffset);
+    LayoutRect primaryGraphicsLayerRect = computePrimaryGraphicsLayerRect(parentGraphicsLayerRect);
</ins><span class="cx"> 
</span><del>-    LayoutRect enclosingRelativeCompositingBounds = LayoutRect(encloseRectToDevicePixels(relativeCompositingBounds, deviceScaleFactor));
-    m_compositedBoundsDeltaFromGraphicsLayer = enclosingRelativeCompositingBounds.location() - relativeCompositingBounds.location();
-    LayoutSize rendererOffsetFromGraphicsLayer =  toLayoutSize(localCompositingBounds.location()) + m_compositedBoundsDeltaFromGraphicsLayer;
</del><ins>+    ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
+    m_compositedBoundsOffsetFromGraphicsLayer = compositedBoundsOffset.fromPrimaryGraphicsLayer();
+    m_graphicsLayer-&gt;setPosition(primaryGraphicsLayerRect.location());
+    m_graphicsLayer-&gt;setSize(primaryGraphicsLayerRect.size());
</ins><span class="cx"> 
</span><del>-    FloatSize devicePixelOffsetFromRenderer;
-    LayoutSize devicePixelFractionFromRenderer;
-    calculateDevicePixelOffsetFromRenderer(rendererOffsetFromGraphicsLayer, devicePixelOffsetFromRenderer, devicePixelFractionFromRenderer, deviceScaleFactor);
-    LayoutSize oldDevicePixelFractionFromRenderer = m_devicePixelFractionFromRenderer;
-    m_devicePixelFractionFromRenderer = LayoutSize(-devicePixelFractionFromRenderer.width(), -devicePixelFractionFromRenderer.height());
-
-    adjustAncestorCompositingBoundsForFlowThread(ancestorCompositingBounds, compAncestor);
-
-    LayoutPoint graphicsLayerParentLocation;
-    if (compAncestor &amp;&amp; compAncestor-&gt;backing()-&gt;hasClippingLayer()) {
-        // If the compositing ancestor has a layer to clip children, we parent in that, and therefore
-        // position relative to it.
-        // FIXME: need to do some pixel snapping here.
-        LayoutRect clippingBox = clipBox(downcast&lt;RenderBox&gt;(compAncestor-&gt;renderer()));
-        graphicsLayerParentLocation = clippingBox.location();
-    } else if (compAncestor)
-        graphicsLayerParentLocation = ancestorCompositingBounds.location();
-    else
-        graphicsLayerParentLocation = renderer().view().documentRect().location();
-
-#if PLATFORM(IOS)
-    if (compAncestor &amp;&amp; compAncestor-&gt;hasTouchScrollableOverflow()) {
-        auto&amp; renderBox = downcast&lt;RenderBox&gt;(compAncestor-&gt;renderer());
-        LayoutRect paddingBox(renderBox.borderLeft(), renderBox.borderTop(),
-            renderBox.width() - renderBox.borderLeft() - renderBox.borderRight(),
-            renderBox.height() - renderBox.borderTop() - renderBox.borderBottom());
-
-        ScrollOffset scrollOffset = compAncestor-&gt;scrollOffset();
-        // FIXME: pixel snap the padding box.
-        graphicsLayerParentLocation = paddingBox.location() - toLayoutSize(scrollOffset);
</del><ins>+    ComputedOffsets rendererOffset(m_owningLayer, LayoutRect(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
+    if (m_ancestorClippingLayer) {
+        // Clipping layer is parented in the ancestor layer.
+        m_ancestorClippingLayer-&gt;setPosition(toLayoutPoint(ancestorClippingLayerOffset));
+        m_ancestorClippingLayer-&gt;setSize(parentGraphicsLayerRect.size());
+        m_ancestorClippingLayer-&gt;setOffsetFromRenderer(-rendererOffset.fromParentGraphicsLayer());
</ins><span class="cx">     }
</span><del>-#else
-    if (compAncestor &amp;&amp; compAncestor-&gt;needsCompositedScrolling()) {
-        auto&amp; renderBox = downcast&lt;RenderBox&gt;(compAncestor-&gt;renderer());
-        LayoutPoint scrollOrigin(renderBox.borderLeft(), renderBox.borderTop());
-        graphicsLayerParentLocation = scrollOrigin - toLayoutSize(compAncestor-&gt;scrollOffset());
-    }
-#endif
</del><span class="cx"> 
</span><del>-    if (compAncestor &amp;&amp; m_ancestorClippingLayer) {
-        // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
-        // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
-        // for a compositing layer, rootLayer is the layer itself.
-        ShouldRespectOverflowClip shouldRespectOverflowClip = compAncestor-&gt;isolatesCompositedBlending() ? RespectOverflowClip : IgnoreOverflowClip;
-        RenderLayer::ClipRectsContext clipRectsContext(compAncestor, TemporaryClipRects, IgnoreOverlayScrollbarSize, shouldRespectOverflowClip);
-        LayoutRect parentClipRect = m_owningLayer.backgroundClipRect(clipRectsContext).rect(); // FIXME: Incorrect for CSS regions.
-        ASSERT(!parentClipRect.isInfinite());
-        FloatPoint enclosingClippingLayerPosition = floorPointToDevicePixels(LayoutPoint(parentClipRect.location() - graphicsLayerParentLocation), deviceScaleFactor);
-        m_ancestorClippingLayer-&gt;setPosition(enclosingClippingLayerPosition);
-        m_ancestorClippingLayer-&gt;setSize(parentClipRect.size());
-
-        // backgroundRect is relative to compAncestor, so subtract deltaX/deltaY to get back to local coords.
-        m_ancestorClippingLayer-&gt;setOffsetFromRenderer(parentClipRect.location() - offsetFromParent);
-
-        // The primary layer is then parented in, and positioned relative to this clipping layer.
-        graphicsLayerParentLocation = parentClipRect.location();
-    }
-
-    LayoutSize contentsSize = enclosingRelativeCompositingBounds.size();
</del><span class="cx">     if (m_contentsContainmentLayer) {
</span><span class="cx">         m_contentsContainmentLayer-&gt;setPreserves3D(preserves3D);
</span><del>-        FloatPoint enclosingGraphicsParentLocation = floorPointToDevicePixels(graphicsLayerParentLocation, deviceScaleFactor);
-        m_contentsContainmentLayer-&gt;setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - enclosingGraphicsParentLocation));
</del><ins>+        m_contentsContainmentLayer-&gt;setPosition(primaryGraphicsLayerRect.location());
+        m_graphicsLayer-&gt;setPosition(FloatPoint());
</ins><span class="cx">         // Use the same size as m_graphicsLayer so transforms behave correctly.
</span><del>-        m_contentsContainmentLayer-&gt;setSize(contentsSize);
-        graphicsLayerParentLocation = enclosingRelativeCompositingBounds.location();
</del><ins>+        m_contentsContainmentLayer-&gt;setSize(primaryGraphicsLayerRect.size());
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    FloatPoint enclosingGraphicsParentLocation = floorPointToDevicePixels(graphicsLayerParentLocation, deviceScaleFactor);
-    m_graphicsLayer-&gt;setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - enclosingGraphicsParentLocation));
-    m_graphicsLayer-&gt;setSize(contentsSize);
-    if (devicePixelOffsetFromRenderer != m_graphicsLayer-&gt;offsetFromRenderer()) {
-        m_graphicsLayer-&gt;setOffsetFromRenderer(devicePixelOffsetFromRenderer);
</del><ins>+    // Compute renderer offset from primary graphics layer. Note that primaryGraphicsLayerRect is in parentGraphicsLayer's coordidate system which is not necessarily
+    // the same as the ancestor graphics layer.
+    OffsetFromRenderer primaryGraphicsLayerOffsetFromRenderer;
+    LayoutSize oldSubpixelOffsetFromRenderer = m_subpixelOffsetFromRenderer;
+    primaryGraphicsLayerOffsetFromRenderer = computeOffsetFromRenderer(-rendererOffset.fromPrimaryGraphicsLayer(), deviceScaleFactor());
+    m_subpixelOffsetFromRenderer = primaryGraphicsLayerOffsetFromRenderer.m_subpixelOffset;
+
+    if (primaryGraphicsLayerOffsetFromRenderer.m_devicePixelOffset != m_graphicsLayer-&gt;offsetFromRenderer()) {
+        m_graphicsLayer-&gt;setOffsetFromRenderer(primaryGraphicsLayerOffsetFromRenderer.m_devicePixelOffset);
</ins><span class="cx">         positionOverflowControlsLayers();
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -873,18 +930,21 @@
</span><span class="cx">     if (!m_isMainFrameRenderViewLayer) {
</span><span class="cx">         // For non-root layers, background is always painted by the primary graphics layer.
</span><span class="cx">         ASSERT(!m_backgroundLayer);
</span><del>-        bool hadSubpixelRounding = enclosingRelativeCompositingBounds != relativeCompositingBounds;
-        m_graphicsLayer-&gt;setContentsOpaque(!hadSubpixelRounding &amp;&amp; m_owningLayer.backgroundIsKnownToBeOpaqueInRect(localCompositingBounds));
</del><ins>+        // Subpixel offset from graphics layer or size changed.
+        bool hadSubpixelRounding = !m_subpixelOffsetFromRenderer.isZero() || compositedBounds().size() != primaryGraphicsLayerRect.size();
+        m_graphicsLayer-&gt;setContentsOpaque(!hadSubpixelRounding &amp;&amp; m_owningLayer.backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // If we have a layer that clips children, position it.
</span><span class="cx">     LayoutRect clippingBox;
</span><span class="cx">     if (GraphicsLayer* clipLayer = clippingLayer()) {
</span><del>-        // FIXME: need to do some pixel snapping here.
</del><span class="cx">         clippingBox = clipBox(downcast&lt;RenderBox&gt;(renderer()));
</span><del>-        clipLayer-&gt;setPosition(FloatPoint(clippingBox.location() - localCompositingBounds.location()));
-        clipLayer-&gt;setSize(clippingBox.size());
-        clipLayer-&gt;setOffsetFromRenderer(toFloatSize(clippingBox.location()));
</del><ins>+        // Clipping layer is parented in the primary graphics layer.
+        LayoutSize clipBoxOffsetFromGraphicsLayer = toLayoutSize(clippingBox.location()) + rendererOffset.fromPrimaryGraphicsLayer();
+        SnappedRectInfo snappedClippingGraphicsLayer = snappedGraphicsLayer(clipBoxOffsetFromGraphicsLayer, clippingBox.size(), deviceScaleFactor());
+        clipLayer-&gt;setPosition(snappedClippingGraphicsLayer.m_snappedRect.location());
+        clipLayer-&gt;setSize(snappedClippingGraphicsLayer.m_snappedRect.size());
+        clipLayer-&gt;setOffsetFromRenderer(toLayoutSize(clippingBox.location() - snappedClippingGraphicsLayer.m_snapDelta));
</ins><span class="cx"> 
</span><span class="cx">         if (m_childClippingMaskLayer &amp;&amp; !m_scrollingLayer) {
</span><span class="cx">             m_childClippingMaskLayer-&gt;setSize(clipLayer-&gt;size());
</span><span class="lines">@@ -899,12 +959,12 @@
</span><span class="cx">     if (m_owningLayer.renderer().hasTransformRelatedProperty()) {
</span><span class="cx">         // Update properties that depend on layer dimensions.
</span><span class="cx">         FloatPoint3D transformOrigin = computeTransformOriginForPainting(downcast&lt;RenderBox&gt;(renderer()).borderBoxRect());
</span><del>-        // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
-        FloatPoint layerOffset = roundPointToDevicePixels(offsetFromParent, deviceScaleFactor);
</del><ins>+        FloatPoint layerOffset = roundPointToDevicePixels(toLayoutPoint(rendererOffset.fromParentGraphicsLayer()), deviceScaleFactor());
</ins><span class="cx">         // Compute the anchor point, which is in the center of the renderer box unless transform-origin is set.
</span><del>-        FloatPoint3D anchor(enclosingRelativeCompositingBounds.width() ? ((layerOffset.x() - enclosingRelativeCompositingBounds.x()) + transformOrigin.x())
-            / enclosingRelativeCompositingBounds.width() : 0.5, enclosingRelativeCompositingBounds.height() ? ((layerOffset.y() - enclosingRelativeCompositingBounds.y())
-            + transformOrigin.y()) / enclosingRelativeCompositingBounds.height() : 0.5, transformOrigin.z());
</del><ins>+        FloatPoint3D anchor(
+            primaryGraphicsLayerRect.width() ? ((layerOffset.x() - primaryGraphicsLayerRect.x()) + transformOrigin.x()) / primaryGraphicsLayerRect.width() : 0.5,
+            primaryGraphicsLayerRect.height() ? ((layerOffset.y() - primaryGraphicsLayerRect.y())+ transformOrigin.y()) / primaryGraphicsLayerRect.height() : 0.5,
+            transformOrigin.z());
</ins><span class="cx"> 
</span><span class="cx">         if (m_contentsContainmentLayer)
</span><span class="cx">             m_contentsContainmentLayer-&gt;setAnchorPoint(anchor);
</span><span class="lines">@@ -935,7 +995,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_foregroundLayer) {
</span><span class="cx">         FloatPoint foregroundPosition;
</span><del>-        FloatSize foregroundSize = contentsSize;
</del><ins>+        FloatSize foregroundSize = primaryGraphicsLayerRect.size();
</ins><span class="cx">         FloatSize foregroundOffset = m_graphicsLayer-&gt;offsetFromRenderer();
</span><span class="cx">         if (hasClippingLayer()) {
</span><span class="cx">             // If we have a clipping layer (which clips descendants), then the foreground layer is a child of it,
</span><span class="lines">@@ -951,7 +1011,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_backgroundLayer) {
</span><span class="cx">         FloatPoint backgroundPosition;
</span><del>-        FloatSize backgroundSize = contentsSize;
</del><ins>+        FloatSize backgroundSize = primaryGraphicsLayerRect.size();
</ins><span class="cx">         if (backgroundLayerPaintsFixedRootBackground()) {
</span><span class="cx">             const FrameView&amp; frameView = renderer().view().frameView();
</span><span class="cx">             backgroundPosition = frameView.scrollPositionForFixedPosition();
</span><span class="lines">@@ -968,7 +1028,7 @@
</span><span class="cx">         
</span><span class="cx">         // The reflection layer has the bounds of m_owningLayer.reflectionLayer(),
</span><span class="cx">         // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
</span><del>-        FloatRect layerBounds = compositedBounds();
</del><ins>+        FloatRect layerBounds = this-&gt;compositedBounds();
</ins><span class="cx">         FloatRect reflectionLayerBounds = reflectionBacking-&gt;compositedBounds();
</span><span class="cx">         reflectionBacking-&gt;graphicsLayer()-&gt;setReplicatedLayerPosition(FloatPoint(layerBounds.location() - reflectionLayerBounds.location()));
</span><span class="cx">     }
</span><span class="lines">@@ -980,7 +1040,7 @@
</span><span class="cx">         ScrollOffset scrollOffset = m_owningLayer.scrollOffset();
</span><span class="cx"> 
</span><span class="cx">         // FIXME: need to do some pixel snapping here.
</span><del>-        m_scrollingLayer-&gt;setPosition(FloatPoint(paddingBox.location() - localCompositingBounds.location()));
</del><ins>+        m_scrollingLayer-&gt;setPosition(FloatPoint(paddingBox.location() - compositedBounds().location()));
</ins><span class="cx"> 
</span><span class="cx">         m_scrollingLayer-&gt;setSize(roundedIntSize(LayoutSize(renderBox.clientWidth(), renderBox.clientHeight())));
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="lines">@@ -1044,13 +1104,15 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     // If this layer was created just for clipping or to apply perspective, it doesn't need its own backing store.
</span><del>-    setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compAncestor, enclosingRelativeCompositingBounds, ancestorCompositingBounds));
</del><ins>+    LayoutRect ancestorCompositedBounds = compositedAncestor ? compositedAncestor-&gt;backing()-&gt;compositedBounds() : LayoutRect();
+    setRequiresOwnBackingStore(compositor().requiresOwnBackingStore(m_owningLayer, compositedAncestor,
+        LayoutRect(toLayoutPoint(compositedBoundsOffset.fromParentGraphicsLayer()), compositedBounds().size()), ancestorCompositedBounds));
</ins><span class="cx"> #if ENABLE(FILTERS_LEVEL_2)
</span><span class="cx">     updateBackdropFiltersGeometry();
</span><span class="cx"> #endif
</span><span class="cx">     updateAfterWidgetResize();
</span><span class="cx"> 
</span><del>-    if (devicePixelFractionGapFromRendererChanged(oldDevicePixelFractionFromRenderer, m_devicePixelFractionFromRenderer, deviceScaleFactor) &amp;&amp; canIssueSetNeedsDisplay())
</del><ins>+    if (subpixelOffsetFromRendererChanged(oldSubpixelOffsetFromRenderer, m_subpixelOffsetFromRenderer, deviceScaleFactor()) &amp;&amp; canIssueSetNeedsDisplay())
</ins><span class="cx">         setContentsNeedDisplay();
</span><span class="cx"> 
</span><span class="cx">     compositor().updateScrollCoordinatedStatus(m_owningLayer);
</span><span class="lines">@@ -1092,7 +1154,7 @@
</span><span class="cx">             // FIXME: Use correct reference box for inlines: https://bugs.webkit.org/show_bug.cgi?id=129047
</span><span class="cx">             LayoutRect boundingBox = m_owningLayer.boundingBox(&amp;m_owningLayer);
</span><span class="cx">             LayoutRect referenceBoxForClippedInline = LayoutRect(snapRectToDevicePixels(boundingBox, deviceScaleFactor()));
</span><del>-            LayoutSize offset = LayoutSize(snapSizeToDevicePixel(m_devicePixelFractionFromRenderer, LayoutPoint(), deviceScaleFactor()));
</del><ins>+            LayoutSize offset = LayoutSize(snapSizeToDevicePixel(-m_subpixelOffsetFromRenderer, LayoutPoint(), deviceScaleFactor()));
</ins><span class="cx">             Path clipPath = m_owningLayer.computeClipPath(offset, referenceBoxForClippedInline, windRule);
</span><span class="cx"> 
</span><span class="cx">             FloatSize pathOffset = m_maskLayer-&gt;offsetFromRenderer();
</span><span class="lines">@@ -1107,9 +1169,6 @@
</span><span class="cx"> 
</span><span class="cx"> void RenderLayerBacking::adjustAncestorCompositingBoundsForFlowThread(LayoutRect&amp; ancestorCompositingBounds, const RenderLayer* compositingAncestor) const
</span><span class="cx"> {
</span><del>-    if (!m_owningLayer.isInsideFlowThread())
-        return;
-
</del><span class="cx">     RenderLayer* flowThreadLayer = m_owningLayer.isInsideOutOfFlowThread() ? m_owningLayer.stackingContainer() : nullptr;
</span><span class="cx">     if (flowThreadLayer &amp;&amp; flowThreadLayer-&gt;isRenderFlowThread()) {
</span><span class="cx">         if (m_owningLayer.isFlowThreadCollectingGraphicsLayersUnderRegions()) {
</span><span class="lines">@@ -2102,7 +2161,7 @@
</span><span class="cx"> // Return the offset from the top-left of this compositing layer at which the renderer's contents are painted.
</span><span class="cx"> LayoutSize RenderLayerBacking::contentOffsetInCompostingLayer() const
</span><span class="cx"> {
</span><del>-    return LayoutSize(-m_compositedBounds.x() - m_compositedBoundsDeltaFromGraphicsLayer.width(), -m_compositedBounds.y() - m_compositedBoundsDeltaFromGraphicsLayer.height());
</del><ins>+    return LayoutSize(-m_compositedBounds.x() + m_compositedBoundsOffsetFromGraphicsLayer.width(), -m_compositedBounds.y() + m_compositedBoundsOffsetFromGraphicsLayer.height());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LayoutRect RenderLayerBacking::contentsBox() const
</span><span class="lines">@@ -2250,13 +2309,13 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_graphicsLayer &amp;&amp; m_graphicsLayer-&gt;drawsContent()) {
</span><span class="cx">         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
</span><del>-        layerDirtyRect.move(-m_graphicsLayer-&gt;offsetFromRenderer() + m_devicePixelFractionFromRenderer);
</del><ins>+        layerDirtyRect.move(-m_graphicsLayer-&gt;offsetFromRenderer() - m_subpixelOffsetFromRenderer);
</ins><span class="cx">         m_graphicsLayer-&gt;setNeedsDisplayInRect(layerDirtyRect, shouldClip);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (m_foregroundLayer &amp;&amp; m_foregroundLayer-&gt;drawsContent()) {
</span><span class="cx">         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
</span><del>-        layerDirtyRect.move(-m_foregroundLayer-&gt;offsetFromRenderer() + m_devicePixelFractionFromRenderer);
</del><ins>+        layerDirtyRect.move(-m_foregroundLayer-&gt;offsetFromRenderer() - m_subpixelOffsetFromRenderer);
</ins><span class="cx">         m_foregroundLayer-&gt;setNeedsDisplayInRect(layerDirtyRect, shouldClip);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -2263,13 +2322,13 @@
</span><span class="cx">     // FIXME: need to split out repaints for the background.
</span><span class="cx">     if (m_backgroundLayer &amp;&amp; m_backgroundLayer-&gt;drawsContent()) {
</span><span class="cx">         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
</span><del>-        layerDirtyRect.move(-m_backgroundLayer-&gt;offsetFromRenderer() + m_devicePixelFractionFromRenderer);
</del><ins>+        layerDirtyRect.move(-m_backgroundLayer-&gt;offsetFromRenderer() - m_subpixelOffsetFromRenderer);
</ins><span class="cx">         m_backgroundLayer-&gt;setNeedsDisplayInRect(layerDirtyRect, shouldClip);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (m_maskLayer &amp;&amp; m_maskLayer-&gt;drawsContent()) {
</span><span class="cx">         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
</span><del>-        layerDirtyRect.move(-m_maskLayer-&gt;offsetFromRenderer() + m_devicePixelFractionFromRenderer);
</del><ins>+        layerDirtyRect.move(-m_maskLayer-&gt;offsetFromRenderer() - m_subpixelOffsetFromRenderer);
</ins><span class="cx">         m_maskLayer-&gt;setNeedsDisplayInRect(layerDirtyRect, shouldClip);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -2281,7 +2340,7 @@
</span><span class="cx"> 
</span><span class="cx">     if (m_scrollingContentsLayer &amp;&amp; m_scrollingContentsLayer-&gt;drawsContent()) {
</span><span class="cx">         FloatRect layerDirtyRect = pixelSnappedRectForPainting;
</span><del>-        layerDirtyRect.move(-m_scrollingContentsLayer-&gt;offsetFromRenderer() + m_devicePixelFractionFromRenderer);
</del><ins>+        layerDirtyRect.move(-m_scrollingContentsLayer-&gt;offsetFromRenderer() - m_subpixelOffsetFromRenderer);
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">         // Account for the fact that RenderLayerBacking::updateGeometry() bakes scrollOffset into offsetFromRenderer on iOS,
</span><span class="cx">         // but the repaint rect is computed without taking the scroll position into account (see shouldApplyClipAndScrollPositionForRepaint()).
</span><span class="lines">@@ -2335,7 +2394,7 @@
</span><span class="cx">         renderer().view().frameView().willPaintContents(context, paintDirtyRect, paintingState);
</span><span class="cx"> 
</span><span class="cx">     // FIXME: GraphicsLayers need a way to split for RenderRegions.
</span><del>-    RenderLayer::LayerPaintingInfo paintingInfo(&amp;m_owningLayer, paintDirtyRect, paintBehavior, m_devicePixelFractionFromRenderer);
</del><ins>+    RenderLayer::LayerPaintingInfo paintingInfo(&amp;m_owningLayer, paintDirtyRect, paintBehavior, -m_subpixelOffsetFromRenderer);
</ins><span class="cx">     m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
</span><span class="cx"> 
</span><span class="cx">     if (m_owningLayer.containsDirtyOverlayScrollbars())
</span><span class="lines">@@ -2359,7 +2418,7 @@
</span><span class="cx"> 
</span><span class="cx">     // The dirtyRect is in the coords of the painting root.
</span><span class="cx">     FloatRect adjustedClipRect = clip;
</span><del>-    adjustedClipRect.move(-m_devicePixelFractionFromRenderer);
</del><ins>+    adjustedClipRect.move(m_subpixelOffsetFromRenderer);
</ins><span class="cx">     IntRect dirtyRect = enclosingIntRect(adjustedClipRect);
</span><span class="cx"> 
</span><span class="cx">     if (graphicsLayer == m_graphicsLayer.get()
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerBackingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerBacking.h (204551 => 204552)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerBacking.h        2016-08-17 03:17:04 UTC (rev 204551)
+++ trunk/Source/WebCore/rendering/RenderLayerBacking.h        2016-08-17 03:18:21 UTC (rev 204552)
</span><span class="lines">@@ -216,6 +216,8 @@
</span><span class="cx">     bool useGiantTiles() const override;
</span><span class="cx">     bool needsPixelAligment() const override { return !m_isMainFrameRenderViewLayer; }
</span><span class="cx"> 
</span><ins>+    LayoutSize subpixelOffsetFromRenderer() const { return m_subpixelOffsetFromRenderer; }
+
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     bool needsIOSDumpRenderTreeMainFrameRenderViewLayerIsAlwaysOpaqueHack(const GraphicsLayer&amp;) const override;
</span><span class="cx"> #endif
</span><span class="lines">@@ -248,8 +250,6 @@
</span><span class="cx">     WEBCORE_EXPORT void setIsTrackingDisplayListReplay(bool);
</span><span class="cx">     WEBCORE_EXPORT String replayDisplayListAsText(DisplayList::AsTextFlags) const;
</span><span class="cx"> 
</span><del>-    LayoutSize devicePixelFractionFromRenderer() const { return m_devicePixelFractionFromRenderer; }
-
</del><span class="cx"> private:
</span><span class="cx">     FloatRect backgroundBoxForSimpleContainerPainting() const;
</span><span class="cx"> 
</span><span class="lines">@@ -343,6 +343,8 @@
</span><span class="cx">     static AnimatedPropertyID cssToGraphicsLayerProperty(CSSPropertyID);
</span><span class="cx"> 
</span><span class="cx">     bool canIssueSetNeedsDisplay() const { return !paintsIntoWindow() &amp;&amp; !paintsIntoCompositedAncestor(); }
</span><ins>+    LayoutRect computeParentGraphicsLayerRect(RenderLayer* compositedAncestor, LayoutSize&amp; ancestorClippingLayerOffset) const;
+    LayoutRect computePrimaryGraphicsLayerRect(const LayoutRect&amp; parentGraphicsLayerRect) const;
</ins><span class="cx"> 
</span><span class="cx">     RenderLayer&amp; m_owningLayer;
</span><span class="cx"> 
</span><span class="lines">@@ -366,8 +368,8 @@
</span><span class="cx">     ScrollingNodeID m_scrollingNodeID;
</span><span class="cx"> 
</span><span class="cx">     LayoutRect m_compositedBounds;
</span><del>-    LayoutSize m_devicePixelFractionFromRenderer;
-    LayoutSize m_compositedBoundsDeltaFromGraphicsLayer; // This is the (subpixel) distance between the edge of the graphics layer and the layer bounds.
</del><ins>+    LayoutSize m_subpixelOffsetFromRenderer; // This is the subpixel distance between the primary graphics layer and the associated renderer's bounds.
+    LayoutSize m_compositedBoundsOffsetFromGraphicsLayer; // This is the subpixel distance between the primary graphics layer and the render layer bounds.
</ins><span class="cx"> 
</span><span class="cx">     bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work
</span><span class="cx">     bool m_isMainFrameRenderViewLayer;
</span></span></pre>
</div>
</div>

</body>
</html>