Upstream version 11.39.250.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / rendering / RenderLayer.cpp
index 3c589e1..88f2d78 100644 (file)
 #include "config.h"
 #include "core/rendering/RenderLayer.h"
 
-#include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "RuntimeEnabledFeatures.h"
-#include "SVGNames.h"
+#include "core/CSSPropertyNames.h"
+#include "core/HTMLNames.h"
 #include "core/css/PseudoStyleRequest.h"
 #include "core/dom/Document.h"
 #include "core/dom/shadow/ShadowRoot.h"
-#include "core/html/HTMLFrameElement.h"
-#include "core/frame/Frame.h"
+#include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLFrameElement.h"
 #include "core/page/Page.h"
-#include "core/page/Settings.h"
-#include "core/frame/animation/AnimationController.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/platform/graphics/GraphicsContextStateSaver.h"
-#include "core/platform/graphics/filters/ReferenceFilter.h"
-#include "core/platform/graphics/filters/SourceGraphic.h"
-#include "core/platform/graphics/filters/custom/CustomFilterGlobalContext.h"
-#include "core/platform/graphics/filters/custom/CustomFilterOperation.h"
-#include "core/platform/graphics/filters/custom/CustomFilterValidatedProgram.h"
-#include "core/platform/graphics/filters/custom/ValidatedCustomFilterOperation.h"
 #include "core/rendering/ColumnInfo.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/FilterEffectRenderer.h"
 #include "core/rendering/HitTestRequest.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/HitTestingTransformState.h"
-#include "core/rendering/RenderBox.h"
 #include "core/rendering/RenderFlowThread.h"
 #include "core/rendering/RenderGeometryMap.h"
 #include "core/rendering/RenderInline.h"
-#include "core/rendering/RenderLayerCompositor.h"
-#include "core/rendering/RenderLayerStackingNodeIterator.h"
+#include "core/rendering/RenderPart.h"
 #include "core/rendering/RenderReplica.h"
 #include "core/rendering/RenderScrollbar.h"
 #include "core/rendering/RenderScrollbarPart.h"
 #include "core/rendering/RenderTreeAsText.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "core/rendering/svg/ReferenceFilterBuilder.h"
 #include "core/rendering/svg/RenderSVGResourceClipper.h"
 #include "platform/LengthFunctions.h"
 #include "platform/Partitions.h"
+#include "platform/RuntimeEnabledFeatures.h"
 #include "platform/TraceEvent.h"
 #include "platform/geometry/FloatPoint3D.h"
 #include "platform/geometry/FloatRect.h"
+#include "platform/geometry/TransformState.h"
+#include "platform/graphics/GraphicsContextStateSaver.h"
+#include "platform/graphics/filters/ReferenceFilter.h"
+#include "platform/graphics/filters/SourceGraphic.h"
 #include "platform/transforms/ScaleTransformOperation.h"
 #include "platform/transforms/TransformationMatrix.h"
 #include "platform/transforms/TranslateTransformOperation.h"
 #include "public/platform/Platform.h"
 #include "wtf/StdLibExtras.h"
-#include "wtf/UnusedParam.h"
 #include "wtf/text/CString.h"
 
-using namespace std;
+namespace blink {
+
+namespace {
+
+static CompositingQueryMode gCompositingQueryMode =
+    CompositingQueriesAreOnlyAllowedInCertainDocumentLifecyclePhases;
 
-namespace WebCore {
+} // namespace
 
 using namespace HTMLNames;
 
-RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
-    : m_hasSelfPaintingLayerDescendant(false)
+RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type)
+    : m_layerType(type)
+    , m_hasSelfPaintingLayerDescendant(false)
     , m_hasSelfPaintingLayerDescendantDirty(false)
-    , m_hasOutOfFlowPositionedDescendant(false)
-    , m_hasOutOfFlowPositionedDescendantDirty(true)
-    , m_hasUnclippedDescendant(false)
-    , m_isUnclippedDescendant(false)
-    , m_needsCompositedScrolling(false)
     , m_isRootLayer(renderer->isRenderView())
     , m_usedTransparency(false)
-    , m_childLayerHasBlendMode(false)
-    , m_childLayerHasBlendModeStatusDirty(false)
     , m_visibleContentStatusDirty(true)
     , m_hasVisibleContent(false)
     , m_visibleDescendantStatusDirty(false)
@@ -124,9 +117,14 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
     , m_3DTransformedDescendantStatusDirty(true)
     , m_has3DTransformedDescendant(false)
     , m_containsDirtyOverlayScrollbars(false)
-    , m_canSkipRepaintRectsUpdateOnScroll(renderer->isTableCell())
     , m_hasFilterInfo(false)
-    , m_blendMode(BlendModeNormal)
+    , m_needsAncestorDependentCompositingInputsUpdate(true)
+    , m_needsDescendantDependentCompositingInputsUpdate(true)
+    , m_childNeedsCompositingInputsUpdate(true)
+    , m_hasCompositingDescendant(false)
+    , m_hasNonCompositedChild(false)
+    , m_shouldIsolateCompositedDescendants(false)
+    , m_lostGroupedMapping(false)
     , m_renderer(renderer)
     , m_parent(0)
     , m_previous(0)
@@ -136,15 +134,16 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
     , m_staticInlinePosition(0)
     , m_staticBlockPosition(0)
     , m_enclosingPaginationLayer(0)
-    , m_forceNeedsCompositedScrolling(DoNotForceCompositedScrolling)
-    , m_repainter(renderer)
-    , m_clipper(renderer)
+    , m_potentialCompositingReasonsFromStyle(CompositingReasonNone)
+    , m_compositingReasons(CompositingReasonNone)
+    , m_groupedMapping(0)
+    , m_clipper(*renderer)
 {
     updateStackingNode();
 
     m_isSelfPaintingLayer = shouldBeSelfPaintingLayer();
 
-    if (!renderer->firstChild() && renderer->style()) {
+    if (!renderer->slowFirstChild() && renderer->style()) {
         m_visibleContentStatusDirty = false;
         m_hasVisibleContent = renderer->style()->visibility() == VISIBLE;
     }
@@ -154,9 +153,6 @@ RenderLayer::RenderLayer(RenderLayerModelObject* renderer)
 
 RenderLayer::~RenderLayer()
 {
-    if (!m_renderer->documentBeingDestroyed())
-        compositor()->removeOutOfFlowPositionedLayer(this);
-
     if (renderer()->frame() && renderer()->frame()->page()) {
         if (ScrollingCoordinator* scrollingCoordinator = renderer()->frame()->page()->scrollingCoordinator())
             scrollingCoordinator->willDestroyRenderLayer(this);
@@ -164,16 +160,26 @@ RenderLayer::~RenderLayer()
 
     removeFilterInfoIfNeeded();
 
+    if (groupedMapping()) {
+        DisableCompositingQueryAsserts disabler;
+        groupedMapping()->removeRenderLayerFromSquashingGraphicsLayer(this);
+        setGroupedMapping(0);
+    }
+
     // Child layers will be deleted by their corresponding render objects, so
     // we don't need to delete them ourselves.
 
     clearCompositedLayerMapping(true);
+
+    if (m_reflectionInfo)
+        m_reflectionInfo->destroy();
 }
 
 String RenderLayer::debugName() const
 {
-    if (isReflection())
-        return m_reflectionInfo->debugName();
+    if (isReflection()) {
+        return renderer()->parent()->debugName() + " (reflection)";
+    }
     return renderer()->debugName();
 }
 
@@ -186,147 +192,92 @@ RenderLayerCompositor* RenderLayer::compositor() const
 
 void RenderLayer::contentChanged(ContentChangeType changeType)
 {
-    // This can get called when video becomes accelerated, so the layers may change.
-    if ((changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged) && compositor()->updateLayerCompositingState(this))
-        compositor()->setCompositingLayersNeedRebuild();
+    // updateLayerCompositingState will query compositingReasons for accelerated overflow scrolling.
+    // This is tripped by LayoutTests/compositing/content-changed-chicken-egg.html
+    DisableCompositingQueryAsserts disabler;
+
+    if (changeType == CanvasChanged)
+        compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
+
+    if (changeType == CanvasContextChanged) {
+        compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
+
+        // Although we're missing test coverage, we need to call
+        // GraphicsLayer::setContentsToPlatformLayer with the new platform
+        // layer for this canvas.
+        // See http://crbug.com/349195
+        if (hasCompositedLayerMapping())
+            compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+    }
 
     if (m_compositedLayerMapping)
         m_compositedLayerMapping->contentChanged(changeType);
 }
 
-bool RenderLayer::canRender3DTransforms() const
-{
-    return compositor()->canRender3DTransforms();
-}
-
 bool RenderLayer::paintsWithFilters() const
 {
     if (!renderer()->hasFilter())
         return false;
 
-    if (compositingState() != PaintsIntoOwnBacking)
-        return true;
-
-    if (!m_compositedLayerMapping || !m_compositedLayerMapping->canCompositeFilters())
-        return true;
-
-    return false;
+    // https://code.google.com/p/chromium/issues/detail?id=343759
+    DisableCompositingQueryAsserts disabler;
+    return !m_compositedLayerMapping || compositingState() != PaintsIntoOwnBacking;
 }
 
-bool RenderLayer::requiresFullLayerImageForFilters() const
+LayoutSize RenderLayer::subpixelAccumulation() const
 {
-    if (!paintsWithFilters())
-        return false;
-    FilterEffectRenderer* filter = filterRenderer();
-    return filter ? filter->hasFilterThatMovesPixels() : false;
+    return m_subpixelAccumulation;
 }
 
-LayoutPoint RenderLayer::computeOffsetFromRoot(bool& hasLayerOffset) const
+void RenderLayer::setSubpixelAccumulation(const LayoutSize& size)
 {
-    hasLayerOffset = true;
-
-    if (!parent())
-        return LayoutPoint();
-
-    // This is similar to root() but we check if an ancestor layer would
-    // prevent the optimization from working.
-    const RenderLayer* rootLayer = 0;
-    for (const RenderLayer* parentLayer = parent(); parentLayer; rootLayer = parentLayer, parentLayer = parentLayer->parent()) {
-        hasLayerOffset = parentLayer->canUseConvertToLayerCoords();
-        if (!hasLayerOffset)
-            return LayoutPoint();
-    }
-    ASSERT(rootLayer == root());
-
-    LayoutPoint offset;
-    parent()->convertToLayerCoords(rootLayer, offset);
-    return offset;
+    m_subpixelAccumulation = size;
 }
 
-void RenderLayer::updateLayerPositionsAfterLayout(const RenderLayer* rootLayer, UpdateLayerPositionsFlags flags)
+void RenderLayer::updateLayerPositionsAfterLayout()
 {
-    RenderGeometryMap geometryMap(UseTransforms);
-    if (this != rootLayer)
-        geometryMap.pushMappingsToAncestor(parent(), 0);
-    updateLayerPositions(&geometryMap, flags);
-}
+    TRACE_EVENT0("blink", "RenderLayer::updateLayerPositionsAfterLayout");
 
-void RenderLayer::updateLayerPositions(RenderGeometryMap* geometryMap, UpdateLayerPositionsFlags flags)
-{
-    updateLayerPosition(); // For relpositioned layers or non-positioned layers,
-                           // we need to keep in sync, since we may have shifted relative
-                           // to our parent layer.
-    if (geometryMap)
-        geometryMap->pushMappingsToAncestor(this, parent());
-
-    // Clear our cached clip rect information.
-    m_clipper.clearClipRects();
+    m_clipper.clearClipRectsIncludingDescendants();
+    updateLayerPositionRecursive();
 
-    if (hasOverflowControls()) {
-        LayoutPoint offsetFromRoot;
-        if (geometryMap)
-            offsetFromRoot = LayoutPoint(geometryMap->absolutePoint(FloatPoint()));
-        else {
-            // FIXME: It looks suspicious to call convertToLayerCoords here
-            // as canUseConvertToLayerCoords may be true for an ancestor layer.
-            convertToLayerCoords(root(), offsetFromRoot);
-        }
-        scrollableArea()->positionOverflowControls(toIntSize(roundedIntPoint(offsetFromRoot)));
+    {
+        // FIXME: Remove incremental compositing updates after fixing the chicken/egg issues
+        // https://code.google.com/p/chromium/issues/detail?id=343756
+        DisableCompositingQueryAsserts disabler;
+        bool needsPaginationUpdate = isPaginated() || enclosingPaginationLayer();
+        updatePaginationRecursive(needsPaginationUpdate);
     }
+}
 
-    updateDescendantDependentFlags();
-
-    if (flags & UpdatePagination)
-        updatePagination();
-    else {
-        m_isPaginated = false;
-        m_enclosingPaginationLayer = 0;
-    }
-
-    repainter().repaintAfterLayout(geometryMap, flags & CheckForRepaint);
-
-    // Go ahead and update the reflection's position and size.
+void RenderLayer::updateLayerPositionRecursive()
+{
     if (m_reflectionInfo)
         m_reflectionInfo->reflection()->layout();
 
-    // Clear the IsCompositingUpdateRoot flag once we've found the first compositing layer in this update.
-    bool isUpdateRoot = (flags & IsCompositingUpdateRoot);
-    if (compositedLayerMapping())
-        flags &= ~IsCompositingUpdateRoot;
-
-    if (useRegionBasedColumns() && renderer()->isInFlowRenderFlowThread()) {
-        updatePagination();
-        flags |= UpdatePagination;
-    }
-
-    if (renderer()->hasColumns())
-        flags |= UpdatePagination;
+    // FIXME: We should be able to remove this call because we don't care about
+    // any descendant-dependent flags, but code somewhere else is reading these
+    // flags and depending on us to update them.
+    updateDescendantDependentFlags();
 
     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
-        child->updateLayerPositions(geometryMap, flags);
-
-    if ((flags & UpdateCompositingLayers) && compositedLayerMapping()) {
-        CompositedLayerMapping::UpdateAfterLayoutFlags updateFlags = CompositedLayerMapping::CompositingChildrenOnly;
-        if (flags & NeedsFullRepaintInBacking)
-            updateFlags |= CompositedLayerMapping::NeedsFullRepaint;
-        if (isUpdateRoot)
-            updateFlags |= CompositedLayerMapping::IsUpdateRoot;
-        compositedLayerMapping()->updateAfterLayout(updateFlags);
-    }
-
-    if (geometryMap)
-        geometryMap->popMappingsToAncestor(parent());
+        child->updateLayerPositionRecursive();
 }
 
-void RenderLayer::setAncestorChainHasSelfPaintingLayerDescendant()
+void RenderLayer::updateHasSelfPaintingLayerDescendant() const
 {
-    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
-        if (!layer->m_hasSelfPaintingLayerDescendantDirty && layer->hasSelfPaintingLayerDescendant())
-            break;
+    ASSERT(m_hasSelfPaintingLayerDescendantDirty);
 
-        layer->m_hasSelfPaintingLayerDescendantDirty = false;
-        layer->m_hasSelfPaintingLayerDescendant = true;
+    m_hasSelfPaintingLayerDescendant = false;
+
+    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
+        if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant()) {
+            m_hasSelfPaintingLayerDescendant = true;
+            break;
+        }
     }
+
+    m_hasSelfPaintingLayerDescendantDirty = false;
 }
 
 void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
@@ -336,217 +287,43 @@ void RenderLayer::dirtyAncestorChainHasSelfPaintingLayerDescendantStatus()
         // If we have reached a self-painting layer, we know our parent should have a self-painting descendant
         // in this case, there is no need to dirty our ancestors further.
         if (layer->isSelfPaintingLayer()) {
-            ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->hasSelfPaintingLayerDescendant());
-            break;
-        }
-    }
-}
-
-void RenderLayer::setAncestorChainHasOutOfFlowPositionedDescendant()
-{
-    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
-        if (!layer->m_hasOutOfFlowPositionedDescendantDirty && layer->hasOutOfFlowPositionedDescendant())
-            break;
-
-        layer->setHasOutOfFlowPositionedDescendantDirty(false);
-        layer->setHasOutOfFlowPositionedDescendant(true);
-    }
-}
-
-void RenderLayer::dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus()
-{
-    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
-        layer->setHasOutOfFlowPositionedDescendantDirty(true);
-
-        // We may or may not have an unclipped descendant. If we do, we'll reset
-        // this to true the next time composited scrolling state is updated.
-        layer->setHasUnclippedDescendant(false);
-
-        // If we have reached an out of flow positioned layer, we know our parent should have an out-of-flow positioned descendant.
-        // In this case, there is no need to dirty our ancestors further.
-        if (layer->renderer()->isOutOfFlowPositioned()) {
-            ASSERT(!parent() || parent()->m_hasOutOfFlowPositionedDescendantDirty || parent()->hasOutOfFlowPositionedDescendant());
+            ASSERT(!parent() || parent()->m_hasSelfPaintingLayerDescendantDirty || parent()->m_hasSelfPaintingLayerDescendant);
             break;
         }
     }
 }
 
-bool RenderLayer::acceleratedCompositingForOverflowScrollEnabled() const
-{
-    const Settings* settings = renderer()->document().settings();
-    return settings && settings->acceleratedCompositingForOverflowScrollEnabled();
-}
-
-// FIXME: This is a temporary flag and should be removed once accelerated
-// overflow scroll is ready (crbug.com/254111).
-bool RenderLayer::compositorDrivenAcceleratedScrollingEnabled() const
+bool RenderLayer::scrollsWithViewport() const
 {
-    if (!acceleratedCompositingForOverflowScrollEnabled())
-        return false;
-
-    const Settings* settings = renderer()->document().settings();
-    return settings && settings->isCompositorDrivenAcceleratedScrollingEnabled();
+    return renderer()->style()->position() == FixedPosition && renderer()->containerForFixedPosition() == renderer()->view();
 }
 
 bool RenderLayer::scrollsWithRespectTo(const RenderLayer* other) const
 {
-    const EPosition position = renderer()->style()->position();
-    const EPosition otherPosition = other->renderer()->style()->position();
-    const RenderObject* containingBlock = renderer()->containingBlock();
-    const RenderObject* otherContainingBlock = other->renderer()->containingBlock();
-    const RenderLayer* rootLayer = renderer()->view()->compositor()->rootRenderLayer();
-
-    // Fixed-position elements are a special case. They are static with respect
-    // to the viewport, which is not represented by any RenderObject, and their
-    // containingBlock() method returns the root HTML element (while its true
-    // containingBlock should really be the viewport). The real measure for a
-    // non-transformed fixed-position element is as follows: any fixed position
-    // element, A, scrolls with respect an element, B, if and only if B is not
-    // fixed position.
-    //
-    // Unfortunately, it gets a bit more complicated - a fixed-position element
-    // which has a transform acts exactly as an absolute-position element
-    // (including having a real, non-viewport containing block).
-    //
-    // Below, a "root" fixed position element is defined to be one whose
-    // containing block is the root. These root-fixed-position elements are
-    // the only ones that need this special case code - other fixed position
-    // elements, as well as all absolute, relative, and static elements use the
-    // logic below.
-    const bool isRootFixedPos = position == FixedPosition && containingBlock->enclosingLayer() == rootLayer;
-    const bool otherIsRootFixedPos = otherPosition == FixedPosition && otherContainingBlock->enclosingLayer() == rootLayer;
-
-    if (isRootFixedPos && otherIsRootFixedPos)
-        return false;
-    if (isRootFixedPos || otherIsRootFixedPos)
+    if (scrollsWithViewport() != other->scrollsWithViewport())
         return true;
-
-    if (containingBlock == otherContainingBlock)
-        return false;
-
-    // Maintain a set of containing blocks between the first layer and its
-    // closest scrollable ancestor.
-    HashSet<const RenderObject*> containingBlocks;
-    while (containingBlock) {
-        if (containingBlock->enclosingLayer()->scrollsOverflow())
-            break;
-        containingBlocks.add(containingBlock);
-        containingBlock = containingBlock->containingBlock();
-    }
-
-    // Do the same for the 2nd layer, but if we find a common containing block,
-    // it means both layers are contained within a single non-scrolling subtree.
-    // Hence, they will not scroll with respect to each other.
-    while (otherContainingBlock) {
-        if (containingBlocks.contains(otherContainingBlock))
-            return false;
-        if (otherContainingBlock->enclosingLayer()->scrollsOverflow())
-            break;
-        otherContainingBlock = otherContainingBlock->containingBlock();
-    }
-
-    return true;
-}
-
-void RenderLayer::updateLayerPositionsAfterDocumentScroll()
-{
-    ASSERT(this == renderer()->view()->layer());
-
-    RenderGeometryMap geometryMap(UseTransforms);
-    updateLayerPositionsAfterScroll(&geometryMap);
+    return ancestorScrollingLayer() != other->ancestorScrollingLayer();
 }
 
-void RenderLayer::updateLayerPositionsAfterOverflowScroll()
+void RenderLayer::updateTransformationMatrix()
 {
-    RenderGeometryMap geometryMap(UseTransforms);
-    RenderView* view = renderer()->view();
-    if (this != view->layer())
-        geometryMap.pushMappingsToAncestor(parent(), 0);
-
-    // FIXME: why is it OK to not check the ancestors of this layer in order to
-    // initialize the HasSeenViewportConstrainedAncestor and HasSeenAncestorWithOverflowClip flags?
-    updateLayerPositionsAfterScroll(&geometryMap, IsOverflowScroll);
-}
-
-void RenderLayer::updateLayerPositionsAfterScroll(RenderGeometryMap* geometryMap, UpdateLayerPositionsAfterScrollFlags flags)
-{
-    // FIXME: This shouldn't be needed, but there are some corner cases where
-    // these flags are still dirty. Update so that the check below is valid.
-    updateDescendantDependentFlags();
-
-    // If we have no visible content and no visible descendants, there is no point recomputing
-    // our rectangles as they will be empty. If our visibility changes, we are expected to
-    // recompute all our positions anyway.
-    if (subtreeIsInvisible())
-        return;
-
-    bool positionChanged = updateLayerPosition();
-    if (positionChanged)
-        flags |= HasChangedAncestor;
-
-    if (geometryMap)
-        geometryMap->pushMappingsToAncestor(this, parent());
-
-    if (flags & HasChangedAncestor || flags & HasSeenViewportConstrainedAncestor || flags & IsOverflowScroll)
-        m_clipper.clearClipRects();
-
-    if (renderer()->style()->hasViewportConstrainedPosition())
-        flags |= HasSeenViewportConstrainedAncestor;
-
-    if (renderer()->hasOverflowClip())
-        flags |= HasSeenAncestorWithOverflowClip;
-
-    if (flags & HasSeenViewportConstrainedAncestor
-        || (flags & IsOverflowScroll && flags & HasSeenAncestorWithOverflowClip && !m_canSkipRepaintRectsUpdateOnScroll)) {
-        // FIXME: We could track the repaint container as we walk down the tree.
-        repainter().computeRepaintRects(renderer()->containerForRepaint(), geometryMap);
-    } else {
-        // Check that RenderLayerRepainter's cached rects are correct.
-        // FIXME: re-enable these assertions when the issue with table cells is resolved: https://bugs.webkit.org/show_bug.cgi?id=103432
-        // ASSERT(repainter().m_repaintRect == renderer()->clippedOverflowRectForRepaint(renderer()->containerForRepaint()));
-        // ASSERT(repainter().m_outlineBox == renderer()->outlineBoundsForRepaint(renderer()->containerForRepaint(), geometryMap));
+    if (m_transform) {
+        RenderBox* box = renderBox();
+        ASSERT(box);
+        m_transform->makeIdentity();
+        box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
+        makeMatrixRenderable(*m_transform, compositor()->hasAcceleratedCompositing());
     }
-
-    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
-        child->updateLayerPositionsAfterScroll(geometryMap, flags);
-
-    // We don't update our reflection as scrolling is a translation which does not change the size()
-    // of an object, thus RenderReplica will still repaint itself properly as the layer position was
-    // updated above.
-
-    if (geometryMap)
-        geometryMap->popMappingsToAncestor(parent());
 }
 
-bool RenderLayer::hasBlendMode() const
+void RenderLayer::updateTransform(const RenderStyle* oldStyle, RenderStyle* newStyle)
 {
-    return RuntimeEnabledFeatures::cssCompositingEnabled() && renderer()->hasBlendMode();
-}
-
-void RenderLayer::updateBlendMode()
-{
-    if (!RuntimeEnabledFeatures::cssCompositingEnabled())
+    if (oldStyle && newStyle->transformDataEquivalent(*oldStyle))
         return;
 
-    bool hadBlendMode = m_blendMode != BlendModeNormal;
-    BlendMode newBlendMode = renderer()->style()->blendMode();
-    if (newBlendMode != m_blendMode) {
-        m_blendMode = newBlendMode;
-
-        // Only update the flag if a blend mode is set or unset.
-        if (!hadBlendMode || !hasBlendMode())
-            dirtyAncestorChainBlendedDescendantStatus();
-
-        if (compositedLayerMapping())
-            compositedLayerMapping()->setBlendMode(newBlendMode);
-    }
-}
-
-void RenderLayer::updateTransform()
-{
     // hasTransform() on the renderer is also true when there is transform-style: preserve-3d or perspective set,
     // so check style too.
-    bool hasTransform = renderer()->hasTransform() && renderer()->style()->hasTransform();
+    bool hasTransform = renderer()->hasTransform() && newStyle->hasTransform();
     bool had3DTransform = has3DTransform();
 
     bool hadTransform = m_transform;
@@ -558,39 +335,47 @@ void RenderLayer::updateTransform()
 
         // Layers with transforms act as clip rects roots, so clear the cached clip rects here.
         m_clipper.clearClipRectsIncludingDescendants();
+    } else if (hasTransform) {
+        m_clipper.clearClipRectsIncludingDescendants(AbsoluteClipRects);
     }
 
-    if (hasTransform) {
-        RenderBox* box = renderBox();
-        ASSERT(box);
-        m_transform->makeIdentity();
-        box->style()->applyTransform(*m_transform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::IncludeTransformOrigin);
-        makeMatrixRenderable(*m_transform, canRender3DTransforms());
-    }
+    updateTransformationMatrix();
 
     if (had3DTransform != has3DTransform())
         dirty3DTransformedDescendantStatus();
 }
 
+static RenderLayer* enclosingLayerForContainingBlock(RenderLayer* layer)
+{
+    if (RenderObject* containingBlock = layer->renderer()->containingBlock())
+        return containingBlock->enclosingLayer();
+    return 0;
+}
+
+RenderLayer* RenderLayer::renderingContextRoot()
+{
+    RenderLayer* renderingContext = 0;
+
+    if (shouldPreserve3D())
+        renderingContext = this;
+
+    for (RenderLayer* current = enclosingLayerForContainingBlock(this); current && current->shouldPreserve3D(); current = enclosingLayerForContainingBlock(current))
+        renderingContext = current;
+
+    return renderingContext;
+}
+
 TransformationMatrix RenderLayer::currentTransform(RenderStyle::ApplyTransformOrigin applyOrigin) const
 {
     if (!m_transform)
         return TransformationMatrix();
 
-    if (renderer()->style()->isRunningAcceleratedAnimation()) {
-        TransformationMatrix currTransform;
-        RefPtr<RenderStyle> style = renderer()->animation().getAnimatedStyleForRenderer(renderer());
-        style->applyTransform(currTransform, renderBox()->pixelSnappedBorderBoxRect().size(), applyOrigin);
-        makeMatrixRenderable(currTransform, canRender3DTransforms());
-        return currTransform;
-    }
-
     // m_transform includes transform-origin, so we need to recompute the transform here.
     if (applyOrigin == RenderStyle::ExcludeTransformOrigin) {
         RenderBox* box = renderBox();
         TransformationMatrix currTransform;
         box->style()->applyTransform(currTransform, box->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
-        makeMatrixRenderable(currTransform, canRender3DTransforms());
+        makeMatrixRenderable(currTransform, compositor()->hasAcceleratedCompositing());
         return currTransform;
     }
 
@@ -611,6 +396,18 @@ TransformationMatrix RenderLayer::renderableTransform(PaintBehavior paintBehavio
     return *m_transform;
 }
 
+RenderLayer* RenderLayer::enclosingOverflowClipLayer(IncludeSelfOrNot includeSelf) const
+{
+    const RenderLayer* layer = (includeSelf == IncludeSelf) ? this : parent();
+    while (layer) {
+        if (layer->renderer()->hasOverflowClip())
+            return const_cast<RenderLayer*>(layer);
+
+        layer = layer->parent();
+    }
+    return 0;
+}
+
 static bool checkContainingBlockChainForPagination(RenderLayerModelObject* renderer, RenderBox* ancestorColumnsRenderer)
 {
     RenderView* view = renderer->view();
@@ -635,16 +432,30 @@ static bool checkContainingBlockChainForPagination(RenderLayerModelObject* rende
 
 bool RenderLayer::useRegionBasedColumns() const
 {
-    const Settings* settings = renderer()->document().settings();
-    return settings && settings->regionBasedColumnsEnabled();
+    return renderer()->document().regionBasedColumnsEnabled();
 }
 
-void RenderLayer::updatePagination()
+void RenderLayer::updatePaginationRecursive(bool needsPaginationUpdate)
 {
     m_isPaginated = false;
     m_enclosingPaginationLayer = 0;
 
-    if (compositedLayerMapping() || !parent())
+    if (useRegionBasedColumns() && renderer()->isRenderFlowThread())
+        needsPaginationUpdate = true;
+
+    if (needsPaginationUpdate)
+        updatePagination();
+
+    if (renderer()->hasColumns())
+        needsPaginationUpdate = true;
+
+    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+        child->updatePaginationRecursive(needsPaginationUpdate);
+}
+
+void RenderLayer::updatePagination()
+{
+    if (compositingState() != NotComposited || !parent())
         return; // FIXME: We will have to deal with paginated compositing layers someday.
                 // FIXME: For now the RenderView can't be paginated.  Eventually printing will move to a model where it is though.
 
@@ -656,7 +467,7 @@ void RenderLayer::updatePagination()
     // layers). We track an enclosingPaginationLayer instead of using a simple bit, since we want to be able to get back
     // to that layer easily.
     bool regionBasedColumnsUsed = useRegionBasedColumns();
-    if (regionBasedColumnsUsed && renderer()->isInFlowRenderFlowThread()) {
+    if (regionBasedColumnsUsed && renderer()->isRenderFlowThread()) {
         m_enclosingPaginationLayer = this;
         return;
     }
@@ -669,8 +480,9 @@ void RenderLayer::updatePagination()
             m_enclosingPaginationLayer = parent()->enclosingPaginationLayer();
             if (m_enclosingPaginationLayer && m_enclosingPaginationLayer->hasTransform())
                 m_enclosingPaginationLayer = 0;
-        } else
+        } else {
             m_isPaginated = parent()->renderer()->hasColumns();
+        }
         return;
     }
 
@@ -696,198 +508,189 @@ void RenderLayer::updatePagination()
     }
 
     // If we're not normal flow, then we need to look for a multi-column object between us and our stacking container.
-    RenderLayerStackingNode* ancestorStackingContainerNode = m_stackingNode->ancestorStackingContainerNode();
+    RenderLayerStackingNode* ancestorStackingContextNode = m_stackingNode->ancestorStackingContextNode();
     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
         if (curr->renderer()->hasColumns()) {
             m_isPaginated = checkContainingBlockChainForPagination(renderer(), curr->renderBox());
             return;
         }
-        if (curr->stackingNode() == ancestorStackingContainerNode)
+        if (curr->stackingNode() == ancestorStackingContextNode)
             return;
     }
 }
 
-void RenderLayer::setHasVisibleContent()
+LayoutPoint RenderLayer::positionFromPaintInvalidationBacking(const RenderObject* renderObject, const RenderLayerModelObject* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState)
 {
-    if (m_hasVisibleContent && !m_visibleContentStatusDirty) {
-        ASSERT(!parent() || parent()->hasVisibleDescendant());
-        return;
-    }
+    FloatPoint point = renderObject->localToContainerPoint(FloatPoint(), paintInvalidationContainer, 0, 0, paintInvalidationState);
 
-    m_visibleContentStatusDirty = false;
-    m_hasVisibleContent = true;
-    repainter().computeRepaintRects(renderer()->containerForRepaint());
-    if (!m_stackingNode->isNormalFlowOnly()) {
-        // We don't collect invisible layers in z-order lists if we are not in compositing mode.
-        // As we became visible, we need to dirty our stacking containers ancestors to be properly
-        // collected. FIXME: When compositing, we could skip this dirtying phase.
-        for (RenderLayerStackingNode* sc = m_stackingNode->ancestorStackingContainerNode(); sc; sc = sc->ancestorStackingContainerNode()) {
-            sc->dirtyZOrderLists();
-            if (sc->layer()->hasVisibleContent())
-                break;
-        }
-    }
+    // FIXME: Eventually we are going to unify coordinates in GraphicsLayer space.
+    if (paintInvalidationContainer && paintInvalidationContainer->layer()->groupedMapping())
+        mapPointToPaintBackingCoordinates(paintInvalidationContainer, point);
 
-    if (parent())
-        parent()->setAncestorChainHasVisibleDescendant();
+    return LayoutPoint(point);
 }
 
-void RenderLayer::dirtyVisibleContentStatus()
+void RenderLayer::mapPointToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, FloatPoint& point)
 {
-    m_visibleContentStatusDirty = true;
-    if (parent())
-        parent()->dirtyAncestorChainVisibleDescendantStatus();
-}
+    RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer();
+    if (!paintInvalidationLayer->groupedMapping()) {
+        point.move(paintInvalidationLayer->compositedLayerMapping()->contentOffsetInCompositingLayer());
+        return;
+    }
 
-void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
-{
-    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
-        if (layer->m_visibleDescendantStatusDirty)
-            break;
+    RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclosingTransformedAncestor()->renderer();
+    if (!transformedAncestor)
+        return;
 
-        layer->m_visibleDescendantStatusDirty = true;
-    }
+    // |paintInvalidationContainer| may have a local 2D transform on it, so take that into account when mapping into the space of the
+    // transformed ancestor.
+    point = paintInvalidationContainer->localToContainerPoint(point, transformedAncestor);
+
+    point.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTransformedAncestor());
 }
 
-void RenderLayer::setAncestorChainHasVisibleDescendant()
+void RenderLayer::mapRectToPaintBackingCoordinates(const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect)
 {
-    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
-        if (!layer->m_visibleDescendantStatusDirty && layer->hasVisibleDescendant())
-            break;
-
-        layer->m_hasVisibleDescendant = true;
-        layer->m_visibleDescendantStatusDirty = false;
+    RenderLayer* paintInvalidationLayer = paintInvalidationContainer->layer();
+    if (!paintInvalidationLayer->groupedMapping()) {
+        rect.move(paintInvalidationLayer->compositedLayerMapping()->contentOffsetInCompositingLayer());
+        return;
     }
+
+    RenderLayerModelObject* transformedAncestor = paintInvalidationLayer->enclosingTransformedAncestor()->renderer();
+    if (!transformedAncestor)
+        return;
+
+    // |paintInvalidationContainer| may have a local 2D transform on it, so take that into account when mapping into the space of the
+    // transformed ancestor.
+    rect = LayoutRect(paintInvalidationContainer->localToContainerQuad(FloatRect(rect), transformedAncestor).boundingBox());
+
+    rect.moveBy(-paintInvalidationLayer->groupedMapping()->squashingOffsetFromTransformedAncestor());
 }
 
-void RenderLayer::dirtyAncestorChainBlendedDescendantStatus()
+void RenderLayer::mapRectToPaintInvalidationBacking(const RenderObject* renderObject, const RenderLayerModelObject* paintInvalidationContainer, LayoutRect& rect, const PaintInvalidationState* paintInvalidationState)
 {
-    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
-        if (layer->m_childLayerHasBlendModeStatusDirty)
-            break;
+    if (!paintInvalidationContainer->layer()->groupedMapping()) {
+        renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, paintInvalidationState);
+        return;
+    }
 
-        layer->m_childLayerHasBlendModeStatusDirty = true;
+    // This code adjusts the paint invalidation rectangle to be in the space of the transformed ancestor of the grouped (i.e. squashed)
+    // layer. This is because all layers that squash together need to issue paint invalidations w.r.t. a single container that is
+    // an ancestor of all of them, in order to properly take into account any local transforms etc.
+    // FIXME: remove this special-case code that works around the paint invalidation code structure.
+    renderObject->mapRectToPaintInvalidationBacking(paintInvalidationContainer, rect, paintInvalidationState);
 
-        if (layer->stackingNode()->isStackingContext())
-            break;
-    }
+    mapRectToPaintBackingCoordinates(paintInvalidationContainer, rect);
 }
 
-void RenderLayer::setAncestorChainBlendedDescendant()
+LayoutRect RenderLayer::computePaintInvalidationRect(const RenderObject* renderObject, const RenderLayer* paintInvalidationContainer, const PaintInvalidationState* paintInvalidationState)
 {
-    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
-        if (!layer->m_childLayerHasBlendModeStatusDirty && layer->childLayerHasBlendMode())
-            break;
+    if (!paintInvalidationContainer->groupedMapping())
+        return renderObject->computePaintInvalidationRect(paintInvalidationContainer->renderer(), paintInvalidationState);
 
-        layer->m_childLayerHasBlendMode = true;
-        layer->m_childLayerHasBlendModeStatusDirty = false;
+    LayoutRect rect = renderObject->clippedOverflowRectForPaintInvalidation(paintInvalidationContainer->renderer(), paintInvalidationState);
+    mapRectToPaintBackingCoordinates(paintInvalidationContainer->renderer(), rect);
+    return rect;
+}
 
-        if (layer->stackingNode()->isStackingContext())
-            break;
-    }
+void RenderLayer::dirtyVisibleContentStatus()
+{
+    m_visibleContentStatusDirty = true;
+    if (parent())
+        parent()->dirtyAncestorChainVisibleDescendantStatus();
 }
 
-void RenderLayer::updateHasUnclippedDescendant()
+void RenderLayer::potentiallyDirtyVisibleContentStatus(EVisibility visibility)
 {
-    TRACE_EVENT0("blink_rendering", "RenderLayer::updateHasUnclippedDescendant");
-    ASSERT(renderer()->isOutOfFlowPositioned());
-    if (!m_hasVisibleContent && !m_hasVisibleDescendant)
+    if (m_visibleContentStatusDirty)
         return;
-
-    FrameView* frameView = renderer()->view()->frameView();
-    if (!frameView)
+    if (hasVisibleContent() == (visibility == VISIBLE))
         return;
+    dirtyVisibleContentStatus();
+}
 
-    const RenderObject* containingBlock = renderer()->containingBlock();
-    setIsUnclippedDescendant(false);
-    for (RenderLayer* ancestor = parent(); ancestor && ancestor->renderer() != containingBlock; ancestor = ancestor->parent()) {
-        // TODO(vollick): This isn't quite right. Whenever ancestor is composited and clips
-        // overflow, we're technically unclipped. However, this will currently cause a huge
-        // number of layers to report that they are unclipped. Eventually, when we've formally
-        // separated the clipping, transform, opacity, and stacking trees here and in the
-        // compositor, we will be able to relax this restriction without it being prohibitively
-        // expensive (currently, we have to do a lot of work in the compositor to honor a
-        // clip child/parent relationship).
-        if (ancestor->scrollsOverflow())
-            setIsUnclippedDescendant(true);
-        ancestor->setHasUnclippedDescendant(true);
+void RenderLayer::dirtyAncestorChainVisibleDescendantStatus()
+{
+    for (RenderLayer* layer = this; layer; layer = layer->parent()) {
+        if (layer->m_visibleDescendantStatusDirty)
+            break;
+
+        layer->m_visibleDescendantStatusDirty = true;
     }
 }
 
 // FIXME: this is quite brute-force. We could be more efficient if we were to
-// track state and update it as appropriate as changes are made in the RenderObject tree.
-void RenderLayer::updateHasVisibleNonLayerContent()
+// track state and update it as appropriate as changes are made in the Render tree.
+void RenderLayer::updateScrollingStateAfterCompositingChange()
 {
-    TRACE_EVENT0("blink_rendering", "RenderLayer::updateHasVisibleNonLayerContent");
+    TRACE_EVENT0("blink", "RenderLayer::updateScrollingStateAfterCompositingChange");
     m_hasVisibleNonLayerContent = false;
-    for (RenderObject* r = renderer()->firstChild(); r; r = r->nextSibling()) {
+    for (RenderObject* r = renderer()->slowFirstChild(); r; r = r->nextSibling()) {
         if (!r->hasLayer()) {
             m_hasVisibleNonLayerContent = true;
             break;
         }
     }
+
+    m_hasNonCompositedChild = false;
+    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
+        if (child->compositingState() == NotComposited || child->compositingState() == HasOwnBackingButPaintsIntoAncestor) {
+            m_hasNonCompositedChild = true;
+            return;
+        }
+    }
 }
 
-static bool subtreeContainsOutOfFlowPositionedLayer(const RenderLayer* subtreeRoot)
+// The descendant-dependent flags system is badly broken because we clean dirty
+// bits in upward tree walks, which means we need to call updateDescendantDependentFlags
+// at every node in the tree to fully clean all the dirty bits. While we'll in
+// the process of fixing this issue, updateDescendantDependentFlagsForEntireSubtree
+// provides a big hammer for actually cleaning all the dirty bits in a subtree.
+//
+// FIXME: Remove this function once the descendant-dependent flags system keeps
+// its dirty bits scoped to subtrees.
+void RenderLayer::updateDescendantDependentFlagsForEntireSubtree()
 {
-    return (subtreeRoot->renderer() && subtreeRoot->renderer()->isOutOfFlowPositioned()) || subtreeRoot->hasOutOfFlowPositionedDescendant();
+    updateDescendantDependentFlags();
+
+    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+        child->updateDescendantDependentFlagsForEntireSubtree();
 }
 
 void RenderLayer::updateDescendantDependentFlags()
 {
-    if (m_visibleDescendantStatusDirty || m_hasSelfPaintingLayerDescendantDirty || m_hasOutOfFlowPositionedDescendantDirty) {
+    if (m_visibleDescendantStatusDirty) {
         m_hasVisibleDescendant = false;
-        m_hasSelfPaintingLayerDescendant = false;
-        m_hasOutOfFlowPositionedDescendant = false;
 
         for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
             child->updateDescendantDependentFlags();
 
-            bool hasVisibleDescendant = child->m_hasVisibleContent || child->m_hasVisibleDescendant;
-            bool hasSelfPaintingLayerDescendant = child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant();
-            bool hasOutOfFlowPositionedDescendant = subtreeContainsOutOfFlowPositionedLayer(child);
-
-            m_hasVisibleDescendant |= hasVisibleDescendant;
-            m_hasSelfPaintingLayerDescendant |= hasSelfPaintingLayerDescendant;
-            m_hasOutOfFlowPositionedDescendant |= hasOutOfFlowPositionedDescendant;
-
-            if (m_hasVisibleDescendant && m_hasSelfPaintingLayerDescendant && hasOutOfFlowPositionedDescendant)
+            if (child->m_hasVisibleContent || child->m_hasVisibleDescendant) {
+                m_hasVisibleDescendant = true;
                 break;
+            }
         }
 
         m_visibleDescendantStatusDirty = false;
-        m_hasSelfPaintingLayerDescendantDirty = false;
-        m_hasOutOfFlowPositionedDescendantDirty = false;
-    }
-
-    if (m_childLayerHasBlendModeStatusDirty) {
-        for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
-            if (!child->stackingNode()->isStackingContext())
-                child->updateDescendantDependentFlags();
-
-            bool childLayerHasBlendMode = child->paintsWithBlendMode() || (child->m_childLayerHasBlendMode && !child->stackingNode()->isStackingContext());
-            m_childLayerHasBlendMode |= childLayerHasBlendMode;
-
-            if (m_childLayerHasBlendMode)
-                break;
-        }
-        m_childLayerHasBlendModeStatusDirty = false;
     }
 
     if (m_visibleContentStatusDirty) {
+        bool previouslyHasVisibleContent = m_hasVisibleContent;
         if (renderer()->style()->visibility() == VISIBLE)
             m_hasVisibleContent = true;
         else {
             // layer may be hidden but still have some visible content, check for this
             m_hasVisibleContent = false;
-            RenderObject* r = renderer()->firstChild();
+            RenderObject* r = renderer()->slowFirstChild();
             while (r) {
                 if (r->style()->visibility() == VISIBLE && !r->hasLayer()) {
                     m_hasVisibleContent = true;
                     break;
                 }
-                if (r->firstChild() && !r->hasLayer())
-                    r = r->firstChild();
+                RenderObject* rendererFirstChild = r->slowFirstChild();
+                if (rendererFirstChild && !r->hasLayer())
+                    r = rendererFirstChild;
                 else if (r->nextSibling())
                     r = r->nextSibling();
                 else {
@@ -902,12 +705,21 @@ void RenderLayer::updateDescendantDependentFlags()
             }
         }
         m_visibleContentStatusDirty = false;
+
+        if (hasVisibleContent() != previouslyHasVisibleContent) {
+            setNeedsCompositingInputsUpdate();
+            // We need to tell m_renderer to recheck its rect because we
+            // pretend that invisible RenderObjects have 0x0 rects. Changing
+            // visibility therefore changes our rect and we need to visit
+            // this RenderObject during the invalidateTreeIfNeeded walk.
+            m_renderer->setMayNeedPaintInvalidation(true);
+        }
     }
 }
 
 void RenderLayer::dirty3DTransformedDescendantStatus()
 {
-    RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContainerNode();
+    RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContextNode();
     if (!stackingNode)
         return;
 
@@ -917,7 +729,7 @@ void RenderLayer::dirty3DTransformedDescendantStatus()
     // Note that preserves3D() creates stacking context, so we can just run up the stacking containers.
     while (stackingNode && stackingNode->layer()->preserves3D()) {
         stackingNode->layer()->m_3DTransformedDescendantStatusDirty = true;
-        stackingNode = stackingNode->ancestorStackingContainerNode();
+        stackingNode = stackingNode->ancestorStackingContextNode();
     }
 }
 
@@ -946,19 +758,29 @@ bool RenderLayer::update3DTransformedDescendantStatus()
     return has3DTransform();
 }
 
-bool RenderLayer::updateLayerPosition()
+IntSize RenderLayer::size() const
+{
+    if (renderer()->isInline() && renderer()->isRenderInline())
+        return toRenderInline(renderer())->linesBoundingBox().size();
+
+    // FIXME: Is snapping the size really needed here?
+    if (RenderBox* box = renderBox())
+        return pixelSnappedIntSize(box->size(), box->location());
+
+    return IntSize();
+}
+
+LayoutPoint RenderLayer::location() const
 {
     LayoutPoint localPoint;
     LayoutSize inlineBoundingBoxOffset; // We don't put this into the RenderLayer x/y for inlines, so we need to subtract it out when done.
+
     if (renderer()->isInline() && renderer()->isRenderInline()) {
         RenderInline* inlineFlow = toRenderInline(renderer());
         IntRect lineBox = inlineFlow->linesBoundingBox();
-        setSize(lineBox.size());
         inlineBoundingBoxOffset = toSize(lineBox.location());
         localPoint += inlineBoundingBoxOffset;
     } else if (RenderBox* box = renderBox()) {
-        // FIXME: Is snapping the size really needed here for the RenderBox case?
-        setSize(pixelSnappedIntSize(box->size(), box->location()));
         localPoint += box->topLeftLocationOffset();
     }
 
@@ -990,21 +812,23 @@ bool RenderLayer::updateLayerPosition()
             localPoint -= offset;
         }
 
-        if (renderer()->isOutOfFlowPositioned() && positionedParent->renderer()->isInFlowPositioned() && positionedParent->renderer()->isRenderInline()) {
-            LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(toRenderBox(renderer()));
+        if (positionedParent->renderer()->isRelPositioned() && positionedParent->renderer()->isRenderInline()) {
+            LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(*toRenderBox(renderer()));
             localPoint += offset;
         }
     } else if (parent()) {
-        if (compositedLayerMapping()) {
+        // FIXME: This code is very wrong. The compositing system doesn't
+        // understand columns and we're hacking around that fact by faking
+        // the position of the RenderLayers when we think we'll end up being
+        // composited. Hopefully we'll be able to unwind this hack when we
+        // implement multi-column using regions.
+        if (hasStyleDeterminedDirectCompositingReasons()) {
             // FIXME: Composited layers ignore pagination, so about the best we can do is make sure they're offset into the appropriate column.
             // They won't split across columns properly.
-            LayoutSize columnOffset;
-            if (!parent()->renderer()->hasColumns() && parent()->renderer()->isRoot() && renderer()->view()->hasColumns())
-                renderer()->view()->adjustForColumns(columnOffset, localPoint);
+            if (!parent()->renderer()->hasColumns() && parent()->renderer()->isDocumentElement() && renderer()->view()->hasColumns())
+                localPoint += renderer()->view()->columnOffset(localPoint);
             else
-                parent()->renderer()->adjustForColumns(columnOffset, localPoint);
-
-            localPoint += columnOffset;
+                localPoint += parent()->renderer()->columnOffset(localPoint);
         }
 
         if (parent()->renderer()->hasOverflowClip()) {
@@ -1013,22 +837,17 @@ bool RenderLayer::updateLayerPosition()
         }
     }
 
-    bool positionOrOffsetChanged = false;
-    if (renderer()->isInFlowPositioned()) {
-        LayoutSize newOffset = toRenderBoxModelObject(renderer())->offsetForInFlowPosition();
-        positionOrOffsetChanged = newOffset != m_offsetForInFlowPosition;
-        m_offsetForInFlowPosition = newOffset;
-        localPoint.move(m_offsetForInFlowPosition);
-    } else {
-        m_offsetForInFlowPosition = LayoutSize();
-    }
+    localPoint.move(offsetForInFlowPosition());
 
     // FIXME: We'd really like to just get rid of the concept of a layer rectangle and rely on the renderers.
     localPoint -= inlineBoundingBoxOffset;
 
-    positionOrOffsetChanged |= location() != localPoint;
-    setLocation(localPoint);
-    return positionOrOffsetChanged;
+    return localPoint;
+}
+
+const LayoutSize RenderLayer::offsetForInFlowPosition() const
+{
+    return renderer()->isRelPositioned() ? toRenderBoxModelObject(renderer())->offsetForInFlowPosition() : LayoutSize();
 }
 
 TransformationMatrix RenderLayer::perspectiveTransform() const
@@ -1069,8 +888,7 @@ FloatPoint RenderLayer::perspectiveOrigin() const
     const LayoutRect borderBox = toRenderBox(renderer())->borderBoxRect();
     RenderStyle* style = renderer()->style();
 
-    return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width()),
-                      floatValueForLength(style->perspectiveOriginY(), borderBox.height()));
+    return FloatPoint(floatValueForLength(style->perspectiveOriginX(), borderBox.width().toFloat()), floatValueForLength(style->perspectiveOriginY(), borderBox.height().toFloat()));
 }
 
 static inline bool isFixedPositionedContainer(RenderLayer* layer)
@@ -1087,156 +905,167 @@ RenderLayer* RenderLayer::enclosingPositionedAncestor() const
     return curr;
 }
 
-RenderLayer* RenderLayer::enclosingScrollableLayer() const
-{
-    if (RenderBox* enclosingScrollableBox = renderer()->enclosingScrollableBox())
-        return enclosingScrollableBox->layer();
-
-    return 0;
-}
-
 RenderLayer* RenderLayer::enclosingTransformedAncestor() const
 {
     RenderLayer* curr = parent();
-    while (curr && !curr->isRootLayer() && !curr->transform())
+    while (curr && !curr->isRootLayer() && !curr->renderer()->hasTransform())
         curr = curr->parent();
 
     return curr;
 }
 
-static inline const RenderLayer* compositingContainer(const RenderLayer* layer)
+LayoutPoint RenderLayer::computeOffsetFromTransformedAncestor() const
 {
-    return layer->stackingNode()->isNormalFlowOnly() ? layer->parent() : (layer->stackingNode()->ancestorStackingContainerNode() ? layer->stackingNode()->ancestorStackingContainerNode()->layer() : 0);
+    const AncestorDependentCompositingInputs& properties = ancestorDependentCompositingInputs();
+
+    TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint());
+    // FIXME: add a test that checks flipped writing mode and ApplyContainerFlip are correct.
+    renderer()->mapLocalToContainer(properties.transformAncestor ? properties.transformAncestor->renderer() : 0, transformState, ApplyContainerFlip);
+    transformState.flatten();
+    return LayoutPoint(transformState.lastPlanarPoint());
 }
 
-// FIXME: having two different functions named enclosingCompositingLayer and enclosingCompositingLayerForRepaint
-// is error-prone and misleading for reading code that uses these functions - especially compounded with
-// the includeSelf option. It is very likely that some call sites of this function actually mean to use
-// enclosingCompositingLayerForRepaint().
-RenderLayer* RenderLayer::enclosingCompositingLayer(bool includeSelf) const
+const RenderLayer* RenderLayer::compositingContainer() const
 {
-    if (includeSelf && compositedLayerMapping())
-        return const_cast<RenderLayer*>(this);
-
-    for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
-        if (curr->compositedLayerMapping())
-            return const_cast<RenderLayer*>(curr);
-    }
-
+    if (stackingNode()->isNormalFlowOnly())
+        return parent();
+    if (RenderLayerStackingNode* ancestorStackingNode = stackingNode()->ancestorStackingContextNode())
+        return ancestorStackingNode->layer();
     return 0;
 }
 
-RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(bool includeSelf) const
+bool RenderLayer::isPaintInvalidationContainer() const
+{
+    return compositingState() == PaintsIntoOwnBacking || compositingState() == PaintsIntoGroupedBacking;
+}
+
+// Note: enclosingCompositingLayer does not include squashed layers. Compositing stacking children of squashed layers
+// receive graphics layers that are parented to the compositing ancestor of the squashed layer.
+RenderLayer* RenderLayer::enclosingLayerWithCompositedLayerMapping(IncludeSelfOrNot includeSelf) const
 {
-    if (includeSelf && compositingState() == PaintsIntoOwnBacking)
+    ASSERT(isAllowedToQueryCompositingState());
+
+    if ((includeSelf == IncludeSelf) && compositingState() != NotComposited && compositingState() != PaintsIntoGroupedBacking)
         return const_cast<RenderLayer*>(this);
 
-    for (const RenderLayer* curr = compositingContainer(this); curr; curr = compositingContainer(curr)) {
-        if (curr->compositingState() == PaintsIntoOwnBacking)
+    for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) {
+        if (curr->compositingState() != NotComposited && curr->compositingState() != PaintsIntoGroupedBacking)
             return const_cast<RenderLayer*>(curr);
     }
 
     return 0;
 }
 
-RenderLayer* RenderLayer::ancestorCompositedScrollingLayer() const
+// Return the enclosingCompositedLayerForPaintInvalidation for the given RenderLayer
+// including crossing frame boundaries.
+RenderLayer* RenderLayer::enclosingLayerForPaintInvalidationCrossingFrameBoundaries() const
 {
-    if (!acceleratedCompositingForOverflowScrollEnabled())
-        return 0;
+    const RenderLayer* layer = this;
+    RenderLayer* compositedLayer = 0;
+    while (!compositedLayer) {
+        compositedLayer = layer->enclosingLayerForPaintInvalidation();
+        if (!compositedLayer) {
+            RenderObject* owner = layer->renderer()->frame()->ownerRenderer();
+            if (!owner)
+                break;
+            layer = owner->enclosingLayer();
+        }
+    }
+    return compositedLayer;
+}
 
-    RenderObject* containingBlock = renderer()->containingBlock();
-    if (!containingBlock)
-        return 0;
+RenderLayer* RenderLayer::enclosingLayerForPaintInvalidation() const
+{
+    ASSERT(isAllowedToQueryCompositingState());
 
-    for (RenderLayer* ancestorLayer = containingBlock->enclosingLayer(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) {
-        if (ancestorLayer->needsCompositedScrolling())
-            return ancestorLayer;
+    if (isPaintInvalidationContainer())
+        return const_cast<RenderLayer*>(this);
+
+    for (const RenderLayer* curr = compositingContainer(); curr; curr = curr->compositingContainer()) {
+        if (curr->isPaintInvalidationContainer())
+            return const_cast<RenderLayer*>(curr);
     }
 
     return 0;
 }
 
-RenderLayer* RenderLayer::ancestorScrollingLayer() const
+void RenderLayer::setNeedsCompositingInputsUpdate()
 {
-    RenderObject* containingBlock = renderer()->containingBlock();
-    if (!containingBlock)
-        return 0;
+    m_needsAncestorDependentCompositingInputsUpdate = true;
+    m_needsDescendantDependentCompositingInputsUpdate = true;
 
-    for (RenderLayer* ancestorLayer = containingBlock->enclosingLayer(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) {
-        if (ancestorLayer->scrollsOverflow())
-            return ancestorLayer;
-    }
+    for (RenderLayer* current = this; current && !current->m_childNeedsCompositingInputsUpdate; current = current->parent())
+        current->m_childNeedsCompositingInputsUpdate = true;
 
-    return 0;
+    compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCompositingInputChange);
 }
 
-RenderLayer* RenderLayer::enclosingFilterLayer(bool includeSelf) const
+void RenderLayer::updateAncestorDependentCompositingInputs(const AncestorDependentCompositingInputs& compositingInputs)
 {
-    const RenderLayer* curr = includeSelf ? this : parent();
-    for (; curr; curr = curr->parent()) {
-        if (curr->requiresFullLayerImageForFilters())
-            return const_cast<RenderLayer*>(curr);
-    }
+    m_ancestorDependentCompositingInputs = compositingInputs;
+    m_needsAncestorDependentCompositingInputsUpdate = false;
+}
 
-    return 0;
+void RenderLayer::updateDescendantDependentCompositingInputs(const DescendantDependentCompositingInputs& compositingInputs)
+{
+    m_descendantDependentCompositingInputs = compositingInputs;
+    m_needsDescendantDependentCompositingInputsUpdate = false;
 }
 
-bool RenderLayer::hasAncestorWithFilterOutsets() const
+void RenderLayer::didUpdateCompositingInputs()
 {
-    for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
-        RenderLayerModelObject* renderer = curr->renderer();
-        if (renderer->style()->hasFilterOutsets())
-            return true;
-    }
-    return false;
+    ASSERT(!needsCompositingInputsUpdate());
+    m_childNeedsCompositingInputsUpdate = false;
+    if (m_scrollableArea)
+        m_scrollableArea->updateNeedsCompositedScrolling();
 }
 
-RenderLayer* RenderLayer::clippingRootForPainting() const
+void RenderLayer::setCompositingReasons(CompositingReasons reasons, CompositingReasons mask)
 {
-    if (compositedLayerMapping())
-        return const_cast<RenderLayer*>(this);
+    if ((compositingReasons() & mask) == (reasons & mask))
+        return;
+    m_compositingReasons = (reasons & mask) | (compositingReasons() & ~mask);
+}
 
-    const RenderLayer* current = this;
-    while (current) {
-        if (current->isRootLayer())
-            return const_cast<RenderLayer*>(current);
-
-        current = compositingContainer(current);
-        ASSERT(current);
-        if (current->transform()
-            || (current->compositingState() == PaintsIntoOwnBacking)
-        )
-            return const_cast<RenderLayer*>(current);
-    }
+void RenderLayer::setHasCompositingDescendant(bool hasCompositingDescendant)
+{
+    if (m_hasCompositingDescendant == static_cast<unsigned>(hasCompositingDescendant))
+        return;
 
-    ASSERT_NOT_REACHED();
-    return 0;
+    m_hasCompositingDescendant = hasCompositingDescendant;
+
+    if (hasCompositedLayerMapping())
+        compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
 }
 
-bool RenderLayer::cannotBlitToWindow() const
+void RenderLayer::setShouldIsolateCompositedDescendants(bool shouldIsolateCompositedDescendants)
 {
-    if (isTransparent() || m_reflectionInfo || hasTransform())
-        return true;
-    if (!parent())
-        return false;
-    return parent()->cannotBlitToWindow();
+    if (m_shouldIsolateCompositedDescendants == static_cast<unsigned>(shouldIsolateCompositedDescendants))
+        return;
+
+    m_shouldIsolateCompositedDescendants = shouldIsolateCompositedDescendants;
+
+    if (hasCompositedLayerMapping())
+        compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
 }
 
-bool RenderLayer::isTransparent() const
+bool RenderLayer::hasAncestorWithFilterOutsets() const
 {
-    if (renderer()->node() && renderer()->node()->isSVGElement())
-        return false;
-
-    return renderer()->isTransparent() || renderer()->hasMask();
+    for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
+        RenderLayerModelObject* renderer = curr->renderer();
+        if (renderer->style()->hasFilterOutsets())
+            return true;
+    }
+    return false;
 }
 
 RenderLayer* RenderLayer::transparentPaintingAncestor()
 {
-    if (compositedLayerMapping())
+    if (hasCompositedLayerMapping())
         return 0;
 
     for (RenderLayer* curr = parent(); curr; curr = curr->parent()) {
-        if (curr->compositedLayerMapping())
+        if (curr->hasCompositedLayerMapping())
             return 0;
         if (curr->isTransparent())
             return curr;
@@ -1254,10 +1083,10 @@ enum TransparencyClipBoxMode {
     RootOfTransparencyClipBox
 };
 
-static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, PaintBehavior = 0);
+static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, const LayoutSize& subPixelAccumulation, PaintBehavior = 0);
 
 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
-    TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
+    TransparencyClipBoxBehavior transparencyBehavior, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
 {
     // If we have a mask, then the clip is limited to the border box area (and there is
     // no need to examine child layers).
@@ -1266,7 +1095,7 @@ static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, cons
         // a stacking container. This means we can just walk the layer tree directly.
         for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
             if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionLayer() != curr)
-                clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior));
+                clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, subPixelAccumulation, paintBehavior));
         }
     }
 
@@ -1284,7 +1113,7 @@ static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, cons
 }
 
 static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
-    TransparencyClipBoxMode transparencyMode, PaintBehavior paintBehavior)
+    TransparencyClipBoxMode transparencyMode, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
 {
     // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
     // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
@@ -1299,14 +1128,16 @@ static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLaye
         LayoutPoint delta;
         layer->convertToLayerCoords(rootLayerForTransform, delta);
 
+        delta.move(subPixelAccumulation);
+        IntPoint pixelSnappedDelta = roundedIntPoint(delta);
         TransformationMatrix transform;
-        transform.translate(delta.x(), delta.y());
+        transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y());
         transform = transform * *layer->transform();
 
         // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
         // paints unfragmented.
-        LayoutRect clipRect = layer->boundingBox(layer);
-        expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, paintBehavior);
+        LayoutRect clipRect = layer->physicalBoundingBox(layer);
+        expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, subPixelAccumulation, paintBehavior);
         layer->renderer()->style()->filterOutsets().expandRect(clipRect);
         LayoutRect result = transform.mapRect(clipRect);
         if (!paginationLayer)
@@ -1324,36 +1155,41 @@ static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLaye
         return result;
     }
 
-    LayoutRect clipRect = layer->boundingBox(rootLayer, RenderLayer::UseFragmentBoxes);
-    expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
+    LayoutRect clipRect = layer->physicalBoundingBox(rootLayer);
+    expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, subPixelAccumulation, paintBehavior);
     layer->renderer()->style()->filterOutsets().expandRect(clipRect);
+    clipRect.move(subPixelAccumulation);
     return clipRect;
 }
 
-LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
+LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
 {
-    return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
+    return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, subPixelAccumulation, paintBehavior), paintDirtyRect);
 }
 
-void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
+void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
 {
-    bool createTransparencyLayerForBlendMode = m_stackingNode->isStackingContext() && m_childLayerHasBlendMode;
-    if (context->paintingDisabled() || ((paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency))
+    bool createTransparencyLayerForBlendMode = m_stackingNode->isStackingContext() && hasDescendantWithBlendMode();
+    if ((paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency)
         return;
 
     RenderLayer* ancestor = transparentPaintingAncestor();
     if (ancestor)
-        ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
+        ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
 
     if (paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) {
         m_usedTransparency = true;
         context->save();
-        LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBehavior);
+        LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
         context->clip(clipRect);
+
         if (paintsWithBlendMode())
-            context->setCompositeOperation(context->compositeOperation(), m_blendMode);
+            context->setCompositeOperation(context->compositeOperation(), m_renderer->style()->blendMode());
 
         context->beginTransparencyLayer(renderer()->opacity());
+
+        if (paintsWithBlendMode())
+            context->setCompositeOperation(context->compositeOperation(), WebBlendModeNormal);
 #ifdef REVEAL_TRANSPARENCY_LAYERS
         context->setFillColor(Color(0.0f, 0.0f, 0.5f, 0.2f));
         context->fillRect(clipRect);
@@ -1388,51 +1224,28 @@ void RenderLayer::addChild(RenderLayer* child, RenderLayer* beforeChild)
     } else
         setLastChild(child);
 
-    child->setParent(this);
+    child->m_parent = this;
+
+    setNeedsCompositingInputsUpdate();
 
     if (child->stackingNode()->isNormalFlowOnly())
         m_stackingNode->dirtyNormalFlowList();
 
     if (!child->stackingNode()->isNormalFlowOnly() || child->firstChild()) {
-        // Dirty the z-order list in which we are contained. The ancestorStackingContainerNode() can be null in the
+        // Dirty the z-order list in which we are contained. The ancestorStackingContextNode() can be null in the
         // case where we're building up generated content layers. This is ok, since the lists will start
         // off dirty in that case anyway.
-        child->stackingNode()->dirtyStackingContainerZOrderLists();
+        child->stackingNode()->dirtyStackingContextZOrderLists();
     }
 
-    child->updateDescendantDependentFlags();
-    if (child->m_hasVisibleContent || child->m_hasVisibleDescendant)
-        setAncestorChainHasVisibleDescendant();
-
-    if (child->isSelfPaintingLayer() || child->hasSelfPaintingLayerDescendant())
-        setAncestorChainHasSelfPaintingLayerDescendant();
-
-    if (child->paintsWithBlendMode() || child->childLayerHasBlendMode())
-        setAncestorChainBlendedDescendant();
-
-    if (subtreeContainsOutOfFlowPositionedLayer(child)) {
-        // Now that the out of flow positioned descendant is in the tree, we
-        // need to tell the compositor to reevaluate the compositing
-        // requirements since we may be able to mark more layers as having
-        // an 'unclipped' descendant.
-        compositor()->setNeedsUpdateCompositingRequirementsState();
-        setAncestorChainHasOutOfFlowPositionedDescendant();
-    }
+    dirtyAncestorChainVisibleDescendantStatus();
+    dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
 
-    // When we first dirty a layer, we will also dirty all the siblings in that
-    // layer's stacking context. We need to manually do it here as well, in case
-    // we're adding this layer after the stacking context has already been
-    // updated.
-    child->stackingNode()->setDescendantsAreContiguousInStackingOrderDirty(true);
-    compositor()->layerWasAdded(this, child);
+    child->updateDescendantDependentFlags();
 }
 
 RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
 {
-    if (!renderer()->documentBeingDestroyed())
-        compositor()->layerWillBeRemoved(this, oldChild);
-
-    // remove the child
     if (oldChild->previousSibling())
         oldChild->previousSibling()->setNextSibling(oldChild->nextSibling());
     if (oldChild->nextSibling())
@@ -1448,32 +1261,25 @@ RenderLayer* RenderLayer::removeChild(RenderLayer* oldChild)
     if (!oldChild->stackingNode()->isNormalFlowOnly() || oldChild->firstChild()) {
         // Dirty the z-order list in which we are contained.  When called via the
         // reattachment process in removeOnlyThisLayer, the layer may already be disconnected
-        // from the main layer tree, so we need to null-check the |stackingContainer| value.
-        oldChild->stackingNode()->dirtyStackingContainerZOrderLists();
+        // from the main layer tree, so we need to null-check the
+        // |stackingContext| value.
+        oldChild->stackingNode()->dirtyStackingContextZOrderLists();
     }
 
+    if (renderer()->style()->visibility() != VISIBLE)
+        dirtyVisibleContentStatus();
+
     oldChild->setPreviousSibling(0);
     oldChild->setNextSibling(0);
-    oldChild->setParent(0);
+    oldChild->m_parent = 0;
+
+    dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
 
     oldChild->updateDescendantDependentFlags();
-    if (subtreeContainsOutOfFlowPositionedLayer(oldChild)) {
-        // It may now be the case that a layer no longer has an unclipped
-        // descendant. Let the compositor know that it needs to reevaluate
-        // its compositing requirements to check this.
-        compositor()->setNeedsUpdateCompositingRequirementsState();
-        dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
-    }
 
     if (oldChild->m_hasVisibleContent || oldChild->m_hasVisibleDescendant)
         dirtyAncestorChainVisibleDescendantStatus();
 
-    if (oldChild->paintsWithBlendMode() || oldChild->childLayerHasBlendMode())
-        dirtyAncestorChainBlendedDescendantStatus();
-
-    if (oldChild->isSelfPaintingLayer() || oldChild->hasSelfPaintingLayerDescendant())
-        dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
-
     return oldChild;
 }
 
@@ -1482,13 +1288,6 @@ void RenderLayer::removeOnlyThisLayer()
     if (!m_parent)
         return;
 
-    // Mark that we are about to lose our layer. This makes render tree
-    // walks ignore this layer while we're removing it.
-    m_renderer->setHasLayer(false);
-
-    compositor()->layerWillBeRemoved(m_parent, this);
-
-    // Dirty the clip rects.
     m_clipper.clearClipRectsIncludingDescendants();
 
     RenderLayer* nextSib = nextSibling();
@@ -1504,10 +1303,9 @@ void RenderLayer::removeOnlyThisLayer()
         RenderLayer* next = current->nextSibling();
         removeChild(current);
         m_parent->addChild(current, nextSib);
-        current->repainter().setRepaintStatus(NeedsFullRepaint);
-        // updateLayerPositions depends on hasLayer() already being false for proper layout.
-        ASSERT(!renderer()->hasLayer());
-        current->updateLayerPositions(0); // FIXME: use geometry map.
+
+        // FIXME: We should call a specialized version of this function.
+        current->updateLayerPositionsAfterLayout();
         current = next;
     }
 
@@ -1528,27 +1326,13 @@ void RenderLayer::insertOnlyThisLayer()
     }
 
     // Remove all descendant layers from the hierarchy and add them to the new position.
-    for (RenderObject* curr = renderer()->firstChild(); curr; curr = curr->nextSibling())
+    for (RenderObject* curr = renderer()->slowFirstChild(); curr; curr = curr->nextSibling())
         curr->moveLayers(m_parent, this);
 
     // Clear out all the clip rects.
     m_clipper.clearClipRectsIncludingDescendants();
 }
 
-void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntPoint& roundedLocation) const
-{
-    LayoutPoint location = roundedLocation;
-    convertToLayerCoords(ancestorLayer, location);
-    roundedLocation = roundedIntPoint(location);
-}
-
-void RenderLayer::convertToPixelSnappedLayerCoords(const RenderLayer* ancestorLayer, IntRect& roundedRect) const
-{
-    LayoutRect rect = roundedRect;
-    convertToLayerCoords(ancestorLayer, rect);
-    roundedRect = pixelSnappedIntRect(rect);
-}
-
 // Returns the layer reached on the walk up towards the ancestor.
 static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLayer* layer, const RenderLayer* ancestorLayer, LayoutPoint& location)
 {
@@ -1565,7 +1349,7 @@ static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLay
     // FIXME: Positioning of out-of-flow(fixed, absolute) elements collected in a RenderFlowThread
     // may need to be revisited in a future patch.
     // If the fixed renderer is inside a RenderFlowThread, we should not compute location using localToAbsolute,
-    // since localToAbsolute maps the coordinates from named flow to regions coordinates and regions can be
+    // since localToAbsolute maps the coordinates from flow thread to regions coordinates and regions can be
     // positioned in a completely different place in the viewport (RenderView).
     if (position == FixedPosition && !fixedFlowThreadContainer && (!ancestorLayer || ancestorLayer == renderer->view()->layer())) {
         // If the fixed layer's container is the root, just add in the offset of the view. We can obtain this by calling
@@ -1633,8 +1417,7 @@ static inline const RenderLayer* accumulateOffsetTowardsAncestor(const RenderLay
 
         // We should not reach RenderView layer past the RenderFlowThread layer for any
         // children of the RenderFlowThread.
-        if (renderer->flowThreadContainingBlock() && !layer->isOutOfFlowRenderFlowThread())
-            ASSERT(parentLayer != renderer->view()->layer());
+        ASSERT(!renderer->flowThreadContainingBlock() || parentLayer != renderer->view()->layer());
 
         if (foundAncestorFirst) {
             // Found ancestorLayer before the abs. positioned container, so compute offset of both relative
@@ -1677,108 +1460,20 @@ void RenderLayer::convertToLayerCoords(const RenderLayer* ancestorLayer, LayoutR
     rect.move(-delta.x(), -delta.y());
 }
 
-bool RenderLayer::adjustForForceCompositedScrollingMode(bool value) const
-{
-    switch (m_forceNeedsCompositedScrolling) {
-    case DoNotForceCompositedScrolling:
-        return value;
-    case CompositedScrollingAlwaysOn:
-        return true;
-    case CompositedScrollingAlwaysOff:
-        return false;
-    }
-
-    ASSERT_NOT_REACHED();
-    return value;
-}
-
-bool RenderLayer::needsCompositedScrolling() const
-{
-    return adjustForForceCompositedScrollingMode(m_needsCompositedScrolling);
-}
-
-RenderLayer* RenderLayer::scrollParent() const
-{
-    if (!compositorDrivenAcceleratedScrollingEnabled())
-        return 0;
-
-    // Normal flow elements will be parented under the main scrolling layer, so
-    // we don't need a scroll parent/child relationship to get them to scroll.
-    if (stackingNode()->isNormalFlowOnly())
-        return 0;
-
-    // A layer scrolls with its containing block. So to find the overflow scrolling layer
-    // that we scroll with respect to, we must ascend the layer tree until we reach the
-    // first overflow scrolling div at or above our containing block. I will refer to this
-    // layer as our 'scrolling ancestor'.
-    //
-    // Now, if we reside in a normal flow list, then we will naturally scroll with our scrolling
-    // ancestor, and we need not be composited. If, on the other hand, we reside in a z-order
-    // list, and on our walk upwards to our scrolling ancestor we find no layer that is a stacking
-    // context, then we know that in the stacking tree, we will not be in the subtree rooted at
-    // our scrolling ancestor, and we will therefore not scroll with it. In this case, we must
-    // be a composited layer since the compositor will need to take special measures to ensure
-    // that we scroll with our scrolling ancestor and it cannot do this if we do not promote.
-    RenderLayer* scrollParent = ancestorCompositedScrollingLayer();
-
-    if (!scrollParent || scrollParent->stackingNode()->isStackingContainer())
-        return 0;
-
-    // If we hit a stacking context on our way up to the ancestor scrolling layer, it will already
-    // be composited due to an overflow scrolling parent, so we don't need to.
-    for (RenderLayer* ancestor = parent(); ancestor && ancestor != scrollParent; ancestor = ancestor->parent()) {
-        if (ancestor->stackingNode()->isStackingContainer())
-            return 0;
-    }
-
-    return scrollParent;
-}
-
-RenderLayer* RenderLayer::clipParent() const
-{
-    const bool needsAncestorClip = compositor()->clippedByAncestor(this);
-
-    RenderLayer* clipParent = 0;
-    if ((compositingReasons() & CompositingReasonOutOfFlowClipping) && !needsAncestorClip) {
-        if (RenderObject* containingBlock = renderer()->containingBlock())
-            clipParent = containingBlock->enclosingLayer()->enclosingCompositingLayer(true);
-    }
-
-    return clipParent;
-}
-
-void RenderLayer::setForceNeedsCompositedScrolling(RenderLayer::ForceNeedsCompositedScrollingMode mode)
-{
-    if (m_forceNeedsCompositedScrolling == mode)
-        return;
-
-    m_forceNeedsCompositedScrolling = mode;
-    didUpdateNeedsCompositedScrolling();
-}
-
 void RenderLayer::didUpdateNeedsCompositedScrolling()
 {
-    m_stackingNode->updateIsNormalFlowOnly();
     updateSelfPaintingLayer();
-
-    if (m_stackingNode->isStackingContainer())
-        m_stackingNode->dirtyZOrderLists();
-    else
-        m_stackingNode->clearZOrderLists();
-
-    m_stackingNode->dirtyStackingContainerZOrderLists();
-
-    compositor()->setNeedsToRecomputeCompositingRequirements();
-    compositor()->setCompositingLayersNeedRebuild();
 }
 
 void RenderLayer::updateReflectionInfo(const RenderStyle* oldStyle)
 {
+    ASSERT(!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle));
     if (renderer()->hasReflection()) {
         if (!m_reflectionInfo)
-            m_reflectionInfo = adoptPtr(new RenderLayerReflectionInfo(toRenderBox(renderer())));
+            m_reflectionInfo = adoptPtrWillBeNoop(new RenderLayerReflectionInfo(*renderBox()));
         m_reflectionInfo->updateAfterStyleChange(oldStyle);
     } else if (m_reflectionInfo) {
+        m_reflectionInfo->destroy();
         m_reflectionInfo = nullptr;
     }
 }
@@ -1794,33 +1489,21 @@ void RenderLayer::updateStackingNode()
 void RenderLayer::updateScrollableArea()
 {
     if (requiresScrollableArea())
-        m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(renderBox()));
+        m_scrollableArea = adoptPtr(new RenderLayerScrollableArea(*this));
     else
         m_scrollableArea = nullptr;
 }
 
-PassOwnPtr<Vector<FloatRect> > RenderLayer::collectTrackedRepaintRects() const
-{
-    if (CompositedLayerMapping* mapping = compositedLayerMapping())
-        return mapping->collectTrackedRepaintRects();
-    return nullptr;
-}
-
 bool RenderLayer::hasOverflowControls() const
 {
     return m_scrollableArea && (m_scrollableArea->hasScrollbar() || m_scrollableArea->hasScrollCorner() || renderer()->style()->resize() != RESIZE_NONE);
 }
 
-void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, RenderRegion* region, PaintLayerFlags paintFlags)
+void RenderLayer::paint(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot, PaintLayerFlags paintFlags)
 {
-    OverlapTestRequestMap overlapTestRequests;
-
-    LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot, region, &overlapTestRequests);
-    paintLayer(context, paintingInfo, paintFlags);
-
-    OverlapTestRequestMap::iterator end = overlapTestRequests.end();
-    for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it)
-        it->key->setIsOverlapped(false);
+    LayerPaintingInfo paintingInfo(this, enclosingIntRect(damageRect), paintBehavior, LayoutSize(), paintingRoot);
+    if (shouldPaintLayerInSoftwareMode(paintingInfo, paintFlags))
+        paintLayer(context, paintingInfo, paintFlags);
 }
 
 void RenderLayer::paintOverlayScrollbars(GraphicsContext* context, const LayoutRect& damageRect, PaintBehavior paintBehavior, RenderObject* paintingRoot)
@@ -1848,10 +1531,10 @@ static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLaye
     return false;
 }
 
-void RenderLayer::clipToRect(RenderLayer* rootLayer, GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect,
-                             BorderRadiusClippingRule rule)
+void RenderLayer::clipToRect(const LayerPaintingInfo& localPaintingInfo, GraphicsContext* context, const ClipRect& clipRect,
+    PaintLayerFlags paintFlags, BorderRadiusClippingRule rule)
 {
-    if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius())
+    if (clipRect.rect() == localPaintingInfo.paintDirtyRect && !clipRect.hasRadius())
         return;
     context->save();
     context->clip(pixelSnappedIntRect(clipRect.rect()));
@@ -1863,13 +1546,20 @@ void RenderLayer::clipToRect(RenderLayer* rootLayer, GraphicsContext* context, c
     // any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
     // containing block chain so we check that also.
     for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
+        // Composited scrolling layers handle border-radius clip in the compositor via a mask layer. We do not
+        // want to apply a border-radius clip to the layer contents itself, because that would require re-rastering
+        // every frame to update the clip. We only want to make sure that the mask layer is properly clipped so
+        // that it can in turn clip the scrolled contents in the compositor.
+        if (layer->needsCompositedScrolling() && !(paintFlags & PaintLayerPaintingChildClippingMaskPhase))
+            break;
+
         if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(this, layer)) {
                 LayoutPoint delta;
-                layer->convertToLayerCoords(rootLayer, delta);
+                layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta);
                 context->clipRoundedRect(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size())));
         }
 
-        if (layer == rootLayer)
+        if (layer == localPaintingInfo.rootLayer)
             break;
     }
 }
@@ -1881,33 +1571,12 @@ void RenderLayer::restoreClip(GraphicsContext* context, const LayoutRect& paintD
     context->restore();
 }
 
-static void performOverlapTests(OverlapTestRequestMap& overlapTestRequests, const RenderLayer* rootLayer, const RenderLayer* layer)
-{
-    Vector<RenderWidget*> overlappedRequestClients;
-    OverlapTestRequestMap::iterator end = overlapTestRequests.end();
-    LayoutRect boundingBox = layer->boundingBox(rootLayer);
-    for (OverlapTestRequestMap::iterator it = overlapTestRequests.begin(); it != end; ++it) {
-        if (!boundingBox.intersects(it->value))
-            continue;
-
-        it->key->setIsOverlapped(true);
-        overlappedRequestClients.append(it->key);
-    }
-    for (size_t i = 0; i < overlappedRequestClients.size(); ++i)
-        overlapTestRequests.remove(overlappedRequestClients[i]);
-}
-
-static bool shouldDoSoftwarePaint(const RenderLayer* layer, bool paintingReflection)
-{
-    return paintingReflection && !layer->has3DTransform();
-}
-
 static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
 {
     // Avoid painting descendants of the root layer 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 (layer->renderer()->document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isRoot())
+    // will do a full paintInvalidationForWholeRenderer().
+    if (layer->renderer()->document().didLayoutWithPendingStylesheets() && !layer->isRootLayer() && !layer->renderer()->isDocumentElement())
         return true;
 
     return false;
@@ -1915,26 +1584,25 @@ static inline bool shouldSuppressPaintingLayer(RenderLayer* layer)
 
 static bool paintForFixedRootBackground(const RenderLayer* layer, PaintLayerFlags paintFlags)
 {
-    return layer->renderer()->isRoot() && (paintFlags & PaintLayerPaintingRootBackgroundOnly);
+    return layer->renderer()->isDocumentElement() && (paintFlags & PaintLayerPaintingRootBackgroundOnly);
+}
+
+static ShouldRespectOverflowClip shouldRespectOverflowClip(PaintLayerFlags paintFlags, const RenderObject* renderer)
+{
+    return (paintFlags & PaintLayerPaintingOverflowContents || (paintFlags & PaintLayerPaintingChildClippingMaskPhase && renderer->hasClipPath())) ? IgnoreOverflowClip : RespectOverflowClip;
 }
 
 void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
 {
+    // https://code.google.com/p/chromium/issues/detail?id=343772
+    DisableCompositingQueryAsserts disabler;
+
     if (compositingState() != NotComposited) {
-        // The updatingControlTints() painting pass goes through compositing layers,
-        // but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
-        if (context->updatingControlTints() || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers)) {
-            paintFlags |= PaintLayerTemporaryClipRects;
-        } else if (!compositedLayerMapping()->paintsIntoCompositedAncestor()
-            && !shouldDoSoftwarePaint(this, paintFlags & PaintLayerPaintingReflection)
-            && !paintForFixedRootBackground(this, paintFlags)) {
-            // If this RenderLayer should paint into its own backing, that will be done via CompositedLayerMapping::paintIntoLayer().
-            return;
+        if (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers) {
+            // FIXME: ok, but what about PaintBehaviorFlattenCompositingLayers? That's for printing.
+            // FIXME: why isn't the code here global, as opposed to being set on each paintLayer() call?
+            paintFlags |= PaintLayerUncachedClipRects;
         }
-    } else if (viewportConstrainedNotCompositedReason() == NotCompositedForBoundsOutOfView) {
-        // Don't paint out-of-view viewport constrained layers (when doing prepainting) because they will never be visible
-        // unless their position or viewport size is changed.
-        return;
     }
 
     // Non self-painting leaf layers don't need to be painted as their renderer() should properly paint itself.
@@ -1962,9 +1630,9 @@ void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo&
         // layer from the parent now, assuming there is a parent
         if (paintFlags & PaintLayerHaveTransparency) {
             if (parent())
-                parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
+                parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
             else
-                beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
+                beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
         }
 
         if (enclosingPaginationLayer()) {
@@ -1975,13 +1643,14 @@ void RenderLayer::paintLayer(GraphicsContext* context, const LayerPaintingInfo&
         // Make sure the parent's clip rects have been calculated.
         ClipRect clipRect = paintingInfo.paintDirtyRect;
         if (parent()) {
-            ClipRectsContext clipRectsContext(paintingInfo.rootLayer, paintingInfo.region, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
-                IgnoreOverlayScrollbarSize, (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip);
-            clipRect = backgroundClipRect(clipRectsContext);
+            ClipRectsContext clipRectsContext(paintingInfo.rootLayer, (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize);
+            if (shouldRespectOverflowClip(paintFlags, renderer()) == IgnoreOverflowClip)
+                clipRectsContext.setIgnoreOverflowClip();
+            clipRect = clipper().backgroundClipRect(clipRectsContext);
             clipRect.intersect(paintingInfo.paintDirtyRect);
 
             // Push the parent coordinate space's clip.
-            parent()->clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, clipRect);
+            parent()->clipToRect(paintingInfo, context, clipRect, paintFlags);
         }
 
         paintLayerByApplyingTransform(context, paintingInfo, paintFlags);
@@ -2026,19 +1695,19 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
     // the outline is painted in the background phase during composited scrolling.
     // If it were painted in the foreground phase, it would move with the scrolled
     // content. When not composited scrolling, the outline is painted in the
-    // foreground phase. Since scrolled contents are moved by repainting in this
+    // foreground phase. Since scrolled contents are moved by paint invalidation in this
     // case, the outline won't get 'dragged along'.
     bool shouldPaintOutline = isSelfPaintingLayer && !isPaintingOverlayScrollbars
         && ((isPaintingScrollingContent && isPaintingCompositedBackground)
         || (!isPaintingScrollingContent && isPaintingCompositedForeground));
     bool shouldPaintContent = m_hasVisibleContent && isSelfPaintingLayer && !isPaintingOverlayScrollbars;
 
-    float deviceScaleFactor = WebCore::deviceScaleFactor(renderer()->frame());
-    context->setUseHighResMarkers(deviceScaleFactor > 1.5f);
+    float deviceScaleFactor = blink::deviceScaleFactor(renderer()->frame());
+    context->setDeviceScaleFactor(deviceScaleFactor);
 
     GraphicsContext* transparencyLayerContext = context;
 
-    if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isRoot())
+    if (paintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer()->isRenderView() && !renderer()->isDocumentElement())
         return;
 
     // Ensure our lists are up-to-date.
@@ -2047,41 +1716,52 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
     LayoutPoint offsetFromRoot;
     convertToLayerCoords(paintingInfo.rootLayer, offsetFromRoot);
 
-    IntRect rootRelativeBounds;
+    if (compositingState() == PaintsIntoOwnBacking)
+        offsetFromRoot.move(subpixelAccumulation());
+
+    LayoutRect rootRelativeBounds;
     bool rootRelativeBoundsComputed = false;
 
     // Apply clip-path to context.
-    bool hasClipPath = false;
+    GraphicsContextStateSaver clipStateSaver(*context, false);
     RenderStyle* style = renderer()->style();
     RenderSVGResourceClipper* resourceClipper = 0;
-    ClipperContext clipperContext;
-    if (renderer()->hasClipPath() && !context->paintingDisabled() && style) {
+    RenderSVGResourceClipper::ClipperState clipperState = RenderSVGResourceClipper::ClipperNotApplied;
+
+    // Clip-path, like border radius, must not be applied to the contents of a composited-scrolling container.
+    // It must, however, still be applied to the mask layer, so that the compositor can properly mask the
+    // scrolling contents and scrollbars.
+    if (renderer()->hasClipPath() && style && (!needsCompositedScrolling() || paintFlags & PaintLayerPaintingChildClippingMaskPhase)) {
         ASSERT(style->clipPath());
-        if (style->clipPath()->getOperationType() == ClipPathOperation::SHAPE) {
-            hasClipPath = true;
-            context->save();
-            ShapeClipPathOperation* clipPath = static_cast<ShapeClipPathOperation*>(style->clipPath());
-
-            if (!rootRelativeBoundsComputed) {
-                rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
-                rootRelativeBoundsComputed = true;
-            }
+        if (style->clipPath()->type() == ClipPathOperation::SHAPE) {
+            ShapeClipPathOperation* clipPath = toShapeClipPathOperation(style->clipPath());
+            if (clipPath->isValid()) {
+                clipStateSaver.save();
+
+                if (!rootRelativeBoundsComputed) {
+                    rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
+                    rootRelativeBoundsComputed = true;
+                }
 
-            context->clipPath(clipPath->path(rootRelativeBounds), clipPath->windRule());
-        } else if (style->clipPath()->getOperationType() == ClipPathOperation::REFERENCE) {
-            ReferenceClipPathOperation* referenceClipPathOperation = static_cast<ReferenceClipPathOperation*>(style->clipPath());
+                context->clipPath(clipPath->path(rootRelativeBounds), clipPath->windRule());
+            }
+        } else if (style->clipPath()->type() == ClipPathOperation::REFERENCE) {
+            ReferenceClipPathOperation* referenceClipPathOperation = toReferenceClipPathOperation(style->clipPath());
             Document& document = renderer()->document();
             // FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405)
             Element* element = document.getElementById(referenceClipPathOperation->fragment());
-            if (element && element->hasTagName(SVGNames::clipPathTag) && element->renderer()) {
+            if (isSVGClipPathElement(element) && element->renderer()) {
+                // FIXME: Saving at this point is not required in the 'mask'-
+                // case, or if the clip ends up empty.
+                clipStateSaver.save();
                 if (!rootRelativeBoundsComputed) {
-                    rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
+                    rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
                     rootRelativeBoundsComputed = true;
                 }
 
                 resourceClipper = toRenderSVGResourceClipper(toRenderSVGResourceContainer(element->renderer()));
                 if (!resourceClipper->applyClippingToContext(renderer(), rootRelativeBounds,
-                    paintingInfo.paintDirtyRect, context, clipperContext)) {
+                    paintingInfo.paintDirtyRect, context, clipperState)) {
                     // No need to post-apply the clipper if this failed.
                     resourceClipper = 0;
                 }
@@ -2091,37 +1771,65 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
 
     // Blending operations must be performed only with the nearest ancestor stacking context.
     // Note that there is no need to create a transparency layer if we're painting the root.
-    bool createTransparencyLayerForBlendMode = !renderer()->isRoot() && m_stackingNode->isStackingContext() && m_childLayerHasBlendMode;
+    bool createTransparencyLayerForBlendMode = !renderer()->isDocumentElement() && m_stackingNode->isStackingContext() && hasDescendantWithBlendMode();
 
     if (createTransparencyLayerForBlendMode)
-        beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
+        beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
 
     LayerPaintingInfo localPaintingInfo(paintingInfo);
+    bool deferredFiltersEnabled = renderer()->document().settings()->deferredFiltersEnabled();
     FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters());
-    if (filterPainter.haveFilterEffect() && !context->paintingDisabled()) {
-        RenderLayerFilterInfo* filterInfo = this->filterInfo();
-        ASSERT(filterInfo);
-        LayoutRect filterRepaintRect = filterInfo->dirtySourceRect();
-        filterRepaintRect.move(offsetFromRoot.x(), offsetFromRoot.y());
-
-        if (!rootRelativeBoundsComputed) {
-            rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
-            rootRelativeBoundsComputed = true;
-        }
 
-        if (filterPainter.prepareFilterEffect(this, rootRelativeBounds, paintingInfo.paintDirtyRect, filterRepaintRect)) {
-            // Now we know for sure, that the source image will be updated, so we can revert our tracking repaint rect back to zero.
-            filterInfo->resetDirtySourceRect();
+    LayerFragments layerFragments;
+    if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
+        // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
+        // fragment should paint.
+        collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.paintDirtyRect,
+            (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
+            shouldRespectOverflowClip(paintFlags, renderer()), &offsetFromRoot, localPaintingInfo.subPixelAccumulation);
+        updatePaintingInfoForFragments(layerFragments, localPaintingInfo, paintFlags, shouldPaintContent, &offsetFromRoot);
+    }
+
+    if (filterPainter.haveFilterEffect()) {
+        ASSERT(this->filterInfo());
+
+        if (!rootRelativeBoundsComputed)
+            rootRelativeBounds = physicalBoundingBoxIncludingReflectionAndStackingChildren(paintingInfo.rootLayer, offsetFromRoot);
+
+        if (filterPainter.prepareFilterEffect(this, rootRelativeBounds, paintingInfo.paintDirtyRect)) {
 
             // Rewire the old context to a memory buffer, so that we can capture the contents of the layer.
             // NOTE: We saved the old context in the "transparencyLayerContext" local variable, to be able to start a transparency layer
             // on the original context and avoid duplicating "beginFilterEffect" after each transparency layer call. Also, note that
             // beginTransparencyLayers will only create a single lazy transparency layer, even though it is called twice in this method.
+            // With deferred filters, we don't need a separate context, but we do need to do transparency and clipping before starting
+            // filter processing.
+            // FIXME: when the legacy path is removed, remove the transparencyLayerContext as well.
+            ClipRect backgroundRect;
+            if (deferredFiltersEnabled) {
+                if (haveTransparency) {
+                    // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one after filter processing.
+                    beginTransparencyLayers(context, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
+                }
+                // We'll handle clipping to the dirty rect before filter rasterization.
+                // Filter processing will automatically expand the clip rect and the offscreen to accommodate any filter outsets.
+                // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
+                backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
+                clipToRect(localPaintingInfo, context, backgroundRect, paintFlags);
+                // Subsequent code should not clip to the dirty rect, since we've already
+                // done it above, and doing it later will defeat the outsets.
+                localPaintingInfo.clipToDirtyRect = false;
+            }
             context = filterPainter.beginFilterEffect(context);
 
+            if (!filterPainter.hasStartedFilterEffect() && deferredFiltersEnabled) {
+                // If the the filter failed to start, undo the clip immediately
+                restoreClip(context, localPaintingInfo.paintDirtyRect, backgroundRect);
+            }
+
             // Check that we didn't fail to allocate the graphics context for the offscreen buffer.
-            if (filterPainter.hasStartedFilterEffect()) {
-                localPaintingInfo.paintDirtyRect = filterPainter.repaintRect();
+            if (filterPainter.hasStartedFilterEffect() && !deferredFiltersEnabled) {
+                localPaintingInfo.paintDirtyRect = filterPainter.paintInvalidationRect();
                 // If the filter needs the full source image, we need to avoid using the clip rectangles.
                 // Otherwise, if for example this layer has overflow:hidden, a drop shadow will not compute correctly.
                 // Note that we will still apply the clipping on the final rendering of the filter.
@@ -2130,9 +1838,9 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
         }
     }
 
-    if (filterPainter.hasStartedFilterEffect() && haveTransparency) {
+    if (filterPainter.hasStartedFilterEffect() && haveTransparency && !deferredFiltersEnabled) {
         // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one with the wrong context.
-        beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
+        beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
     }
 
     // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
@@ -2143,10 +1851,7 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
     if (localPaintingInfo.paintingRoot && !renderer()->isDescendantOf(localPaintingInfo.paintingRoot))
         paintingRootForRenderer = localPaintingInfo.paintingRoot;
 
-    if (localPaintingInfo.overlapTestRequests && isSelfPaintingLayer)
-        performOverlapTests(*localPaintingInfo.overlapTestRequests, localPaintingInfo.rootLayer, this);
-
-    bool forceBlackText = localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText;
+    ASSERT(!(localPaintingInfo.paintBehavior & PaintBehaviorForceBlackText));
     bool selectionOnly  = localPaintingInfo.paintBehavior & PaintBehaviorSelectionOnly;
 
     bool shouldPaintBackground = isPaintingCompositedBackground && shouldPaintContent && !selectionOnly;
@@ -2163,43 +1868,35 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
     else if (paintFlags & PaintLayerPaintingRootBackgroundOnly)
         paintBehavior |= PaintBehaviorRootBackgroundOnly;
 
-    LayerFragments layerFragments;
-    if (shouldPaintContent || shouldPaintOutline || isPaintingOverlayScrollbars) {
-        // Collect the fragments. This will compute the clip rectangles and paint offsets for each layer fragment, as well as whether or not the content of each
-        // fragment should paint.
-        collectFragments(layerFragments, localPaintingInfo.rootLayer, localPaintingInfo.region, localPaintingInfo.paintDirtyRect,
-            (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
-            (isPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetFromRoot);
-        updatePaintingInfoForFragments(layerFragments, localPaintingInfo, paintFlags, shouldPaintContent, &offsetFromRoot);
-    }
-
-    if (shouldPaintBackground)
+    if (shouldPaintBackground) {
         paintBackgroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
-                localPaintingInfo, paintBehavior, paintingRootForRenderer);
+            localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
+    }
 
     if (shouldPaintNegZOrderList)
-        paintList(m_stackingNode->negZOrderList(), context, localPaintingInfo, paintFlags);
+        paintChildren(NegativeZOrderChildren, context, paintingInfo, paintFlags);
 
-    if (shouldPaintOwnContents)
+    if (shouldPaintOwnContents) {
         paintForegroundForFragments(layerFragments, context, transparencyLayerContext, paintingInfo.paintDirtyRect, haveTransparency,
-                localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, forceBlackText);
+            localPaintingInfo, paintBehavior, paintingRootForRenderer, selectionOnly, paintFlags);
+    }
 
     if (shouldPaintOutline)
-        paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer);
+        paintOutlineForFragments(layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
 
-    if (shouldPaintNormalFlowAndPosZOrderLists) {
-        paintList(m_stackingNode->normalFlowList(), context, localPaintingInfo, paintFlags);
-        paintList(m_stackingNode->posZOrderList(), context, localPaintingInfo, paintFlags);
-    }
+    if (shouldPaintNormalFlowAndPosZOrderLists)
+        paintChildren(NormalFlowChildren | PositiveZOrderChildren, context, paintingInfo, paintFlags);
 
     if (shouldPaintOverlayScrollbars)
-        paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo);
+        paintOverflowControlsForFragments(layerFragments, context, localPaintingInfo, paintFlags);
 
     if (filterPainter.hasStartedFilterEffect()) {
         // Apply the correct clipping (ie. overflow: hidden).
         // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
         ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
-        clipToRect(localPaintingInfo.rootLayer, transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
+        if (!deferredFiltersEnabled)
+            clipToRect(localPaintingInfo, transparencyLayerContext, backgroundRect, paintFlags);
+
         context = filterPainter.applyFilterEffect();
         restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
     }
@@ -2208,11 +1905,11 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
     ASSERT(transparencyLayerContext == context);
 
     if (shouldPaintMask)
-        paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer);
+        paintMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
 
     if (shouldPaintClippingMask) {
         // Paint the border radius mask for the fragments.
-        paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer);
+        paintChildClippingMaskForFragments(layerFragments, context, localPaintingInfo, paintingRootForRenderer, paintFlags);
     }
 
     // End our transparency layer
@@ -2223,10 +1920,7 @@ void RenderLayer::paintLayerContents(GraphicsContext* context, const LayerPainti
     }
 
     if (resourceClipper)
-        resourceClipper->postApplyStatefulResource(renderer(), context, clipperContext);
-
-    if (hasClipPath)
-        context->restore();
+        resourceClipper->postApplyStatefulResource(renderer(), context, clipperState);
 }
 
 void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags, const LayoutPoint& translationOffset)
@@ -2242,29 +1936,46 @@ void RenderLayer::paintLayerByApplyingTransform(GraphicsContext* context, const
     LayoutSize adjustedSubPixelAccumulation = paintingInfo.subPixelAccumulation + (delta - roundedDelta);
 
     // Apply the transform.
-    GraphicsContextStateSaver stateSaver(*context);
-    context->concatCTM(transform.toAffineTransform());
+    GraphicsContextStateSaver stateSaver(*context, false);
+    if (!transform.isIdentity()) {
+        stateSaver.save();
+        context->concatCTM(transform.toAffineTransform());
+    }
 
     // Now do a paint with the root layer shifted to be us.
     LayerPaintingInfo transformedPaintingInfo(this, enclosingIntRect(transform.inverse().mapRect(paintingInfo.paintDirtyRect)), paintingInfo.paintBehavior,
-        adjustedSubPixelAccumulation, paintingInfo.paintingRoot, paintingInfo.region, paintingInfo.overlapTestRequests);
+        adjustedSubPixelAccumulation, paintingInfo.paintingRoot);
     paintLayerContentsAndReflection(context, transformedPaintingInfo, paintFlags);
 }
 
-void RenderLayer::paintList(Vector<RenderLayerStackingNode*>* list, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
+bool RenderLayer::shouldPaintLayerInSoftwareMode(const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
 {
-    if (!list)
-        return;
+    DisableCompositingQueryAsserts disabler;
 
+    return compositingState() == NotComposited
+        || compositingState() == HasOwnBackingButPaintsIntoAncestor
+        || (paintingInfo.paintBehavior & PaintBehaviorFlattenCompositingLayers)
+        || ((paintFlags & PaintLayerPaintingReflection) && !has3DTransform())
+        || paintForFixedRootBackground(this, paintFlags);
+}
+
+void RenderLayer::paintChildren(unsigned childrenToVisit, GraphicsContext* context, const LayerPaintingInfo& paintingInfo, PaintLayerFlags paintFlags)
+{
     if (!hasSelfPaintingLayerDescendant())
         return;
 
-#if !ASSERT_DISABLED
+#if ENABLE(ASSERT)
     LayerListMutationDetector mutationChecker(m_stackingNode.get());
 #endif
 
-    for (size_t i = 0; i < list->size(); ++i) {
-        RenderLayer* childLayer = list->at(i)->layer();
+    RenderLayerStackingNodeIterator iterator(*m_stackingNode, childrenToVisit);
+    while (RenderLayerStackingNode* child = iterator.next()) {
+        RenderLayer* childLayer = child->layer();
+        // If this RenderLayer should paint into its own backing or a grouped backing, that will be done via CompositedLayerMapping::paintContents()
+        // and CompositedLayerMapping::doPaintTask().
+        if (!childLayer->shouldPaintLayerInSoftwareMode(paintingInfo, paintFlags))
+            continue;
+
         if (!childLayer->isPaginated())
             childLayer->paintLayer(context, paintingInfo, paintFlags);
         else
@@ -2272,15 +1983,17 @@ void RenderLayer::paintList(Vector<RenderLayerStackingNode*>* list, GraphicsCont
     }
 }
 
-void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, RenderRegion* region, const LayoutRect& dirtyRect,
-    ClipRectsType clipRectsType, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot,
-    const LayoutRect* layerBoundingBox)
+void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer* rootLayer, const LayoutRect& dirtyRect,
+    ClipRectsCacheSlot clipRectsCacheSlot, OverlayScrollbarSizeRelevancy inOverlayScrollbarSizeRelevancy, ShouldRespectOverflowClip respectOverflowClip, const LayoutPoint* offsetFromRoot,
+    const LayoutSize& subPixelAccumulation, const LayoutRect* layerBoundingBox)
 {
     if (!enclosingPaginationLayer() || hasTransform()) {
         // For unpaginated layers, there is only one fragment.
         LayerFragment fragment;
-        ClipRectsContext clipRectsContext(rootLayer, region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
-        calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot);
+        ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy, subPixelAccumulation);
+        if (respectOverflowClip == IgnoreOverflowClip)
+            clipRectsContext.setIgnoreOverflowClip();
+        clipper().calculateRects(clipRectsContext, dirtyRect, fragment.layerBounds, fragment.backgroundRect, fragment.foregroundRect, fragment.outlineRect, offsetFromRoot);
         fragments.append(fragment);
         return;
     }
@@ -2291,16 +2004,18 @@ void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer*
 
     // Calculate clip rects relative to the enclosingPaginationLayer. The purpose of this call is to determine our bounds clipped to intermediate
     // layers between us and the pagination context. It's important to minimize the number of fragments we need to create and this helps with that.
-    ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
+    ClipRectsContext paginationClipRectsContext(enclosingPaginationLayer(), clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy);
+    if (respectOverflowClip == IgnoreOverflowClip)
+        paginationClipRectsContext.setIgnoreOverflowClip();
     LayoutRect layerBoundsInFlowThread;
     ClipRect backgroundRectInFlowThread;
     ClipRect foregroundRectInFlowThread;
     ClipRect outlineRectInFlowThread;
-    calculateRects(paginationClipRectsContext, PaintInfo::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread,
+    clipper().calculateRects(paginationClipRectsContext, PaintInfo::infiniteRect(), layerBoundsInFlowThread, backgroundRectInFlowThread, foregroundRectInFlowThread,
         outlineRectInFlowThread, &offsetWithinPaginatedLayer);
 
     // Take our bounding box within the flow thread and clip it.
-    LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : boundingBox(enclosingPaginationLayer(), 0, &offsetWithinPaginatedLayer);
+    LayoutRect layerBoundingBoxInFlowThread = layerBoundingBox ? *layerBoundingBox : physicalBoundingBox(enclosingPaginationLayer(), &offsetWithinPaginatedLayer);
     layerBoundingBoxInFlowThread.intersect(backgroundRectInFlowThread.rect());
 
     // Shift the dirty rect into flow thread coordinates.
@@ -2320,8 +2035,10 @@ void RenderLayer::collectFragments(LayerFragments& fragments, const RenderLayer*
     // Get the parent clip rects of the pagination layer, since we need to intersect with that when painting column contents.
     ClipRect ancestorClipRect = dirtyRect;
     if (enclosingPaginationLayer()->parent()) {
-        ClipRectsContext clipRectsContext(rootLayer, region, clipRectsType, inOverlayScrollbarSizeRelevancy, respectOverflowClip);
-        ancestorClipRect = enclosingPaginationLayer()->backgroundClipRect(clipRectsContext);
+        ClipRectsContext clipRectsContext(rootLayer, clipRectsCacheSlot, inOverlayScrollbarSizeRelevancy);
+        if (respectOverflowClip == IgnoreOverflowClip)
+            clipRectsContext.setIgnoreOverflowClip();
+        ancestorClipRect = enclosingPaginationLayer()->clipper().backgroundClipRect(clipRectsContext);
         ancestorClipRect.intersect(dirtyRect);
     }
 
@@ -2362,10 +2079,10 @@ void RenderLayer::paintTransformedLayerIntoFragments(GraphicsContext* context, c
 {
     LayerFragments enclosingPaginationFragments;
     LayoutPoint offsetOfPaginationLayerFromRoot;
-    LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.paintBehavior);
-    enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.region, paintingInfo.paintDirtyRect,
-        (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
-        (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetOfPaginationLayerFromRoot, &transformedExtent);
+    LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
+    enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect,
+        (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
+        shouldRespectOverflowClip(paintFlags, renderer()), &offsetOfPaginationLayerFromRoot, paintingInfo.subPixelAccumulation, &transformedExtent);
 
     for (size_t i = 0; i < enclosingPaginationFragments.size(); ++i) {
         const LayerFragment& fragment = enclosingPaginationFragments.at(i);
@@ -2378,22 +2095,32 @@ void RenderLayer::paintTransformedLayerIntoFragments(GraphicsContext* context, c
         if (parent() != enclosingPaginationLayer()) {
             enclosingPaginationLayer()->convertToLayerCoords(paintingInfo.rootLayer, offsetOfPaginationLayerFromRoot);
 
-            ClipRectsContext clipRectsContext(enclosingPaginationLayer(), paintingInfo.region, (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects,
-                IgnoreOverlayScrollbarSize, (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip);
-            LayoutRect parentClipRect = backgroundClipRect(clipRectsContext).rect();
+            ClipRectsContext clipRectsContext(enclosingPaginationLayer(), (paintFlags & PaintLayerUncachedClipRects) ? UncachedClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize);
+            if (shouldRespectOverflowClip(paintFlags, renderer()) == IgnoreOverflowClip)
+                clipRectsContext.setIgnoreOverflowClip();
+            LayoutRect parentClipRect = clipper().backgroundClipRect(clipRectsContext).rect();
             parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
             clipRect.intersect(parentClipRect);
         }
 
-        parent()->clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, clipRect);
+        parent()->clipToRect(paintingInfo, context, clipRect, paintFlags);
         paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset);
         parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
     }
 }
 
+static inline LayoutSize subPixelAccumulationIfNeeded(const LayoutSize& subPixelAccumulation, CompositingState compositingState)
+{
+    // Only apply the sub-pixel accumulation if we don't paint into our own backing layer, otherwise the position
+    // of the renderer already includes any sub-pixel offset.
+    if (compositingState == PaintsIntoOwnBacking)
+        return LayoutSize();
+    return subPixelAccumulation;
+}
+
 void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
     const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
-    RenderObject* paintingRootForRenderer)
+    RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
 {
     for (size_t i = 0; i < layerFragments.size(); ++i) {
         const LayerFragment& fragment = layerFragments.at(i);
@@ -2402,18 +2129,18 @@ void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen
 
         // Begin transparency layers lazily now that we know we have to paint something.
         if (haveTransparency || paintsWithBlendMode())
-            beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
+            beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
 
         if (localPaintingInfo.clipToDirtyRect) {
             // Paint our background first, before painting any child layers.
             // Establish the clip used to paint our background.
-            clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
+            clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
         }
 
         // Paint the background.
         // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
-        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
-        renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
+        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseBlockBackground, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
+        renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
 
         if (localPaintingInfo.clipToDirtyRect)
             restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
@@ -2422,35 +2149,33 @@ void RenderLayer::paintBackgroundForFragments(const LayerFragments& layerFragmen
 
 void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragments, GraphicsContext* context, GraphicsContext* transparencyLayerContext,
     const LayoutRect& transparencyPaintDirtyRect, bool haveTransparency, const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior,
-    RenderObject* paintingRootForRenderer, bool selectionOnly, bool forceBlackText)
+    RenderObject* paintingRootForRenderer, bool selectionOnly, PaintLayerFlags paintFlags)
 {
     // Begin transparency if we have something to paint.
     if (haveTransparency || paintsWithBlendMode()) {
         for (size_t i = 0; i < layerFragments.size(); ++i) {
             const LayerFragment& fragment = layerFragments.at(i);
             if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) {
-                beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
+                beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
                 break;
             }
         }
     }
 
-    PaintBehavior localPaintBehavior = forceBlackText ? (PaintBehavior)PaintBehaviorForceBlackText : paintBehavior;
-
     // Optimize clipping for the single fragment case.
     bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty();
     if (shouldClip)
-        clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect);
+        clipToRect(localPaintingInfo, context, layerFragments[0].foregroundRect, paintFlags);
 
-    // We have to loop through every fragment multiple times, since we have to repaint in each specific phase in order for
+    // We have to loop through every fragment multiple times, since we have to issue paint invalidations in each specific phase in order for
     // interleaving of the fragments to work properly.
     paintForegroundForFragmentsWithPhase(selectionOnly ? PaintPhaseSelection : PaintPhaseChildBlockBackgrounds, layerFragments,
-        context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
+        context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
 
     if (!selectionOnly) {
-        paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
-        paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
-        paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, localPaintBehavior, paintingRootForRenderer);
+        paintForegroundForFragmentsWithPhase(PaintPhaseFloat, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
+        paintForegroundForFragmentsWithPhase(PaintPhaseForeground, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
+        paintForegroundForFragmentsWithPhase(PaintPhaseChildOutlines, layerFragments, context, localPaintingInfo, paintBehavior, paintingRootForRenderer, paintFlags);
     }
 
     if (shouldClip)
@@ -2458,7 +2183,7 @@ void RenderLayer::paintForegroundForFragments(const LayerFragments& layerFragmen
 }
 
 void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const LayerFragments& layerFragments, GraphicsContext* context,
-    const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer)
+    const LayerPaintingInfo& localPaintingInfo, PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
 {
     bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() > 1;
 
@@ -2468,12 +2193,10 @@ void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const L
             continue;
 
         if (shouldClip)
-            clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
+            clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags);
 
-        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
-        if (phase == PaintPhaseForeground)
-            paintInfo.overlapTestRequests = localPaintingInfo.overlapTestRequests;
-        renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
+        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
+        renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
 
         if (shouldClip)
             restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
@@ -2481,7 +2204,7 @@ void RenderLayer::paintForegroundForFragmentsWithPhase(PaintPhase phase, const L
 }
 
 void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
-    PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer)
+    PaintBehavior paintBehavior, RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
 {
     for (size_t i = 0; i < layerFragments.size(); ++i) {
         const LayerFragment& fragment = layerFragments.at(i);
@@ -2489,15 +2212,15 @@ void RenderLayer::paintOutlineForFragments(const LayerFragments& layerFragments,
             continue;
 
         // Paint our own outline
-        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
-        clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.outlineRect, DoNotIncludeSelfForBorderRadius);
-        renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
+        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
+        clipToRect(localPaintingInfo, context, fragment.outlineRect, paintFlags, DoNotIncludeSelfForBorderRadius);
+        renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
         restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect);
     }
 }
 
 void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
-    RenderObject* paintingRootForRenderer)
+    RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
 {
     for (size_t i = 0; i < layerFragments.size(); ++i) {
         const LayerFragment& fragment = layerFragments.at(i);
@@ -2505,12 +2228,12 @@ void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, Gr
             continue;
 
         if (localPaintingInfo.clipToDirtyRect)
-            clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
+            clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
 
         // Paint the mask.
         // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
-        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
-        renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
+        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseMask, PaintBehaviorNormal, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
+        renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
 
         if (localPaintingInfo.clipToDirtyRect)
             restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
@@ -2518,7 +2241,7 @@ void RenderLayer::paintMaskForFragments(const LayerFragments& layerFragments, Gr
 }
 
 void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo,
-    RenderObject* paintingRootForRenderer)
+    RenderObject* paintingRootForRenderer, PaintLayerFlags paintFlags)
 {
     for (size_t i = 0; i < layerFragments.size(); ++i) {
         const LayerFragment& fragment = layerFragments.at(i);
@@ -2526,24 +2249,24 @@ void RenderLayer::paintChildClippingMaskForFragments(const LayerFragments& layer
             continue;
 
         if (localPaintingInfo.clipToDirtyRect)
-            clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self.
+            clipToRect(localPaintingInfo, context, fragment.foregroundRect, paintFlags, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self.
 
         // Paint the the clipped mask.
-        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, localPaintingInfo.region, 0, 0, localPaintingInfo.rootLayer->renderer());
-        renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation));
+        PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, 0, localPaintingInfo.rootLayer->renderer());
+        renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
 
         if (localPaintingInfo.clipToDirtyRect)
             restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
     }
 }
 
-void RenderLayer::paintOverflowControlsForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo)
+void RenderLayer::paintOverflowControlsForFragments(const LayerFragments& layerFragments, GraphicsContext* context, const LayerPaintingInfo& localPaintingInfo, PaintLayerFlags paintFlags)
 {
     for (size_t i = 0; i < layerFragments.size(); ++i) {
         const LayerFragment& fragment = layerFragments.at(i);
-        clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
+        clipToRect(localPaintingInfo, context, fragment.backgroundRect, paintFlags);
         if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea())
-            scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - renderBoxLocation() + localPaintingInfo.subPixelAccumulation)), pixelSnappedIntRect(fragment.backgroundRect.rect()), true);
+            scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true);
         restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
     }
 }
@@ -2552,7 +2275,7 @@ void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsCont
 {
     // We need to do multiple passes, breaking up our child layer into strips.
     Vector<RenderLayer*> columnLayers;
-    RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContainerNode();
+    RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode();
     for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
         if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
             columnLayers.append(curr);
@@ -2561,8 +2284,9 @@ void RenderLayer::paintPaginatedChildLayer(RenderLayer* childLayer, GraphicsCont
     }
 
     // It is possible for paintLayer() to be called after the child layer ceases to be paginated but before
-    // updateLayerPositions() is called and resets the isPaginated() flag, see <rdar://problem/10098679>.
-    // If this is the case, just bail out, since the upcoming call to updateLayerPositions() will repaint the layer.
+    // updatePaginationRecusive() is called and resets the isPaginated() flag, see <rdar://problem/10098679>.
+    // If this is the case, just bail out, since the upcoming call to updatePaginationRecusive() will paint invalidate the layer.
+    // FIXME: Is this true anymore? This seems very suspicious.
     if (!columnLayers.size())
         return;
 
@@ -2616,7 +2340,7 @@ void RenderLayer::paintChildLayerIntoColumns(RenderLayer* childLayer, GraphicsCo
 
             // Each strip pushes a clip, since column boxes are specified as being
             // like overflow:hidden.
-            context->clip(pixelSnappedIntRect(colRect));
+            context->clip(enclosingIntRect(colRect));
 
             if (!colIndex) {
                 // Apply a translation transform to change where the layer paints.
@@ -2685,9 +2409,9 @@ bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation&
 
     // RenderView should make sure to update layout before entering hit testing
     ASSERT(!renderer()->frame()->view()->layoutPending());
-    ASSERT(!renderer()->document().renderer()->needsLayout());
+    ASSERT(!renderer()->document().renderView()->needsLayout());
 
-    LayoutRect hitTestArea = isOutOfFlowRenderFlowThread() ? toRenderFlowThread(renderer())->borderBoxRect() : renderer()->view()->documentRect();
+    LayoutRect hitTestArea = renderer()->view()->documentRect();
     if (!request.ignoreClipping())
         hitTestArea.intersect(frameVisibleRect(renderer()));
 
@@ -2696,7 +2420,10 @@ bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation&
         // We didn't hit any layer. If we are the root layer and the mouse is -- or just was -- down,
         // return ourselves. We do this so mouse events continue getting delivered after a drag has
         // exited the WebView, and so hit testing over a scrollbar hits the content document.
-        if (!request.isChildFrameHitTest() && (request.active() || request.release()) && isRootLayer()) {
+        // In addtion, it is possible for the mouse to stay in the document but there is no element.
+        // At that time, the events of the mouse should be fired.
+        LayoutPoint hitPoint = hitTestLocation.point();
+        if (!request.isChildFrameHitTest() && ((request.active() || request.release()) || (request.move() && hitTestArea.contains(hitPoint.x(), hitPoint.y()))) && isRootLayer()) {
             renderer()->updateHitTestResult(result, toRenderView(renderer())->flipForWritingMode(hitTestLocation.point()));
             insideLayer = this;
         }
@@ -2705,7 +2432,7 @@ bool RenderLayer::hitTest(const HitTestRequest& request, const HitTestLocation&
     // Now determine if the result is inside an anchor - if the urlElement isn't already set.
     Node* node = result.innerNode();
     if (node && !result.URLElement())
-        result.setURLElement(toElement(node->enclosingLinkEventParentOrSelf()));
+        result.setURLElement(node->enclosingLinkEventParentOrSelf());
 
     // Now return whether we were inside this layer (this will always be true for the root
     // layer).
@@ -2728,15 +2455,6 @@ bool RenderLayer::isInTopLayer() const
     return node && node->isElementNode() && toElement(node)->isInTopLayer();
 }
 
-bool RenderLayer::isInTopLayerSubtree() const
-{
-    for (const RenderLayer* layer = this; layer; layer = layer->parent()) {
-        if (layer->isInTopLayer())
-            return true;
-    }
-    return false;
-}
-
 // Compute the z-offset of the point in the transformState.
 // This is effectively projecting a ray normal to the plane of ancestor, finding where that
 // ray intersects target, and computing the z delta between those two points.
@@ -2834,8 +2552,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
 
         // Make sure the parent's clip rects have been calculated.
         if (parent()) {
-            ClipRectsContext clipRectsContext(rootLayer, hitTestLocation.region(), RootRelativeClipRects, IncludeOverlayScrollbarSize);
-            ClipRect clipRect = backgroundClipRect(clipRectsContext);
+            ClipRect clipRect = clipper().backgroundClipRect(ClipRectsContext(rootLayer, RootRelativeClipRects, IncludeOverlayScrollbarSize));
             // Go ahead and test the enclosing clip now.
             if (!clipRect.intersects(hitTestLocation))
                 return 0;
@@ -2876,7 +2593,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
 
     // The following are used for keeping track of the z-depth of the hit point of 3d-transformed
     // descendants.
-    double localZOffset = -numeric_limits<double>::infinity();
+    double localZOffset = -std::numeric_limits<double>::infinity();
     double* zOffsetForDescendantsPtr = 0;
     double* zOffsetForContentsPtr = 0;
 
@@ -2886,11 +2603,6 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
         // Our layers can depth-test with our container, so share the z depth pointer with the container, if it passed one down.
         zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
         zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
-    } else if (m_has3DTransformedDescendant) {
-        // Flattening layer with 3d children; use a local zOffset pointer to depth-test children and foreground.
-        depthSortDescendants = true;
-        zOffsetForDescendantsPtr = zOffset ? zOffset : &localZOffset;
-        zOffsetForContentsPtr = zOffset ? zOffset : &localZOffset;
     } else if (zOffset) {
         zOffsetForDescendantsPtr = 0;
         // Container needs us to give back a z offset for the hit layer.
@@ -2901,7 +2613,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
     RenderLayer* candidateLayer = 0;
 
     // Begin by walking our list of positive layers from highest z-index down to the lowest z-index.
-    RenderLayer* hitLayer = hitTestList(m_stackingNode->posZOrderList(), rootLayer, request, result, hitTestRect, hitTestLocation,
+    RenderLayer* hitLayer = hitTestChildren(PositiveZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
                                         localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
     if (hitLayer) {
         if (!depthSortDescendants)
@@ -2910,7 +2622,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
     }
 
     // Now check our overflow objects.
-    hitLayer = hitTestList(m_stackingNode->normalFlowList(), rootLayer, request, result, hitTestRect, hitTestLocation,
+    hitLayer = hitTestChildren(NormalFlowChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
                            localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
     if (hitLayer) {
         if (!depthSortDescendants)
@@ -2920,7 +2632,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
 
     // Collect the fragments. This will compute the clip rectangles for each layer fragment.
     LayerFragments layerFragments;
-    collectFragments(layerFragments, rootLayer, hitTestLocation.region(), hitTestRect, RootRelativeClipRects, IncludeOverlayScrollbarSize);
+    collectFragments(layerFragments, rootLayer, hitTestRect, RootRelativeClipRects, IncludeOverlayScrollbarSize);
 
     if (m_scrollableArea && m_scrollableArea->hitTestResizerInFragments(layerFragments, hitTestLocation)) {
         renderer()->updateHitTestResult(result, hitTestLocation.point());
@@ -2948,7 +2660,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
     }
 
     // Now check our negative z-index children.
-    hitLayer = hitTestList(m_stackingNode->negZOrderList(), rootLayer, request, result, hitTestRect, hitTestLocation,
+    hitLayer = hitTestChildren(NegativeZOrderChildren, rootLayer, request, result, hitTestRect, hitTestLocation,
         localTransformState.get(), zOffsetForDescendantsPtr, zOffset, unflattenedTransformState.get(), depthSortDescendants);
     if (hitLayer) {
         if (!depthSortDescendants)
@@ -3002,9 +2714,10 @@ RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLa
 {
     LayerFragments enclosingPaginationFragments;
     LayoutPoint offsetOfPaginationLayerFromRoot;
-    LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox);
-    enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestLocation.region(), hitTestRect,
-        RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, &transformedExtent);
+    // FIXME: We're missing a sub-pixel offset here crbug.com/348728
+    LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox, LayoutSize());
+    enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestRect,
+        RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent);
 
     for (int i = enclosingPaginationFragments.size() - 1; i >= 0; --i) {
         const LayerFragment& fragment = enclosingPaginationFragments.at(i);
@@ -3016,9 +2729,7 @@ RenderLayer* RenderLayer::hitTestTransformedLayerInFragments(RenderLayer* rootLa
         // Now compute the clips within a given fragment
         if (parent() != enclosingPaginationLayer()) {
             enclosingPaginationLayer()->convertToLayerCoords(rootLayer, offsetOfPaginationLayerFromRoot);
-
-            ClipRectsContext clipRectsContext(enclosingPaginationLayer(), hitTestLocation.region(), RootRelativeClipRects, IncludeOverlayScrollbarSize);
-            LayoutRect parentClipRect = backgroundClipRect(clipRectsContext).rect();
+            LayoutRect parentClipRect = clipper().backgroundClipRect(ClipRectsContext(enclosingPaginationLayer(), RootRelativeClipRects, IncludeOverlayScrollbarSize)).rect();
             parentClipRect.moveBy(fragment.paginationOffset + offsetOfPaginationLayerFromRoot);
             clipRect.intersect(parentClipRect);
         }
@@ -3091,23 +2802,21 @@ bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult&
     return true;
 }
 
-RenderLayer* RenderLayer::hitTestList(Vector<RenderLayerStackingNode*>* list, RenderLayer* rootLayer,
-                                      const HitTestRequest& request, HitTestResult& result,
-                                      const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
-                                      const HitTestingTransformState* transformState,
-                                      double* zOffsetForDescendants, double* zOffset,
-                                      const HitTestingTransformState* unflattenedTransformState,
-                                      bool depthSortDescendants)
+RenderLayer* RenderLayer::hitTestChildren(ChildrenIteration childrentoVisit, RenderLayer* rootLayer,
+    const HitTestRequest& request, HitTestResult& result,
+    const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation,
+    const HitTestingTransformState* transformState,
+    double* zOffsetForDescendants, double* zOffset,
+    const HitTestingTransformState* unflattenedTransformState,
+    bool depthSortDescendants)
 {
-    if (!list)
-        return 0;
-
     if (!hasSelfPaintingLayerDescendant())
         return 0;
 
     RenderLayer* resultLayer = 0;
-    for (int i = list->size() - 1; i >= 0; --i) {
-        RenderLayer* childLayer = list->at(i)->layer();
+    RenderLayerStackingNodeReverseIterator iterator(*m_stackingNode, childrentoVisit);
+    while (RenderLayerStackingNode* child = iterator.next()) {
+        RenderLayer* childLayer = child->layer();
         RenderLayer* hitLayer = 0;
         HitTestResult tempResult(result.hitTestLocation());
         if (childLayer->isPaginated())
@@ -3136,7 +2845,7 @@ RenderLayer* RenderLayer::hitTestPaginatedChildLayer(RenderLayer* childLayer, Re
                                                      const LayoutRect& hitTestRect, const HitTestLocation& hitTestLocation, const HitTestingTransformState* transformState, double* zOffset)
 {
     Vector<RenderLayer*> columnLayers;
-    RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContainerNode();
+    RenderLayerStackingNode* ancestorNode = m_stackingNode->isNormalFlowOnly() ? parent()->stackingNode() : m_stackingNode->ancestorStackingContextNode();
     for (RenderLayer* curr = childLayer->parent(); curr; curr = curr->parent()) {
         if (curr->renderer()->hasColumns() && checkContainingBlockChainForPagination(childLayer->renderer(), curr->renderBox()))
             columnLayers.append(curr);
@@ -3252,166 +2961,15 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
     return 0;
 }
 
-void RenderLayer::parentClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const
+void RenderLayer::blockSelectionGapsBoundsChanged()
 {
-    ASSERT(parent());
-    if (clipRectsContext.clipRectsType == TemporaryClipRects) {
-        parent()->clipper().calculateClipRects(clipRectsContext, clipRects);
-        return;
-    }
-
-    parent()->m_clipper.updateClipRects(clipRectsContext);
-    clipRects = *parent()->clipper().clipRects(clipRectsContext);
-}
-
-static inline ClipRect backgroundClipRectForPosition(const ClipRects& parentRects, EPosition position)
-{
-    if (position == FixedPosition)
-        return parentRects.fixedClipRect();
-
-    if (position == AbsolutePosition)
-        return parentRects.posClipRect();
-
-    return parentRects.overflowClipRect();
-}
-
-ClipRect RenderLayer::backgroundClipRect(const ClipRectsContext& clipRectsContext) const
-{
-    ASSERT(parent());
-
-    ClipRects parentRects;
-
-    // If we cross into a different pagination context, then we can't rely on the cache.
-    // Just switch over to using TemporaryClipRects.
-    if (clipRectsContext.clipRectsType != TemporaryClipRects && parent()->enclosingPaginationLayer() != enclosingPaginationLayer()) {
-        ClipRectsContext tempContext(clipRectsContext);
-        tempContext.clipRectsType = TemporaryClipRects;
-        parentClipRects(tempContext, parentRects);
-    } else
-        parentClipRects(clipRectsContext, parentRects);
-
-    ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, renderer()->style()->position());
-    RenderView* view = renderer()->view();
-    ASSERT(view);
-
-    // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite.
-    if (parentRects.fixed() && clipRectsContext.rootLayer->renderer() == view && backgroundClipRect != PaintInfo::infiniteRect())
-        backgroundClipRect.move(view->frameView()->scrollOffsetForFixedPosition());
-
-    return backgroundClipRect;
-}
-
-void RenderLayer::calculateRects(const ClipRectsContext& clipRectsContext, const LayoutRect& paintDirtyRect, LayoutRect& layerBounds,
-    ClipRect& backgroundRect, ClipRect& foregroundRect, ClipRect& outlineRect, const LayoutPoint* offsetFromRoot) const
-{
-    if (clipRectsContext.rootLayer != this && parent()) {
-        backgroundRect = backgroundClipRect(clipRectsContext);
-        backgroundRect.intersect(paintDirtyRect);
-    } else
-        backgroundRect = paintDirtyRect;
-
-    foregroundRect = backgroundRect;
-    outlineRect = backgroundRect;
-
-    LayoutPoint offset;
-    if (offsetFromRoot)
-        offset = *offsetFromRoot;
-    else
-        convertToLayerCoords(clipRectsContext.rootLayer, offset);
-    layerBounds = LayoutRect(offset, size());
-
-    // Update the clip rects that will be passed to child layers.
-    if (renderer()->hasOverflowClip()) {
-        // This layer establishes a clip of some kind.
-        if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip) {
-            foregroundRect.intersect(toRenderBox(renderer())->overflowClipRect(offset, clipRectsContext.region, clipRectsContext.overlayScrollbarSizeRelevancy));
-            if (renderer()->style()->hasBorderRadius())
-                foregroundRect.setHasRadius(true);
-        }
-
-        // If we establish an overflow clip at all, then go ahead and make sure our background
-        // rect is intersected with our layer's bounds including our visual overflow,
-        // since any visual overflow like box-shadow or border-outset is not clipped by overflow:auto/hidden.
-        if (renderBox()->hasVisualOverflow()) {
-            // FIXME: Perhaps we should be propagating the borderbox as the clip rect for children, even though
-            //        we may need to inflate our clip specifically for shadows or outsets.
-            // FIXME: Does not do the right thing with CSS regions yet, since we don't yet factor in the
-            // individual region boxes as overflow.
-            LayoutRect layerBoundsWithVisualOverflow = renderBox()->visualOverflowRect();
-            renderBox()->flipForWritingMode(layerBoundsWithVisualOverflow); // Layers are in physical coordinates, so the overflow has to be flipped.
-            layerBoundsWithVisualOverflow.moveBy(offset);
-            if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)
-                backgroundRect.intersect(layerBoundsWithVisualOverflow);
-        } else {
-            // Shift the bounds to be for our region only.
-            LayoutRect bounds = renderBox()->borderBoxRectInRegion(clipRectsContext.region);
-            bounds.moveBy(offset);
-            if (this != clipRectsContext.rootLayer || clipRectsContext.respectOverflowClip == RespectOverflowClip)
-                backgroundRect.intersect(bounds);
-        }
-    }
-
-    // CSS clip (different than clipping due to overflow) can clip to any box, even if it falls outside of the border box.
-    if (renderer()->hasClip()) {
-        // Clip applies to *us* as well, so go ahead and update the damageRect.
-        LayoutRect newPosClip = toRenderBox(renderer())->clipRect(offset, clipRectsContext.region);
-        backgroundRect.intersect(newPosClip);
-        foregroundRect.intersect(newPosClip);
-        outlineRect.intersect(newPosClip);
-    }
-}
-
-LayoutRect RenderLayer::childrenClipRect() const
-{
-    // FIXME: border-radius not accounted for.
-    // FIXME: Regions not accounted for.
-    RenderView* renderView = renderer()->view();
-    RenderLayer* clippingRootLayer = clippingRootForPainting();
-    LayoutRect layerBounds;
-    ClipRect backgroundRect, foregroundRect, outlineRect;
-    ClipRectsContext clipRectsContext(clippingRootLayer, 0, TemporaryClipRects);
-    // Need to use temporary clip rects, because the value of 'dontClipToOverflow' may be different from the painting path (<rdar://problem/11844909>).
-    calculateRects(clipRectsContext, renderView->unscaledDocumentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
-    return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(foregroundRect.rect())).enclosingBoundingBox();
-}
-
-LayoutRect RenderLayer::selfClipRect() const
-{
-    // FIXME: border-radius not accounted for.
-    // FIXME: Regions not accounted for.
-    RenderView* renderView = renderer()->view();
-    RenderLayer* clippingRootLayer = clippingRootForPainting();
-    LayoutRect layerBounds;
-    ClipRect backgroundRect, foregroundRect, outlineRect;
-    ClipRectsContext clipRectsContext(clippingRootLayer, 0, PaintingClipRects);
-    calculateRects(clipRectsContext, renderView->documentRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
-    return clippingRootLayer->renderer()->localToAbsoluteQuad(FloatQuad(backgroundRect.rect())).enclosingBoundingBox();
-}
-
-LayoutRect RenderLayer::localClipRect() const
-{
-    // FIXME: border-radius not accounted for.
-    // FIXME: Regions not accounted for.
-    RenderLayer* clippingRootLayer = clippingRootForPainting();
-    LayoutRect layerBounds;
-    ClipRect backgroundRect, foregroundRect, outlineRect;
-    ClipRectsContext clipRectsContext(clippingRootLayer, 0, PaintingClipRects);
-    calculateRects(clipRectsContext, PaintInfo::infiniteRect(), layerBounds, backgroundRect, foregroundRect, outlineRect);
-
-    LayoutRect clipRect = backgroundRect.rect();
-    if (clipRect == PaintInfo::infiniteRect())
-        return clipRect;
-
-    LayoutPoint clippingRootOffset;
-    convertToLayerCoords(clippingRootLayer, clippingRootOffset);
-    clipRect.moveBy(-clippingRootOffset);
-
-    return clipRect;
+    setNeedsCompositingInputsUpdate();
 }
 
 void RenderLayer::addBlockSelectionGapsBounds(const LayoutRect& bounds)
 {
     m_blockSelectionGapsBounds.unite(enclosingIntRect(bounds));
+    blockSelectionGapsBoundsChanged();
 }
 
 void RenderLayer::clearBlockSelectionGapsBounds()
@@ -3419,12 +2977,13 @@ void RenderLayer::clearBlockSelectionGapsBounds()
     m_blockSelectionGapsBounds = IntRect();
     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
         child->clearBlockSelectionGapsBounds();
+    blockSelectionGapsBoundsChanged();
 }
 
-void RenderLayer::repaintBlockSelectionGaps()
+void RenderLayer::invalidatePaintForBlockSelectionGaps()
 {
     for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
-        child->repaintBlockSelectionGaps();
+        child->invalidatePaintForBlockSelectionGaps();
 
     if (m_blockSelectionGapsBounds.isEmpty())
         return;
@@ -3434,25 +2993,43 @@ void RenderLayer::repaintBlockSelectionGaps()
         RenderBox* box = renderBox();
         rect.move(-box->scrolledContentOffset());
         if (!scrollableArea()->usesCompositedScrolling())
-            rect.intersect(box->overflowClipRect(LayoutPoint(), 0)); // FIXME: Regions not accounted for.
+            rect.intersect(box->overflowClipRect(LayoutPoint()));
     }
     if (renderer()->hasClip())
-        rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint(), 0)); // FIXME: Regions not accounted for.
+        rect.intersect(toRenderBox(renderer())->clipRect(LayoutPoint()));
     if (!rect.isEmpty())
-        renderer()->repaintRectangle(rect);
+        renderer()->invalidatePaintRectangle(rect);
+}
+
+IntRect RenderLayer::blockSelectionGapsBounds() const
+{
+    if (!renderer()->isRenderBlock())
+        return IntRect();
+
+    RenderBlock* renderBlock = toRenderBlock(renderer());
+    LayoutRect gapRects = renderBlock->selectionGapRectsForPaintInvalidation(renderBlock);
+
+    return pixelSnappedIntRect(gapRects);
 }
 
 bool RenderLayer::hasBlockSelectionGapBounds() const
 {
-    return !m_blockSelectionGapsBounds.isEmpty();
+    // FIXME: it would be more accurate to return !blockSelectionGapsBounds().isEmpty(), but this is impossible
+    // at the moment because it causes invalid queries to layout-dependent code (crbug.com/372802).
+    // ASSERT(renderer()->document().lifecycle().state() >= DocumentLifecycle::LayoutClean);
+
+    if (!renderer()->isRenderBlock())
+        return false;
+
+    return toRenderBlock(renderer())->shouldPaintSelectionGaps();
 }
 
 bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutPoint* offsetFromRoot) const
 {
     // Always examine the canvas and the root.
-    // FIXME: Could eliminate the isRoot() check if we fix background painting so that the RenderView
+    // FIXME: Could eliminate the isDocumentElement() check if we fix background painting so that the RenderView
     // paints the root's background.
-    if (isRootLayer() || renderer()->isRoot())
+    if (isRootLayer() || renderer()->isDocumentElement())
         return true;
 
     // If we aren't an inline flow, and our layer bounds do intersect the damage rect, then we
@@ -3460,18 +3037,16 @@ bool RenderLayer::intersectsDamageRect(const LayoutRect& layerBounds, const Layo
     RenderView* view = renderer()->view();
     ASSERT(view);
     if (view && !renderer()->isRenderInline()) {
-        LayoutRect b = layerBounds;
-        b.inflate(view->maximalOutlineSize());
-        if (b.intersects(damageRect))
+        if (layerBounds.intersects(damageRect))
             return true;
     }
 
     // Otherwise we need to compute the bounding box of this single layer and see if it intersects
     // the damage rect.
-    return boundingBox(rootLayer, 0, offsetFromRoot).intersects(damageRect);
+    return physicalBoundingBox(rootLayer, offsetFromRoot).intersects(damageRect);
 }
 
-LayoutRect RenderLayer::localBoundingBox(CalculateLayerBoundsFlags flags) const
+LayoutRect RenderLayer::logicalBoundingBox() const
 {
     // There are three special cases we need to consider.
     // (1) Inline Flows.  For inline flows we will create a bounding box that fully encompasses all of the lines occupied by the
@@ -3483,11 +3058,11 @@ LayoutRect RenderLayer::localBoundingBox(CalculateLayerBoundsFlags flags) const
     // as part of our bounding box.  We do this because we are the responsible layer for both hit testing and painting those
     // floats.
     LayoutRect result;
-    if (renderer()->isInline() && renderer()->isRenderInline())
+    if (renderer()->isInline() && renderer()->isRenderInline()) {
         result = toRenderInline(renderer())->linesVisualOverflowBoundingBox();
-    else if (renderer()->isTableRow()) {
+    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()) {
+        for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) {
             if (child->isTableCell()) {
                 LayoutRect bbox = toRenderBox(child)->borderBoxRect();
                 result.unite(bbox);
@@ -3499,52 +3074,21 @@ LayoutRect RenderLayer::localBoundingBox(CalculateLayerBoundsFlags flags) const
     } else {
         RenderBox* box = renderBox();
         ASSERT(box);
-        if (!(flags & DontConstrainForMask) && box->hasMask()) {
-            result = box->maskClipRect();
-            box->flipForWritingMode(result); // The mask clip rect is in physical coordinates, so we have to flip, since localBoundingBox is not.
-        } else {
-            LayoutRect bbox = box->borderBoxRect();
-            result = bbox;
-            LayoutRect overflowRect = box->visualOverflowRect();
-            if (bbox != overflowRect)
-                result.unite(overflowRect);
-        }
+        result = box->borderBoxRect();
+        result.unite(box->visualOverflowRect());
     }
 
-    RenderView* view = renderer()->view();
-    ASSERT(view);
-    if (view)
-        result.inflate(view->maximalOutlineSize()); // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
-
+    ASSERT(renderer()->view());
     return result;
 }
 
-LayoutRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer, CalculateLayerBoundsFlags flags, const LayoutPoint* offsetFromRoot) const
+LayoutRect RenderLayer::physicalBoundingBox(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot) const
 {
-    LayoutRect result = localBoundingBox(flags);
-    if (renderer()->isBox())
+    LayoutRect result = logicalBoundingBox();
+    if (m_renderer->isBox())
         renderBox()->flipForWritingMode(result);
     else
-        renderer()->containingBlock()->flipForWritingMode(result);
-
-    if (enclosingPaginationLayer() && (flags & UseFragmentBoxes)) {
-        // Split our box up into the actual fragment boxes that render in the columns/pages and unite those together to
-        // get our true bounding box.
-        LayoutPoint offsetWithinPaginationLayer;
-        convertToLayerCoords(enclosingPaginationLayer(), offsetWithinPaginationLayer);
-        result.moveBy(offsetWithinPaginationLayer);
-
-        RenderFlowThread* enclosingFlowThread = toRenderFlowThread(enclosingPaginationLayer()->renderer());
-        result = enclosingFlowThread->fragmentsBoundingBox(result);
-
-        LayoutPoint delta;
-        if (offsetFromRoot)
-            delta = *offsetFromRoot;
-        else
-            enclosingPaginationLayer()->convertToLayerCoords(ancestorLayer, delta);
-        result.moveBy(delta);
-        return result;
-    }
+        m_renderer->containingBlock()->flipForWritingMode(result);
 
     LayoutPoint delta;
     if (offsetFromRoot)
@@ -3556,154 +3100,202 @@ LayoutRect RenderLayer::boundingBox(const RenderLayer* ancestorLayer, CalculateL
     return result;
 }
 
-IntRect RenderLayer::absoluteBoundingBox() const
+static void expandRectForReflectionAndStackingChildren(const RenderLayer* ancestorLayer, RenderLayer::CalculateBoundsOptions options, LayoutRect& result)
 {
-    return pixelSnappedIntRect(boundingBox(root()));
+    if (ancestorLayer->reflectionInfo() && !ancestorLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping())
+        result.unite(ancestorLayer->reflectionInfo()->reflectionLayer()->boundingBoxForCompositing(ancestorLayer));
+
+    ASSERT(ancestorLayer->stackingNode()->isStackingContext() || !ancestorLayer->stackingNode()->hasPositiveZOrderList());
+
+#if ENABLE(ASSERT)
+    LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(ancestorLayer)->stackingNode());
+#endif
+
+    RenderLayerStackingNodeIterator iterator(*ancestorLayer->stackingNode(), AllChildren);
+    while (RenderLayerStackingNode* node = iterator.next()) {
+        // Here we exclude both directly composited layers and squashing layers
+        // because those RenderLayers don't paint into the graphics layer
+        // for this RenderLayer. For example, the bounds of squashed RenderLayers
+        // will be included in the computation of the appropriate squashing
+        // GraphicsLayer.
+        if (options != RenderLayer::ApplyBoundsChickenEggHacks && node->layer()->compositingState() != NotComposited)
+            continue;
+        result.unite(node->layer()->boundingBoxForCompositing(ancestorLayer, options));
+    }
 }
 
-IntRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, const LayoutPoint* offsetFromRoot, CalculateLayerBoundsFlags flags) const
+LayoutRect RenderLayer::physicalBoundingBoxIncludingReflectionAndStackingChildren(const RenderLayer* ancestorLayer, const LayoutPoint& offsetFromRoot) const
 {
-    if (!isSelfPaintingLayer())
-        return IntRect();
-
-    // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580).
-    if ((flags & ExcludeHiddenDescendants) && this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant())
-        return IntRect();
+    LayoutPoint origin;
+    LayoutRect result = physicalBoundingBox(ancestorLayer, &origin);
 
-    RenderLayerModelObject* renderer = this->renderer();
+    const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
 
-    if (isRootLayer()) {
-        // The root layer is always just the size of the document.
-        return renderer->view()->unscaledDocumentRect();
-    }
+    expandRectForReflectionAndStackingChildren(this, DoNotApplyBoundsChickenEggHacks, result);
 
-    LayoutRect boundingBoxRect = localBoundingBox(flags);
+    result.moveBy(offsetFromRoot);
+    return result;
+}
 
-    if (renderer->isBox())
-        toRenderBox(renderer)->flipForWritingMode(boundingBoxRect);
-    else
-        renderer->containingBlock()->flipForWritingMode(boundingBoxRect);
-
-    if (renderer->isRoot()) {
-        // If the root layer becomes composited (e.g. because some descendant with negative z-index is composited),
-        // then it has to be big enough to cover the viewport in order to display the background. This is akin
-        // to the code in RenderBox::paintRootBoxFillLayers().
-        if (FrameView* frameView = renderer->view()->frameView()) {
-            LayoutUnit contentsWidth = frameView->contentsWidth();
-            LayoutUnit contentsHeight = frameView->contentsHeight();
-
-            boundingBoxRect.setWidth(max(boundingBoxRect.width(), contentsWidth - boundingBoxRect.x()));
-            boundingBoxRect.setHeight(max(boundingBoxRect.height(), contentsHeight - boundingBoxRect.y()));
-        }
-    }
+LayoutRect RenderLayer::boundingBoxForCompositing(const RenderLayer* ancestorLayer, CalculateBoundsOptions options) const
+{
+    if (!isSelfPaintingLayer())
+        return LayoutRect();
 
-    LayoutRect unionBounds = boundingBoxRect;
-    bool shouldIncludeTransform = paintsWithTransform(PaintBehaviorNormal) || (transform() && flags & PretendLayerHasOwnBacking);
+    if (!ancestorLayer)
+        ancestorLayer = this;
 
-    if (flags & UseLocalClipRectIfPossible) {
-        LayoutRect localClipRect = this->localClipRect();
-        if (localClipRect != PaintInfo::infiniteRect()) {
-            if ((flags & IncludeSelfTransform) && shouldIncludeTransform)
-                localClipRect = transform()->mapRect(localClipRect);
+    // FIXME: This could be improved to do a check like hasVisibleNonCompositingDescendantLayers() (bug 92580).
+    if (this != ancestorLayer && !hasVisibleContent() && !hasVisibleDescendant())
+        return LayoutRect();
 
-            LayoutPoint ancestorRelOffset;
-            convertToLayerCoords(ancestorLayer, ancestorRelOffset);
-            localClipRect.moveBy(ancestorRelOffset);
-            return pixelSnappedIntRect(localClipRect);
-        }
-    }
+    // The root layer is always just the size of the document.
+    if (isRootLayer())
+        return m_renderer->view()->unscaledDocumentRect();
 
-    // FIXME: should probably just pass 'flags' down to descendants.
-    CalculateLayerBoundsFlags descendantFlags = DefaultCalculateLayerBoundsFlags | (flags & ExcludeHiddenDescendants) | (flags & IncludeCompositedDescendants);
+    const bool shouldIncludeTransform = paintsWithTransform(PaintBehaviorNormal) || (options == ApplyBoundsChickenEggHacks && transform());
 
-    const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
+    LayoutRect localClipRect = clipper().localClipRect();
+    if (localClipRect != PaintInfo::infiniteRect()) {
+        if (shouldIncludeTransform)
+            localClipRect = transform()->mapRect(localClipRect);
 
-    if (m_reflectionInfo) {
-        RenderLayer* reflectionLayer = m_reflectionInfo->reflectionLayer();
-        if (!reflectionLayer->compositedLayerMapping()) {
-            IntRect childUnionBounds = reflectionLayer->calculateLayerBounds(this, 0, descendantFlags);
-            unionBounds.unite(childUnionBounds);
-        }
+        LayoutPoint delta;
+        convertToLayerCoords(ancestorLayer, delta);
+        localClipRect.moveBy(delta);
+        return localClipRect;
     }
 
-    ASSERT(m_stackingNode->isStackingContainer() || (!m_stackingNode->posZOrderList() || !m_stackingNode->posZOrderList()->size()));
+    LayoutPoint origin;
+    LayoutRect result = physicalBoundingBox(ancestorLayer, &origin);
 
-#if !ASSERT_DISABLED
-    LayerListMutationDetector mutationChecker(const_cast<RenderLayer*>(this)->stackingNode());
-#endif
+    const_cast<RenderLayer*>(this)->stackingNode()->updateLayerListsIfNeeded();
 
-    // FIXME: Descendants that are composited should not necessarily be skipped, if they don't paint into their own
-    // separate backing. Instead, they ought to contribute to the bounds of the layer we're trying to compute.
-    // This applies to all z-order lists below.
-    RenderLayerStackingNodeIterator iterator(*m_stackingNode.get(), AllChildren);
-    while (RenderLayerStackingNode* node = iterator.next()) {
-        if (flags & IncludeCompositedDescendants || !node->layer()->compositedLayerMapping()) {
-            IntRect childUnionBounds = node->layer()->calculateLayerBounds(this, 0, descendantFlags);
-            unionBounds.unite(childUnionBounds);
-        }
-    }
+    // Reflections are implemented with RenderLayers that hang off of the reflected layer. However,
+    // the reflection layer subtree does not include the subtree of the parent RenderLayer, so
+    // a recursive computation of stacking children yields no results. This breaks cases when there are stacking
+    // children of the parent, that need to be included in reflected composited bounds.
+    // Fix this by including composited bounds of stacking children of the reflected RenderLayer.
+    if (hasCompositedLayerMapping() && parent() && parent()->reflectionInfo() && parent()->reflectionInfo()->reflectionLayer() == this)
+        expandRectForReflectionAndStackingChildren(parent(), options, result);
+    else
+        expandRectForReflectionAndStackingChildren(this, options, result);
 
     // FIXME: We can optimize the size of the composited layers, by not enlarging
     // filtered areas with the outsets if we know that the filter is going to render in hardware.
     // https://bugs.webkit.org/show_bug.cgi?id=81239
-    if (flags & IncludeLayerFilterOutsets)
-        renderer->style()->filterOutsets().expandRect(unionBounds);
+    m_renderer->style()->filterOutsets().expandRect(result);
 
-    if ((flags & IncludeSelfTransform) && shouldIncludeTransform) {
-        TransformationMatrix* affineTrans = transform();
-        boundingBoxRect = affineTrans->mapRect(boundingBoxRect);
-        unionBounds = affineTrans->mapRect(unionBounds);
-    }
-
-    LayoutPoint ancestorRelOffset;
-    if (offsetFromRoot)
-        ancestorRelOffset = *offsetFromRoot;
-    else
-        convertToLayerCoords(ancestorLayer, ancestorRelOffset);
-    unionBounds.moveBy(ancestorRelOffset);
+    if (shouldIncludeTransform)
+        result = transform()->mapRect(result);
 
-    return pixelSnappedIntRect(unionBounds);
+    LayoutPoint delta;
+    convertToLayerCoords(ancestorLayer, delta);
+    result.moveBy(delta);
+    return result;
 }
 
 CompositingState RenderLayer::compositingState() const
 {
+    ASSERT(isAllowedToQueryCompositingState());
+
     // This is computed procedurally so there is no redundant state variable that
     // can get out of sync from the real actual compositing state.
 
+    if (m_groupedMapping) {
+        ASSERT(compositor()->layerSquashingEnabled());
+        ASSERT(!m_compositedLayerMapping);
+        return PaintsIntoGroupedBacking;
+    }
+
     if (!m_compositedLayerMapping)
         return NotComposited;
 
-    if (m_compositedLayerMapping && compositedLayerMapping()->paintsIntoCompositedAncestor())
+    if (compositedLayerMapping()->paintsIntoCompositedAncestor())
         return HasOwnBackingButPaintsIntoAncestor;
 
-    ASSERT(m_compositedLayerMapping);
     return PaintsIntoOwnBacking;
 }
 
+bool RenderLayer::isAllowedToQueryCompositingState() const
+{
+    if (gCompositingQueryMode == CompositingQueriesAreAllowed)
+        return true;
+    return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCompositingUpdate;
+}
+
+CompositedLayerMapping* RenderLayer::compositedLayerMapping() const
+{
+    ASSERT(isAllowedToQueryCompositingState());
+    return m_compositedLayerMapping.get();
+}
+
+GraphicsLayer* RenderLayer::graphicsLayerBacking() const
+{
+    switch (compositingState()) {
+    case NotComposited:
+        return 0;
+    case PaintsIntoGroupedBacking:
+        return groupedMapping()->squashingLayer();
+    default:
+        return compositedLayerMapping()->mainGraphicsLayer();
+    }
+}
+
+GraphicsLayer* RenderLayer::graphicsLayerBackingForScrolling() const
+{
+    switch (compositingState()) {
+    case NotComposited:
+        return 0;
+    case PaintsIntoGroupedBacking:
+        return groupedMapping()->squashingLayer();
+    default:
+        return compositedLayerMapping()->scrollingContentsLayer() ? compositedLayerMapping()->scrollingContentsLayer() : compositedLayerMapping()->mainGraphicsLayer();
+    }
+}
+
 CompositedLayerMapping* RenderLayer::ensureCompositedLayerMapping()
 {
     if (!m_compositedLayerMapping) {
-        m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(this));
-        compositor()->layerBecameComposited(this);
+        m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(*this));
+        m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
 
         updateOrRemoveFilterEffectRenderer();
-
-        if (RuntimeEnabledFeatures::cssCompositingEnabled())
-            compositedLayerMapping()->setBlendMode(m_blendMode);
     }
     return m_compositedLayerMapping.get();
 }
 
 void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed)
 {
-    if (m_compositedLayerMapping && !renderer()->documentBeingDestroyed())
-        compositor()->layerBecameNonComposited(this);
+    if (!layerBeingDestroyed) {
+        // We need to make sure our decendants get a geometry update. In principle,
+        // we could call setNeedsGraphicsLayerUpdate on our children, but that would
+        // require walking the z-order lists to find them. Instead, we over-invalidate
+        // by marking our parent as needing a geometry update.
+        if (RenderLayer* compositingParent = enclosingLayerWithCompositedLayerMapping(ExcludeSelf))
+            compositingParent->compositedLayerMapping()->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+    }
+
     m_compositedLayerMapping.clear();
 
     if (!layerBeingDestroyed)
         updateOrRemoveFilterEffectRenderer();
 }
 
+void RenderLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed)
+{
+    if (groupedMapping == m_groupedMapping)
+        return;
+
+    if (!layerBeingDestroyed && m_groupedMapping) {
+        m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+        m_groupedMapping->removeRenderLayerFromSquashingGraphicsLayer(this);
+    }
+    m_groupedMapping = groupedMapping;
+    if (!layerBeingDestroyed && m_groupedMapping)
+        m_groupedMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateSubtree);
+}
+
 bool RenderLayer::hasCompositedMask() const
 {
     return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer();
@@ -3714,11 +3306,25 @@ bool RenderLayer::hasCompositedClippingMask() const
     return m_compositedLayerMapping && m_compositedLayerMapping->hasChildClippingMaskLayer();
 }
 
+bool RenderLayer::clipsCompositingDescendantsWithBorderRadius() const
+{
+    RenderStyle* style = renderer()->style();
+    if (!style)
+        return false;
+
+    return compositor()->clipsCompositingDescendants(this) && style->hasBorderRadius();
+}
+
 bool RenderLayer::paintsWithTransform(PaintBehavior paintBehavior) const
 {
     return transform() && ((paintBehavior & PaintBehaviorFlattenCompositingLayers) || compositingState() != PaintsIntoOwnBacking);
 }
 
+bool RenderLayer::paintsWithBlendMode() const
+{
+    return m_renderer->hasBlendMode() && compositingState() != PaintsIntoOwnBacking;
+}
+
 bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
 {
     if (!isSelfPaintingLayer() && !hasSelfPaintingLayerDescendant())
@@ -3755,19 +3361,16 @@ bool RenderLayer::backgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect)
     if (renderer()->hasOverflowClip())
         return false;
 
-    return listBackgroundIsKnownToBeOpaqueInRect(m_stackingNode->posZOrderList(), localRect)
-        || listBackgroundIsKnownToBeOpaqueInRect(m_stackingNode->negZOrderList(), localRect)
-        || listBackgroundIsKnownToBeOpaqueInRect(m_stackingNode->normalFlowList(), localRect);
+    return childBackgroundIsKnownToBeOpaqueInRect(localRect);
 }
 
-bool RenderLayer::listBackgroundIsKnownToBeOpaqueInRect(const Vector<RenderLayerStackingNode*>* list, const LayoutRect& localRect) const
+bool RenderLayer::childBackgroundIsKnownToBeOpaqueInRect(const LayoutRect& localRect) const
 {
-    if (!list || list->isEmpty())
-        return false;
-
-    for (Vector<RenderLayerStackingNode*>::const_reverse_iterator iter = list->rbegin(); iter != list->rend(); ++iter) {
-        const RenderLayer* childLayer = (*iter)->layer();
-        if (childLayer->compositedLayerMapping())
+    RenderLayerStackingNodeReverseIterator revertseIterator(*m_stackingNode, PositiveZOrderChildren | NormalFlowChildren | NegativeZOrderChildren);
+    while (RenderLayerStackingNode* child = revertseIterator.next()) {
+        const RenderLayer* childLayer = child->layer();
+        // Stop at composited paint boundaries.
+        if (childLayer->isPaintInvalidationContainer())
             continue;
 
         if (!childLayer->canUseConvertToLayerCoords())
@@ -3784,46 +3387,24 @@ bool RenderLayer::listBackgroundIsKnownToBeOpaqueInRect(const Vector<RenderLayer
     return false;
 }
 
-void RenderLayer::setParent(RenderLayer* parent)
-{
-    if (parent == m_parent)
-        return;
-
-    if (m_parent && !renderer()->documentBeingDestroyed())
-        compositor()->layerWillBeRemoved(m_parent, this);
-
-    m_parent = parent;
-
-    if (m_parent && !renderer()->documentBeingDestroyed())
-        compositor()->layerWasAdded(m_parent, this);
-}
-
 bool RenderLayer::shouldBeSelfPaintingLayer() const
 {
-    return !m_stackingNode->isNormalFlowOnly()
+    if (renderer()->isRenderPart() && toRenderPart(renderer())->requiresAcceleratedCompositing())
+        return true;
+    return m_layerType == NormalLayer
         || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars())
-        || needsCompositedScrolling()
-        || renderer()->hasReflection()
-        || renderer()->hasMask()
-        || renderer()->isTableRow()
-        || renderer()->isCanvas()
-        || renderer()->isVideo()
-        || renderer()->isEmbeddedObject()
-        || renderer()->isRenderIFrame();
+        || needsCompositedScrolling();
 }
 
 void RenderLayer::updateSelfPaintingLayer()
 {
     bool isSelfPaintingLayer = shouldBeSelfPaintingLayer();
-    if (m_isSelfPaintingLayer == isSelfPaintingLayer)
+    if (this->isSelfPaintingLayer() == isSelfPaintingLayer)
         return;
 
     m_isSelfPaintingLayer = isSelfPaintingLayer;
-    if (!parent())
-        return;
-    if (isSelfPaintingLayer)
-        parent()->setAncestorChainHasSelfPaintingLayerDescendant();
-    else
+
+    if (parent())
         parent()->dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
 }
 
@@ -3834,7 +3415,7 @@ bool RenderLayer::hasNonEmptyChildRenderers() const
     // <img src=...>
     // </div>
     // so test for 0x0 RenderTexts here
-    for (RenderObject* child = renderer()->firstChild(); child; child = child->nextSibling()) {
+    for (RenderObject* child = renderer()->slowFirstChild(); child; child = child->nextSibling()) {
         if (!child->hasLayer()) {
             if (child->isRenderInline() || !child->isBox())
                 return true;
@@ -3846,14 +3427,9 @@ bool RenderLayer::hasNonEmptyChildRenderers() const
     return false;
 }
 
-static bool hasBoxDecorations(const RenderStyle* style)
-{
-    return style->hasBorder() || style->hasBorderRadius() || style->hasOutline() || style->hasAppearance() || style->boxShadow() || style->hasFilter();
-}
-
 bool RenderLayer::hasBoxDecorationsOrBackground() const
 {
-    return hasBoxDecorations(renderer()->style()) || renderer()->hasBackground();
+    return renderer()->style()->hasBoxDecorations() || renderer()->style()->hasBackground();
 }
 
 bool RenderLayer::hasVisibleBoxDecorations() const
@@ -3880,151 +3456,99 @@ bool RenderLayer::isVisuallyNonEmpty() const
     return false;
 }
 
-void RenderLayer::updateVisibilityAfterStyleChange(const RenderStyle* oldStyle)
-{
-    if (!oldStyle || (oldStyle->visibility() != renderer()->style()->visibility()))
-        compositor()->setNeedsUpdateCompositingRequirementsState();
-}
-
-void RenderLayer::updateOutOfFlowPositioned(const RenderStyle* oldStyle)
+void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
 {
-    if (oldStyle && (renderer()->style()->position() == oldStyle->position()))
-        return;
-
-    bool wasOutOfFlowPositioned = oldStyle && (oldStyle->position() == AbsolutePosition || oldStyle->position() == FixedPosition);
-    bool isOutOfFlowPositioned = renderer()->isOutOfFlowPositioned();
-    if (!wasOutOfFlowPositioned && !isOutOfFlowPositioned)
-        return;
-
-    // Even if the layer remains out-of-flow, a change to this property
-    // will likely change its containing block. We must clear these bits
-    // so that they can be set properly by the RenderLayerCompositor.
-    for (RenderLayer* ancestor = parent(); ancestor; ancestor = ancestor->parent())
-        ancestor->setHasUnclippedDescendant(false);
-
-    // Ensures that we reset the above bits correctly.
-    compositor()->setNeedsUpdateCompositingRequirementsState();
-
-    if (wasOutOfFlowPositioned && isOutOfFlowPositioned)
+    if (!newStyle->hasFilter() && (!oldStyle || !oldStyle->hasFilter()))
         return;
 
-    if (isOutOfFlowPositioned) {
-        setAncestorChainHasOutOfFlowPositionedDescendant();
-        compositor()->addOutOfFlowPositionedLayer(this);
-    } else {
-        dirtyAncestorChainHasSelfPaintingLayerDescendantStatus();
-        compositor()->removeOutOfFlowPositionedLayer(this);
-
-        // We need to reset the isUnclippedDescendant bit here because normally
-        // the "unclipped-ness" property is only updated in
-        // RenderLayerCompositor::updateCompositingRequirementsState(). However,
-        // it is only updated for layers which are known to be out of flow.
-        // Since this is no longer out of flow, we have to explicitly ensure
-        // that it doesn't think it is unclipped.
-        setIsUnclippedDescendant(false);
-    }
-}
-
-static bool hasOrHadFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
-{
-    ASSERT(newStyle);
-    return (oldStyle && oldStyle->hasFilter()) || newStyle->hasFilter();
+    updateOrRemoveFilterClients();
+    updateOrRemoveFilterEffectRenderer();
 }
 
-inline bool RenderLayer::needsCompositingLayersRebuiltForClip(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
+bool RenderLayer::attemptDirectCompositingUpdate(StyleDifference diff, const RenderStyle* oldStyle)
 {
-    ASSERT(newStyle);
-    return oldStyle && (oldStyle->clip() != newStyle->clip() || oldStyle->hasClip() != newStyle->hasClip());
-}
+    CompositingReasons oldPotentialCompositingReasonsFromStyle = m_potentialCompositingReasonsFromStyle;
+    compositor()->updatePotentialCompositingReasonsFromStyle(this);
 
-inline bool RenderLayer::needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
-{
-    ASSERT(newStyle);
-    return !compositedLayerMapping() && oldStyle && (oldStyle->overflowX() != newStyle->overflowX()) && m_stackingNode->ancestorStackingContainerNode()->layer()->hasCompositingDescendant();
-}
+    // This function implements an optimization for transforms and opacity.
+    // A common pattern is for a touchmove handler to update the transform
+    // and/or an opacity of an element every frame while the user moves their
+    // finger across the screen. The conditions below recognize when the
+    // compositing state is set up to receive a direct transform or opacity
+    // update.
 
-inline bool RenderLayer::needsCompositingLayersRebuiltForFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle, bool didPaintWithFilters) const
-{
-    if (!hasOrHadFilters(oldStyle, newStyle))
+    if (!diff.hasAtMostPropertySpecificDifferences(StyleDifference::TransformChanged | StyleDifference::OpacityChanged))
+        return false;
+    // The potentialCompositingReasonsFromStyle could have changed without
+    // a corresponding StyleDifference if an animation started or ended.
+    if (m_potentialCompositingReasonsFromStyle != oldPotentialCompositingReasonsFromStyle)
+        return false;
+    // We could add support for reflections if we updated the transform on
+    // the reflection layers.
+    if (renderer()->hasReflection())
+        return false;
+    // If we're unwinding a scheduleSVGFilterLayerUpdateHack(), then we can't
+    // perform a direct compositing update because the filters code is going
+    // to produce different output this time around. We can remove this code
+    // once we fix the chicken/egg bugs in the filters code and delete the
+    // scheduleSVGFilterLayerUpdateHack().
+    if (renderer()->node() && renderer()->node()->svgFilterNeedsLayerUpdate())
+        return false;
+    if (!m_compositedLayerMapping)
         return false;
 
-    if (renderer()->animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitFilter)) {
-        // When the compositor is performing the filter animation, we shouldn't touch the compositing layers.
-        // All of the layers above us should have been promoted to compositing layers already.
+    // To cut off almost all the work in the compositing update for
+    // this case, we treat inline transforms has having assumed overlap
+    // (similar to how we treat animated transforms). Notice that we read
+    // CompositingReasonInlineTransform from the m_compositingReasons, which
+    // means that the inline transform actually triggered assumed overlap in
+    // the overlap map.
+    if (diff.transformChanged() && !(m_compositingReasons & CompositingReasonInlineTransform))
         return false;
-    }
 
-    FilterOutsets newOutsets = newStyle->filterOutsets();
-    if (oldStyle && (oldStyle->filterOutsets() != newOutsets)) {
-        // When filter outsets change, we need to:
-        // (1) Recompute the overlap map to promote the correct layers to composited layers.
-        // (2) Update the composited layer bounds (and child GraphicsLayer positions) on platforms
-        //     whose compositors can't compute their own filter outsets.
-        return true;
-    }
+    // We composite transparent RenderLayers differently from non-transparent
+    // RenderLayers even when the non-transparent RenderLayers are already a
+    // stacking context.
+    if (diff.opacityChanged() && m_renderer->style()->hasOpacity() != oldStyle->hasOpacity())
+        return false;
 
-#if HAVE(COMPOSITOR_FILTER_OUTSETS)
-    if ((didPaintWithFilters != paintsWithFilters()) && !newOutsets.isZero()) {
-        // When the layer used to paint filters in software and now paints filters in the
-        // compositor, the compositing layer bounds need to change from including filter outsets to
-        // excluding filter outsets, on platforms whose compositors compute their own outsets.
-        // Similarly for the reverse change from compositor-painted to software-painted filters.
-        return true;
-    }
-#endif
+    updateTransform(oldStyle, renderer()->style());
 
-    return false;
+    // FIXME: Consider introducing a smaller graphics layer update scope
+    // that just handles transforms and opacity. GraphicsLayerUpdateLocal
+    // will also program bounds, clips, and many other properties that could
+    // not possibly have changed.
+    m_compositedLayerMapping->setNeedsGraphicsLayerUpdate(GraphicsLayerUpdateLocal);
+    compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterGeometryChange);
+    return true;
 }
 
-void RenderLayer::updateFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle)
+void RenderLayer::styleChanged(StyleDifference diff, const RenderStyle* oldStyle)
 {
-    if (!hasOrHadFilters(oldStyle, newStyle))
+    if (attemptDirectCompositingUpdate(diff, oldStyle))
         return;
 
-    updateOrRemoveFilterClients();
-    // During an accelerated animation, both WebKit and the compositor animate properties.
-    // However, WebKit shouldn't ask the compositor to update its filters if the compositor is performing the animation.
-    bool shouldUpdateFilters = compositedLayerMapping() && !renderer()->animation().isRunningAcceleratedAnimationOnRenderer(renderer(), CSSPropertyWebkitFilter);
-    if (shouldUpdateFilters)
-        compositedLayerMapping()->updateFilters(renderer()->style());
-    updateOrRemoveFilterEffectRenderer();
-}
-
-void RenderLayer::styleChanged(StyleDifference, const RenderStyle* oldStyle)
-{
     m_stackingNode->updateIsNormalFlowOnly();
+    m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle);
 
     if (m_scrollableArea)
         m_scrollableArea->updateAfterStyleChange(oldStyle);
-    m_stackingNode->updateStackingNodesAfterStyleChange(oldStyle);
-    updateVisibilityAfterStyleChange(oldStyle);
+
     // Overlay scrollbars can make this layer self-painting so we need
     // to recompute the bit once scrollbars have been updated.
     updateSelfPaintingLayer();
-    updateOutOfFlowPositioned(oldStyle);
 
-    updateReflectionInfo(oldStyle);
-
-    if (RuntimeEnabledFeatures::cssCompositingEnabled())
-        updateBlendMode();
+    if (!oldStyle || !renderer()->style()->reflectionDataEquivalent(oldStyle)) {
+        ASSERT(!oldStyle || diff.needsFullLayout());
+        updateReflectionInfo(oldStyle);
+    }
 
     updateDescendantDependentFlags();
-    updateTransform();
 
-    bool didPaintWithFilters = false;
-
-    if (paintsWithFilters())
-        didPaintWithFilters = true;
+    updateTransform(oldStyle, renderer()->style());
     updateFilters(oldStyle, renderer()->style());
 
-    const RenderStyle* newStyle = renderer()->style();
-    if (compositor()->updateLayerCompositingState(this)
-        || needsCompositingLayersRebuiltForClip(oldStyle, newStyle)
-        || needsCompositingLayersRebuiltForOverflow(oldStyle, newStyle)
-        || needsCompositingLayersRebuiltForFilters(oldStyle, newStyle, didPaintWithFilters))
-        compositor()->setCompositingLayersNeedRebuild();
-    else if (compositedLayerMapping())
-        compositedLayerMapping()->updateGraphicsLayerGeometry();
+    setNeedsCompositingInputsUpdate();
 }
 
 bool RenderLayer::scrollsOverflow() const
@@ -4035,66 +3559,26 @@ bool RenderLayer::scrollsOverflow() const
     return false;
 }
 
-bool RenderLayer::isCSSCustomFilterEnabled() const
-{
-    // We only want to enable shaders if WebGL is also enabled on this platform.
-    const Settings* settings = renderer()->document().settings();
-    return settings && RuntimeEnabledFeatures::cssCustomFilterEnabled() && settings->webGLEnabled();
-}
-
 FilterOperations RenderLayer::computeFilterOperations(const RenderStyle* style)
 {
     const FilterOperations& filters = style->filter();
     if (filters.hasReferenceFilter()) {
         for (size_t i = 0; i < filters.size(); ++i) {
             FilterOperation* filterOperation = filters.operations().at(i).get();
-            if (filterOperation->getOperationType() != FilterOperation::REFERENCE)
+            if (filterOperation->type() != FilterOperation::REFERENCE)
                 continue;
-            ReferenceFilterOperation* referenceOperation = static_cast<ReferenceFilterOperation*>(filterOperation);
+            ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation);
             // FIXME: Cache the ReferenceFilter if it didn't change.
             RefPtr<ReferenceFilter> referenceFilter = ReferenceFilter::create();
-            float zoom = style->effectiveZoom() * WebCore::deviceScaleFactor(renderer()->frame());
-            referenceFilter->setFilterResolution(FloatSize(zoom, zoom));
+            float zoom = style->effectiveZoom();
+            referenceFilter->setAbsoluteTransform(AffineTransform().scale(zoom, zoom));
             referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referenceFilter.get(), renderer(), referenceFilter->sourceGraphic(),
                 referenceOperation));
             referenceOperation->setFilter(referenceFilter.release());
         }
     }
 
-    if (!filters.hasCustomFilter())
-        return filters;
-
-    if (!isCSSCustomFilterEnabled()) {
-        // CSS Custom filters should not parse at all in this case, but there might be
-        // remaining styles that were parsed when the flag was enabled. Reproduces in DumpRenderTree
-        // because it resets the flag while the previous test is still loaded.
-        return FilterOperations();
-    }
-
-    FilterOperations outputFilters;
-    for (size_t i = 0; i < filters.size(); ++i) {
-        RefPtr<FilterOperation> filterOperation = filters.operations().at(i);
-        if (filterOperation->getOperationType() == FilterOperation::CUSTOM) {
-            // We have to wait until the program of CSS Shaders is loaded before setting it on the layer.
-            // Note that we will handle the loading of the shaders and repainting of the layer in updateOrRemoveFilterClients.
-            const CustomFilterOperation* customOperation = static_cast<const CustomFilterOperation*>(filterOperation.get());
-            RefPtr<CustomFilterProgram> program = customOperation->program();
-            if (!program->isLoaded())
-                continue;
-
-            CustomFilterGlobalContext* globalContext = renderer()->view()->customFilterGlobalContext();
-            RefPtr<CustomFilterValidatedProgram> validatedProgram = globalContext->getValidatedProgram(program->programInfo());
-            if (!validatedProgram->isInitialized())
-                continue;
-
-            RefPtr<ValidatedCustomFilterOperation> validatedOperation = ValidatedCustomFilterOperation::create(validatedProgram.release(),
-                customOperation->parameters(), customOperation->meshRows(), customOperation->meshColumns(), customOperation->meshType());
-            outputFilters.operations().append(validatedOperation.release());
-            continue;
-        }
-        outputFilters.operations().append(filterOperation.release());
-    }
-    return outputFilters;
+    return filters;
 }
 
 void RenderLayer::updateOrRemoveFilterClients()
@@ -4104,11 +3588,6 @@ void RenderLayer::updateOrRemoveFilterClients()
         return;
     }
 
-    if (renderer()->style()->filter().hasCustomFilter())
-        ensureFilterInfo()->updateCustomFilterClients(renderer()->style()->filter());
-    else if (hasFilterInfo())
-        filterInfo()->removeCustomFilterClients();
-
     if (renderer()->style()->filter().hasReferenceFilter())
         ensureFilterInfo()->updateReferenceFilterClients(renderer()->style()->filter());
     else if (hasFilterInfo())
@@ -4124,7 +3603,7 @@ void RenderLayer::updateOrRemoveFilterEffectRenderer()
         // Don't delete the whole filter info here, because we might use it
         // for loading CSS shader files.
         if (RenderLayerFilterInfo* filterInfo = this->filterInfo())
-            filterInfo->setRenderer(0);
+            filterInfo->setRenderer(nullptr);
 
         return;
     }
@@ -4132,69 +3611,98 @@ void RenderLayer::updateOrRemoveFilterEffectRenderer()
     RenderLayerFilterInfo* filterInfo = ensureFilterInfo();
     if (!filterInfo->renderer()) {
         RefPtr<FilterEffectRenderer> filterRenderer = FilterEffectRenderer::create();
-        RenderingMode renderingMode = renderer()->frame()->settings()->acceleratedFiltersEnabled() ? Accelerated : Unaccelerated;
-        filterRenderer->setRenderingMode(renderingMode);
         filterInfo->setRenderer(filterRenderer.release());
-
-        // We can optimize away code paths in other places if we know that there are no software filters.
-        renderer()->document().view()->setHasSoftwareFilters(true);
     }
 
     // If the filter fails to build, remove it from the layer. It will still attempt to
     // go through regular processing (e.g. compositing), but never apply anything.
     if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(renderer()->style())))
-        filterInfo->setRenderer(0);
+        filterInfo->setRenderer(nullptr);
 }
 
-void RenderLayer::filterNeedsRepaint()
+void RenderLayer::filterNeedsPaintInvalidation()
 {
-    toElement(renderer()->node())->scheduleLayerUpdate();
-    if (renderer()->view())
-        renderer()->repaint();
+    {
+        DeprecatedScheduleStyleRecalcDuringLayout marker(renderer()->document().lifecycle());
+        // It's possible for scheduleSVGFilterLayerUpdateHack to schedule a style recalc, which
+        // is a problem because this function can be called while performing layout.
+        // Presumably this represents an illegal data flow of layout or compositing
+        // information into the style system.
+        toElement(renderer()->node())->scheduleSVGFilterLayerUpdateHack();
+    }
+
+    renderer()->setShouldDoFullPaintInvalidation(true);
 }
 
 void RenderLayer::addLayerHitTestRects(LayerHitTestRects& rects) const
 {
+    computeSelfHitTestRects(rects);
+    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
+        child->addLayerHitTestRects(rects);
+}
+
+void RenderLayer::computeSelfHitTestRects(LayerHitTestRects& rects) const
+{
     if (!size().isEmpty()) {
         Vector<LayoutRect> rect;
 
         if (renderBox() && renderBox()->scrollsOverflow()) {
             // For scrolling layers, rects are taken to be in the space of the contents.
-            // We need to include both the entire contents, and also the bounding box
-            // of the layer in the space of it's parent (eg. for border / scroll bars).
-            rect.append(m_scrollableArea->overflowRect());
+            // We need to include the bounding box of the layer in the space of its parent
+            // (eg. for border / scroll bars) and if it's composited then the entire contents
+            // as well as they may be on another composited layer. Skip reporting contents
+            // for non-composited layers as they'll get projected to the same layer as the
+            // bounding box.
+            if (compositingState() != NotComposited)
+                rect.append(m_scrollableArea->overflowRect());
+
             rects.set(this, rect);
             if (const RenderLayer* parentLayer = parent()) {
                 LayerHitTestRects::iterator iter = rects.find(parentLayer);
-                if (iter == rects.end())
-                    iter = rects.add(parentLayer, Vector<LayoutRect>()).iterator;
-                iter->value.append(boundingBox(parentLayer));
+                if (iter == rects.end()) {
+                    rects.add(parentLayer, Vector<LayoutRect>()).storedValue->value.append(physicalBoundingBox(parentLayer));
+                } else {
+                    iter->value.append(physicalBoundingBox(parentLayer));
+                }
             }
         } else {
-            rect.append(localBoundingBox());
+            rect.append(logicalBoundingBox());
             rects.set(this, rect);
         }
     }
+}
 
-    for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
-        child->addLayerHitTestRects(rects);
+void RenderLayer::setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants()
+{
+    renderer()->setShouldDoFullPaintInvalidation(true);
+
+    // Disable for reading compositingState() in isPaintInvalidationContainer() below.
+    DisableCompositingQueryAsserts disabler;
+
+    for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) {
+        if (!child->isPaintInvalidationContainer())
+            child->setShouldDoFullPaintInvalidationIncludingNonCompositingDescendants();
+    }
 }
 
-} // namespace WebCore
+DisableCompositingQueryAsserts::DisableCompositingQueryAsserts()
+    : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { }
+
+} // namespace blink
 
 #ifndef NDEBUG
-void showLayerTree(const WebCore::RenderLayer* layer)
+void showLayerTree(const blink::RenderLayer* layer)
 {
     if (!layer)
         return;
 
-    if (WebCore::Frame* frame = layer->renderer()->frame()) {
-        WTF::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses | WebCore::RenderAsTextShowIDAndClass | WebCore::RenderAsTextDontUpdateLayout | WebCore::RenderAsTextShowLayoutState);
+    if (blink::LocalFrame* frame = layer->renderer()->frame()) {
+        WTF::String output = externalRepresentation(frame, blink::RenderAsTextShowAllLayers | blink::RenderAsTextShowLayerNesting | blink::RenderAsTextShowCompositedLayers | blink::RenderAsTextShowAddresses | blink::RenderAsTextShowIDAndClass | blink::RenderAsTextDontUpdateLayout | blink::RenderAsTextShowLayoutState);
         fprintf(stderr, "%s\n", output.utf8().data());
     }
 }
 
-void showLayerTree(const WebCore::RenderObject* renderer)
+void showLayerTree(const blink::RenderObject* renderer)
 {
     if (!renderer)
         return;