REGRESSION (r155660): box-shadow causes overlay scrollbars to be in the wrong position when element is composited (85647)
https://bugs.webkit.org/show_bug.cgi?id=124090

Source/WebCore:

Reviewed by Beth Dakin.

After r155660 we did fewer layouts, so were left with overlay scrollbars in the
wrong locations because nothing would update them after RenderLayerBacking
computed a new offsetFromRenderer.

First part of the fix is to wean positionOverflowControlsLayers() off of
an absolute offset from the root. Do this by not using Widget::frameRect()
to position the layers, but instead RenderLayer::rectFor{Horizontal|Vertical}Scrollbar
which is what we used to position the scrollbars in the first place.

Second part of the fix is to call positionOverflowControlsLayers() from
RenderLayerBacking::updateGraphicsLayerGeometry() if the offsetFromRenderer
changed.

Test: compositing/overflow/overflow-scrollbar-layer-positions.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::positionOverflowControls):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::updateGraphicsLayerGeometry):
(WebCore::RenderLayerBacking::positionOverflowControlsLayers):
* rendering/RenderLayerBacking.h:

LayoutTests:

Reviewed by Beth Dakin.

Test, but it doesn't actually test the fix until we enable overlay scrollbars
in tests (bug 60716).

* compositing/overflow/overflow-scrollbar-layer-positions-expected.txt: Added.
* compositing/overflow/overflow-scrollbar-layer-positions.html: Added.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@159082 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/rendering/RenderLayerBacking.cpp b/Source/WebCore/rendering/RenderLayerBacking.cpp
index 7962365..faab4db 100644
--- a/Source/WebCore/rendering/RenderLayerBacking.cpp
+++ b/Source/WebCore/rendering/RenderLayerBacking.cpp
@@ -697,7 +697,11 @@
 
     m_graphicsLayer->setPosition(FloatPoint(relativeCompositingBounds.location() - graphicsLayerParentLocation));
     m_graphicsLayer->setSize(contentsSize);
-    m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
+    IntSize offsetFromRenderer = toIntSize(localCompositingBounds.location());
+    if (offsetFromRenderer != m_graphicsLayer->offsetFromRenderer()) {
+        m_graphicsLayer->setOffsetFromRenderer(toIntSize(localCompositingBounds.location()));
+        positionOverflowControlsLayers();
+    }
 
     if (!m_isMainFrameRenderViewLayer) {
         // For non-root layers, background is always painted by the primary graphics layer.
@@ -1124,35 +1128,36 @@
     return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
 }
 
-void RenderLayerBacking::positionOverflowControlsLayers(const IntSize& offsetFromRoot)
+void RenderLayerBacking::positionOverflowControlsLayers()
 {
+    if (!m_owningLayer.hasScrollbars())
+        return;
+
+    const IntRect borderBox = toRenderBox(renderer()).pixelSnappedBorderBoxRect();
+
     IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer();
     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
-        Scrollbar* hBar = m_owningLayer.horizontalScrollbar();
-        if (hBar) {
-            layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
-            layer->setSize(hBar->frameRect().size());
-            if (layer->hasContentsLayer()) {
-                IntRect barRect = IntRect(IntPoint(), hBar->frameRect().size());
-                layer->setContentsRect(barRect);
-                layer->setContentsClippingRect(barRect);
-            }
+        IntRect hBarRect = m_owningLayer.rectForHorizontalScrollbar(borderBox);
+        layer->setPosition(hBarRect.location() - offsetFromRenderer);
+        layer->setSize(hBarRect.size());
+        if (layer->hasContentsLayer()) {
+            IntRect barRect = IntRect(IntPoint(), hBarRect.size());
+            layer->setContentsRect(barRect);
+            layer->setContentsClippingRect(barRect);
         }
-        layer->setDrawsContent(hBar && !layer->hasContentsLayer());
+        layer->setDrawsContent(m_owningLayer.horizontalScrollbar() && !layer->hasContentsLayer());
     }
     
     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
-        Scrollbar* vBar = m_owningLayer.verticalScrollbar();
-        if (vBar) {
-            layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
-            layer->setSize(vBar->frameRect().size());
-            if (layer->hasContentsLayer()) {
-                IntRect barRect = IntRect(IntPoint(), vBar->frameRect().size());
-                layer->setContentsRect(barRect);
-                layer->setContentsClippingRect(barRect);
-            }
+        IntRect vBarRect = m_owningLayer.rectForVerticalScrollbar(borderBox);
+        layer->setPosition(vBarRect.location() - offsetFromRenderer);
+        layer->setSize(vBarRect.size());
+        if (layer->hasContentsLayer()) {
+            IntRect barRect = IntRect(IntPoint(), vBarRect.size());
+            layer->setContentsRect(barRect);
+            layer->setContentsClippingRect(barRect);
         }
-        layer->setDrawsContent(vBar && !layer->hasContentsLayer());
+        layer->setDrawsContent(m_owningLayer.verticalScrollbar() && !layer->hasContentsLayer());
     }
 
     if (GraphicsLayer* layer = layerForScrollCorner()) {