2011-06-06 Emil A Eklund <eae@chromium.org>
[WebKit-https.git] / Source / WebCore / rendering / RenderLayer.cpp
index 633ce7a..e2d9fb7 100644 (file)
@@ -56,6 +56,7 @@
 #include "FloatRect.h"
 #include "FocusController.h"
 #include "Frame.h"
+#include "FrameSelection.h"
 #include "FrameTree.h"
 #include "FrameView.h"
 #include "Gradient.h"
@@ -80,7 +81,6 @@
 #include "ScaleTransformOperation.h"
 #include "Scrollbar.h"
 #include "ScrollbarTheme.h"
-#include "SelectionController.h"
 #include "TextStream.h"
 #include "TransformState.h"
 #include "TransformationMatrix.h"
@@ -135,18 +135,6 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
     , m_next(0)
     , m_first(0)
     , m_last(0)
-    , m_relX(0)
-    , m_relY(0)
-    , m_x(0)
-    , m_y(0)
-    , m_width(0)
-    , m_height(0)
-    , m_scrollX(0)
-    , m_scrollY(0)
-    , m_scrollLeftOverflow(0)
-    , m_scrollTopOverflow(0)
-    , m_scrollWidth(0)
-    , m_scrollHeight(0)
     , m_inResizeMode(false)
     , m_posZOrderList(0)
     , m_negZOrderList(0)
@@ -175,13 +163,17 @@ RenderLayer::RenderLayer(RenderBoxModelObject* renderer)
     , m_hasCompositingDescendant(false)
     , m_mustOverlapCompositedLayers(false)
 #endif
+    , m_containsDirtyOverlayScrollbars(false)
     , m_marquee(0)
-    , m_staticX(0)
-    , m_staticY(0)
+    , m_staticInlinePosition(0)
+    , m_staticBlockPosition(0)
     , m_reflection(0)
     , m_scrollCorner(0)
     , m_resizer(0)
+    , m_scrollableAreaPage(0)
 {
+    ScrollableArea::setConstrainsScrollingToContentEdge(false);
+
     if (!renderer->firstChild() && renderer->style()) {
         m_visibleContentStatusDirty = false;
         m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
@@ -195,9 +187,15 @@ RenderLayer::~RenderLayer()
             frame->eventHandler()->resizeLayerDestroyed();
     }
 
+    if (m_scrollableAreaPage)
+        m_scrollableAreaPage->removeScrollableArea(this);
+
     destroyScrollbar(HorizontalScrollbar);
     destroyScrollbar(VerticalScrollbar);
 
+    if (m_reflection)
+        removeReflection();
+
     // Child layers will be deleted by their corresponding render objects, so
     // we don't need to delete them ourselves.
 
@@ -213,9 +211,6 @@ RenderLayer::~RenderLayer()
     // Make sure we have no lingering clip rects.
     ASSERT(!m_clipRects);
     
-    if (m_reflection)
-        removeReflection();
-    
     if (m_scrollCorner)
         m_scrollCorner->destroy();
     if (m_resizer)
@@ -260,19 +255,6 @@ bool RenderLayer::canRender3DTransforms() const
 
 void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags, IntPoint* cachedOffset)
 {
-    if (flags & DoFullRepaint) {
-        renderer()->repaint();
-#if USE(ACCELERATED_COMPOSITING)
-        flags &= ~CheckForRepaint;
-        // We need the full repaint to propagate to child layers if we are hardware compositing.
-        if (!compositor()->inCompositingMode())
-            flags &= ~DoFullRepaint;
-#else
-        flags &= ~(CheckForRepaint | DoFullRepaint);
-#endif
-    }
-    
-
     updateLayerPosition(); // For relpositioned layers or non-positioned layers,
                            // we need to keep in sync, since we may have shifted relative
                            // to our parent layer.
@@ -288,34 +270,29 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags, IntPoint
         else {
             oldCachedOffset = *cachedOffset;
             // Frequently our parent layer's renderer will be the same as our renderer's containing block.  In that case,
-            // we just update the cache using our offset to our parent (which is m_x / m_y).  Otherwise, regenerated cached
+            // we just update the cache using our offset to our parent (which is m_topLeft). Otherwise, regenerated cached
             // offsets to the root from the render tree.
             if (!m_parent || m_parent->renderer() == renderer()->containingBlock())
-                cachedOffset->move(m_x, m_y); // Fast case
+                cachedOffset->move(m_topLeft.x(), m_topLeft.y()); // Fast case
             else {
-                int x = 0;
-                int y = 0;
-                convertToLayerCoords(root(), x, y);
-                *cachedOffset = IntPoint(x, y);
+                IntPoint offset;
+                convertToLayerCoords(root(), offset);
+                *cachedOffset = offset;
             }
         }
     }
 
-    int x = 0;
-    int y = 0;
+    IntPoint offset;
     if (cachedOffset) {
-        x += cachedOffset->x();
-        y += cachedOffset->y();
+        offset = *cachedOffset;
 #ifndef NDEBUG
-        int nonCachedX = 0;
-        int nonCachedY = 0;
-        convertToLayerCoords(root(), nonCachedX, nonCachedY);
-        ASSERT(x == nonCachedX);
-        ASSERT(y == nonCachedY);
+        IntPoint nonCachedOffset;
+        convertToLayerCoords(root(), nonCachedOffset);
+        ASSERT(offset == nonCachedOffset);
 #endif
     } else
-        convertToLayerCoords(root(), x, y);
-    positionOverflowControls(x, y);
+        convertToLayerCoords(root(), offset);
+    positionOverflowControls(toSize(offset));
 
     updateVisibilityStatus();
 
@@ -327,7 +304,7 @@ void RenderLayer::updateLayerPositions(UpdateLayerPositionsFlags flags, IntPoint
     if (m_hasVisibleContent) {
         RenderView* view = renderer()->view();
         ASSERT(view);
-        // FIXME: Optimize using LayoutState and remove the disableLayoutState() call
+        // FIXME: Optimize using LayoutState and remove LayoutStateDisabler instantiation
         // from updateScrollInfoAfterLayout().
         ASSERT(!view->layoutStateEnabled());
 
@@ -405,7 +382,7 @@ void RenderLayer::updateRepaintRectsAfterScroll(bool fixed)
     if (fixed || renderer()->style()->position() == FixedPosition) {
         computeRepaintRects();
         fixed = true;
-    } else if (renderer()->hasTransform()) {
+    } else if (renderer()->hasTransform() && !renderer()->isRenderView()) {
         // Transforms act as fixed position containers, so nothing inside a
         // transformed element can be fixed relative to the viewport if the
         // transformed element is not fixed itself or child of a fixed element.
@@ -426,7 +403,7 @@ void RenderLayer::updateTransform()
     bool hadTransform = m_transform;
     if (hasTransform != hadTransform) {
         if (hasTransform)
-            m_transform.set(new TransformationMatrix);
+            m_transform = adoptPtr(new TransformationMatrix);
         else
             m_transform.clear();
     }
@@ -669,13 +646,11 @@ void RenderLayer::updateLayerPosition()
     if (renderer()->isRenderInline()) {
         RenderInline* inlineFlow = toRenderInline(renderer());
         IntRect lineBox = inlineFlow->linesBoundingBox();
-        setWidth(lineBox.width());
-        setHeight(lineBox.height());
-        inlineBoundingBoxOffset = IntSize(lineBox.x(), lineBox.y());
+        setSize(lineBox.size());
+        inlineBoundingBoxOffset = toSize(lineBox.location());
         localPoint += inlineBoundingBoxOffset;
     } else if (RenderBox* box = renderBox()) {
-        setWidth(box->width());
-        setHeight(box->height());
+        setSize(box->size());
         localPoint += box->locationOffsetIncludingFlipping();
     }
 
@@ -725,11 +700,11 @@ void RenderLayer::updateLayerPosition()
         localPoint -= scrollOffset;
     }
         
-    m_relX = m_relY = 0;
     if (renderer()->isRelPositioned()) {
-        m_relX = renderer()->relativePositionOffsetX();
-        m_relY = renderer()->relativePositionOffsetY();
-        localPoint.move(m_relX, m_relY);
+        m_relativeOffset = renderer()->relativePositionOffset();
+        localPoint.move(m_relativeOffset);
+    } else {
+        m_relativeOffset = IntSize();
     }
 
     // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
@@ -921,12 +896,11 @@ static void expandClipRectForDescendantsAndReflection(IntRect& clipRect, const R
     // FIXME: Accelerated compositing will eventually want to do something smart here to avoid incorporating this
     // size into the parent layer.
     if (l->renderer()->hasReflection()) {
-        int deltaX = 0;
-        int deltaY = 0;
-        l->convertToLayerCoords(rootLayer, deltaX, deltaY);
-        clipRect.move(-deltaX, -deltaY);
+        IntPoint delta;
+        l->convertToLayerCoords(rootLayer, delta);
+        clipRect.move(-delta.x(), -delta.y());
         clipRect.unite(l->renderBox()->reflectedRect(clipRect));
-        clipRect.move(deltaX, deltaY);
+        clipRect.moveBy(delta);
     }
 }
 
@@ -939,13 +913,12 @@ static IntRect transparencyClipBox(const RenderLayer* l, const RenderLayer* root
     if (rootLayer != l && l->paintsWithTransform(paintBehavior)) {
         // The best we can do here is to use enclosed bounding boxes to establish a "fuzzy" enough clip to encompass
         // the transformed layer and all of its children.
-        int x = 0;
-        int y = 0;
-        l->convertToLayerCoords(rootLayer, x, y);
+        IntPoint delta;
+        l->convertToLayerCoords(rootLayer, delta);
 
         TransformationMatrix transform;
-        transform.translate(x, y);
-        transform = *l->transform() * transform;
+        transform.translate(delta.x(), delta.y());
+        transform = transform * *l->transform();
 
         IntRect clipRect = l->boundingBox(l);
         expandClipRectForDescendantsAndReflection(clipRect, l, l, paintBehavior);
@@ -1104,6 +1077,7 @@ void RenderLayer::removeOnlyThisLayer()
         RenderLayer* next = current->nextSibling();
         removeChild(current);
         parent->addChild(current, nextSib);
+        current->setNeedsFullRepaint();
         current->updateLayerPositions(); // Depends on hasLayer() already being false for proper layout.
         current = next;
     }
@@ -1131,7 +1105,7 @@ void RenderLayer::insertOnlyThisLayer()
 }
 
 void 
-RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, int& yPos) const
+RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, IntPoint& location) const
 {
     if (ancestorLayer == this)
         return;
@@ -1141,8 +1115,7 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
         // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
         // localToAbsolute() on the RenderView.
         FloatPoint absPos = renderer()->localToAbsolute(FloatPoint(), true);
-        xPos += absPos.x();
-        yPos += absPos.y();
+        location += flooredIntSize(absPos);
         return;
     }
  
@@ -1158,7 +1131,7 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
 
             if (isFixedPositionedContainer(currLayer)) {
                 fixedPositionContainerLayer = currLayer;
-                ASSERT(foundAncestor);
+                ASSERT_UNUSED(foundAncestor, foundAncestor);
                 break;
             }
         }
@@ -1166,16 +1139,13 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
         ASSERT(fixedPositionContainerLayer); // We should have hit the RenderView's layer at least.
 
         if (fixedPositionContainerLayer != ancestorLayer) {
-            int fixedContainerX = 0;
-            int fixedContainerY = 0;
-            convertToLayerCoords(fixedPositionContainerLayer, fixedContainerX, fixedContainerY);
-            
-            int ancestorX = 0;
-            int ancestorY = 0;
-            ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorX, ancestorY);
-        
-            xPos += (fixedContainerX - ancestorX);
-            yPos += (fixedContainerY - ancestorY);
+            IntPoint fixedContainerCoords;
+            convertToLayerCoords(fixedPositionContainerLayer, fixedContainerCoords);
+
+            IntPoint ancestorCoords;
+            ancestorLayer->convertToLayerCoords(fixedPositionContainerLayer, ancestorCoords);
+
+            location += (fixedContainerCoords - ancestorCoords);
             return;
         }
     }
@@ -1202,16 +1172,13 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
             // to enclosingPositionedAncestor and subtract.
             RenderLayer* positionedAncestor = parentLayer->enclosingPositionedAncestor();
 
-            int thisX = 0;
-            int thisY = 0;
-            convertToLayerCoords(positionedAncestor, thisX, thisY);
+            IntPoint thisCoords;
+            convertToLayerCoords(positionedAncestor, thisCoords);
             
-            int ancestorX = 0;
-            int ancestorY = 0;
-            ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorX, ancestorY);
-        
-            xPos += (thisX - ancestorX);
-            yPos += (thisY - ancestorY);
+            IntPoint ancestorCoords;
+            ancestorLayer->convertToLayerCoords(positionedAncestor, ancestorCoords);
+
+            location += (thisCoords - ancestorCoords);
             return;
         }
     } else
@@ -1219,11 +1186,18 @@ RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, int& xPos, i
     
     if (!parentLayer)
         return;
-    
-    parentLayer->convertToLayerCoords(ancestorLayer, xPos, yPos);
-    
-    xPos += x();
-    yPos += y();
+
+    parentLayer->convertToLayerCoords(ancestorLayer, location);
+
+    location += toSize(m_topLeft);
+}
+
+void
+RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, IntRect& rect) const
+{
+    IntPoint delta;
+    convertToLayerCoords(ancestorLayer, delta);
+    rect.move(-delta.x(), -delta.y());
 }
 
 static inline int adjustedScrollDelta(int beginningDelta) {
@@ -1306,23 +1280,36 @@ void RenderLayer::scrollByRecursively(int xDelta, int yDelta)
     }
 }
 
-void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repaint)
+void RenderLayer::scrollToOffset(int x, int y)
+{
+    ScrollableArea::scrollToOffsetWithoutAnimation(IntPoint(x, y));
+}
+
+void RenderLayer::scrollTo(int x, int y)
 {
     RenderBox* box = renderBox();
     if (!box)
         return;
 
     if (box->style()->overflowX() != OMARQUEE) {
-        if (x < 0) x = 0;
-        if (y < 0) y = 0;
+        if (x < 0)
+            x = 0;
+        if (y < 0)
+            y = 0;
     
         // Call the scrollWidth/Height functions so that the dimensions will be computed if they need
         // to be (for overflow:hidden blocks).
         int maxX = scrollWidth() - box->clientWidth();
+        if (maxX < 0)
+            maxX = 0;
         int maxY = scrollHeight() - box->clientHeight();
-        
-        if (x > maxX) x = maxX;
-        if (y > maxY) y = maxY;
+        if (maxY < 0)
+            maxY = 0;
+
+        if (x > maxX)
+            x = maxX;
+        if (y > maxY)
+            y = maxY;
     }
     
     // FIXME: Eventually, we will want to perform a blit.  For now never
@@ -1330,12 +1317,10 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
     // complicated (since it will involve testing whether our layer
     // is either occluded by another layer or clipped by an enclosing
     // layer or contains fixed backgrounds, etc.).
-    int newScrollX = x - m_scrollOrigin.x();
-    int newScrollY = y - m_scrollOrigin.y();
-    if (m_scrollY == newScrollY && m_scrollX == newScrollX)
+    IntSize newScrollOffset = IntSize(x - m_scrollOrigin.x(), y - m_scrollOrigin.y());
+    if (m_scrollOffset == newScrollOffset)
         return;
-    m_scrollX = newScrollX;
-    m_scrollY = newScrollY;
+    m_scrollOffset = newScrollOffset;
 
     // Update the positions of our child layers. Don't have updateLayerPositions() update
     // compositing layers, because we need to do a deep update from the compositing ancestor.
@@ -1386,25 +1371,17 @@ void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repai
     }
 
     // Just schedule a full repaint of our object.
-    if (view && repaint)
+    if (view)
         renderer()->repaintUsingContainer(repaintContainer, rectForRepaint);
 
-    if (updateScrollbars) {
-        if (m_hBar)
-            m_hBar->setValue(scrollXOffset(), Scrollbar::NotFromScrollAnimator);
-        if (m_vBar)
-            m_vBar->setValue(m_scrollY, Scrollbar::NotFromScrollAnimator);
-    }
-
     // Schedule the scroll DOM event.
-    renderer()->node()->document()->eventQueue()->enqueueScrollEvent(renderer()->node(), EventQueue::ScrollEventElementTarget);
+    renderer()->node()->document()->eventQueue()->enqueueOrDispatchScrollEvent(renderer()->node(), EventQueue::ScrollEventElementTarget);
 }
 
-void RenderLayer::scrollRectToVisible(const IntRect& rect, bool scrollToAnchor, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
+void RenderLayer::scrollRectToVisible(const IntRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
 {
     RenderLayer* parentLayer = 0;
     IntRect newRect = rect;
-    int xOffset = 0, yOffset = 0;
 
     // We may end up propagating a scroll event. It is important that we suspend events until 
     // the end of the function since they could delete the layer or the layer's renderer().
@@ -1430,8 +1407,8 @@ void RenderLayer::scrollRectToVisible(const IntRect& rect, bool scrollToAnchor,
         IntRect exposeRect = IntRect(rect.x() + scrollXOffset(), rect.y() + scrollYOffset(), rect.width(), rect.height());
         IntRect r = getRectToExpose(layerBounds, exposeRect, alignX, alignY);
         
-        xOffset = r.x() - absPos.x();
-        yOffset = r.y() - absPos.y();
+        int xOffset = r.x() - absPos.x();
+        int yOffset = r.y() - absPos.y();
         // Adjust offsets if they're outside of the allowable range.
         xOffset = max(0, min(scrollWidth() - layerBounds.width(), xOffset));
         yOffset = max(0, min(scrollHeight() - layerBounds.height(), yOffset));
@@ -1445,14 +1422,14 @@ void RenderLayer::scrollRectToVisible(const IntRect& rect, bool scrollToAnchor,
             newRect.setX(rect.x() - diffX);
             newRect.setY(rect.y() - diffY);
         }
-    } else if (!parentLayer && renderer()->isBox() && renderBox()->canBeProgramaticallyScrolled(scrollToAnchor)) {
+    } else if (!parentLayer && renderer()->isBox() && renderBox()->canBeProgramaticallyScrolled()) {
         if (frameView) {
             if (renderer()->document() && renderer()->document()->ownerElement() && renderer()->document()->ownerElement()->renderer()) {
                 IntRect viewRect = frameView->visibleContentRect();
                 IntRect r = getRectToExpose(viewRect, rect, alignX, alignY);
                 
-                xOffset = r.x();
-                yOffset = r.y();
+                int xOffset = r.x();
+                int yOffset = r.y();
                 // Adjust offsets if they're outside of the allowable range.
                 xOffset = max(0, min(frameView->contentsWidth(), xOffset));
                 yOffset = max(0, min(frameView->contentsHeight(), yOffset));
@@ -1481,7 +1458,7 @@ void RenderLayer::scrollRectToVisible(const IntRect& rect, bool scrollToAnchor,
     }
     
     if (parentLayer)
-        parentLayer->scrollRectToVisible(newRect, scrollToAnchor, alignX, alignY);
+        parentLayer->scrollRectToVisible(newRect, alignX, alignY);
 
     if (frameView)
         frameView->resumeScheduledEvents();
@@ -1510,7 +1487,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
         scrollX = ScrollAlignment::getHiddenBehavior(alignX);
     // If we're trying to align to the closest edge, and the exposeRect is further right
     // than the visibleRect, and not bigger than the visible area, then align with the right.
-    if (scrollX == alignToClosestEdge && exposeRect.right() > visibleRect.right() && exposeRect.width() < visibleRect.width())
+    if (scrollX == alignToClosestEdge && exposeRect.maxX() > visibleRect.maxX() && exposeRect.width() < visibleRect.width())
         scrollX = alignRight;
 
     // Given the X behavior, compute the X coordinate.
@@ -1518,7 +1495,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
     if (scrollX == noScroll) 
         x = visibleRect.x();
     else if (scrollX == alignRight)
-        x = exposeRect.right() - visibleRect.width();
+        x = exposeRect.maxX() - visibleRect.width();
     else if (scrollX == alignCenter)
         x = exposeRect.x() + (exposeRect.width() - visibleRect.width()) / 2;
     else
@@ -1543,7 +1520,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
         scrollY = ScrollAlignment::getHiddenBehavior(alignY);
     // If we're trying to align to the closest edge, and the exposeRect is further down
     // than the visibleRect, and not bigger than the visible area, then align with the bottom.
-    if (scrollY == alignToClosestEdge && exposeRect.bottom() > visibleRect.bottom() && exposeRect.height() < visibleRect.height())
+    if (scrollY == alignToClosestEdge && exposeRect.maxY() > visibleRect.maxY() && exposeRect.height() < visibleRect.height())
         scrollY = alignBottom;
 
     // Given the Y behavior, compute the Y coordinate.
@@ -1551,7 +1528,7 @@ IntRect RenderLayer::getRectToExpose(const IntRect &visibleRect, const IntRect &
     if (scrollY == noScroll) 
         y = visibleRect.y();
     else if (scrollY == alignBottom)
-        y = exposeRect.bottom() - visibleRect.height();
+        y = exposeRect.maxY() - visibleRect.height();
     else if (scrollY == alignCenter)
         y = exposeRect.y() + (exposeRect.height() - visibleRect.height()) / 2;
     else
@@ -1575,7 +1552,7 @@ void RenderLayer::autoscroll()
 #endif
 
     IntPoint currentDocumentPosition = frameView->windowToContents(frame->eventHandler()->currentMousePosition());
-    scrollRectToVisible(IntRect(currentDocumentPosition, IntSize(1, 1)), false, ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
+    scrollRectToVisible(IntRect(currentDocumentPosition, IntSize(1, 1)), ScrollAlignment::alignToEdgeIfNeeded, ScrollAlignment::alignToEdgeIfNeeded);
 }
 
 void RenderLayer::resize(const PlatformMouseEvent& evt, const IntSize& oldOffset)
@@ -1649,36 +1626,57 @@ int RenderLayer::scrollSize(ScrollbarOrientation orientation) const
     return scrollbar ? (scrollbar->totalSize() - scrollbar->visibleSize()) : 0;
 }
 
-void RenderLayer::setScrollOffsetFromAnimation(const IntPoint& offset)
+void RenderLayer::setScrollOffset(const IntPoint& offset)
 {
-    if (m_hBar)
-        m_hBar->setValue(offset.x(), Scrollbar::FromScrollAnimator);
-    if (m_vBar)
-        m_vBar->setValue(offset.y(), Scrollbar::FromScrollAnimator);
+    scrollTo(offset.x(), offset.y());
 }
 
-void RenderLayer::valueChanged(Scrollbar*)
+int RenderLayer::scrollPosition(Scrollbar* scrollbar) const
 {
-    // Update scroll position from scrollbars.
+    if (scrollbar->orientation() == HorizontalScrollbar)
+        return scrollXOffset();
+    if (scrollbar->orientation() == VerticalScrollbar)
+        return scrollYOffset();
+    return 0;
+}
 
-    bool needUpdate = false;
-    int newX = scrollXOffset();
-    int newY = m_scrollY;
-    
-    if (m_hBar) {
-        newX = m_hBar->value();
-        if (newX != scrollXOffset())
-           needUpdate = true;
-    }
+IntPoint RenderLayer::scrollPosition() const
+{
+    return m_scrollOrigin + m_scrollOffset;
+}
 
-    if (m_vBar) {
-        newY = m_vBar->value();
-        if (newY != m_scrollY)
-           needUpdate = true;
+IntPoint RenderLayer::minimumScrollPosition() const
+{
+    return m_scrollOrigin;
+}
+
+IntPoint RenderLayer::maximumScrollPosition() const
+{
+    // FIXME: m_scrollSize may not be up-to-date if m_scrollDimensionsDirty is true.
+    return m_scrollOrigin + m_scrollSize;
+}
+
+IntRect RenderLayer::visibleContentRect(bool includeScrollbars) const
+{
+    int verticalScrollbarWidth = 0;
+    int horizontalScrollbarHeight = 0;
+    if (includeScrollbars) {
+        verticalScrollbarWidth = (verticalScrollbar() && !verticalScrollbar()->isOverlayScrollbar()) ? verticalScrollbar()->width() : 0;
+        horizontalScrollbarHeight = (horizontalScrollbar() && !horizontalScrollbar()->isOverlayScrollbar()) ? horizontalScrollbar()->height() : 0;
     }
+    
+    return IntRect(IntPoint(scrollXOffset(), scrollYOffset()),
+                   IntSize(max(0, m_layerSize.width() - verticalScrollbarWidth), 
+                           max(0, m_layerSize.height() - horizontalScrollbarHeight)));
+}
+
+IntSize RenderLayer::overhangAmount() const
+{
+    return IntSize();
+}
 
-    if (needUpdate)
-        scrollToOffset(newX, newY, false);
+void RenderLayer::didCompleteRubberBand(const IntSize&) const
+{
 }
 
 bool RenderLayer::isActive() const
@@ -1687,7 +1685,6 @@ bool RenderLayer::isActive() const
     return page && page->focusController()->isActive();
 }
 
-
 static IntRect cornerRect(const RenderLayer* layer, const IntRect& bounds)
 {
     int horizontalThickness;
@@ -1707,22 +1704,22 @@ static IntRect cornerRect(const RenderLayer* layer, const IntRect& bounds)
         horizontalThickness = layer->verticalScrollbar()->width();
         verticalThickness = layer->horizontalScrollbar()->height();
     }
-    return IntRect(bounds.right() - horizontalThickness - layer->renderer()->style()->borderRightWidth(), 
-                   bounds.bottom() - verticalThickness - layer->renderer()->style()->borderBottomWidth(),
+    return IntRect(bounds.maxX() - horizontalThickness - layer->renderer()->style()->borderRightWidth(), 
+                   bounds.maxY() - verticalThickness - layer->renderer()->style()->borderBottomWidth(),
                    horizontalThickness, verticalThickness);
 }
 
-static IntRect scrollCornerRect(const RenderLayer* layer, const IntRect& bounds)
+IntRect RenderLayer::scrollCornerRect() const
 {
     // We have a scrollbar corner when a scrollbar is visible and not filling the entire length of the box.
     // This happens when:
     // (a) A resizer is present and at least one scrollbar is present
     // (b) Both scrollbars are present.
-    bool hasHorizontalBar = layer->horizontalScrollbar();
-    bool hasVerticalBar = layer->verticalScrollbar();
-    bool hasResizer = layer->renderer()->style()->resize() != RESIZE_NONE;
+    bool hasHorizontalBar = horizontalScrollbar();
+    bool hasVerticalBar = verticalScrollbar();
+    bool hasResizer = renderer()->style()->resize() != RESIZE_NONE;
     if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
-        return cornerRect(layer, bounds);
+        return cornerRect(this, renderBox()->borderBoxRect());
     return IntRect();
 }
 
@@ -1734,10 +1731,21 @@ static IntRect resizerCornerRect(const RenderLayer* layer, const IntRect& bounds
     return cornerRect(layer, bounds);
 }
 
-bool RenderLayer::scrollbarCornerPresent() const
+IntRect RenderLayer::scrollCornerAndResizerRect() const
+{
+    RenderBox* box = renderBox();
+    if (!box)
+        return IntRect();
+    IntRect scrollCornerAndResizer = scrollCornerRect();
+    if (scrollCornerAndResizer.isEmpty())
+        scrollCornerAndResizer = resizerCornerRect(this, box->borderBoxRect());
+    return scrollCornerAndResizer;
+}
+
+bool RenderLayer::isScrollCornerVisible() const
 {
     ASSERT(renderer()->isBox());
-    return !scrollCornerRect(this, renderBox()->borderBoxRect()).isEmpty();
+    return !scrollCornerRect().isEmpty();
 }
 
 IntRect RenderLayer::convertFromScrollbarToContainingView(const Scrollbar* scrollbar, const IntRect& scrollbarRect) const
@@ -1786,6 +1794,34 @@ IntPoint RenderLayer::convertFromContainingViewToScrollbar(const Scrollbar* scro
     return point;
 }
 
+IntSize RenderLayer::contentsSize() const
+{
+    return IntSize(const_cast<RenderLayer*>(this)->scrollWidth(), const_cast<RenderLayer*>(this)->scrollHeight());
+}
+
+int RenderLayer::visibleHeight() const
+{
+    return m_layerSize.height();
+}
+
+int RenderLayer::visibleWidth() const
+{
+    return m_layerSize.width();
+}
+
+bool RenderLayer::shouldSuspendScrollAnimations() const
+{
+    RenderView* view = renderer()->view();
+    if (!view)
+        return true;
+    return view->frameView()->shouldSuspendScrollAnimations();
+}
+
+IntPoint RenderLayer::currentMousePosition() const
+{
+    return renderer()->frame() ? renderer()->frame()->eventHandler()->currentMousePosition() : IntPoint();
+}
+
 IntSize RenderLayer::scrollbarOffset(const Scrollbar* scrollbar) const
 {
     RenderBox* box = renderBox();
@@ -1802,6 +1838,19 @@ IntSize RenderLayer::scrollbarOffset(const Scrollbar* scrollbar) const
 
 void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
 {
+#if USE(ACCELERATED_COMPOSITING)
+    if (scrollbar == m_vBar.get()) {
+        if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
+            layer->setNeedsDisplayInRect(rect);
+            return;
+        }
+    } else {
+        if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
+            layer->setNeedsDisplayInRect(rect);
+            return;
+        }
+    }
+#endif
     IntRect scrollRect = rect;
     RenderBox* box = renderBox();
     ASSERT(box);
@@ -1812,6 +1861,20 @@ void RenderLayer::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& r
     renderer()->repaintRectangle(scrollRect);
 }
 
+void RenderLayer::invalidateScrollCornerRect(const IntRect& rect)
+{
+#if USE(ACCELERATED_COMPOSITING)
+    if (GraphicsLayer* layer = layerForScrollCorner()) {
+        layer->setNeedsDisplayInRect(rect);
+        return;
+    }
+#endif
+    if (m_scrollCorner)
+        m_scrollCorner->repaintRectangle(rect);
+    if (m_resizer)
+        m_resizer->repaintRectangle(rect);
+}
+
 PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientation)
 {
     RefPtr<Scrollbar> widget;
@@ -1819,8 +1882,13 @@ PassRefPtr<Scrollbar> RenderLayer::createScrollbar(ScrollbarOrientation orientat
     bool hasCustomScrollbarStyle = actualRenderer->isBox() && actualRenderer->style()->hasPseudoStyle(SCROLLBAR);
     if (hasCustomScrollbarStyle)
         widget = RenderScrollbar::createCustomScrollbar(this, orientation, toRenderBox(actualRenderer));
-    else
+    else {
         widget = Scrollbar::createNativeScrollbar(this, orientation, RegularScrollbar);
+        if (orientation == HorizontalScrollbar)
+            didAddHorizontalScrollbar(widget.get());
+        else 
+            didAddVerticalScrollbar(widget.get());
+    }
     renderer()->document()->view()->addChild(widget.get());        
     return widget.release();
 }
@@ -1831,13 +1899,40 @@ void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
     if (scrollbar) {
         if (scrollbar->isCustomScrollbar())
             static_cast<RenderScrollbar*>(scrollbar.get())->clearOwningRenderer();
+        else {
+            if (orientation == HorizontalScrollbar)
+                willRemoveHorizontalScrollbar(scrollbar.get());
+            else
+                willRemoveVerticalScrollbar(scrollbar.get());
+        }
 
         scrollbar->removeFromParent();
-        scrollbar->setClient(0);
+        scrollbar->disconnectFromScrollableArea();
         scrollbar = 0;
     }
 }
 
+bool RenderLayer::scrollsOverflow() const
+{
+    if (!renderer()->isBox())
+        return false;
+    
+    return toRenderBox(renderer())->scrollsOverflow();
+}
+
+void RenderLayer::didAddHorizontalScrollbar(Scrollbar* scrollbar)
+{
+    m_renderer->document()->didAddWheelEventHandler();
+    ScrollableArea::didAddHorizontalScrollbar(scrollbar);
+}
+
+void RenderLayer::willRemoveHorizontalScrollbar(Scrollbar* scrollbar)
+{
+    ScrollableArea::willRemoveHorizontalScrollbar(scrollbar);
+    // FIXME: maybe need a separate ScrollableArea::didRemoveHorizontalScrollbar callback?
+    m_renderer->document()->didRemoveWheelEventHandler();
+}
+
 void RenderLayer::setHasHorizontalScrollbar(bool hasScrollbar)
 {
     if (hasScrollbar == (m_hBar != 0))
@@ -1884,16 +1979,16 @@ void RenderLayer::setHasVerticalScrollbar(bool hasScrollbar)
 #endif
 }
 
-int RenderLayer::verticalScrollbarWidth() const
+int RenderLayer::verticalScrollbarWidth(OverlayScrollbarSizeRelevancy relevancy) const
 {
-    if (!m_vBar)
+    if (!m_vBar || (m_vBar->isOverlayScrollbar() && relevancy == IgnoreOverlayScrollbarSize))
         return 0;
     return m_vBar->width();
 }
 
-int RenderLayer::horizontalScrollbarHeight() const
+int RenderLayer::horizontalScrollbarHeight(OverlayScrollbarSizeRelevancy relevancy) const
 {
-    if (!m_hBar)
+    if (!m_hBar || (m_hBar->isOverlayScrollbar() && relevancy == IgnoreOverlayScrollbarSize))
         return 0;
     return m_hBar->height();
 }
@@ -1901,7 +1996,8 @@ int RenderLayer::horizontalScrollbarHeight() const
 IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
 {
     // Currently the resize corner is always the bottom right corner
-    IntPoint bottomRight(width(), height());
+    // FIXME: This assumes the location is 0, 0. Is this guaranteed to always be the case?
+    IntPoint bottomRight = toPoint(size());
     IntPoint localPoint = absoluteToContents(absolutePoint);
     return localPoint - bottomRight;
 }
@@ -1911,7 +2007,7 @@ bool RenderLayer::hasOverflowControls() const
     return m_hBar || m_vBar || m_scrollCorner || renderer()->style()->resize() != RESIZE_NONE;
 }
 
-void RenderLayer::positionOverflowControls(int tx, int ty)
+void RenderLayer::positionOverflowControls(const IntSize& offsetFromLayer)
 {
     if (!m_hBar && !m_vBar && (!renderer()->hasOverflowClip() || renderer()->style()->resize() == RESIZE_NONE))
         return;
@@ -1920,21 +2016,45 @@ void RenderLayer::positionOverflowControls(int tx, int ty)
     if (!box)
         return;
 
-    IntRect borderBox = box->borderBoxRect();
-    IntRect scrollCorner(scrollCornerRect(this, borderBox));
-    IntRect absBounds(borderBox.x() + tx, borderBox.y() + ty, borderBox.width(), borderBox.height());
+    const IntRect& borderBox = box->borderBoxRect();
+    const IntRect& scrollCorner = scrollCornerRect();
+    IntRect absBounds(borderBox.location() + offsetFromLayer, borderBox.size());
     if (m_vBar)
-        m_vBar->setFrameRect(IntRect(absBounds.right() - box->borderRight() - m_vBar->width(),
+        m_vBar->setFrameRect(IntRect(absBounds.maxX() - box->borderRight() - m_vBar->width(),
                                      absBounds.y() + box->borderTop(),
                                      m_vBar->width(),
                                      absBounds.height() - (box->borderTop() + box->borderBottom()) - scrollCorner.height()));
 
     if (m_hBar)
         m_hBar->setFrameRect(IntRect(absBounds.x() + box->borderLeft(),
-                                     absBounds.bottom() - box->borderBottom() - m_hBar->height(),
+                                     absBounds.maxY() - box->borderBottom() - m_hBar->height(),
                                      absBounds.width() - (box->borderLeft() + box->borderRight()) - scrollCorner.width(),
                                      m_hBar->height()));
-    
+
+#if USE(ACCELERATED_COMPOSITING)
+    if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
+        if (m_hBar) {
+            layer->setPosition(m_hBar->frameRect().location() - offsetFromLayer);
+            layer->setSize(m_hBar->frameRect().size());
+        }
+        layer->setDrawsContent(m_hBar);
+    }
+    if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
+        if (m_vBar) {
+            layer->setPosition(m_vBar->frameRect().location() - offsetFromLayer);
+            layer->setSize(m_vBar->frameRect().size());
+        }
+        layer->setDrawsContent(m_vBar);
+    }
+
+    if (GraphicsLayer* layer = layerForScrollCorner()) {
+        const IntRect& scrollCornerAndResizer = scrollCornerAndResizerRect();
+        layer->setPosition(scrollCornerAndResizer.location());
+        layer->setSize(scrollCornerAndResizer.size());
+        layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
+    }
+#endif
+
     if (m_scrollCorner)
         m_scrollCorner->setFrameRect(scrollCorner);
     if (m_resizer)
@@ -1945,14 +2065,14 @@ int RenderLayer::scrollWidth()
 {
     if (m_scrollDimensionsDirty)
         computeScrollDimensions();
-    return m_scrollWidth;
+    return m_scrollSize.width();
 }
 
 int RenderLayer::scrollHeight()
 {
     if (m_scrollDimensionsDirty)
         computeScrollDimensions();
-    return m_scrollHeight;
+    return m_scrollSize.height();
 }
 
 int RenderLayer::overflowTop() const
@@ -1968,7 +2088,7 @@ int RenderLayer::overflowBottom() const
     RenderBox* box = renderBox();
     IntRect overflowRect(box->layoutOverflowRect());
     box->flipForWritingMode(overflowRect);
-    return overflowRect.bottom();
+    return overflowRect.maxY();
 }
 
 int RenderLayer::overflowLeft() const
@@ -1984,7 +2104,7 @@ int RenderLayer::overflowRight() const
     RenderBox* box = renderBox();
     IntRect overflowRect(box->layoutOverflowRect());
     box->flipForWritingMode(overflowRect);
-    return overflowRect.right();
+    return overflowRect.maxX();
 }
 
 void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
@@ -1994,18 +2114,18 @@ void RenderLayer::computeScrollDimensions(bool* needHBar, bool* needVBar)
     
     m_scrollDimensionsDirty = false;
 
-    m_scrollLeftOverflow = overflowLeft() - box->borderLeft();
-    m_scrollTopOverflow = overflowTop() - box->borderTop();
+    m_scrollOverflow.setWidth(overflowLeft() - box->borderLeft());
+    m_scrollOverflow.setHeight(overflowTop() - box->borderTop());
 
-    m_scrollWidth = overflowRight() - overflowLeft();
-    m_scrollHeight = overflowBottom() - overflowTop();
+    m_scrollSize.setWidth(overflowRight() - overflowLeft());
+    m_scrollSize.setHeight(overflowBottom() - overflowTop());
     
-    m_scrollOrigin = IntPoint(-m_scrollLeftOverflow, -m_scrollTopOverflow);
+    m_scrollOrigin = IntPoint(-m_scrollOverflow.width(), -m_scrollOverflow.height());
 
     if (needHBar)
-        *needHBar = m_scrollWidth > box->clientWidth();
+        *needHBar = m_scrollSize.width() > box->clientWidth();
     if (needVBar)
-        *needVBar = m_scrollHeight > box->clientHeight();
+        *needVBar = m_scrollSize.height() > box->clientHeight();
 }
 
 void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOverflow)
@@ -2031,8 +2151,7 @@ void RenderLayer::updateOverflowStatus(bool horizontalOverflow, bool verticalOve
     }
 }
 
-void
-RenderLayer::updateScrollInfoAfterLayout()
+void RenderLayer::updateScrollInfoAfterLayout()
 {
     RenderBox* box = renderBox();
     if (!box)
@@ -2047,18 +2166,15 @@ RenderLayer::updateScrollInfoAfterLayout()
         // Layout may cause us to be in an invalid scroll position.  In this case we need
         // to pull our scroll offsets back to the max (or push them up to the min).
         int newX = max(0, min(scrollXOffset(), scrollWidth() - box->clientWidth()));
-        int newY = max(0, min(m_scrollY, scrollHeight() - box->clientHeight()));
-        if (newX != scrollXOffset() || newY != m_scrollY) {
+        int newY = max(0, min(scrollYOffset(), scrollHeight() - box->clientHeight()));
+        if (newX != scrollXOffset() || newY != scrollYOffset()) {
             RenderView* view = renderer()->view();
             ASSERT(view);
             // scrollToOffset() may call updateLayerPositions(), which doesn't work
             // with LayoutState.
-            // FIXME: Remove the disableLayoutState/enableLayoutState if the above changes.
-            if (view)
-                view->disableLayoutState();
+            // FIXME: Remove the LayoutStateDisabler instantiation if the above changes.
+            LayoutStateDisabler layoutStateDisabler(view);
             scrollToOffset(newX, newY);
-            if (view)
-                view->enableLayoutState();
         }
     }
 
@@ -2123,65 +2239,92 @@ RenderLayer::updateScrollInfoAfterLayout()
         int clientWidth = box->clientWidth();
         int pageStep = max(max<int>(clientWidth * Scrollbar::minFractionToStepWhenPaging(), clientWidth - Scrollbar::maxOverlapBetweenPages()), 1);
         m_hBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
-        m_hBar->setProportion(clientWidth, m_scrollWidth);
-        // Explicitly set the horizontal scroll value.  This ensures that when a
-        // right-to-left scrollable area's width (or content width) changes, the
-        // top right corner of the content doesn't shift with respect to the top
-        // right corner of the area. Conceptually, right-to-left areas have
-        // their origin at the top-right, but RenderLayer is top-left oriented,
-        // so this is needed to keep everything working.
-        m_hBar->setValue(scrollXOffset(), Scrollbar::NotFromScrollAnimator);
+        m_hBar->setProportion(clientWidth, m_scrollSize.width());
     }
     if (m_vBar) {
         int clientHeight = box->clientHeight();
         int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
         m_vBar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
-        m_vBar->setProportion(clientHeight, m_scrollHeight);
-        // Explicitly set the vertical scroll value.  This ensures that when a
-        // right-to-left vertical writing-mode scrollable area's height (or content height) changes, the
-        // bottom right corner of the content doesn't shift with respect to the bottom
-        // right corner of the area. Conceptually, right-to-left vertical writing-mode areas have
-        // their origin at the bottom-right, but RenderLayer is top-left oriented,
-        // so this is needed to keep everything working.
-        m_vBar->setValue(scrollYOffset(), Scrollbar::NotFromScrollAnimator);
+        m_vBar->setProportion(clientHeight, m_scrollSize.height());
     }
  
+    RenderView* view = renderer()->view();
+    {
+        LayoutStateDisabler layoutStateDisabler(view);
+        scrollToOffset(scrollXOffset(), scrollYOffset());
+    }
+
     if (renderer()->node() && renderer()->document()->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
         updateOverflowStatus(horizontalOverflow, verticalOverflow);
 }
 
-void RenderLayer::paintOverflowControls(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
+void RenderLayer::paintOverflowControls(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls)
 {
     // Don't do anything if we have no overflow.
     if (!renderer()->hasOverflowClip())
         return;
-    
+
+    // Overlay scrollbars paint in a second pass through the layer tree so that they will paint
+    // on top of everything else. If this is the normal painting pass, paintingOverlayControls
+    // will be false, and we should just tell the root layer that there are overlay scrollbars
+    // that need to be painted. That will cause the second pass through the layer tree to run,
+    // and we'll paint the scrollbars then. In the meantime, cache tx and ty so that the 
+    // second pass doesn't need to re-enter the RenderTree to get it right.
+    if (hasOverlayScrollbars() && !paintingOverlayControls) {
+        RenderView* renderView = renderer()->view();
+        renderView->layer()->setContainsDirtyOverlayScrollbars(true);
+        m_cachedOverlayScrollbarOffset = paintOffset;
+        renderView->frameView()->setContainsScrollableAreaWithOverlayScrollbars(true);
+        return;
+    }
+
+    // This check is required to avoid painting custom CSS scrollbars twice.
+    if (paintingOverlayControls && !hasOverlayScrollbars())
+        return;
+
+    IntPoint adjustedPaintOffset = paintOffset;
+    if (paintingOverlayControls)
+        adjustedPaintOffset = m_cachedOverlayScrollbarOffset;
+
     // Move the scrollbar widgets if necessary.  We normally move and resize widgets during layout, but sometimes
     // widgets can move without layout occurring (most notably when you scroll a document that
     // contains fixed positioned elements).
-    positionOverflowControls(tx, ty);
+    positionOverflowControls(toSize(adjustedPaintOffset));
 
     // Now that we're sure the scrollbars are in the right place, paint them.
-    if (m_hBar)
+    if (m_hBar
+#if USE(ACCELERATED_COMPOSITING)
+        && !layerForHorizontalScrollbar()
+#endif
+              )
         m_hBar->paint(context, damageRect);
-    if (m_vBar)
+    if (m_vBar
+#if USE(ACCELERATED_COMPOSITING)
+        && !layerForVerticalScrollbar()
+#endif
+              )
         m_vBar->paint(context, damageRect);
 
+#if USE(ACCELERATED_COMPOSITING)
+    if (layerForScrollCorner())
+        return;
+#endif
+
     // We fill our scroll corner with white if we have a scrollbar that doesn't run all the way up to the
     // edge of the box.
-    paintScrollCorner(context, tx, ty, damageRect);
+    paintScrollCorner(context, adjustedPaintOffset, damageRect);
     
     // Paint our resizer last, since it sits on top of the scroll corner.
-    paintResizer(context, tx, ty, damageRect);
+    paintResizer(context, adjustedPaintOffset, damageRect);
 }
 
-void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
+void RenderLayer::paintScrollCorner(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
 {
     RenderBox* box = renderBox();
     ASSERT(box);
 
-    IntRect cornerRect = scrollCornerRect(this, box->borderBoxRect());
-    IntRect absRect = IntRect(cornerRect.x() + tx, cornerRect.y() + ty, cornerRect.width(), cornerRect.height());
+    IntRect absRect = scrollCornerRect();
+    absRect.moveBy(paintOffset);
     if (!absRect.intersects(damageRect))
         return;
 
@@ -2191,14 +2334,17 @@ void RenderLayer::paintScrollCorner(GraphicsContext* context, int tx, int ty, co
     }
 
     if (m_scrollCorner) {
-        m_scrollCorner->paintIntoRect(context, tx, ty, absRect);
+        m_scrollCorner->paintIntoRect(context, paintOffset.x(), paintOffset.y(), absRect);
         return;
     }
-    
-    context->fillRect(absRect, Color::white, box->style()->colorSpace());
+
+    // We don't want to paint white if we have overlay scrollbars, since we need
+    // to see what is behind it.
+    if (!hasOverlayScrollbars())
+        context->fillRect(absRect, Color::white, box->style()->colorSpace());
 }
 
-void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const IntRect& damageRect)
+void RenderLayer::paintResizer(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect)
 {
     if (renderer()->style()->resize() == RESIZE_NONE)
         return;
@@ -2206,8 +2352,8 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
     RenderBox* box = renderBox();
     ASSERT(box);
 
-    IntRect cornerRect = resizerCornerRect(this, box->borderBoxRect());
-    IntRect absRect = IntRect(cornerRect.x() + tx, cornerRect.y() + ty, cornerRect.width(), cornerRect.height());
+    IntRect absRect = resizerCornerRect(this, box->borderBoxRect());
+    absRect.moveBy(paintOffset);
     if (!absRect.intersects(damageRect))
         return;
 
@@ -2217,19 +2363,19 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
     }
     
     if (m_resizer) {
-        m_resizer->paintIntoRect(context, tx, ty, absRect);
+        m_resizer->paintIntoRect(context, paintOffset.x(), paintOffset.y(), absRect);
         return;
     }
 
     // Paint the resizer control.
     DEFINE_STATIC_LOCAL(RefPtr<Image>, resizeCornerImage, (Image::loadPlatformResource("textAreaResizeCorner")));
-    IntPoint imagePoint(absRect.right() - resizeCornerImage->width(), absRect.bottom() - resizeCornerImage->height());
+    IntPoint imagePoint(absRect.maxX() - resizeCornerImage->width(), absRect.maxY() - resizeCornerImage->height());
     context->drawImage(resizeCornerImage.get(), box->style()->colorSpace(), imagePoint);
 
     // Draw a frame around the resizer (1px grey line) if there are any scrollbars present.
     // Clipping will exclude the right and bottom edges of this frame.
-    if (m_hBar || m_vBar) {
-        context->save();
+    if (!hasOverlayScrollbars() && (m_vBar || m_hBar)) {
+        GraphicsContextStateSaver stateSaver(*context);
         context->clip(absRect);
         IntRect largerCorner = absRect;
         largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.height() + 1));
@@ -2237,7 +2383,6 @@ void RenderLayer::paintResizer(GraphicsContext* context, int tx, int ty, const I
         context->setStrokeThickness(1.0f);
         context->setFillColor(Color::transparent, ColorSpaceDeviceRGB);
         context->drawRect(largerCorner);
-        context->restore();
     }
 }
 
@@ -2300,15 +2445,7 @@ bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const IntPoint&
 
 bool RenderLayer::scroll(ScrollDirection direction, ScrollGranularity granularity, float multiplier)
 {
-    bool didHorizontalScroll = false;
-    bool didVerticalScroll = false;
-
-    if (m_hBar)
-        didHorizontalScroll = m_hBar->scroll(direction, granularity, multiplier);
-    if (m_vBar)
-        didVerticalScroll = m_vBar->scroll(direction, granularity, multiplier);
-
-    return (didHorizontalScroll || didVerticalScroll);
+    return ScrollableArea::scroll(direction, granularity, multiplier);
 }
 
 void RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot)
@@ -2320,6 +2457,15 @@ void RenderLayer::paint(GraphicsContext* p, const IntRect& damageRect, PaintBeha
         it->first->setOverlapTestResult(false);
 }
 
+void RenderLayer::paintOverlayScrollbars(GraphicsContext* p, const IntRect& damageRect, PaintBehavior paintBehavior, RenderObject *paintingRoot)
+{
+    if (!m_containsDirtyOverlayScrollbars)
+        return;
+    paintLayer(this, p, damageRect, paintBehavior, paintingRoot, 0, PaintLayerHaveTransparency | PaintLayerTemporaryClipRects 
+               | PaintLayerPaintingOverlayScrollbars);
+    m_containsDirtyOverlayScrollbars = false;
+}
+
 static void setClip(GraphicsContext* p, const IntRect& paintDirtyRect, const IntRect& clipRect)
 {
     if (paintDirtyRect == clipRect)
@@ -2379,7 +2525,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
     // Avoid painting layers when stylesheets haven't loaded.  This eliminates FOUC.
     // It's ok not to draw, because later on, when all the stylesheets do load, updateStyleSelector on the Document
     // will do a full repaint().
-    if (renderer()->document()->mayCauseFlashOfUnstyledContent() && !renderer()->isRenderView() && !renderer()->isRoot())
+    if (renderer()->document()->didLayoutWithPendingStylesheets() && !renderer()->isRenderView() && !renderer()->isRoot())
         return;
     
     // If this layer is totally invisible then there is nothing to paint.
@@ -2397,10 +2543,14 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
             return;
 
         // If we have a transparency layer enclosing us and we are the root of a transform, then we need to establish the transparency
-        // layer from the parent now.
-        if (paintFlags & PaintLayerHaveTransparency)
-            parent()->beginTransparencyLayers(p, rootLayer, paintBehavior);
-  
+        // layer from the parent now, assuming there is a parent
+        if (paintFlags & PaintLayerHaveTransparency) {
+            if (parent())
+                parent()->beginTransparencyLayers(p, rootLayer, paintBehavior);
+            else
+                beginTransparencyLayers(p, rootLayer, paintBehavior);
+        }
+
         // Make sure the parent's clip rects have been calculated.
         IntRect clipRect = paintDirtyRect;
         if (parent()) {
@@ -2413,21 +2563,20 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
 
         // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space.
         // This involves subtracting out the position of the layer in our current coordinate space.
-        int x = 0;
-        int y = 0;
-        convertToLayerCoords(rootLayer, x, y);
+        IntPoint delta;
+        convertToLayerCoords(rootLayer, delta);
         TransformationMatrix transform(layerTransform);
-        transform.translateRight(x, y);
+        transform.translateRight(delta.x(), delta.y());
         
         // Apply the transform.
-        p->save();
-        p->concatCTM(transform.toAffineTransform());
+        {
+            GraphicsContextStateSaver stateSaver(*p);
+            p->concatCTM(transform.toAffineTransform());
 
-        // Now do a paint with the root layer shifted to be us.
-        paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, overlapTestRequests, paintFlags | PaintLayerAppliedTransform);
+            // Now do a paint with the root layer shifted to be us.
+            paintLayer(this, p, transform.inverse().mapRect(paintDirtyRect), paintBehavior, paintingRoot, overlapTestRequests, paintFlags | PaintLayerAppliedTransform);
+        }        
 
-        p->restore();
-        
         // Restore the clip.
         restoreClip(p, paintDirtyRect, clipRect);
         
@@ -2470,9 +2619,11 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
     if (overlapTestRequests && isSelfPaintingLayer())
         performOverlapTests(*overlapTestRequests, rootLayer, this);
 
+    bool paintingOverlayScrollbars = paintFlags & PaintLayerPaintingOverlayScrollbars;
+
     // We want to paint our layer, but only if we intersect the damage rect.
     bool shouldPaint = intersectsDamageRect(layerBounds, damageRect, rootLayer) && m_hasVisibleContent && isSelfPaintingLayer();
-    if (shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
+    if (shouldPaint && !selectionOnly && !damageRect.isEmpty() && !paintingOverlayScrollbars) {
         // Begin transparency layers lazily now that we know we have to paint something.
         if (haveTransparency)
             beginTransparencyLayers(p, rootLayer, paintBehavior);
@@ -2493,7 +2644,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
     paintList(m_negZOrderList, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
 
     // Now establish the appropriate clip and paint our child RenderObjects.
-    if (shouldPaint && !clipRectToApply.isEmpty()) {
+    if (shouldPaint && !clipRectToApply.isEmpty() && !paintingOverlayScrollbars) {
         // Begin transparency layers lazily now that we know we have to paint something.
         if (haveTransparency)
             beginTransparencyLayers(p, rootLayer, paintBehavior);
@@ -2518,7 +2669,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
         restoreClip(p, paintDirtyRect, clipRectToApply);
     }
     
-    if (!outlineRect.isEmpty() && isSelfPaintingLayer()) {
+    if (!outlineRect.isEmpty() && isSelfPaintingLayer() && !paintingOverlayScrollbars) {
         // Paint our own outline
         PaintInfo paintInfo(p, outlineRect, PaintPhaseSelfOutline, false, paintingRootForRenderer, 0);
         setClip(p, paintDirtyRect, outlineRect);
@@ -2532,7 +2683,7 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
     // Now walk the sorted list of children with positive z-indices.
     paintList(m_posZOrderList, rootLayer, p, paintDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, localPaintFlags);
         
-    if (renderer()->hasMask() && shouldPaint && !selectionOnly && !damageRect.isEmpty()) {
+    if (renderer()->hasMask() && shouldPaint && !selectionOnly && !damageRect.isEmpty() && !paintingOverlayScrollbars) {
         setClip(p, paintDirtyRect, damageRect);
 
         // Paint the mask.
@@ -2543,6 +2694,12 @@ void RenderLayer::paintLayer(RenderLayer* rootLayer, GraphicsContext* p,
         restoreClip(p, paintDirtyRect, damageRect);
     }
 
+    if (paintingOverlayScrollbars) {
+        setClip(p, paintDirtyRect, damageRect);
+        paintOverflowControls(p, IntPoint(tx, ty), damageRect, true);
+        restoreClip(p, paintDirtyRect, damageRect);
+    }
+
     // End our transparency layer
     if (haveTransparency && m_usedTransparency && !m_paintingInsideReflection) {
         p->endTransparencyLayer();
@@ -2577,9 +2734,9 @@ void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, RenderLayer*
     Vector<RenderLayer*> columnLayers;
     RenderLayer* ancestorLayer = isNormalFlowOnly() ? parent() : stackingContext();
     for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
-        if (curr->renderer()->hasColumns())
+        if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
             columnLayers.append(curr);
-        if (curr == ancestorLayer || (curr->parent() && curr->parent()->renderer()->isPositioned()))
+        if (curr == ancestorLayer)
             break;
     }
 
@@ -2599,24 +2756,28 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
     if (!columnBlock || !columnBlock->hasColumns())
         return;
     
-    int layerX = 0;
-    int layerY = 0;
-    columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
+    IntPoint layerOffset;
+    columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset);
     
+    bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
+
     ColumnInfo* colInfo = columnBlock->columnInfo();
     unsigned colCount = columnBlock->columnCount(colInfo);
-    int currYOffset = 0;
+    int currLogicalTopOffset = 0;
     for (unsigned i = 0; i < colCount; i++) {
         // For each rect, we clip to the rect, and then we adjust our coords.
         IntRect colRect = columnBlock->columnRectAt(colInfo, i);
-        int currXOffset = colRect.x() - (columnBlock->borderLeft() + columnBlock->paddingLeft());
-        colRect.move(layerX, layerY);
+        columnBlock->flipForWritingMode(colRect);
+        int logicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - columnBlock->logicalLeftOffsetForContent();
+        IntSize offset = isHorizontal ? IntSize(logicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, logicalLeftOffset);
+
+        colRect.moveBy(layerOffset);
 
         IntRect localDirtyRect(paintDirtyRect);
         localDirtyRect.intersect(colRect);
         
         if (!localDirtyRect.isEmpty()) {
-            context->save();
+            GraphicsContextStateSaver stateSaver(*context);
             
             // Each strip pushes a clip, since column boxes are specified as being
             // like overflow:hidden.
@@ -2629,22 +2790,21 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
                 if (oldHasTransform)
                     oldTransform = *childLayer->transform();
                 TransformationMatrix newTransform(oldTransform);
-                newTransform.translateRight(currXOffset, currYOffset);
+                newTransform.translateRight(offset.width(), offset.height());
                 
-                childLayer->m_transform.set(new TransformationMatrix(newTransform));
+                childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
                 childLayer->paintLayer(rootLayer, context, localDirtyRect, paintBehavior, paintingRoot, overlapTestRequests, paintFlags);
                 if (oldHasTransform)
-                    childLayer->m_transform.set(new TransformationMatrix(oldTransform));
+                    childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
                 else
                     childLayer->m_transform.clear();
             } else {
                 // Adjust the transform such that the renderer's upper left corner will paint at (0,0) in user space.
                 // This involves subtracting out the position of the layer in our current coordinate space.
-                int childX = 0;
-                int childY = 0;
-                columnLayers[colIndex - 1]->convertToLayerCoords(rootLayer, childX, childY);
+                IntPoint childOffset;
+                columnLayers[colIndex - 1]->convertToLayerCoords(rootLayer, childOffset);
                 TransformationMatrix transform;
-                transform.translateRight(childX + currXOffset, childY + currYOffset);
+                transform.translateRight(childOffset.x() + offset.width(), childOffset.y() + offset.height());
                 
                 // Apply the transform.
                 context->concatCTM(transform.toAffineTransform());
@@ -2654,12 +2814,14 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, RenderLaye
                                            paintingRoot, overlapTestRequests, paintFlags, 
                                            columnLayers, colIndex - 1);
             }
-
-            context->restore();
         }
 
         // Move to the next position.
-        currYOffset -= colRect.height();
+        int blockDelta = isHorizontal ? colRect.height() : colRect.width();
+        if (columnBlock->style()->isFlippedBlocksWritingMode())
+            currLogicalTopOffset += blockDelta;
+        else
+            currLogicalTopOffset -= blockDelta;
     }
 }
 
@@ -2736,26 +2898,25 @@ PassRefPtr<HitTestingTransformState> RenderLayer::createLocalTransformState(Rend
                                         const HitTestingTransformState* containerTransformState) const
 {
     RefPtr<HitTestingTransformState> transformState;
-    int offsetX = 0;
-    int offsetY = 0;
+    IntPoint offset;
     if (containerTransformState) {
         // If we're already computing transform state, then it's relative to the container (which we know is non-null).
         transformState = HitTestingTransformState::create(*containerTransformState);
-        convertToLayerCoords(containerLayer, offsetX, offsetY);
+        convertToLayerCoords(containerLayer, offset);
     } else {
         // If this is the first time we need to make transform state, then base it off of hitTestPoint,
         // which is relative to rootLayer.
         transformState = HitTestingTransformState::create(hitTestPoint, FloatQuad(hitTestRect));
-        convertToLayerCoords(rootLayer, offsetX, offsetY);
+        convertToLayerCoords(rootLayer, offset);
     }
     
     RenderObject* containerRenderer = containerLayer ? containerLayer->renderer() : 0;
     if (renderer()->shouldUseTransformFromContainer(containerRenderer)) {
         TransformationMatrix containerTransform;
-        renderer()->getTransformFromContainer(containerRenderer, IntSize(offsetX, offsetY), containerTransform);
+        renderer()->getTransformFromContainer(containerRenderer, toSize(offset), containerTransform);
         transformState->applyTransform(containerTransform, HitTestingTransformState::AccumulateTransform);
     } else {
-        transformState->translate(offsetX, offsetY, HitTestingTransformState::AccumulateTransform);
+        transformState->translate(offset.x(), offset.y(), HitTestingTransformState::AccumulateTransform);
     }
     
     return transformState;
@@ -2804,6 +2965,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
 #if USE(ACCELERATED_COMPOSITING)
     useTemporaryClipRects = compositor()->inCompositingMode();
 #endif
+    useTemporaryClipRects |= renderer()->view()->frameView()->containsScrollableAreaWithOverlayScrollbars();
 
     IntRect hitTestArea = result.rectForPoint(hitTestPoint);
 
@@ -2811,7 +2973,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
     if (transform() && !appliedTransform) {
         // Make sure the parent's clip rects have been calculated.
         if (parent()) {
-            IntRect clipRect = backgroundClipRect(rootLayer, useTemporaryClipRects);
+            IntRect clipRect = backgroundClipRect(rootLayer, useTemporaryClipRects, IncludeOverlayScrollbarSize);
             // Go ahead and test the enclosing clip now.
             if (!clipRect.intersects(hitTestArea))
                 return 0;
@@ -2879,7 +3041,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
     IntRect bgRect;
     IntRect fgRect;
     IntRect outlineRect;
-    calculateRects(rootLayer, hitTestRect, layerBounds, bgRect, fgRect, outlineRect, useTemporaryClipRects);
+    calculateRects(rootLayer, hitTestRect, layerBounds, bgRect, fgRect, outlineRect, useTemporaryClipRects, IncludeOverlayScrollbarSize);
     
     // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
     // descendants.
@@ -3043,9 +3205,9 @@ RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, Re
     Vector<RenderLayer*> columnLayers;
     RenderLayer* ancestorLayer = isNormalFlowOnly() ? parent() : stackingContext();
     for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
-        if (curr->renderer()->hasColumns())
+        if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
             columnLayers.append(curr);
-        if (curr == ancestorLayer || (curr->parent() && curr->parent()->renderer()->isPositioned()))
+        if (curr == ancestorLayer)
             break;
     }
 
@@ -3063,30 +3225,43 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
     ASSERT(columnBlock && columnBlock->hasColumns());
     if (!columnBlock || !columnBlock->hasColumns())
         return 0;
-    
-    int layerX = 0;
-    int layerY = 0;
-    columnBlock->layer()->convertToLayerCoords(rootLayer, layerX, layerY);
+
+    IntPoint layerOffset;
+    columnBlock->layer()->convertToLayerCoords(rootLayer, layerOffset);
     
     ColumnInfo* colInfo = columnBlock->columnInfo();
     int colCount = columnBlock->columnCount(colInfo);
     
     // We have to go backwards from the last column to the first.
-    int left = columnBlock->borderLeft() + columnBlock->paddingLeft();
-    int currYOffset = 0;
+    bool isHorizontal = columnBlock->style()->isHorizontalWritingMode();
+    int logicalLeft = columnBlock->logicalLeftOffsetForContent();
+    int currLogicalTopOffset = 0;
     int i;
-    for (i = 0; i < colCount; i++)
-        currYOffset -= columnBlock->columnRectAt(colInfo, i).height();
+    for (i = 0; i < colCount; i++) {
+        IntRect colRect = columnBlock->columnRectAt(colInfo, i);
+        int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
+        if (columnBlock->style()->isFlippedBlocksWritingMode())
+            currLogicalTopOffset += blockDelta;
+        else
+            currLogicalTopOffset -= blockDelta;
+    }
     for (i = colCount - 1; i >= 0; i--) {
         // For each rect, we clip to the rect, and then we adjust our coords.
         IntRect colRect = columnBlock->columnRectAt(colInfo, i);
-        int currXOffset = colRect.x() - left;
-        currYOffset += colRect.height();
-        colRect.move(layerX, layerY);
+        columnBlock->flipForWritingMode(colRect);
+        int currLogicalLeftOffset = (isHorizontal ? colRect.x() : colRect.y()) - logicalLeft;
+        int blockDelta =  (isHorizontal ? colRect.height() : colRect.width());
+        if (columnBlock->style()->isFlippedBlocksWritingMode())
+            currLogicalTopOffset -= blockDelta;
+        else
+            currLogicalTopOffset += blockDelta;
+        colRect.moveBy(layerOffset);
 
         IntRect localClipRect(hitTestRect);
         localClipRect.intersect(colRect);
         
+        IntSize offset = isHorizontal ? IntSize(currLogicalLeftOffset, currLogicalTopOffset) : IntSize(currLogicalTopOffset, currLogicalLeftOffset);
+
         if (!localClipRect.isEmpty() && localClipRect.intersects(result.rectForPoint(hitTestPoint))) {
             RenderLayer* hitLayer = 0;
             if (!columnIndex) {
@@ -3096,12 +3271,12 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
                 if (oldHasTransform)
                     oldTransform = *childLayer->transform();
                 TransformationMatrix newTransform(oldTransform);
-                newTransform.translateRight(currXOffset, currYOffset);
+                newTransform.translateRight(offset.width(), offset.height());
                 
-                childLayer->m_transform.set(new TransformationMatrix(newTransform));
+                childLayer->m_transform = adoptPtr(new TransformationMatrix(newTransform));
                 hitLayer = childLayer->hitTestLayer(rootLayer, columnLayers[0], request, result, localClipRect, hitTestPoint, false, transformState, zOffset);
                 if (oldHasTransform)
-                    childLayer->m_transform.set(new TransformationMatrix(oldTransform));
+                    childLayer->m_transform = adoptPtr(new TransformationMatrix(oldTransform));
                 else
                     childLayer->m_transform.clear();
             } else {
@@ -3109,7 +3284,7 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
                 // This involves subtracting out the position of the layer in our current coordinate space.
                 RenderLayer* nextLayer = columnLayers[columnIndex - 1];
                 RefPtr<HitTestingTransformState> newTransformState = nextLayer->createLocalTransformState(rootLayer, nextLayer, localClipRect, hitTestPoint, transformState);
-                newTransformState->translate(currXOffset, currYOffset, HitTestingTransformState::AccumulateTransform);
+                newTransformState->translate(offset.width(), offset.height(), HitTestingTransformState::AccumulateTransform);
                 IntPoint localPoint = roundedIntPoint(newTransformState->mappedPoint());
                 IntRect localHitTestRect = newTransformState->mappedQuad().enclosingBoundingBox();
                 newTransformState->flatten();
@@ -3126,7 +3301,7 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
     return 0;
 }
 
-void RenderLayer::updateClipRects(const RenderLayer* rootLayer)
+void RenderLayer::updateClipRects(const RenderLayer* rootLayer, OverlayScrollbarSizeRelevancy relevancy)
 {
     if (m_clipRects) {
         ASSERT(rootLayer == m_clipRectsRoot);
@@ -3137,10 +3312,10 @@ void RenderLayer::updateClipRects(const RenderLayer* rootLayer)
     // examine the parent.  We want to cache clip rects with us as the root.
     RenderLayer* parentLayer = rootLayer != this ? parent() : 0;
     if (parentLayer)
-        parentLayer->updateClipRects(rootLayer);
+        parentLayer->updateClipRects(rootLayer, relevancy);
 
     ClipRects clipRects;
-    calculateClipRects(rootLayer, clipRects, true);
+    calculateClipRects(rootLayer, clipRects, true, relevancy);
 
     if (parentLayer && parentLayer->clipRects() && clipRects == *parentLayer->clipRects())
         m_clipRects = parentLayer->clipRects();
@@ -3152,7 +3327,7 @@ void RenderLayer::updateClipRects(const RenderLayer* rootLayer)
 #endif
 }
 
-void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& clipRects, bool useCached) const
+void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& clipRects, bool useCached, OverlayScrollbarSizeRelevancy relevancy) const
 {
     if (!parent()) {
         // The root layer's clip rect is always infinite.
@@ -3189,24 +3364,22 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl
     // Update the clip rects that will be passed to child layers.
     if (renderer()->hasOverflowClip() || renderer()->hasClip()) {
         // This layer establishes a clip of some kind.
-        int x = 0;
-        int y = 0;
-        convertToLayerCoords(rootLayer, x, y);
+        IntPoint offset;
+        convertToLayerCoords(rootLayer, offset);
         RenderView* view = renderer()->view();
         ASSERT(view);
         if (view && clipRects.fixed() && rootLayer->renderer() == view) {
-            x -= view->frameView()->scrollX();
-            y -= view->frameView()->scrollY();
+            offset -= view->frameView()->scrollOffsetForFixedPosition();
         }
         
         if (renderer()->hasOverflowClip()) {
-            IntRect newOverflowClip = toRenderBox(renderer())->overflowClipRect(x, y);
+            IntRect newOverflowClip = toRenderBox(renderer())->overflowClipRect(offset, relevancy);
             clipRects.setOverflowClipRect(intersection(newOverflowClip, clipRects.overflowClipRect()));
             if (renderer()->isPositioned() || renderer()->isRelPositioned())
                 clipRects.setPosClipRect(intersection(newOverflowClip, clipRects.posClipRect()));
         }
         if (renderer()->hasClip()) {
-            IntRect newPosClip = toRenderBox(renderer())->clipRect(x, y);
+            IntRect newPosClip = toRenderBox(renderer())->clipRect(offset);
             clipRects.setPosClipRect(intersection(newPosClip, clipRects.posClipRect()));
             clipRects.setOverflowClipRect(intersection(newPosClip, clipRects.overflowClipRect()));
             clipRects.setFixedClipRect(intersection(newPosClip, clipRects.fixedClipRect()));
@@ -3214,40 +3387,41 @@ void RenderLayer::calculateClipRects(const RenderLayer* rootLayer, ClipRects& cl
     }
 }
 
-void RenderLayer::parentClipRects(const RenderLayer* rootLayer, ClipRects& clipRects, bool temporaryClipRects) const
+void RenderLayer::parentClipRects(const RenderLayer* rootLayer, ClipRects& clipRects, bool temporaryClipRects, OverlayScrollbarSizeRelevancy relevancy) const
 {
     ASSERT(parent());
     if (temporaryClipRects) {
-        parent()->calculateClipRects(rootLayer, clipRects);
+        parent()->calculateClipRects(rootLayer, clipRects, false, relevancy);
         return;
     }
 
-    parent()->updateClipRects(rootLayer);
+    parent()->updateClipRects(rootLayer, relevancy);
     clipRects = *parent()->clipRects();
 }
 
-IntRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, bool temporaryClipRects) const
+IntRect RenderLayer::backgroundClipRect(const RenderLayer* rootLayer, bool temporaryClipRects, OverlayScrollbarSizeRelevancy relevancy) const
 {
     IntRect backgroundRect;
     if (parent()) {
         ClipRects parentRects;
-        parentClipRects(rootLayer, parentRects, temporaryClipRects);
+        parentClipRects(rootLayer, parentRects, temporaryClipRects, relevancy);
         backgroundRect = renderer()->style()->position() == FixedPosition ? parentRects.fixedClipRect() :
                          (renderer()->isPositioned() ? parentRects.posClipRect() : 
                                                        parentRects.overflowClipRect());
         RenderView* view = renderer()->view();
         ASSERT(view);
         if (view && parentRects.fixed() && rootLayer->renderer() == view)
-            backgroundRect.move(view->frameView()->scrollX(), view->frameView()->scrollY());
+            backgroundRect.move(view->frameView()->scrollXForFixedPosition(), view->frameView()->scrollYForFixedPosition());
     }
     return backgroundRect;
 }
 
 void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& paintDirtyRect, IntRect& layerBounds,
-                                 IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect, bool temporaryClipRects) const
+                                 IntRect& backgroundRect, IntRect& foregroundRect, IntRect& outlineRect, bool temporaryClipRects,
+                                 OverlayScrollbarSizeRelevancy relevancy) const
 {
     if (rootLayer != this && parent()) {
-        backgroundRect = backgroundClipRect(rootLayer, temporaryClipRects);
+        backgroundRect = backgroundClipRect(rootLayer, temporaryClipRects, relevancy);
         backgroundRect.intersect(paintDirtyRect);
     } else
         backgroundRect = paintDirtyRect;
@@ -3255,19 +3429,18 @@ void RenderLayer::calculateRects(const RenderLayer* rootLayer, const IntRect& pa
     foregroundRect = backgroundRect;
     outlineRect = backgroundRect;
     
-    int x = 0;
-    int y = 0;
-    convertToLayerCoords(rootLayer, x, y);
-    layerBounds = IntRect(x, y, width(), height());
+    IntPoint offset;
+    convertToLayerCoords(rootLayer, offset);
+    layerBounds = IntRect(offset, size());
     
     // Update the clip rects that will be passed to child layers.
     if (renderer()->hasOverflowClip() || renderer()->hasClip()) {
         // This layer establishes a clip of some kind.
         if (renderer()->hasOverflowClip())
-            foregroundRect.intersect(toRenderBox(renderer())->overflowClipRect(x, y));
+            foregroundRect.intersect(toRenderBox(renderer())->overflowClipRect(offset, relevancy));
         if (renderer()->hasClip()) {
             // Clip applies to *us* as well, so go ahead and update the damageRect.
-            IntRect newPosClip = toRenderBox(renderer())->clipRect(x, y);
+            IntRect newPosClip = toRenderBox(renderer())->clipRect(offset);
             backgroundRect.intersect(newPosClip);
             foregroundRect.intersect(newPosClip);
             outlineRect.intersect(newPosClip);
@@ -3336,9 +3509,9 @@ void RenderLayer::repaintBlockSelectionGaps()
     IntRect rect = m_blockSelectionGapsBounds;
     rect.move(-scrolledContentOffset());
     if (renderer()->hasOverflowClip())
-        rect.intersect(toRenderBox(renderer())->overflowClipRect(0, 0));
+        rect.intersect(toRenderBox(renderer())->overflowClipRect(IntPoint()));
     if (renderer()->hasClip())
-        rect.intersect(toRenderBox(renderer())->clipRect(0, 0));
+        rect.intersect(toRenderBox(renderer())->clipRect(IntPoint()));
     if (!rect.isEmpty())
         renderer()->repaintRectangle(rect);
 }
@@ -3379,19 +3552,9 @@ IntRect RenderLayer::localBoundingBox() const
     // as part of our bounding box.  We do this because we are the responsible layer for both hit testing and painting those
     // floats.
     IntRect result;
-    if (renderer()->isRenderInline()) {
-        // Go from our first line box to our last line box.
-        RenderInline* inlineFlow = toRenderInline(renderer());
-        InlineFlowBox* firstBox = inlineFlow->firstLineBox();
-        if (!firstBox)
-            return result;
-        int top = firstBox->topVisualOverflow();
-        int bottom = inlineFlow->lastLineBox()->bottomVisualOverflow();
-        int left = firstBox->x();
-        for (InlineFlowBox* curr = firstBox->nextLineBox(); curr; curr = curr->nextLineBox())
-            left = min(left, curr->x());
-        result = IntRect(left, top, width(), bottom - top);
-    } else if (renderer()->isTableRow()) {
+    if (renderer()->isRenderInline())
+        result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
+    else if (renderer()->isTableRow()) {
         // Our bounding box is just the union of all of our cells' border/overflow rects.
         for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
             if (child->isTableCell()) {
@@ -3427,10 +3590,13 @@ IntRect RenderLayer::localBoundingBox() const
 IntRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer) const
 {    
     IntRect result = localBoundingBox();
-
-    int deltaX = 0, deltaY = 0;
-    convertToLayerCoords(ancestorLayer, deltaX, deltaY);
-    result.move(deltaX, deltaY);
+    if (renderer()->isBox())
+        renderBox()->flipForWritingMode(result);
+    else
+        renderer()->containingBlock()->flipForWritingMode(result);
+    IntPoint delta;
+    convertToLayerCoords(ancestorLayer, delta);
+    result.moveBy(delta);
     return result;
 }
 
@@ -3465,7 +3631,7 @@ void RenderLayer::clearClipRects()
 RenderLayerBacking* RenderLayer::ensureBacking()
 {
     if (!m_backing)
-        m_backing.set(new RenderLayerBacking(this));
+        m_backing = adoptPtr(new RenderLayerBacking(this));
     return m_backing.get();
 }
 
@@ -3478,8 +3644,33 @@ bool RenderLayer::hasCompositedMask() const
 {
     return m_backing && m_backing->hasMaskLayer();
 }
+
+GraphicsLayer* RenderLayer::layerForHorizontalScrollbar() const
+{
+    return m_backing ? m_backing->layerForHorizontalScrollbar() : 0;
+}
+
+GraphicsLayer* RenderLayer::layerForVerticalScrollbar() const
+{
+    return m_backing ? m_backing->layerForVerticalScrollbar() : 0;
+}
+
+GraphicsLayer* RenderLayer::layerForScrollCorner() const
+{
+    return m_backing ? m_backing->layerForScrollCorner() : 0;
+}
 #endif
 
+bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
+{
+#if USE(ACCELERATED_COMPOSITING)
+    bool paintsToWindow = !isComposited() || backing()->paintingGoesToWindow();
+#else
+    bool paintsToWindow = true;
+#endif    
+    return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || paintsToWindow);
+}
+
 void RenderLayer::setParent(RenderLayer* parent)
 {
     if (parent == m_parent)
@@ -3740,10 +3931,9 @@ void RenderLayer::setBackingNeedsRepaintInRect(const IntRect& r)
         // If we're trying to repaint the placeholder document layer, propagate the
         // repaint to the native view system.
         IntRect absRect(r);
-        int x = 0;
-        int y = 0;
-        convertToLayerCoords(root(), x, y);
-        absRect.move(x, y);
+        IntPoint delta;
+        convertToLayerCoords(root(), delta);
+        absRect.moveBy(delta);
 
         RenderView* view = renderer()->view();
         if (view)
@@ -3792,7 +3982,7 @@ bool RenderLayer::isSelfPaintingLayer() const
         || renderer()->isRenderIFrame();
 }
 
-void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*)
+void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
 {
     bool isNormalFlowOnly = shouldBeNormalFlowOnly();
     if (isNormalFlowOnly != m_isNormalFlowOnly) {
@@ -3821,6 +4011,20 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*)
         updateReflectionStyle();
     }
     
+    if (scrollsOverflow()) {
+        if (!m_scrollableAreaPage) {
+            if (Frame* frame = renderer()->frame()) {
+                if (Page* page = frame->page()) {
+                    m_scrollableAreaPage = page;
+                    m_scrollableAreaPage->addScrollableArea(this);
+                }
+            }
+        }
+    } else if (m_scrollableAreaPage) {
+        m_scrollableAreaPage->removeScrollableArea(this);
+        m_scrollableAreaPage = 0;
+    }
+    
     // FIXME: Need to detect a swap from custom to native scrollbars (and vice versa).
     if (m_hBar)
         m_hBar->styleChanged();
@@ -3837,7 +4041,11 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*)
         compositor()->setCompositingLayersNeedRebuild();
     else if (m_backing)
         m_backing->updateGraphicsLayerGeometry();
-
+    else if (oldStyle && oldStyle->overflowX() != renderer()->style()->overflowX()) {
+        if (stackingContext()->hasCompositingDescendant())
+            compositor()->setCompositingLayersNeedRebuild();
+    }
+    
     if (m_backing && diff >= StyleDifferenceRepaint)
         m_backing->setContentsNeedDisplay();
 #else
@@ -3848,7 +4056,7 @@ void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle*)
 void RenderLayer::updateScrollCornerStyle()
 {
     RenderObject* actualRenderer = renderer()->node() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
-    RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, actualRenderer->style()) : 0;
+    RefPtr<RenderStyle> corner = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(SCROLLBAR_CORNER, actualRenderer->style()) : PassRefPtr<RenderStyle>(0);
     if (corner) {
         if (!m_scrollCorner) {
             m_scrollCorner = new (renderer()->renderArena()) RenderScrollbarPart(renderer()->document());
@@ -3864,7 +4072,7 @@ void RenderLayer::updateScrollCornerStyle()
 void RenderLayer::updateResizerStyle()
 {
     RenderObject* actualRenderer = renderer()->node() ? renderer()->node()->shadowAncestorNode()->renderer() : renderer();
-    RefPtr<RenderStyle> resizer = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(RESIZER, actualRenderer->style()) : 0;
+    RefPtr<RenderStyle> resizer = renderer()->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(RESIZER, actualRenderer->style()) : PassRefPtr<RenderStyle>(0);
     if (resizer) {
         if (!m_resizer) {
             m_resizer = new (renderer()->renderArena()) RenderScrollbarPart(renderer()->document());