REGRESSION (r164449): Subpixel rendering: http://www.apple.com/iphone-6/ "Faster...
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 May 2015 22:03:12 +0000 (22:03 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 7 May 2015 22:03:12 +0000 (22:03 +0000)
https://bugs.webkit.org/show_bug.cgi?id=144723
rdar://problem/18307094

Reviewed by Simon Fraser.

This patch ensures that the backing store's graphics layer is always positioned on a device pixel boundary.

While calculating the backing store's graphics layer location, its ancestor layer's compositing bounds is taken into account.
However the compositing bounds is an unsnapped value, so in order to place the graphics layer properly,
we need to pixel align the ancestor compositing bounds before using it to adjust the child's graphics layer position.

Source/WebCore:

Test: compositing/ancestor-compositing-layer-is-on-subpixel-position.html

* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateGeometry):

LayoutTests:

* compositing/ancestor-compositing-layer-is-on-subpixel-position-expected.html: Added.
* compositing/ancestor-compositing-layer-is-on-subpixel-position.html: Added.
* platform/mac/compositing/layer-creation/overlap-animation-container-expected.txt: progression.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183950 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/compositing/ancestor-compositing-layer-is-on-subpixel-position-expected.html [new file with mode: 0644]
LayoutTests/compositing/ancestor-compositing-layer-is-on-subpixel-position.html [new file with mode: 0644]
LayoutTests/platform/mac/compositing/layer-creation/overlap-animation-container-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayerBacking.cpp

index e8b8303..92f0119 100644 (file)
@@ -1,3 +1,21 @@
+2015-05-07  Zalan Bujtas  <zalan@apple.com>
+
+        REGRESSION (r164449): Subpixel rendering: http://www.apple.com/iphone-6/ "Faster wireless." image displays vertical black line on 1x displays at specific window width.
+        https://bugs.webkit.org/show_bug.cgi?id=144723
+        rdar://problem/18307094
+
+        Reviewed by Simon Fraser.
+
+        This patch ensures that the backing store's graphics layer is always positioned on a device pixel boundary.
+
+        While calculating the backing store's graphics layer location, its ancestor layer's compositing bounds is taken into account.
+        However the compositing bounds is an unsnapped value, so in order to place the graphics layer properly,
+        we need to pixel align the ancestor compositing bounds before using it to adjust the child's graphics layer position.
+
+        * compositing/ancestor-compositing-layer-is-on-subpixel-position-expected.html: Added.
+        * compositing/ancestor-compositing-layer-is-on-subpixel-position.html: Added.
+        * platform/mac/compositing/layer-creation/overlap-animation-container-expected.txt: progression.
+
 2015-05-07  Yoav Weiss  <yoav@yoav.ws>
 
         Fix sizes crash and add invalid value tests.
diff --git a/LayoutTests/compositing/ancestor-compositing-layer-is-on-subpixel-position-expected.html b/LayoutTests/compositing/ancestor-compositing-layer-is-on-subpixel-position-expected.html
new file mode 100644 (file)
index 0000000..1525a03
--- /dev/null
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that child content snapped to device pixel (borders are clear) when ancestor compositing layer has fractional bounds.</title>
+<style>
+       .container {
+       position: absolute;
+       top: 10px;
+               width: 40px;
+               height: 40px;
+       }
+
+       .fuzzy {
+               border: 1px solid blue;
+               width: 10px;
+               height: 10px;
+       }
+</style>
+</head>
+<body>
+<script>
+       var delta = -1;
+       for (i = 0; i < 11; ++i) {
+               var container = document.createElement("div");
+               container.className = "container";
+               container.style.left = 45 * i + "px";
+               document.body.appendChild(container);
+
+               var fuzzy = document.createElement("div");
+               fuzzy.className = "fuzzy";
+               container.appendChild(fuzzy);
+               delta -= 0.1;
+       }
+</script>
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/compositing/ancestor-compositing-layer-is-on-subpixel-position.html b/LayoutTests/compositing/ancestor-compositing-layer-is-on-subpixel-position.html
new file mode 100644 (file)
index 0000000..ce0076d
--- /dev/null
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<html>
+<head>
+<title>This tests that child content snapped to device pixel (borders are clear) when ancestor compositing layer has fractional bounds.</title>
+<style>
+       .overlap { 
+               -webkit-transform: translateZ(0);
+               width: 500px;
+               height: 40px;
+               margin-bottom: -5px;
+       }
+
+       .container {
+       position: absolute;
+       top: 10px;
+               width: 40px;
+               height: 40px;
+               z-index: 0;
+       }
+
+       .push_horizontal {
+               position: absolute;
+               left: -1.4px;
+               width: 5px;
+               height: 5px;
+       }
+
+       .push_vertical {
+               position: absolute;
+               top: -1.4px;
+               width: 5px;
+               height: 5px;
+       }
+
+       .fuzzy {
+               border: 1px solid blue;
+               width: 10px;
+               height: 10px;
+               -webkit-transform: translateZ(0);
+       }
+</style>
+</head>
+<body>
+    <div class=overlap></div>
+<script>
+       var delta = -1;
+       for (i = 0; i < 11; ++i) {
+               var container = document.createElement("div");
+               container.className = "container";
+               container.style.left = 45 * i + "px";
+               document.body.appendChild(container);
+
+               var pushHorizontal = document.createElement("div");
+               pushHorizontal.className = "push_horizontal";
+               pushHorizontal.style.left = delta + "px";
+               pushHorizontal.style.top = "0px"; 
+               container.appendChild(pushHorizontal);
+
+               var pushVertical = document.createElement("div");
+               pushVertical.className = "push_vertical";
+               pushVertical.style.left = "0px";
+               pushVertical.style.top = delta + "px"; 
+               container.appendChild(pushVertical);
+
+               var fuzzy = document.createElement("div");
+               fuzzy.className = "fuzzy";
+               container.appendChild(fuzzy);
+               delta -= 0.1;
+       }
+</script>
+</body>
+</html>
\ No newline at end of file
index 5fe6910..bcfb184 100644 (file)
@@ -18,7 +18,7 @@ Before:
           (drawsContent 1)
           (children 1
             (GraphicsLayer
-              (position 21.13 11.00)
+              (position 22.00 11.00)
               (bounds 102.00 102.00)
               (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 -1.00 1.00])
             )
index aca981d..6184e7f 100644 (file)
@@ -1,3 +1,22 @@
+2015-05-07  Zalan Bujtas  <zalan@apple.com>
+
+        REGRESSION (r164449): Subpixel rendering: http://www.apple.com/iphone-6/ "Faster wireless." image displays vertical black line on 1x displays at specific window width.
+        https://bugs.webkit.org/show_bug.cgi?id=144723
+        rdar://problem/18307094
+
+        Reviewed by Simon Fraser.
+
+        This patch ensures that the backing store's graphics layer is always positioned on a device pixel boundary.
+
+        While calculating the backing store's graphics layer location, its ancestor layer's compositing bounds is taken into account.
+        However the compositing bounds is an unsnapped value, so in order to place the graphics layer properly,
+        we need to pixel align the ancestor compositing bounds before using it to adjust the child's graphics layer position.
+
+        Test: compositing/ancestor-compositing-layer-is-on-subpixel-position.html
+
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::updateGeometry):
+
 2015-05-07  Yoav Weiss  <yoav@yoav.ws>
 
         Fix sizes crash and add invalid value tests.
index fd423d6..7a45d2a 100644 (file)
@@ -695,16 +695,6 @@ void RenderLayerBacking::updateGeometry()
     bool preserves3D = style.transformStyle3D() == TransformStyle3DPreserve3D && !renderer().hasReflection();
     m_graphicsLayer->setPreserves3D(preserves3D);
     m_graphicsLayer->setBackfaceVisibility(style.backfaceVisibility() == BackfaceVisibilityVisible);
-
-    RenderLayer* compAncestor = m_owningLayer.ancestorCompositingLayer();
-    
-    // We compute everything relative to the enclosing compositing layer.
-    LayoutRect ancestorCompositingBounds;
-    if (compAncestor) {
-        ASSERT(compAncestor->backing());
-        ancestorCompositingBounds = compAncestor->backing()->compositedBounds();
-    }
-
     /*
     * GraphicsLayer: device pixel positioned, enclosing rect.
     * RenderLayer: subpixel positioned.
@@ -730,6 +720,13 @@ void RenderLayerBacking::updateGeometry()
     * devicePixelFractionFromRenderer: rendererOffsetFromGraphicsLayer's fractional part (6.9px -> 0.4px in case of 2x display)
     */
     float deviceScaleFactor = this->deviceScaleFactor();
+    RenderLayer* compAncestor = m_owningLayer.ancestorCompositingLayer();
+    // We compute everything relative to the enclosing compositing layer.
+    LayoutRect ancestorCompositingBounds;
+    if (compAncestor) {
+        ASSERT(compAncestor->backing());
+        ancestorCompositingBounds = compAncestor->backing()->compositedBounds();
+    }
     LayoutRect localCompositingBounds = compositedBounds();
     LayoutRect relativeCompositingBounds(localCompositingBounds);
 
@@ -800,16 +797,17 @@ void RenderLayerBacking::updateGeometry()
     }
 
     LayoutSize contentsSize = enclosingRelativeCompositingBounds.size();
-    
     if (m_contentsContainmentLayer) {
         m_contentsContainmentLayer->setPreserves3D(preserves3D);
-        m_contentsContainmentLayer->setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - graphicsLayerParentLocation));
+        FloatPoint enclosingGraphicsParentLocation = floorPointToDevicePixels(graphicsLayerParentLocation, deviceScaleFactor);
+        m_contentsContainmentLayer->setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - enclosingGraphicsParentLocation));
         // Use the same size as m_graphicsLayer so transforms behave correctly.
         m_contentsContainmentLayer->setSize(contentsSize);
         graphicsLayerParentLocation = enclosingRelativeCompositingBounds.location();
     }
 
-    m_graphicsLayer->setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - graphicsLayerParentLocation));
+    FloatPoint enclosingGraphicsParentLocation = floorPointToDevicePixels(graphicsLayerParentLocation, deviceScaleFactor);
+    m_graphicsLayer->setPosition(FloatPoint(enclosingRelativeCompositingBounds.location() - enclosingGraphicsParentLocation));
     m_graphicsLayer->setSize(contentsSize);
     if (devicePixelOffsetFromRenderer != m_graphicsLayer->offsetFromRenderer()) {
         m_graphicsLayer->setOffsetFromRenderer(devicePixelOffsetFromRenderer);