[Async overflow scroll] Clipped composited layers inside overflow scroll jitter and...
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Jun 2019 03:09:40 +0000 (03:09 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 24 Jun 2019 03:09:40 +0000 (03:09 +0000)
https://bugs.webkit.org/show_bug.cgi?id=199133
rdar://problem/43614439

Reviewed by Antti Koivisto.
Source/WebCore:

Currently a composited layer with an overflow:scroll ancestor (which is not a paint-order
ancestor) gets a single "ancestor clip layer" that represents the intersection of all the
clips provided by its containing-block ancestors with non-visible overflow (both scrolling
and non-scrolling ones).

To correctly update clips with async overflow scroll, this single clip layer needs to be
broken up into multiple clipping ancestors. We need a separate layer, and scrolling tree
node for each ancestor that is an overflow scroll, and layers that represent non-moving
clips (i.e. overflow:hidden and 'clip') between them. This patch adds
LayerAncestorClippingStack to represent this stack of clipping layers. For example with the
following content:

<div style="overflow:hidden"> <--- A
    <div style="overflow:scroll"> <--- B
        <div style="overflow:hidden"> <--- C
            <div style="overflow:hidden"> <--- D
                <div style="overflow:scroll">  <--- E
                    <div style="overflow:hidden"> <--- F
                        <div style="overflow:hidden"> <--- G
                            <div></div> <--- H
                        <div>
                    <div>
                <div>
            <div>
        <div>
    <div>
<div>

the composited RenderLayer for H owns a LayerAncestorClippingStack with the following contents:
    [clip - A]
    [scroller - B]
    [clip - intersection of C and D]
    [scroller - E]
    [clip - intersection of F and G]

Each stack entry has a 'masksToBounds' GraphicsLayer for clipping. Entries representing
overflow:scroll clips have a ScrollingNodeID for their OverflowScrollProxy scrolling tree
node (which references the actual OverflowScrollingNode). The non-scroller clips in this
stack are computed unconstrained by the enclosing overflow:scroll.

When the OverflowScrollingNode is scrolled, the boundsOrigin of related OverflowScrollProxy nodes
is adjusted to move the descendant layers (other clipping layers, or composited layers).

OverflowScrollProxy nodes thus take over the role that "Moves" ScrollingTreePositionedNode had.
With this patch, ScrollingTreePositionedNode are purely for absolute position inside non-containing-block
stacking context overflow scroll. LayoutConstraints is renamed to AbsolutePositionConstraints accordingly.

Tests: compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll.html
       compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested.html
       compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow.html
       compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden.html
       compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible.html
       compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer.html
       compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped.html
       compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer.html
       compositing/scrolling/async-overflow-scrolling/layer-in-overflow.html
       scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested.html
       scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow.html

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::setPositionedNodeConstraints):
(WebCore::AsyncScrollingCoordinator::setPositionedNodeGeometry): Deleted.
* page/scrolling/AsyncScrollingCoordinator.h:
* page/scrolling/ScrollingConstraints.cpp:
(WebCore::operator<<):
* page/scrolling/ScrollingConstraints.h:
(WebCore::AbsolutePositionConstraints::operator== const):
(WebCore::AbsolutePositionConstraints::operator!= const):
(WebCore::LayoutConstraints::operator== const): Deleted.
(WebCore::LayoutConstraints::operator!= const): Deleted.
(WebCore::LayoutConstraints::alignmentOffset const): Deleted.
(WebCore::LayoutConstraints::setAlignmentOffset): Deleted.
(WebCore::LayoutConstraints::layerPositionAtLastLayout const): Deleted.
(WebCore::LayoutConstraints::setLayerPositionAtLastLayout): Deleted.
(WebCore::LayoutConstraints::scrollPositioningBehavior const): Deleted.
(WebCore::LayoutConstraints::setScrollPositioningBehavior): Deleted.
* page/scrolling/ScrollingCoordinator.h:
(WebCore::ScrollingCoordinator::setPositionedNodeConstraints):
(WebCore::ScrollingCoordinator::setPositionedNodeGeometry): Deleted.
* page/scrolling/ScrollingStatePositionedNode.cpp:
(WebCore::ScrollingStatePositionedNode::updateConstraints):
* page/scrolling/ScrollingStatePositionedNode.h:
* page/scrolling/ScrollingTree.cpp:
(WebCore::ScrollingTree::commitTreeState):
* page/scrolling/ScrollingTree.h:
(WebCore::ScrollingTree::nodesWithRelatedOverflow):
(WebCore::ScrollingTree::positionedNodesWithRelatedOverflow): Deleted.
* page/scrolling/cocoa/ScrollingTreeFixedNode.mm:
(WebCore::ScrollingTreeFixedNode::applyLayerPositions):
* page/scrolling/cocoa/ScrollingTreeOverflowScrollProxyNode.mm:
(WebCore::ScrollingTreeOverflowScrollProxyNode::commitStateBeforeChildren):
* page/scrolling/cocoa/ScrollingTreePositionedNode.h:
(WebCore::ScrollingTreePositionedNode::scrollPositioningBehavior const): Deleted.
* page/scrolling/cocoa/ScrollingTreePositionedNode.mm:
(WebCore::ScrollingTreePositionedNode::commitStateBeforeChildren):
(WebCore::ScrollingTreePositionedNode::scrollDeltaSinceLastCommit const):
* page/scrolling/cocoa/ScrollingTreeStickyNode.mm:
(WebCore::ScrollingTreeStickyNode::computeLayerPosition const):
* rendering/LayerAncestorClippingStack.cpp: Added.
(WebCore::LayerAncestorClippingStack::LayerAncestorClippingStack):
(WebCore::LayerAncestorClippingStack::equalToClipData const):
(WebCore::LayerAncestorClippingStack::hasAnyScrollingLayers const):
(WebCore::LayerAncestorClippingStack::clear):
(WebCore::LayerAncestorClippingStack::detachFromScrollingCoordinator):
(WebCore::LayerAncestorClippingStack::firstClippingLayer const):
(WebCore::LayerAncestorClippingStack::lastClippingLayer const):
(WebCore::LayerAncestorClippingStack::lastOverflowScrollProxyNodeID const):
(WebCore::LayerAncestorClippingStack::updateScrollingNodeLayers):
(WebCore::LayerAncestorClippingStack::updateWithClipData):
(WebCore::operator<<):
* rendering/LayerAncestorClippingStack.h: Added.
(WebCore::CompositedClipData::CompositedClipData):
(WebCore::CompositedClipData::operator== const):
(WebCore::CompositedClipData::operator!= const):
(WebCore::LayerAncestorClippingStack::stack):
(WebCore::LayerAncestorClippingStack::stack const):
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::~RenderLayerBacking):
(WebCore::RenderLayerBacking::updateDebugIndicators):
(WebCore::RenderLayerBacking::destroyGraphicsLayers):
(WebCore::RenderLayerBacking::updateTransform):
(WebCore::RenderLayerBacking::updateBlendMode):
(WebCore::RenderLayerBacking::updateAfterLayout):
(WebCore::RenderLayerBacking::updateConfiguration):
(WebCore::computeOffsetFromAncestorGraphicsLayer):
(WebCore::RenderLayerBacking::computePrimaryGraphicsLayerRect const):
(WebCore::RenderLayerBacking::computeParentGraphicsLayerRect const):
(WebCore::RenderLayerBacking::updateGeometry):
(WebCore::RenderLayerBacking::updateInternalHierarchy):
(WebCore::RenderLayerBacking::updateAncestorClippingStack):
(WebCore::RenderLayerBacking::updateAncestorClipping):
(WebCore::RenderLayerBacking::detachFromScrollingCoordinator):
(WebCore::RenderLayerBacking::scrollingNodeIDForChildren const):
(WebCore::RenderLayerBacking::childForSuperlayers const):
(WebCore::RenderLayerBacking::backingStoreMemoryEstimate const):
(WebCore::operator<<):
(WebCore::RenderLayerBacking::updateAncestorClippingLayer): Deleted.
(WebCore::RenderLayerBacking::coordinatedScrollingRoles const): Deleted.
* rendering/RenderLayerBacking.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::didChangePlatformLayerForLayer):
(WebCore::RenderLayerCompositor::updateBackingAndHierarchy):
(WebCore::RenderLayerCompositor::layerStyleChanged): We need to run the checks for changed
clipping whether or not this layer has backing, because a non-composited layer with clipping can be
represented in the clipping stack of some other layer.
(WebCore::RenderLayerCompositor::clippedByAncestor const):
(WebCore::RenderLayerCompositor::updateAncestorClippingStack const):
(WebCore::RenderLayerCompositor::computeAncestorClippingStack const): The output of this function
is a Vector<CompositedClipData> which represents the ancestor clipping stack, but without the proxy node
and GraphicsLayer information. It's input to LayerAncestorClippingStack::updateWithClipData() which does
the merging of old and new states.
(WebCore::collectRelatedCoordinatedScrollingNodes):
(WebCore::RenderLayerCompositor::removeFromScrollCoordinatedLayers):
(WebCore::scrollCoordinationRoleForNodeType):
(WebCore::RenderLayerCompositor::attachScrollingNode):
(WebCore::RenderLayerCompositor::registerScrollingNodeID):
(WebCore::RenderLayerCompositor::detachScrollCoordinatedLayerWithRole):
(WebCore::RenderLayerCompositor::detachScrollCoordinatedLayer):
(WebCore::RenderLayerCompositor::coordinatedScrollingRolesForLayer const): Code moved from RenderLayerBacking.
(WebCore::RenderLayerCompositor::updateScrollCoordinationForLayer):
(WebCore::RenderLayerCompositor::updateScrollingNodeForScrollingProxyRole):
(WebCore::RenderLayerCompositor::updateScrollingNodeForPositioningRole):
* rendering/RenderLayerCompositor.h:
(WebCore::allScrollCoordinationRoles):

Source/WebKit:

LayoutConstraints -> AbsolutePositionConstraints rename.

* Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp:
(ArgumentCoder<ScrollingStatePositionedNode>::decode):
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<AbsolutePositionConstraints>::encode):
(IPC::ArgumentCoder<AbsolutePositionConstraints>::decode):
(IPC::ArgumentCoder<LayoutConstraints>::encode): Deleted.
(IPC::ArgumentCoder<LayoutConstraints>::decode): Deleted.
* Shared/WebCoreArgumentCoders.h:
* Shared/WebRenderLayer.cpp:
(WebKit::WebRenderLayer::WebRenderLayer):
* UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm:
(WebKit::RemoteScrollingCoordinatorProxy::establishLayerTreeScrollingRelations): ScrollingTreeOverflowScrollProxyNode
have overflow scroll relations now too.

LayoutTests:

New baselines for:
- clipping layers no longer have offsetFromRenderer(), which they didn't need.
- positioned nodes don't print scrollBehavior (they are always "Stationary")
- "Moves" positioned nodes are replaced with overflow scroll proxy nodes

* compositing/backing/backing-store-attachment-empty-keyframe-expected.txt:
* compositing/geometry/clip-expected.txt:
* compositing/geometry/clip-inside-expected.txt:
* compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
* compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt:
* compositing/layer-creation/clipping-scope/nested-scroller-overlap.html:
* compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt:
* compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt:
* compositing/overflow/clip-descendents-expected.txt:
* compositing/overflow/scrolling-content-clip-to-viewport-expected.txt:
* compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt:
* compositing/rtl/rtl-scrolling-with-transformed-descendants.html:
* compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll-expected.txt: Added.
* compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll.html: Added.
* compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-expected.txt: Added.
* compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested-expected.txt: Added.
* compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested.html: Added.
* compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow.html: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden-expected.txt: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden.html: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible-expected.txt: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible.html: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-expected.txt: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer-expected.txt: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer.html: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped-expected.txt: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped.html: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer-expected.txt: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer.html: Added.
* compositing/scrolling/async-overflow-scrolling/layer-in-overflow.html: Added.
* compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt:
* compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt:
* compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness.html:
* platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt:
* platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt:
* platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt:
* platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll-expected.txt: Added.
* platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-expected.txt: Added.
* platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested-expected.txt: Added.
* platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden-expected.txt: Added.
* platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible-expected.txt: Added.
* platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-expected.txt: Added.
* platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer-expected.txt: Added.
* platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped-expected.txt: Added.
* platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer-expected.txt: Added.
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt:
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt:
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-in-nested-sc-scrollers-expected.txt:
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt:
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-expected.txt: Copied from LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt.
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested-expected.txt: Copied from LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-overflow-scroll-expected.txt.
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/composited-in-absolute-in-stacking-context-overflow-expected.txt:
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt:
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt:
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt:
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-overflow-scroll-expected.txt:
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/positioned-nodes-complex-expected.txt:
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/positioned-nodes-expected.txt:
* platform/ios-wk2/scrollingcoordinator/scrolling-tree/sticky-in-overflow-expected.txt:
* platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
* platform/ios/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt:
* scrollingcoordinator/scrolling-tree/absolute-in-nested-sc-scrollers-expected.txt:
* scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt:
* scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-expected.txt: Copied from LayoutTests/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt.
* scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested-expected.txt: Copied from LayoutTests/scrollingcoordinator/scrolling-tree/nested-overflow-scroll-expected.txt.
* scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested.html: Added.
* scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow.html: Added.
* scrollingcoordinator/scrolling-tree/composited-in-absolute-in-stacking-context-overflow-expected.txt:
* scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt:
* scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt:
* scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt:
* scrollingcoordinator/scrolling-tree/nested-overflow-scroll-expected.txt:
* scrollingcoordinator/scrolling-tree/positioned-nodes-complex-expected.txt:
* scrollingcoordinator/scrolling-tree/positioned-nodes-expected.txt:
* scrollingcoordinator/scrolling-tree/sticky-in-overflow-expected.txt:

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

112 files changed:
LayoutTests/ChangeLog
LayoutTests/compositing/backing/backing-store-attachment-empty-keyframe-expected.txt
LayoutTests/compositing/geometry/clip-expected.txt
LayoutTests/compositing/geometry/clip-inside-expected.txt
LayoutTests/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt
LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt
LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap.html
LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt
LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt
LayoutTests/compositing/overflow/clip-descendents-expected.txt
LayoutTests/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt
LayoutTests/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt
LayoutTests/compositing/rtl/rtl-scrolling-with-transformed-descendants.html
LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll-expected.txt [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll.html [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-expected.txt [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested-expected.txt [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested.html [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow.html [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden-expected.txt [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden.html [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible-expected.txt [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible.html [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-expected.txt [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer-expected.txt [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer.html [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped-expected.txt [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped.html [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer-expected.txt [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer.html [new file with mode: 0644]
LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt
LayoutTests/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt
LayoutTests/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness.html
LayoutTests/legacy-animation-engine/compositing/backing/backing-store-attachment-empty-keyframe-expected.txt
LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt
LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt
LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt
LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt
LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-in-nested-sc-scrollers-expected.txt
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/composited-in-absolute-in-stacking-context-overflow-expected.txt
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-overflow-scroll-expected.txt
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/positioned-nodes-complex-expected.txt
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/positioned-nodes-expected.txt
LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/sticky-in-overflow-expected.txt
LayoutTests/platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt
LayoutTests/platform/ios/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt
LayoutTests/platform/ios/media/video-play-glyph-composited-outside-overflow-scrolling-touch-container-expected.txt
LayoutTests/platform/mac-wk1/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt
LayoutTests/platform/mac-wk1/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/absolute-in-nested-sc-scrollers-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-expected.txt [new file with mode: 0644]
LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested-expected.txt [new file with mode: 0644]
LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested.html [new file with mode: 0644]
LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow.html [new file with mode: 0644]
LayoutTests/scrollingcoordinator/scrolling-tree/composited-in-absolute-in-stacking-context-overflow-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/nested-overflow-scroll-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/positioned-nodes-complex-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/positioned-nodes-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/sticky-in-overflow-expected.txt
Source/WebCore/ChangeLog
Source/WebCore/Headers.cmake
Source/WebCore/Sources.txt
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.h
Source/WebCore/page/scrolling/ScrollingConstraints.cpp
Source/WebCore/page/scrolling/ScrollingConstraints.h
Source/WebCore/page/scrolling/ScrollingCoordinator.h
Source/WebCore/page/scrolling/ScrollingStatePositionedNode.cpp
Source/WebCore/page/scrolling/ScrollingStatePositionedNode.h
Source/WebCore/page/scrolling/ScrollingTree.cpp
Source/WebCore/page/scrolling/ScrollingTree.h
Source/WebCore/page/scrolling/cocoa/ScrollingTreeFixedNode.mm
Source/WebCore/page/scrolling/cocoa/ScrollingTreeOverflowScrollProxyNode.mm
Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.h
Source/WebCore/page/scrolling/cocoa/ScrollingTreePositionedNode.mm
Source/WebCore/page/scrolling/cocoa/ScrollingTreeStickyNode.mm
Source/WebCore/platform/graphics/GraphicsContext.h
Source/WebCore/rendering/LayerAncestorClippingStack.cpp [new file with mode: 0644]
Source/WebCore/rendering/LayerAncestorClippingStack.h [new file with mode: 0644]
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerBacking.h
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerCompositor.h
Source/WebKit/ChangeLog
Source/WebKit/Shared/RemoteLayerTree/RemoteScrollingCoordinatorTransaction.cpp
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Source/WebKit/Shared/WebCoreArgumentCoders.h
Source/WebKit/Shared/WebRenderLayer.cpp
Source/WebKit/UIProcess/RemoteLayerTree/ios/RemoteScrollingCoordinatorProxyIOS.mm

index 7a71643..f5b8ecb 100644 (file)
@@ -1,3 +1,92 @@
+2019-06-23  Simon Fraser  <simon.fraser@apple.com>
+
+        [Async overflow scroll] Clipped composited layers inside overflow scroll jitter and get incorrectly clipped
+        https://bugs.webkit.org/show_bug.cgi?id=199133
+        rdar://problem/43614439
+
+        Reviewed by Antti Koivisto.
+        
+        New baselines for:
+        - clipping layers no longer have offsetFromRenderer(), which they didn't need.
+        - positioned nodes don't print scrollBehavior (they are always "Stationary")
+        - "Moves" positioned nodes are replaced with overflow scroll proxy nodes
+
+        * compositing/backing/backing-store-attachment-empty-keyframe-expected.txt:
+        * compositing/geometry/clip-expected.txt:
+        * compositing/geometry/clip-inside-expected.txt:
+        * compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
+        * compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt:
+        * compositing/layer-creation/clipping-scope/nested-scroller-overlap.html:
+        * compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt:
+        * compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt:
+        * compositing/overflow/clip-descendents-expected.txt:
+        * compositing/overflow/scrolling-content-clip-to-viewport-expected.txt:
+        * compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt:
+        * compositing/rtl/rtl-scrolling-with-transformed-descendants.html:
+        * compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll-expected.txt: Added.
+        * compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-expected.txt: Added.
+        * compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested-expected.txt: Added.
+        * compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden-expected.txt: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible-expected.txt: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-expected.txt: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer-expected.txt: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped-expected.txt: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer-expected.txt: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer.html: Added.
+        * compositing/scrolling/async-overflow-scrolling/layer-in-overflow.html: Added.
+        * compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt:
+        * compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt:
+        * compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness.html:
+        * platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt:
+        * platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt:
+        * platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt:
+        * platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll-expected.txt: Added.
+        * platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-expected.txt: Added.
+        * platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested-expected.txt: Added.
+        * platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden-expected.txt: Added.
+        * platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible-expected.txt: Added.
+        * platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-expected.txt: Added.
+        * platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer-expected.txt: Added.
+        * platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped-expected.txt: Added.
+        * platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer-expected.txt: Added.
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt:
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt:
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-in-nested-sc-scrollers-expected.txt:
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt:
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-expected.txt: Copied from LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt.
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested-expected.txt: Copied from LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-overflow-scroll-expected.txt.
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/composited-in-absolute-in-stacking-context-overflow-expected.txt:
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt:
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt:
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt:
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/nested-overflow-scroll-expected.txt:
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/positioned-nodes-complex-expected.txt:
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/positioned-nodes-expected.txt:
+        * platform/ios-wk2/scrollingcoordinator/scrolling-tree/sticky-in-overflow-expected.txt:
+        * platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
+        * platform/ios/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt:
+        * scrollingcoordinator/scrolling-tree/absolute-in-nested-sc-scrollers-expected.txt:
+        * scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt:
+        * scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-expected.txt: Copied from LayoutTests/scrollingcoordinator/scrolling-tree/absolute-inside-stacking-in-scroller-expected.txt.
+        * scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested-expected.txt: Copied from LayoutTests/scrollingcoordinator/scrolling-tree/nested-overflow-scroll-expected.txt.
+        * scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested.html: Added.
+        * scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow.html: Added.
+        * scrollingcoordinator/scrolling-tree/composited-in-absolute-in-stacking-context-overflow-expected.txt:
+        * scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt:
+        * scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt:
+        * scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt:
+        * scrollingcoordinator/scrolling-tree/nested-overflow-scroll-expected.txt:
+        * scrollingcoordinator/scrolling-tree/positioned-nodes-complex-expected.txt:
+        * scrollingcoordinator/scrolling-tree/positioned-nodes-expected.txt:
+        * scrollingcoordinator/scrolling-tree/sticky-in-overflow-expected.txt:
+
 2019-06-23  Antoine Quint  <graouts@apple.com>
 
         [Pointer Events WPT] Unflake imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_pointercapture_in_frame.html
index 840c4fe..62fdbea 100644 (file)
@@ -9,7 +9,6 @@
       (backingStoreAttached 1)
       (children 1
         (GraphicsLayer
-          (offsetFromRenderer width=-501 height=0)
           (position 9.00 101.00)
           (bounds 501.00 150.00)
           (backingStoreAttached 1)
index 35a0025..6fe9f72 100644 (file)
@@ -16,7 +16,6 @@ Test CSS clip with composited layers. Left and right sides should look the same.
           (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 1.00 1.00])
         )
         (GraphicsLayer
-          (offsetFromRenderer width=5 height=5)
           (position 215.00 15.00)
           (bounds 110.00 110.00)
           (children 1
index 9b49989..cf6a396 100644 (file)
@@ -17,7 +17,6 @@ Test CSS clip with composited layers. Left and right sides should look the same.
           (transform [1.00 0.00 0.00 0.00] [0.00 1.00 0.00 0.00] [0.00 0.00 1.00 0.00] [0.00 0.00 1.00 1.00])
         )
         (GraphicsLayer
-          (offsetFromRenderer width=15 height=25)
           (position 225.00 35.00)
           (bounds 90.00 80.00)
           (children 1
index 8620e41..65c4c45 100644 (file)
@@ -22,7 +22,6 @@ middlebottom
           (drawsContent 1)
         )
         (GraphicsLayer
-          (offsetFromRenderer width=0 height=100)
           (position 28.00 250.00)
           (bounds 185.00 200.00)
           (children 1
index a608569..476b3cf 100644 (file)
@@ -1,6 +1,7 @@
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)
+  (clips 1)
   (children 1
     (GraphicsLayer
       (bounds 800.00 600.00)
@@ -15,6 +16,7 @@
               (offsetFromRenderer width=1 height=1)
               (position 1.00 1.00)
               (bounds 385.00 350.00)
+              (clips 1)
               (children 1
                 (GraphicsLayer
                   (offsetFromRenderer width=1 height=1)
@@ -31,6 +33,7 @@
                           (offsetFromRenderer width=1 height=1)
                           (position 1.00 1.00)
                           (bounds 285.00 200.00)
+                          (clips 1)
                           (children 1
                             (GraphicsLayer
                               (offsetFromRenderer width=1 height=1)
@@ -49,9 +52,9 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-10)
           (position 24.00 106.00)
           (bounds 385.00 350.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
               (position 10.00 10.00)
           (bounds 60.00 550.00)
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-10)
-          (position 45.00 217.00)
-          (bounds 285.00 200.00)
+          (position 24.00 106.00)
+          (bounds 385.00 350.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
-              (position 10.00 10.00)
-              (bounds 100.00 80.00)
-              (contentsOpaque 1)
+              (position 21.00 111.00)
+              (bounds 285.00 200.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 10.00)
+                  (bounds 100.00 80.00)
+                  (contentsOpaque 1)
+                )
+              )
             )
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-100)
-          (position 45.00 217.00)
-          (bounds 285.00 200.00)
+          (position 24.00 106.00)
+          (bounds 385.00 350.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
-              (position 10.00 100.00)
-              (bounds 100.00 80.00)
-              (contentsOpaque 1)
+              (position 21.00 111.00)
+              (bounds 285.00 200.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 100.00)
+                  (bounds 100.00 80.00)
+                  (contentsOpaque 1)
+                )
+              )
             )
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-190)
-          (position 45.00 217.00)
-          (bounds 285.00 200.00)
+          (position 24.00 106.00)
+          (bounds 385.00 350.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
-              (position 10.00 190.00)
-              (bounds 100.00 80.00)
-              (contentsOpaque 1)
+              (position 21.00 111.00)
+              (bounds 285.00 200.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 190.00)
+                  (bounds 100.00 80.00)
+                  (contentsOpaque 1)
+                )
+              )
             )
           )
         )
index 56fa0b7..02f3481 100644 (file)
@@ -49,7 +49,7 @@
 
                window.addEventListener('load', () => {
                        if (window.testRunner)
-                               document.getElementById('layers').innerText = window.internals.layerTreeAsText(document);
+                               document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
                }, false);
        </script>
 </head>
index 2e6044a..49db9d9 100644 (file)
@@ -26,7 +26,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-10)
           (position 9.00 9.00)
           (bounds 285.00 300.00)
           (children 1
@@ -38,7 +37,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-40 height=-20)
           (position 9.00 9.00)
           (bounds 285.00 300.00)
           (children 1
@@ -50,7 +48,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-40 height=-140)
           (position 9.00 9.00)
           (bounds 285.00 300.00)
           (children 1
@@ -62,7 +59,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-40 height=-260)
           (position 9.00 9.00)
           (bounds 285.00 300.00)
           (children 1
index b8a99a2..cd78b43 100644 (file)
@@ -26,7 +26,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-10)
           (position 9.00 9.00)
           (bounds 285.00 300.00)
           (children 1
@@ -38,7 +37,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-40 height=-20)
           (position 9.00 9.00)
           (bounds 285.00 300.00)
           (children 1
@@ -50,7 +48,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-40 height=-260)
           (position 9.00 9.00)
           (bounds 285.00 300.00)
           (children 1
index 73617af..753061a 100644 (file)
@@ -7,7 +7,6 @@
       (contentsOpaque 1)
       (children 4
         (GraphicsLayer
-          (offsetFromRenderer width=-2 height=-12)
           (position 48.00 38.00)
           (bounds 60.00 70.00)
           (children 1
@@ -20,7 +19,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-2 height=-12)
           (position 240.00 38.00)
           (bounds 60.00 70.00)
           (children 1
index 7d97811..8a3b7b8 100644 (file)
@@ -21,7 +21,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-10)
           (bounds 305.00 325.00)
           (children 1
             (GraphicsLayer
index 78d6316..c446161 100644 (file)
@@ -2,6 +2,7 @@
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)
+  (clips 1)
   (children 1
     (GraphicsLayer
       (bounds 800.00 600.00)
@@ -17,6 +18,7 @@
               (position 2.00 2.00)
               (bounds origin 366.00 0.00)
               (bounds 400.00 204.00)
+              (clips 1)
               (children 1
                 (GraphicsLayer
                   (offsetFromRenderer width=2 height=2)
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-96 height=0)
           (position 10.00 10.00)
+          (bounds origin 366.00 0.00)
           (bounds 400.00 204.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
-              (position 96.00 0.00)
+              (position 462.00 0.00)
               (anchor 0.00 0.00)
               (bounds 150.00 200.00)
               (contentsOpaque 1)
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=58 height=0)
           (position 10.00 10.00)
+          (bounds origin 366.00 0.00)
           (bounds 400.00 204.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
-              (position -58.00 0.00)
+              (position 308.00 0.00)
               (bounds 150.00 200.00)
               (contentsOpaque 1)
             )
index 9f1c191..08bc35b 100644 (file)
@@ -30,7 +30,7 @@
 
         function dumpLayers()
         {
-            document.getElementById('layertree').textContent = window.internals.layerTreeAsText(document);
+            document.getElementById('layertree').textContent = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
         }
         window.addEventListener('load', dumpLayers, false);
     </script>
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll-expected.txt b/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll-expected.txt
new file mode 100644 (file)
index 0000000..e2155d4
--- /dev/null
@@ -0,0 +1,59 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 300.00)
+              (bounds 301.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,300))
+                  (anchor 0.00 0.00)
+                  (bounds 301.00 640.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 300.00)
+          (bounds 301.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 20.00 220.00)
+              (bounds 100.00 200.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=-6 height=-6)
+                  (position 24.00 44.00)
+                  (bounds 112.00 112.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll.html b/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll.html
new file mode 100644 (file)
index 0000000..beef442
--- /dev/null
@@ -0,0 +1,65 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests that the bounds of the layer for non-scrolled clipping is not intersected with the scroller's clip</title>
+    <style>
+        #scroller {
+            overflow-y: scroll;
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .clipping {
+            overflow: hidden;
+            margin: 10px;
+            width: 100px;
+            height: 200px;
+            border: 2px solid gray;
+        }
+
+        .box {
+            margin-top: 50px;
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 300);
+            if (window.internals)
+                document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div class="spacer"></div>
+        <div class="clipping">
+            <div class="composited box"></div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-expected.txt b/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-expected.txt
new file mode 100644 (file)
index 0000000..3b8c02c
--- /dev/null
@@ -0,0 +1,59 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 301.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 301.00 540.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 301.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 34.00 234.00)
+              (bounds 100.00 86.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=-6 height=-6)
+                  (position 24.00 44.00)
+                  (bounds 112.00 112.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested-expected.txt b/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested-expected.txt
new file mode 100644 (file)
index 0000000..397d866
--- /dev/null
@@ -0,0 +1,105 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 301.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 301.00 640.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (position 20.00 220.00)
+                      (bounds 200.00 200.00)
+                      (clips 1)
+                      (children 1
+                        (GraphicsLayer
+                          (position 20.00 20.00)
+                          (bounds 216.00 216.00)
+                          (drawsContent 1)
+                          (children 1
+                            (GraphicsLayer
+                              (offsetFromRenderer width=3 height=3)
+                              (position 3.00 3.00)
+                              (bounds origin 0.00 150.00)
+                              (bounds 195.00 210.00)
+                              (clips 1)
+                              (children 1
+                                (GraphicsLayer
+                                  (offsetFromRenderer width=3 height=3)
+                                  (scrollOffset (0,150))
+                                  (anchor 0.00 0.00)
+                                  (bounds 195.00 554.00)
+                                  (drawsContent 1)
+                                )
+                              )
+                            )
+                          )
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 301.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 20.00 220.00)
+              (bounds 200.00 200.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (position 23.00 23.00)
+                  (bounds 195.00 210.00)
+                  (clips 1)
+                  (children 1
+                    (GraphicsLayer
+                      (position 2.00 202.00)
+                      (bounds 191.00 150.00)
+                      (clips 1)
+                      (children 1
+                        (GraphicsLayer
+                          (offsetFromRenderer width=-6 height=-6)
+                          (position 24.00 44.00)
+                          (bounds 112.00 112.00)
+                          (drawsContent 1)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested.html b/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested.html
new file mode 100644 (file)
index 0000000..f17498c
--- /dev/null
@@ -0,0 +1,85 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests clipped layer in overflow in clipped in overflow</title>
+    <style>
+        #scroller {
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .scroller {
+            overflow-y: scroll;
+        }
+        
+        .inner.scroller {
+            height: 210px;
+            width: 210px;
+            margin: 20px;
+            border: 3px solid purple;
+        }
+        
+        .clipping {
+            overflow: hidden;
+            border: 2px solid gray;
+        }
+        
+        .outer.clipping {
+            margin: 10px;
+            width: 200px;
+            height: 200px;
+        }
+
+        .box {
+            margin-top: 50px;
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 50);
+            scroller2.scrollTo(0, 150);
+            if (window.internals)
+                document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller" class="scroller">
+        <div class="spacer"></div>
+        <div class="outer clipping">
+            <div id="scroller2" class="inner scroller">
+                <div class="spacer"></div>
+                <div class="clipping">
+                    <div class="composited box"></div>
+                </div>
+                <div class="spacer"></div>
+            </div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow.html b/LayoutTests/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow.html
new file mode 100644 (file)
index 0000000..1d3bb33
--- /dev/null
@@ -0,0 +1,76 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests the bounds of the clipping layer for nested clips in non-stacking context overflow</title>
+    <style>
+        #scroller {
+            overflow-y: scroll;
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .clipping {
+            overflow: hidden;
+            border: 2px solid gray;
+        }
+        
+        .outer.clipping {
+            margin: 10px;
+            width: 200px;
+            height: 100px;
+        }
+
+        .inner.clipping {
+            margin: 12px;
+            width: 100px;
+            height: 200px;
+        }
+        
+        .box {
+            margin-top: 50px;
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 50);
+            if (window.internals)
+                document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div class="spacer"></div>
+        <div class="outer clipping">
+            <div class="inner clipping">
+                <div class="composited box"></div>
+            </div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden-expected.txt b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden-expected.txt
new file mode 100644 (file)
index 0000000..a07156b
--- /dev/null
@@ -0,0 +1,59 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 301.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 301.00 540.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 301.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 20.00 220.00)
+              (bounds 200.00 100.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=-6 height=-6)
+                  (position 24.00 44.00)
+                  (bounds 112.00 112.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden.html b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden.html
new file mode 100644 (file)
index 0000000..66d587c
--- /dev/null
@@ -0,0 +1,79 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests the bounds of the clipping layer for nested clips in non-stacking context overflow</title>
+    <style>
+        #scroller {
+            overflow-y: scroll;
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .clipping {
+            position: relative; /* keep it in a layer */
+            overflow: visible;
+            border: 2px solid gray;
+            margin: 10px;
+            width: 200px;
+            height: 100px;
+        }
+        
+        .clipping.changed {
+            overflow: hidden;
+        }
+        
+        .box {
+            margin-top: 50px;
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+        }
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 50);
+            
+            setTimeout(() => {
+                document.getElementById('target').classList.add('changed');
+                if (window.internals)
+                    document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div class="spacer"></div>
+        <div id="target" class="clipping">
+            <div class="composited box"></div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible-expected.txt b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible-expected.txt
new file mode 100644 (file)
index 0000000..caeb3ec
--- /dev/null
@@ -0,0 +1,52 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 301.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 301.00 540.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 301.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=-6 height=-6)
+              (position 44.00 264.00)
+              (bounds 112.00 112.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible.html b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible.html
new file mode 100644 (file)
index 0000000..98102b5
--- /dev/null
@@ -0,0 +1,79 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests the bounds of the clipping layer for nested clips in non-stacking context overflow</title>
+    <style>
+        #scroller {
+            overflow-y: scroll;
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .clipping {
+            position: relative; /* keep it in a layer */
+            overflow: hidden;
+            border: 2px solid gray;
+            margin: 10px;
+            width: 200px;
+            height: 100px;
+        }
+        
+        .clipping.changed {
+            overflow: visible;
+        }
+        
+        .box {
+            margin-top: 50px;
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+        }
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 50);
+            
+            setTimeout(() => {
+                document.getElementById('target').classList.add('changed');
+                if (window.internals)
+                    document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div class="spacer"></div>
+        <div id="target" class="clipping">
+            <div class="composited box"></div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-expected.txt b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-expected.txt
new file mode 100644 (file)
index 0000000..0a0d537
--- /dev/null
@@ -0,0 +1,52 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 301.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 301.00 516.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 301.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=-6 height=-6)
+              (position 32.00 202.00)
+              (bounds 112.00 112.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer-expected.txt b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer-expected.txt
new file mode 100644 (file)
index 0000000..a07156b
--- /dev/null
@@ -0,0 +1,59 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 301.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 301.00 540.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 301.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 20.00 220.00)
+              (bounds 200.00 100.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=-6 height=-6)
+                  (position 24.00 44.00)
+                  (bounds 112.00 112.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer.html b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer.html
new file mode 100644 (file)
index 0000000..6914aa1
--- /dev/null
@@ -0,0 +1,78 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests the bounds of the clipping layer for nested clips in non-stacking context overflow</title>
+    <style>
+        #scroller {
+            overflow-y: scroll;
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .clipping {
+            overflow: visible;
+            border: 2px solid gray;
+            margin: 10px;
+            width: 200px;
+            height: 100px;
+        }
+        
+        .clipping.changed {
+            overflow: hidden;
+        }
+        
+        .box {
+            margin-top: 50px;
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+        }
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 50);
+            
+            setTimeout(() => {
+                document.getElementById('target').classList.add('changed');
+                if (window.internals)
+                    document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div class="spacer"></div>
+        <div id="target" class="clipping">
+            <div class="composited box"></div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped-expected.txt b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped-expected.txt
new file mode 100644 (file)
index 0000000..d1d8778
--- /dev/null
@@ -0,0 +1,66 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 33.00 25.00)
+          (bounds 312.00 212.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=-10 height=-10)
+              (position 16.00 16.00)
+              (bounds 362.00 362.00)
+              (drawsContent 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (position 23.00 23.00)
+                  (bounds origin 0.00 50.00)
+                  (bounds 301.00 316.00)
+                  (clips 1)
+                  (children 1
+                    (GraphicsLayer
+                      (offsetFromRenderer width=13 height=13)
+                      (scrollOffset (0,50))
+                      (anchor 0.00 0.00)
+                      (bounds 301.00 516.00)
+                      (drawsContent 1)
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 33.00 25.00)
+          (bounds 312.00 212.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 39.00 39.00)
+              (bounds origin 0.00 50.00)
+              (bounds 301.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=-6 height=-6)
+                  (position 32.00 202.00)
+                  (bounds 112.00 112.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped.html b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped.html
new file mode 100644 (file)
index 0000000..5cceb91
--- /dev/null
@@ -0,0 +1,66 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests the ancestor clipping stack where the first layer is a non-scrolling clip</title>
+    <style>
+        .clipping {
+            overflow: hidden;
+            height: 200px;
+            width: 300px;
+            margin: 20px;
+            border: 5px solid gray;
+            box-shadow: 0 0 7px black;
+            padding: 6px;
+        }
+
+        #scroller {
+            overflow-y: scroll;
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .box {
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 50);
+            if (window.internals)
+                document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="clipping">
+        <div id="scroller">
+            <div class="spacer"></div>
+            <div class="composited box"></div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer-expected.txt b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer-expected.txt
new file mode 100644 (file)
index 0000000..caeb3ec
--- /dev/null
@@ -0,0 +1,52 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 301.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 301.00 540.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 301.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=-6 height=-6)
+              (position 44.00 264.00)
+              (bounds 112.00 112.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer.html b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer.html
new file mode 100644 (file)
index 0000000..92ca70c
--- /dev/null
@@ -0,0 +1,78 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests the bounds of the clipping layer for nested clips in non-stacking context overflow</title>
+    <style>
+        #scroller {
+            overflow-y: scroll;
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .clipping {
+            overflow: hidden;
+            border: 2px solid gray;
+            margin: 10px;
+            width: 200px;
+            height: 100px;
+        }
+        
+        .clipping.changed {
+            overflow: visible; /* The renderer will lose its RenderLayer */
+        }
+        
+        .box {
+            margin-top: 50px;
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+        }
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 50);
+            
+            setTimeout(() => {
+                document.getElementById('target').classList.add('changed');
+                if (window.internals)
+                    document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div class="spacer"></div>
+        <div id="target" class="clipping">
+            <div class="composited box"></div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow.html b/LayoutTests/compositing/scrolling/async-overflow-scrolling/layer-in-overflow.html
new file mode 100644 (file)
index 0000000..4ea06d5
--- /dev/null
@@ -0,0 +1,54 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Layer tree dump for a simple composited layer in non-stacking context overflow</title>
+    <style>
+        #scroller {
+            overflow-y: scroll;
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .box {
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 50);
+            if (window.internals)
+                document.getElementById('layers').innerText = window.internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div class="spacer"></div>
+        <div class="composited box"></div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
index 2344046..c32817f 100644 (file)
@@ -1,6 +1,7 @@
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)
+  (clips 1)
   (children 1
     (GraphicsLayer
       (bounds 800.00 600.00)
@@ -14,6 +15,7 @@
               (offsetFromRenderer width=2 height=2)
               (position 2.00 2.00)
               (bounds 320.00 320.00)
+              (clips 1)
               (children 1
                 (GraphicsLayer
                   (position 10.00 10.00)
@@ -24,6 +26,7 @@
                       (offsetFromRenderer width=2 height=2)
                       (position 2.00 2.00)
                       (bounds 281.00 296.00)
+                      (clips 1)
                       (children 1
                         (GraphicsLayer
                           (offsetFromRenderer width=2 height=2)
           (contentsOpaque 1)
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-20 height=-20)
-          (position 42.00 34.00)
-          (bounds 281.00 296.00)
+          (position 30.00 22.00)
+          (bounds 320.00 320.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
-              (position 20.00 20.00)
-              (bounds 241.00 24.00)
-              (drawsContent 1)
+              (position 12.00 12.00)
+              (bounds 281.00 296.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (position 20.00 20.00)
+                  (bounds 241.00 24.00)
+                  (drawsContent 1)
+                )
+              )
             )
           )
         )
index 4da38b4..6447283 100644 (file)
@@ -47,7 +47,7 @@
 
         window.addEventListener('load', () => {
             if (window.internals)
-                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_CLIPPING);
         }, false);
     </script>
 </head>
index e44d701..e62e90b 100644 (file)
@@ -9,7 +9,6 @@
       (backingStoreAttached 1)
       (children 1
         (GraphicsLayer
-          (offsetFromRenderer width=-501 height=0)
           (position 9.00 101.00)
           (bounds 501.00 150.00)
           (backingStoreAttached 1)
index 9ba74cd..73d1e79 100644 (file)
@@ -1,6 +1,7 @@
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)
+  (clips 1)
   (children 1
     (GraphicsLayer
       (bounds 800.00 600.00)
@@ -15,6 +16,7 @@
               (offsetFromRenderer width=1 height=1)
               (position 1.00 1.00)
               (bounds 400.00 350.00)
+              (clips 1)
               (children 1
                 (GraphicsLayer
                   (offsetFromRenderer width=1 height=1)
@@ -31,6 +33,7 @@
                           (offsetFromRenderer width=1 height=1)
                           (position 1.00 1.00)
                           (bounds 300.00 200.00)
+                          (clips 1)
                           (children 1
                             (GraphicsLayer
                               (offsetFromRenderer width=1 height=1)
@@ -49,9 +52,9 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-10)
           (position 24.00 106.00)
           (bounds 400.00 350.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
               (position 10.00 10.00)
           (bounds 60.00 550.00)
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-10)
-          (position 45.00 217.00)
-          (bounds 300.00 200.00)
+          (position 24.00 106.00)
+          (bounds 400.00 350.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
-              (position 10.00 10.00)
-              (bounds 100.00 80.00)
-              (contentsOpaque 1)
+              (position 21.00 111.00)
+              (bounds 300.00 200.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 10.00)
+                  (bounds 100.00 80.00)
+                  (contentsOpaque 1)
+                )
+              )
             )
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-100)
-          (position 45.00 217.00)
-          (bounds 300.00 200.00)
+          (position 24.00 106.00)
+          (bounds 400.00 350.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
-              (position 10.00 100.00)
-              (bounds 100.00 80.00)
-              (contentsOpaque 1)
+              (position 21.00 111.00)
+              (bounds 300.00 200.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 100.00)
+                  (bounds 100.00 80.00)
+                  (contentsOpaque 1)
+                )
+              )
             )
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-190)
-          (position 45.00 217.00)
-          (bounds 300.00 200.00)
+          (position 24.00 106.00)
+          (bounds 400.00 350.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
-              (position 10.00 190.00)
-              (bounds 100.00 80.00)
-              (contentsOpaque 1)
+              (position 21.00 111.00)
+              (bounds 300.00 200.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 190.00)
+                  (bounds 100.00 80.00)
+                  (contentsOpaque 1)
+                )
+              )
             )
           )
         )
index 88f8318..97afdb5 100644 (file)
@@ -26,7 +26,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-10)
           (position 9.00 9.00)
           (bounds 300.00 300.00)
           (children 1
@@ -38,7 +37,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-40 height=-20)
           (position 9.00 9.00)
           (bounds 300.00 300.00)
           (children 1
@@ -50,7 +48,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-40 height=-140)
           (position 9.00 9.00)
           (bounds 300.00 300.00)
           (children 1
@@ -62,7 +59,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-40 height=-260)
           (position 9.00 9.00)
           (bounds 300.00 300.00)
           (children 1
index d4b4263..0d9b8fa 100644 (file)
@@ -26,7 +26,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-10)
           (position 9.00 9.00)
           (bounds 300.00 300.00)
           (children 1
@@ -38,7 +37,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-40 height=-20)
           (position 9.00 9.00)
           (bounds 300.00 300.00)
           (children 1
@@ -50,7 +48,6 @@
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-40 height=-260)
           (position 9.00 9.00)
           (bounds 300.00 300.00)
           (children 1
diff --git a/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll-expected.txt b/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll-expected.txt
new file mode 100644 (file)
index 0000000..0938fa7
--- /dev/null
@@ -0,0 +1,59 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 300.00)
+              (bounds 316.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,300))
+                  (anchor 0.00 0.00)
+                  (bounds 316.00 640.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 300.00)
+          (bounds 316.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 20.00 220.00)
+              (bounds 100.00 200.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=-6 height=-6)
+                  (position 24.00 44.00)
+                  (bounds 112.00 112.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-expected.txt b/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-expected.txt
new file mode 100644 (file)
index 0000000..80aa626
--- /dev/null
@@ -0,0 +1,59 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 316.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 316.00 540.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 316.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 34.00 234.00)
+              (bounds 100.00 86.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=-6 height=-6)
+                  (position 24.00 44.00)
+                  (bounds 112.00 112.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested-expected.txt b/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested-expected.txt
new file mode 100644 (file)
index 0000000..9256867
--- /dev/null
@@ -0,0 +1,105 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 316.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 316.00 640.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (position 20.00 220.00)
+                      (bounds 200.00 200.00)
+                      (clips 1)
+                      (children 1
+                        (GraphicsLayer
+                          (position 20.00 20.00)
+                          (bounds 216.00 216.00)
+                          (drawsContent 1)
+                          (children 1
+                            (GraphicsLayer
+                              (offsetFromRenderer width=3 height=3)
+                              (position 3.00 3.00)
+                              (bounds origin 0.00 150.00)
+                              (bounds 210.00 210.00)
+                              (clips 1)
+                              (children 1
+                                (GraphicsLayer
+                                  (offsetFromRenderer width=3 height=3)
+                                  (scrollOffset (0,150))
+                                  (anchor 0.00 0.00)
+                                  (bounds 210.00 554.00)
+                                  (drawsContent 1)
+                                )
+                              )
+                            )
+                          )
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 316.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 20.00 220.00)
+              (bounds 200.00 200.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (position 23.00 23.00)
+                  (bounds 210.00 210.00)
+                  (clips 1)
+                  (children 1
+                    (GraphicsLayer
+                      (position 2.00 202.00)
+                      (bounds 206.00 150.00)
+                      (clips 1)
+                      (children 1
+                        (GraphicsLayer
+                          (offsetFromRenderer width=-6 height=-6)
+                          (position 24.00 44.00)
+                          (bounds 112.00 112.00)
+                          (drawsContent 1)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden-expected.txt b/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden-expected.txt
new file mode 100644 (file)
index 0000000..ee09d6f
--- /dev/null
@@ -0,0 +1,59 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 316.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 316.00 540.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 316.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 20.00 220.00)
+              (bounds 200.00 100.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=-6 height=-6)
+                  (position 24.00 44.00)
+                  (bounds 112.00 112.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible-expected.txt b/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible-expected.txt
new file mode 100644 (file)
index 0000000..c219f45
--- /dev/null
@@ -0,0 +1,52 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 316.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 316.00 540.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 316.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=-6 height=-6)
+              (position 44.00 264.00)
+              (bounds 112.00 112.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-expected.txt b/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-expected.txt
new file mode 100644 (file)
index 0000000..d16a33b
--- /dev/null
@@ -0,0 +1,52 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 316.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 316.00 516.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 316.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=-6 height=-6)
+              (position 32.00 202.00)
+              (bounds 112.00 112.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer-expected.txt b/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer-expected.txt
new file mode 100644 (file)
index 0000000..ee09d6f
--- /dev/null
@@ -0,0 +1,59 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 316.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 316.00 540.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 316.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 20.00 220.00)
+              (bounds 200.00 100.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=-6 height=-6)
+                  (position 24.00 44.00)
+                  (bounds 112.00 112.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped-expected.txt b/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped-expected.txt
new file mode 100644 (file)
index 0000000..62d120b
--- /dev/null
@@ -0,0 +1,66 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 33.00 25.00)
+          (bounds 312.00 212.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=-10 height=-10)
+              (position 16.00 16.00)
+              (bounds 362.00 362.00)
+              (drawsContent 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (position 23.00 23.00)
+                  (bounds origin 0.00 50.00)
+                  (bounds 316.00 316.00)
+                  (clips 1)
+                  (children 1
+                    (GraphicsLayer
+                      (offsetFromRenderer width=13 height=13)
+                      (scrollOffset (0,50))
+                      (anchor 0.00 0.00)
+                      (bounds 316.00 516.00)
+                      (drawsContent 1)
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 33.00 25.00)
+          (bounds 312.00 212.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (position 39.00 39.00)
+              (bounds origin 0.00 50.00)
+              (bounds 316.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=-6 height=-6)
+                  (position 32.00 202.00)
+                  (bounds 112.00 112.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer-expected.txt b/LayoutTests/platform/ios-wk2/compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer-expected.txt
new file mode 100644 (file)
index 0000000..c219f45
--- /dev/null
@@ -0,0 +1,52 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (clips 1)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (position 18.00 10.00)
+          (bounds 362.00 362.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=13 height=13)
+              (position 23.00 23.00)
+              (bounds origin 0.00 50.00)
+              (bounds 316.00 316.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=13 height=13)
+                  (scrollOffset (0,50))
+                  (anchor 0.00 0.00)
+                  (bounds 316.00 540.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 41.00 33.00)
+          (bounds origin 0.00 50.00)
+          (bounds 316.00 316.00)
+          (clips 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=-6 height=-6)
+              (position 44.00 264.00)
+              (bounds 112.00 112.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
index 7071bf5..0a62e59 100644 (file)
@@ -1,6 +1,7 @@
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)
+  (clips 1)
   (children 1
     (GraphicsLayer
       (bounds 800.00 600.00)
@@ -14,6 +15,7 @@
               (offsetFromRenderer width=2 height=2)
               (position 2.00 2.00)
               (bounds 320.00 320.00)
+              (clips 1)
               (children 1
                 (GraphicsLayer
                   (position 10.00 10.00)
@@ -24,6 +26,7 @@
                       (offsetFromRenderer width=2 height=2)
                       (position 2.00 2.00)
                       (bounds 296.00 296.00)
+                      (clips 1)
                       (children 1
                         (GraphicsLayer
                           (offsetFromRenderer width=2 height=2)
           (contentsOpaque 1)
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-20 height=-20)
-          (position 42.00 34.00)
-          (bounds 296.00 296.00)
+          (position 30.00 22.00)
+          (bounds 320.00 320.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
-              (position 20.00 20.00)
-              (bounds 256.00 24.00)
-              (drawsContent 1)
+              (position 12.00 12.00)
+              (bounds 296.00 296.00)
+              (clips 1)
+              (children 1
+                (GraphicsLayer
+                  (position 20.00 20.00)
+                  (bounds 256.00 24.00)
+                  (drawsContent 1)
+                )
+              )
             )
           )
         )
index 33045c3..9640547 100644 (file)
@@ -37,8 +37,7 @@
           (children 1
             (Positioned node
               (layout constraints 
-                (layer-position-at-last-layout (-2,6))
-                (positioning-behavior stationary))
+                (layer-position-at-last-layout (-2,6)))
               (related overflow nodes 2)
             )
           )
index 86cd129..461ca65 100644 (file)
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,10))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
       (children 1
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (71,22))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (71,22)))
           (related overflow nodes 1)
         )
       )
diff --git a/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-expected.txt b/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-expected.txt
new file mode 100644 (file)
index 0000000..13f46c8
--- /dev/null
@@ -0,0 +1,36 @@
+
+(Frame scrolling node
+  (scrollable area size 800 600)
+  (contents size 800 600)
+  (parent relative scrollable rect at (0,0) size 800x600)
+  (scrollable area parameters 
+    (horizontal scroll elasticity 1)
+    (vertical scroll elasticity 1)
+    (horizontal scrollbar mode 0)
+    (vertical scrollbar mode 0))
+  (layout viewport at (0,0) size 800x600)
+  (min layout viewport origin (0,0))
+  (max layout viewport origin (0,0))
+  (behavior for fixed 0)
+  (children 2
+    (Overflow scrolling node
+      (scroll position 0 50)
+      (scrollable area size 316 316)
+      (contents size 316 540)
+      (requested scroll position 0 50)
+      (requested scroll position represents programmatic scroll 1)
+      (parent relative scrollable rect at (41,33) size 316x316)
+      (scrollable area parameters 
+        (horizontal scroll elasticity 1)
+        (vertical scroll elasticity 1)
+        (horizontal scrollbar mode 0)
+        (vertical scrollbar mode 0)
+        (has enabled vertical scrollbar 1))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,50))
+    )
+  )
+)
+
+
diff --git a/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested-expected.txt b/LayoutTests/platform/ios-wk2/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested-expected.txt
new file mode 100644 (file)
index 0000000..cd1068c
--- /dev/null
@@ -0,0 +1,55 @@
+
+(Frame scrolling node
+  (scrollable area size 800 600)
+  (contents size 800 600)
+  (parent relative scrollable rect at (0,0) size 800x600)
+  (scrollable area parameters 
+    (horizontal scroll elasticity 1)
+    (vertical scroll elasticity 1)
+    (horizontal scrollbar mode 0)
+    (vertical scrollbar mode 0))
+  (layout viewport at (0,0) size 800x600)
+  (min layout viewport origin (0,0))
+  (max layout viewport origin (0,0))
+  (behavior for fixed 0)
+  (children 3
+    (Overflow scrolling node
+      (scroll position 0 50)
+      (scrollable area size 316 316)
+      (contents size 316 640)
+      (requested scroll position 0 50)
+      (requested scroll position represents programmatic scroll 1)
+      (parent relative scrollable rect at (41,33) size 316x316)
+      (scrollable area parameters 
+        (horizontal scroll elasticity 1)
+        (vertical scroll elasticity 1)
+        (horizontal scrollbar mode 0)
+        (vertical scrollbar mode 0)
+        (has enabled vertical scrollbar 1))
+      (children 1
+        (Overflow scrolling node
+          (scroll position 0 150)
+          (scrollable area size 200 200)
+          (contents size 200 554)
+          (requested scroll position 0 150)
+          (requested scroll position represents programmatic scroll 1)
+          (parent relative scrollable rect at (56,206) size 200x200)
+          (scrollable area parameters 
+            (horizontal scroll elasticity 1)
+            (vertical scroll elasticity 1)
+            (horizontal scrollbar mode 0)
+            (vertical scrollbar mode 0)
+            (has enabled vertical scrollbar 1))
+        )
+      )
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,50))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,150))
+    )
+  )
+)
+
+
index 14f4bfc..a856d91 100644 (file)
       (children 2
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (20,28))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (20,28)))
           (related overflow nodes 1)
         )
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (40,48))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (40,48)))
           (related overflow nodes 1)
         )
       )
index ba7ad1a..08d2d55 100644 (file)
@@ -27,29 +27,17 @@ abs
         (has enabled horizontal scrollbar 1)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,10))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (50,50))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (62,82))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (77,77))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
   )
 )
index af9309b..b1bc828 100644 (file)
@@ -26,41 +26,23 @@ abs
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,10))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (0,30))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (13,43))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (53,83))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (65,115))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (80,110))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
   )
 )
index 208a7bd..e4f2412 100644 (file)
@@ -28,20 +28,17 @@ abs
       (children 3
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (20,28))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (20,28)))
           (related overflow nodes 1)
         )
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (32,60))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (32,60)))
           (related overflow nodes 1)
         )
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (47,55))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (47,55)))
           (related overflow nodes 1)
         )
       )
index 0ed8613..e33f8e5 100644 (file)
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,130))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
       (children 1
         (Overflow scrolling node
           (scrollable area size 200 200)
           (contents size 200 520)
-          (parent relative scrollable rect at (2,2) size 200x200)
+          (parent relative scrollable rect at (0,0) size 200x200)
           (scrollable area parameters 
             (horizontal scroll elasticity 1)
             (vertical scroll elasticity 1)
index 161f398..4235b98 100644 (file)
@@ -38,23 +38,14 @@ Stacking
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,40))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,60))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,80))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 220 170)
@@ -67,17 +58,11 @@ Stacking
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,40))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,60))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 220 170)
@@ -90,11 +75,8 @@ Stacking
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,40))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 220 170)
@@ -107,11 +89,8 @@ Stacking
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,40))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 220 170)
@@ -124,29 +103,17 @@ Stacking
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,40))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,60))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,90))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (110,110))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 220 170)
@@ -159,22 +126,15 @@ Stacking
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,40))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,60))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
       (children 1
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (79,50))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (79,50)))
           (related overflow nodes 1)
         )
       )
index 5073379..2852f8d 100644 (file)
@@ -54,11 +54,8 @@ Scrolling content
         )
       )
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,30))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 220 170)
@@ -84,8 +81,7 @@ Scrolling content
       (children 1
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (81,30))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (81,30)))
           (related overflow nodes 1)
         )
       )
index 4a67728..00aa8a6 100644 (file)
@@ -25,11 +25,8 @@ Sticky content
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (50,50))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
       (children 1
         (Sticky node
           (anchor edges: AnchorEdgeTop )
index b30dbb9..1648a49 100644 (file)
@@ -22,7 +22,6 @@ middlebottom
           (drawsContent 1)
         )
         (GraphicsLayer
-          (offsetFromRenderer width=0 height=100)
           (position 28.00 250.00)
           (bounds 185.00 200.00)
           (children 1
index 31fe83d..4094fdc 100644 (file)
@@ -2,6 +2,7 @@
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)
+  (clips 1)
   (children 1
     (GraphicsLayer
       (bounds 800.00 600.00)
@@ -17,6 +18,7 @@
               (position 2.00 2.00)
               (bounds origin 366.00 0.00)
               (bounds 400.00 205.00)
+              (clips 1)
               (children 1
                 (GraphicsLayer
                   (offsetFromRenderer width=2 height=2)
index 8f4dd05..0dbf07a 100644 (file)
@@ -20,7 +20,6 @@
                   (drawsContent 1)
                   (children 1
                     (GraphicsLayer
-                      (offsetFromRenderer width=-114 height=-300)
                       (bounds 300.00 672.00)
                       (children 1
                         (GraphicsLayer
index 6bc82b3..4a9a42e 100644 (file)
@@ -7,7 +7,6 @@
       (contentsOpaque 1)
       (children 1
         (GraphicsLayer
-          (offsetFromRenderer width=-10 height=-10)
           (bounds 305.00 325.00)
           (children 1
             (GraphicsLayer
index ad1cc6a..1c15270 100644 (file)
@@ -2,15 +2,16 @@
 (GraphicsLayer
   (anchor 0.00 0.00)
   (bounds 800.00 600.00)
+  (clips 1)
   (children 1
     (GraphicsLayer
       (bounds 800.00 600.00)
       (contentsOpaque 1)
       (children 1
         (GraphicsLayer
-          (offsetFromRenderer width=-96 height=0)
           (position 10.00 10.00)
           (bounds 400.00 204.00)
+          (clips 1)
           (children 1
             (GraphicsLayer
               (position 96.00 0.00)
index 86b8d92..bb593e4 100644 (file)
@@ -37,8 +37,7 @@
           (children 1
             (Positioned node
               (layout constraints 
-                (layer-position-at-last-layout (-2,6))
-                (positioning-behavior stationary))
+                (layer-position-at-last-layout (-2,6)))
               (related overflow nodes 2)
             )
           )
index 227bdb1..e12e573 100644 (file)
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,10))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
       (children 1
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (71,22))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (71,22)))
           (related overflow nodes 1)
         )
       )
diff --git a/LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-expected.txt b/LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-expected.txt
new file mode 100644 (file)
index 0000000..763e2bf
--- /dev/null
@@ -0,0 +1,36 @@
+
+(Frame scrolling node
+  (scrollable area size 800 600)
+  (contents size 800 600)
+  (parent relative scrollable rect at (0,0) size 800x600)
+  (scrollable area parameters 
+    (horizontal scroll elasticity 2)
+    (vertical scroll elasticity 2)
+    (horizontal scrollbar mode 0)
+    (vertical scrollbar mode 0))
+  (layout viewport at (0,0) size 800x600)
+  (min layout viewport origin (0,0))
+  (max layout viewport origin (0,0))
+  (behavior for fixed 0)
+  (children 2
+    (Overflow scrolling node
+      (scroll position 0 50)
+      (scrollable area size 301 316)
+      (contents size 301 540)
+      (requested scroll position 0 50)
+      (requested scroll position represents programmatic scroll 1)
+      (parent relative scrollable rect at (41,33) size 301x316)
+      (scrollable area parameters 
+        (horizontal scroll elasticity 1)
+        (vertical scroll elasticity 0)
+        (horizontal scrollbar mode 0)
+        (vertical scrollbar mode 0)
+        (has enabled vertical scrollbar 1))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,50))
+    )
+  )
+)
+
+
diff --git a/LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested-expected.txt b/LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested-expected.txt
new file mode 100644 (file)
index 0000000..aaa3748
--- /dev/null
@@ -0,0 +1,55 @@
+
+(Frame scrolling node
+  (scrollable area size 800 600)
+  (contents size 800 600)
+  (parent relative scrollable rect at (0,0) size 800x600)
+  (scrollable area parameters 
+    (horizontal scroll elasticity 2)
+    (vertical scroll elasticity 2)
+    (horizontal scrollbar mode 0)
+    (vertical scrollbar mode 0))
+  (layout viewport at (0,0) size 800x600)
+  (min layout viewport origin (0,0))
+  (max layout viewport origin (0,0))
+  (behavior for fixed 0)
+  (children 3
+    (Overflow scrolling node
+      (scroll position 0 50)
+      (scrollable area size 301 316)
+      (contents size 301 640)
+      (requested scroll position 0 50)
+      (requested scroll position represents programmatic scroll 1)
+      (parent relative scrollable rect at (41,33) size 301x316)
+      (scrollable area parameters 
+        (horizontal scroll elasticity 1)
+        (vertical scroll elasticity 0)
+        (horizontal scrollbar mode 0)
+        (vertical scrollbar mode 0)
+        (has enabled vertical scrollbar 1))
+      (children 1
+        (Overflow scrolling node
+          (scroll position 0 150)
+          (scrollable area size 185 200)
+          (contents size 185 554)
+          (requested scroll position 0 150)
+          (requested scroll position represents programmatic scroll 1)
+          (parent relative scrollable rect at (56,206) size 185x200)
+          (scrollable area parameters 
+            (horizontal scroll elasticity 1)
+            (vertical scroll elasticity 0)
+            (horizontal scrollbar mode 0)
+            (vertical scrollbar mode 0)
+            (has enabled vertical scrollbar 1))
+        )
+      )
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,50))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,150))
+    )
+  )
+)
+
+
diff --git a/LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested.html b/LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested.html
new file mode 100644 (file)
index 0000000..a7ba0a0
--- /dev/null
@@ -0,0 +1,85 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests clipped layer in overflow in clipped in overflow</title>
+    <style>
+        #scroller {
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .scroller {
+            overflow-y: scroll;
+        }
+        
+        .inner.scroller {
+            height: 200px;
+            width: 200px;
+            margin: 20px;
+            border: 3px solid purple;
+        }
+        
+        .clipping {
+            overflow: hidden;
+            border: 2px solid gray;
+        }
+        
+        .outer.clipping {
+            margin: 10px;
+            width: 200px;
+            height: 200px;
+        }
+
+        .box {
+            margin-top: 50px;
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 50);
+            scroller2.scrollTo(0, 150);
+            if (window.internals)
+                document.getElementById('scrollingTree').innerText = window.internals.scrollingStateTreeAsText() + "\n";
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller" class="scroller">
+        <div class="spacer"></div>
+        <div class="outer clipping">
+            <div id="scroller2" class="inner scroller">
+                <div class="spacer"></div>
+                <div class="clipping">
+                    <div class="composited box"></div>
+                </div>
+                <div class="spacer"></div>
+            </div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="scrollingTree"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow.html b/LayoutTests/scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow.html
new file mode 100644 (file)
index 0000000..94b9690
--- /dev/null
@@ -0,0 +1,76 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests the bounds of the clipping layer for nested clips in non-stacking context overflow</title>
+    <style>
+        #scroller {
+            overflow-y: scroll;
+            height: 300px;
+            width: 300px;
+            margin: 20px;
+            border: 13px solid black;
+            box-shadow: 0 0 7px black;
+            padding: 8px;
+        }
+        
+        .clipping {
+            overflow: hidden;
+            border: 2px solid gray;
+        }
+        
+        .outer.clipping {
+            margin: 10px;
+            width: 200px;
+            height: 100px;
+        }
+
+        .inner.clipping {
+            margin: 12px;
+            width: 100px;
+            height: 200px;
+        }
+        
+        .box {
+            margin-top: 50px;
+            margin-left: 30px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+            box-shadow: 0 0 4px black;
+        }
+
+        .spacer {
+            height: 200px;
+            width: 20px;
+            background-color: silver;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            scroller.scrollTo(0, 50);
+            if (window.internals)
+                document.getElementById('scrollingTree').innerText = window.internals.scrollingStateTreeAsText() + "\n";
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller">
+        <div class="spacer"></div>
+        <div class="outer clipping">
+            <div class="inner clipping">
+                <div class="composited box"></div>
+            </div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="scrollingTree"></pre>
+</body>
+</html>
+
index b11f860..3dd3232 100644 (file)
       (children 2
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (20,28))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (20,28)))
           (related overflow nodes 1)
         )
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (40,48))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (40,48)))
           (related overflow nodes 1)
         )
       )
index 81be073..1881928 100644 (file)
@@ -27,29 +27,17 @@ abs
         (has enabled horizontal scrollbar 1)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,10))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (50,50))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (62,80))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (77,77))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
   )
 )
index 1ac1643..ca30f80 100644 (file)
@@ -26,41 +26,23 @@ abs
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,10))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (0,30))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (13,43))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (53,83))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (65,113))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (80,110))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
   )
 )
index f5913a7..f008148 100644 (file)
@@ -28,20 +28,17 @@ abs
       (children 3
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (20,28))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (20,28)))
           (related overflow nodes 1)
         )
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (32,58))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (32,58)))
           (related overflow nodes 1)
         )
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (47,55))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (47,55)))
           (related overflow nodes 1)
         )
       )
index c8df37f..469f4c6 100644 (file)
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,130))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
       (children 1
         (Overflow scrolling node
           (scrollable area size 185 185)
           (contents size 185 520)
-          (parent relative scrollable rect at (2,2) size 185x185)
+          (parent relative scrollable rect at (0,0) size 185x185)
           (scrollable area parameters 
             (horizontal scroll elasticity 0)
             (vertical scroll elasticity 0)
index 8fa8d8b..5653e19 100644 (file)
@@ -40,23 +40,14 @@ Stacking
         (has enabled horizontal scrollbar 1)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,38))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,58))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,76))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 205 155)
@@ -70,17 +61,11 @@ Stacking
         (has enabled horizontal scrollbar 1)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,38))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,58))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 205 155)
@@ -93,11 +78,8 @@ Stacking
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,38))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 205 155)
@@ -110,11 +92,8 @@ Stacking
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,38))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 205 155)
@@ -128,29 +107,17 @@ Stacking
         (has enabled horizontal scrollbar 1)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,38))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,58))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,86))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (110,106))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 205 155)
@@ -163,22 +130,15 @@ Stacking
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (20,38))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
-    )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,58))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
+    )
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
       (children 1
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (79,48))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (79,48)))
           (related overflow nodes 1)
         )
       )
index 7f3ec7b..5e65b54 100644 (file)
@@ -55,11 +55,8 @@ Scrolling content
         )
       )
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (10,28))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
     )
     (Overflow scrolling node
       (scrollable area size 205 155)
@@ -85,8 +82,7 @@ Scrolling content
       (children 1
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (81,28))
-            (positioning-behavior stationary))
+            (layer-position-at-last-layout (81,28)))
           (related overflow nodes 1)
         )
       )
index 1349c22..760fa72 100644 (file)
@@ -25,11 +25,8 @@ Sticky content
         (vertical scrollbar mode 0)
         (has enabled vertical scrollbar 1))
     )
-    (Positioned node
-      (layout constraints 
-        (layer-position-at-last-layout (50,50))
-        (positioning-behavior moves))
-      (related overflow nodes 1)
+    (Overflow scroll proxy node
+      (related overflow scrolling node scroll position (0,0))
       (children 1
         (Sticky node
           (anchor edges: AnchorEdgeTop )
index 94ec8a3..be3669f 100644 (file)
@@ -1,5 +1,180 @@
 2019-06-23  Simon Fraser  <simon.fraser@apple.com>
 
+        [Async overflow scroll] Clipped composited layers inside overflow scroll jitter and get incorrectly clipped
+        https://bugs.webkit.org/show_bug.cgi?id=199133
+        rdar://problem/43614439
+
+        Reviewed by Antti Koivisto.
+
+        Currently a composited layer with an overflow:scroll ancestor (which is not a paint-order
+        ancestor) gets a single "ancestor clip layer" that represents the intersection of all the
+        clips provided by its containing-block ancestors with non-visible overflow (both scrolling
+        and non-scrolling ones).
+
+        To correctly update clips with async overflow scroll, this single clip layer needs to be
+        broken up into multiple clipping ancestors. We need a separate layer, and scrolling tree
+        node for each ancestor that is an overflow scroll, and layers that represent non-moving
+        clips (i.e. overflow:hidden and 'clip') between them. This patch adds
+        LayerAncestorClippingStack to represent this stack of clipping layers. For example with the
+        following content:
+        
+        <div style="overflow:hidden"> <--- A
+            <div style="overflow:scroll"> <--- B
+                <div style="overflow:hidden"> <--- C
+                    <div style="overflow:hidden"> <--- D
+                        <div style="overflow:scroll">  <--- E
+                            <div style="overflow:hidden"> <--- F
+                                <div style="overflow:hidden"> <--- G
+                                    <div></div> <--- H
+                                <div>
+                            <div>
+                        <div>
+                    <div>
+                <div>
+            <div>
+        <div>
+        
+        the composited RenderLayer for H owns a LayerAncestorClippingStack with the following contents:
+            [clip - A]
+            [scroller - B]
+            [clip - intersection of C and D]
+            [scroller - E]
+            [clip - intersection of F and G]
+
+        Each stack entry has a 'masksToBounds' GraphicsLayer for clipping. Entries representing
+        overflow:scroll clips have a ScrollingNodeID for their OverflowScrollProxy scrolling tree
+        node (which references the actual OverflowScrollingNode). The non-scroller clips in this
+        stack are computed unconstrained by the enclosing overflow:scroll.
+
+        When the OverflowScrollingNode is scrolled, the boundsOrigin of related OverflowScrollProxy nodes
+        is adjusted to move the descendant layers (other clipping layers, or composited layers).
+
+        OverflowScrollProxy nodes thus take over the role that "Moves" ScrollingTreePositionedNode had.
+        With this patch, ScrollingTreePositionedNode are purely for absolute position inside non-containing-block
+        stacking context overflow scroll. LayoutConstraints is renamed to AbsolutePositionConstraints accordingly.
+
+        Tests: compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-clipped-by-scroll.html
+               compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow-nested.html
+               compositing/scrolling/async-overflow-scrolling/clipped-layer-in-overflow.html
+               compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-hidden.html
+               compositing/scrolling/async-overflow-scrolling/layer-in-overflow-clip-to-visible.html
+               compositing/scrolling/async-overflow-scrolling/layer-in-overflow-gain-clipping-layer.html
+               compositing/scrolling/async-overflow-scrolling/layer-in-overflow-in-clipped.html
+               compositing/scrolling/async-overflow-scrolling/layer-in-overflow-lose-clipping-layer.html
+               compositing/scrolling/async-overflow-scrolling/layer-in-overflow.html
+               scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow-nested.html
+               scrollingcoordinator/scrolling-tree/clipped-layer-in-overflow.html
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::setPositionedNodeConstraints):
+        (WebCore::AsyncScrollingCoordinator::setPositionedNodeGeometry): Deleted.
+        * page/scrolling/AsyncScrollingCoordinator.h:
+        * page/scrolling/ScrollingConstraints.cpp:
+        (WebCore::operator<<):
+        * page/scrolling/ScrollingConstraints.h:
+        (WebCore::AbsolutePositionConstraints::operator== const):
+        (WebCore::AbsolutePositionConstraints::operator!= const):
+        (WebCore::LayoutConstraints::operator== const): Deleted.
+        (WebCore::LayoutConstraints::operator!= const): Deleted.
+        (WebCore::LayoutConstraints::alignmentOffset const): Deleted.
+        (WebCore::LayoutConstraints::setAlignmentOffset): Deleted.
+        (WebCore::LayoutConstraints::layerPositionAtLastLayout const): Deleted.
+        (WebCore::LayoutConstraints::setLayerPositionAtLastLayout): Deleted.
+        (WebCore::LayoutConstraints::scrollPositioningBehavior const): Deleted.
+        (WebCore::LayoutConstraints::setScrollPositioningBehavior): Deleted.
+        * page/scrolling/ScrollingCoordinator.h:
+        (WebCore::ScrollingCoordinator::setPositionedNodeConstraints):
+        (WebCore::ScrollingCoordinator::setPositionedNodeGeometry): Deleted.
+        * page/scrolling/ScrollingStatePositionedNode.cpp:
+        (WebCore::ScrollingStatePositionedNode::updateConstraints):
+        * page/scrolling/ScrollingStatePositionedNode.h:
+        * page/scrolling/ScrollingTree.cpp:
+        (WebCore::ScrollingTree::commitTreeState):
+        * page/scrolling/ScrollingTree.h:
+        (WebCore::ScrollingTree::nodesWithRelatedOverflow):
+        (WebCore::ScrollingTree::positionedNodesWithRelatedOverflow): Deleted.
+        * page/scrolling/cocoa/ScrollingTreeFixedNode.mm:
+        (WebCore::ScrollingTreeFixedNode::applyLayerPositions):
+        * page/scrolling/cocoa/ScrollingTreeOverflowScrollProxyNode.mm:
+        (WebCore::ScrollingTreeOverflowScrollProxyNode::commitStateBeforeChildren):
+        * page/scrolling/cocoa/ScrollingTreePositionedNode.h:
+        (WebCore::ScrollingTreePositionedNode::scrollPositioningBehavior const): Deleted.
+        * page/scrolling/cocoa/ScrollingTreePositionedNode.mm:
+        (WebCore::ScrollingTreePositionedNode::commitStateBeforeChildren):
+        (WebCore::ScrollingTreePositionedNode::scrollDeltaSinceLastCommit const):
+        * page/scrolling/cocoa/ScrollingTreeStickyNode.mm:
+        (WebCore::ScrollingTreeStickyNode::computeLayerPosition const):
+        * rendering/LayerAncestorClippingStack.cpp: Added.
+        (WebCore::LayerAncestorClippingStack::LayerAncestorClippingStack):
+        (WebCore::LayerAncestorClippingStack::equalToClipData const):
+        (WebCore::LayerAncestorClippingStack::hasAnyScrollingLayers const):
+        (WebCore::LayerAncestorClippingStack::clear):
+        (WebCore::LayerAncestorClippingStack::detachFromScrollingCoordinator):
+        (WebCore::LayerAncestorClippingStack::firstClippingLayer const):
+        (WebCore::LayerAncestorClippingStack::lastClippingLayer const):
+        (WebCore::LayerAncestorClippingStack::lastOverflowScrollProxyNodeID const):
+        (WebCore::LayerAncestorClippingStack::updateScrollingNodeLayers):
+        (WebCore::LayerAncestorClippingStack::updateWithClipData):
+        (WebCore::operator<<):
+        * rendering/LayerAncestorClippingStack.h: Added.
+        (WebCore::CompositedClipData::CompositedClipData):
+        (WebCore::CompositedClipData::operator== const):
+        (WebCore::CompositedClipData::operator!= const):
+        (WebCore::LayerAncestorClippingStack::stack):
+        (WebCore::LayerAncestorClippingStack::stack const):
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::~RenderLayerBacking):
+        (WebCore::RenderLayerBacking::updateDebugIndicators):
+        (WebCore::RenderLayerBacking::destroyGraphicsLayers):
+        (WebCore::RenderLayerBacking::updateTransform):
+        (WebCore::RenderLayerBacking::updateBlendMode):
+        (WebCore::RenderLayerBacking::updateAfterLayout):
+        (WebCore::RenderLayerBacking::updateConfiguration):
+        (WebCore::computeOffsetFromAncestorGraphicsLayer):
+        (WebCore::RenderLayerBacking::computePrimaryGraphicsLayerRect const):
+        (WebCore::RenderLayerBacking::computeParentGraphicsLayerRect const):
+        (WebCore::RenderLayerBacking::updateGeometry):
+        (WebCore::RenderLayerBacking::updateInternalHierarchy):
+        (WebCore::RenderLayerBacking::updateAncestorClippingStack):
+        (WebCore::RenderLayerBacking::updateAncestorClipping):
+        (WebCore::RenderLayerBacking::detachFromScrollingCoordinator):
+        (WebCore::RenderLayerBacking::scrollingNodeIDForChildren const):
+        (WebCore::RenderLayerBacking::childForSuperlayers const):
+        (WebCore::RenderLayerBacking::backingStoreMemoryEstimate const):
+        (WebCore::operator<<):
+        (WebCore::RenderLayerBacking::updateAncestorClippingLayer): Deleted.
+        (WebCore::RenderLayerBacking::coordinatedScrollingRoles const): Deleted.
+        * rendering/RenderLayerBacking.h:
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::didChangePlatformLayerForLayer):
+        (WebCore::RenderLayerCompositor::updateBackingAndHierarchy):
+        (WebCore::RenderLayerCompositor::layerStyleChanged): We need to run the checks for changed
+        clipping whether or not this layer has backing, because a non-composited layer with clipping can be
+        represented in the clipping stack of some other layer.
+        (WebCore::RenderLayerCompositor::clippedByAncestor const):
+        (WebCore::RenderLayerCompositor::updateAncestorClippingStack const):
+        (WebCore::RenderLayerCompositor::computeAncestorClippingStack const): The output of this function
+        is a Vector<CompositedClipData> which represents the ancestor clipping stack, but without the proxy node
+        and GraphicsLayer information. It's input to LayerAncestorClippingStack::updateWithClipData() which does
+        the merging of old and new states.
+        (WebCore::collectRelatedCoordinatedScrollingNodes):
+        (WebCore::RenderLayerCompositor::removeFromScrollCoordinatedLayers):
+        (WebCore::scrollCoordinationRoleForNodeType):
+        (WebCore::RenderLayerCompositor::attachScrollingNode):
+        (WebCore::RenderLayerCompositor::registerScrollingNodeID):
+        (WebCore::RenderLayerCompositor::detachScrollCoordinatedLayerWithRole):
+        (WebCore::RenderLayerCompositor::detachScrollCoordinatedLayer):
+        (WebCore::RenderLayerCompositor::coordinatedScrollingRolesForLayer const): Code moved from RenderLayerBacking.
+        (WebCore::RenderLayerCompositor::updateScrollCoordinationForLayer):
+        (WebCore::RenderLayerCompositor::updateScrollingNodeForScrollingProxyRole):
+        (WebCore::RenderLayerCompositor::updateScrollingNodeForPositioningRole):
+        * rendering/RenderLayerCompositor.h:
+        (WebCore::allScrollCoordinationRoles):
+
+2019-06-23  Simon Fraser  <simon.fraser@apple.com>
+
         Add OverflowScrollProxyNodes to the scrolling tree
         https://bugs.webkit.org/show_bug.cgi?id=199132
 
index 2dbefa0..a81d82a 100644 (file)
@@ -1243,6 +1243,7 @@ set(WebCore_PRIVATE_FRAMEWORK_HEADERS
     rendering/HitTestResult.h
     rendering/InlineBox.h
     rendering/InlineFlowBox.h
+    rendering/LayerAncestorClippingStack.h
     rendering/LayerFragment.h
     rendering/MarkedText.h
     rendering/OrderIterator.h
index 21c6b73..155c661 100644 (file)
@@ -1986,6 +1986,7 @@ rendering/InlineElementBox.cpp
 rendering/InlineFlowBox.cpp
 rendering/InlineIterator.cpp
 rendering/InlineTextBox.cpp
+rendering/LayerAncestorClippingStack.cpp
 rendering/LayerOverlapMap.cpp
 rendering/LayoutDisallowedScope.cpp
 rendering/LayoutRepainter.cpp
index da28870..94df9a5 100644 (file)
                0FEA3E80191B3169000F1B55 /* ScrollingTreeOverflowScrollingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA3E7E191B3169000F1B55 /* ScrollingTreeOverflowScrollingNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FEA3E84191B31BF000F1B55 /* ScrollingStateOverflowScrollingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA3E82191B31BF000F1B55 /* ScrollingStateOverflowScrollingNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FEA3E88191B3BD7000F1B55 /* ScrollingTreeFrameScrollingNode.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEA3E86191B3BD7000F1B55 /* ScrollingTreeFrameScrollingNode.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               0FEC120C22BF2CD2004E9D35 /* LayerAncestorClippingStack.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FEC120922BF2CC7004E9D35 /* LayerAncestorClippingStack.h */; settings = {ATTRIBUTES = (Private, ); }; };
                0FF3B9291EE3B6DE00B84144 /* JSDOMQuad.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF3B9251EE3B6DE00B84144 /* JSDOMQuad.h */; };
                0FF3B92B1EE3B6DE00B84144 /* JSDOMQuadInit.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF3B9271EE3B6DE00B84144 /* JSDOMQuadInit.h */; };
                0FF5026A102BA9430066F39A /* JSStyleMedia.h in Headers */ = {isa = PBXBuildFile; fileRef = 0FF50268102BA9430066F39A /* JSStyleMedia.h */; };
                0FEA3E82191B31BF000F1B55 /* ScrollingStateOverflowScrollingNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingStateOverflowScrollingNode.h; sourceTree = "<group>"; };
                0FEA3E85191B3BD7000F1B55 /* ScrollingTreeFrameScrollingNode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ScrollingTreeFrameScrollingNode.cpp; sourceTree = "<group>"; };
                0FEA3E86191B3BD7000F1B55 /* ScrollingTreeFrameScrollingNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollingTreeFrameScrollingNode.h; sourceTree = "<group>"; };
+               0FEC120922BF2CC7004E9D35 /* LayerAncestorClippingStack.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LayerAncestorClippingStack.h; sourceTree = "<group>"; };
+               0FEC120B22BF2CC7004E9D35 /* LayerAncestorClippingStack.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = LayerAncestorClippingStack.cpp; sourceTree = "<group>"; };
                0FEF20CD1BD4A24100128E5D /* LengthSize.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LengthSize.cpp; sourceTree = "<group>"; };
                0FEF20CF1BD4A64F00128E5D /* RenderStyleConstants.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderStyleConstants.cpp; sourceTree = "<group>"; };
                0FF2E80C1EE0D430009EABD4 /* PerformanceLoggingClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceLoggingClient.cpp; sourceTree = "<group>"; };
                                BCE789151120D6080060ECE5 /* InlineIterator.h */,
                                BCEA481A097D93020094C9E4 /* InlineTextBox.cpp */,
                                BCEA481B097D93020094C9E4 /* InlineTextBox.h */,
+                               0FEC120B22BF2CC7004E9D35 /* LayerAncestorClippingStack.cpp */,
+                               0FEC120922BF2CC7004E9D35 /* LayerAncestorClippingStack.h */,
                                580371631A66F1D300BAF519 /* LayerFragment.h */,
                                0F69F2B7228B98FF008D3565 /* LayerOverlapMap.cpp */,
                                0F69F2B6228B98FF008D3565 /* LayerOverlapMap.h */,
                                E15FF7D518C9553800FE4C87 /* KeypressCommand.h in Headers */,
                                450CEBF115073BBE002BB149 /* LabelableElement.h in Headers */,
                                A456FA2711AD4A830020B420 /* LabelsNodeList.h in Headers */,
+                               0FEC120C22BF2CD2004E9D35 /* LayerAncestorClippingStack.h in Headers */,
                                E4916FF7195DF6A0005AB349 /* LayerFlushThrottleState.h in Headers */,
                                580371641A66F1D300BAF519 /* LayerFragment.h in Headers */,
                                7AA3A6A0194B59B6001CBD24 /* LayerPool.h in Headers */,
index 0093aba..509b62d 100644 (file)
@@ -694,7 +694,7 @@ void AsyncScrollingCoordinator::setViewportConstraintedNodeConstraints(Scrolling
     }
 }
 
-void AsyncScrollingCoordinator::setPositionedNodeGeometry(ScrollingNodeID nodeID, const LayoutConstraints& constraints)
+void AsyncScrollingCoordinator::setPositionedNodeConstraints(ScrollingNodeID nodeID, const AbsolutePositionConstraints& constraints)
 {
     auto* node = m_scrollingStateTree->stateNodeForID(nodeID);
     if (!node)
index b153bac..324bb96 100644 (file)
@@ -115,7 +115,7 @@ private:
     WEBCORE_EXPORT void setScrollingNodeScrollableAreaGeometry(ScrollingNodeID, ScrollableArea&) override;
     WEBCORE_EXPORT void setFrameScrollingNodeState(ScrollingNodeID, const FrameView&) override;
     WEBCORE_EXPORT void setViewportConstraintedNodeConstraints(ScrollingNodeID, const ViewportConstraints&) override;
-    WEBCORE_EXPORT void setPositionedNodeGeometry(ScrollingNodeID, const LayoutConstraints&) override;
+    WEBCORE_EXPORT void setPositionedNodeConstraints(ScrollingNodeID, const AbsolutePositionConstraints&) override;
     WEBCORE_EXPORT void setRelatedOverflowScrollingNodes(ScrollingNodeID, Vector<ScrollingNodeID>&&) override;
 
     WEBCORE_EXPORT void reconcileScrollingState(FrameView&, const FloatPoint&, const LayoutViewportOriginOrOverrideRect&, ScrollType, ViewportRectStability, ScrollingLayerPositionAction) override;
index 13bcc55..6ce88ed 100644 (file)
@@ -110,10 +110,9 @@ TextStream& operator<<(TextStream& ts, ScrollPositioningBehavior behavior)
     return ts;
 }
 
-TextStream& operator<<(TextStream& ts, const LayoutConstraints& constraints)
+TextStream& operator<<(TextStream& ts, const AbsolutePositionConstraints& constraints)
 {
     ts.dumpProperty("layer-position-at-last-layout", constraints.layerPositionAtLastLayout());
-    ts.dumpProperty("positioning-behavior", constraints.scrollPositioningBehavior());
 
     return ts;
 }
index ef35577..e349b80 100644 (file)
 
 namespace WebCore {
 
-// LayoutConstraints classes encapsulate data and logic required to reposition elements whose layout
-// depends on the scroll position of ancestor elements.
-class LayoutConstraints {
+class AbsolutePositionConstraints {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    LayoutConstraints() = default;
+    AbsolutePositionConstraints() = default;
 
-    bool operator==(const LayoutConstraints& other) const
+    bool operator==(const AbsolutePositionConstraints& other) const
     {
         return alignmentOffset() == other.alignmentOffset()
-            && layerPositionAtLastLayout() == other.layerPositionAtLastLayout()
-            && scrollPositioningBehavior() == other.scrollPositioningBehavior();
+            && layerPositionAtLastLayout() == other.layerPositionAtLastLayout();
     }
 
-    bool operator!=(const LayoutConstraints& other) const { return !(*this == other); }
+    bool operator!=(const AbsolutePositionConstraints& other) const { return !(*this == other); }
     
     FloatSize alignmentOffset() const { return m_alignmentOffset; }
     void setAlignmentOffset(FloatSize offset) { m_alignmentOffset = offset; }
@@ -52,13 +49,9 @@ public:
     FloatPoint layerPositionAtLastLayout() const { return m_layerPositionAtLastLayout; }
     void setLayerPositionAtLastLayout(FloatPoint position) { m_layerPositionAtLastLayout = position; }
     
-    ScrollPositioningBehavior scrollPositioningBehavior() const { return m_scrollPositioningBehavior; }
-    void setScrollPositioningBehavior(ScrollPositioningBehavior behavior) { m_scrollPositioningBehavior = behavior; }
-
 private:
     FloatSize m_alignmentOffset;
     FloatPoint m_layerPositionAtLastLayout;
-    ScrollPositioningBehavior m_scrollPositioningBehavior { ScrollPositioningBehavior::None };
 };
 
 // ViewportConstraints classes encapsulate data and logic required to reposition elements whose layout
@@ -205,7 +198,7 @@ private:
 
 
 WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, ScrollPositioningBehavior);
-WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const LayoutConstraints&);
+WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const AbsolutePositionConstraints&);
 WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const FixedPositionViewportConstraints&);
 WEBCORE_EXPORT WTF::TextStream& operator<<(WTF::TextStream&, const StickyPositionViewportConstraints&);
 
index 65c6258..1bdfddd 100644 (file)
@@ -52,11 +52,11 @@ class TextStream;
 
 namespace WebCore {
 
+class AbsolutePositionConstraints;
 class Document;
 class Frame;
 class FrameView;
 class GraphicsLayer;
-class LayoutConstraints;
 class Page;
 class Region;
 class RenderLayer;
@@ -149,7 +149,7 @@ public:
     virtual void setScrollingNodeScrollableAreaGeometry(ScrollingNodeID, ScrollableArea&) { }
     virtual void setFrameScrollingNodeState(ScrollingNodeID, const FrameView&) { }
     virtual void setViewportConstraintedNodeConstraints(ScrollingNodeID, const ViewportConstraints&) { }
-    virtual void setPositionedNodeGeometry(ScrollingNodeID, const LayoutConstraints&) { }
+    virtual void setPositionedNodeConstraints(ScrollingNodeID, const AbsolutePositionConstraints&) { }
     virtual void setRelatedOverflowScrollingNodes(ScrollingNodeID, Vector<ScrollingNodeID>&&) { }
 
     virtual void reconcileViewportConstrainedLayerPositions(ScrollingNodeID, const LayoutRect&, ScrollingLayerPositionAction) { }
index 6777be2..ed4b9dd 100644 (file)
@@ -75,7 +75,7 @@ void ScrollingStatePositionedNode::setRelatedOverflowScrollingNodes(Vector<Scrol
     setPropertyChanged(RelatedOverflowScrollingNodes);
 }
 
-void ScrollingStatePositionedNode::updateConstraints(const LayoutConstraints& constraints)
+void ScrollingStatePositionedNode::updateConstraints(const AbsolutePositionConstraints& constraints)
 {
     if (m_constraints == constraints)
         return;
index 566828b..ac42acd 100644 (file)
@@ -35,7 +35,7 @@
 namespace WebCore {
 
 // ScrollingStatePositionedNode is used to manage the layers for z-order composited descendants of overflow:scroll
-// which are not containing block descendants. These layers must have their position inside their ancestor clipping
+// which are not containing block descendants (i.e. position:absolute). These layers must have their position inside their ancestor clipping
 // layer adjusted on the scrolling thread.
 class ScrollingStatePositionedNode final : public ScrollingStateNode {
 public:
@@ -54,8 +54,8 @@ public:
     const Vector<ScrollingNodeID>& relatedOverflowScrollingNodes() const { return m_relatedOverflowScrollingNodes; }
     WEBCORE_EXPORT void setRelatedOverflowScrollingNodes(Vector<ScrollingNodeID>&&);
 
-    WEBCORE_EXPORT void updateConstraints(const LayoutConstraints&);
-    const LayoutConstraints& layoutConstraints() const { return m_constraints; }
+    WEBCORE_EXPORT void updateConstraints(const AbsolutePositionConstraints&);
+    const AbsolutePositionConstraints& layoutConstraints() const { return m_constraints; }
 
 private:
     ScrollingStatePositionedNode(ScrollingStateTree&, ScrollingNodeID);
@@ -66,7 +66,7 @@ private:
     void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
 
     Vector<ScrollingNodeID> m_relatedOverflowScrollingNodes;
-    LayoutConstraints m_constraints;
+    AbsolutePositionConstraints m_constraints;
 };
 
 } // namespace WebCore
index 7d39398..10e380d 100644 (file)
@@ -169,7 +169,7 @@ void ScrollingTree::commitTreeState(std::unique_ptr<ScrollingStateTree> scrollin
         unvisitedNodes.add(nodeID);
 
     m_overflowRelatedNodesMap.clear();
-    m_positionedNodesWithRelatedOverflow.clear();
+    m_nodesWithRelatedOverflow.clear();
 
     // orphanNodes keeps child nodes alive while we rebuild child lists.
     OrphanScrollingNodeMap orphanNodes;
index 8eda675..b65b660 100644 (file)
@@ -154,7 +154,7 @@ public:
     using RelatedNodesMap = HashMap<ScrollingNodeID, Vector<ScrollingNodeID>>;
     RelatedNodesMap& overflowRelatedNodes() { return m_overflowRelatedNodesMap; }
 
-    HashSet<ScrollingNodeID>& positionedNodesWithRelatedOverflow() { return m_positionedNodesWithRelatedOverflow; }
+    HashSet<ScrollingNodeID>& nodesWithRelatedOverflow() { return m_nodesWithRelatedOverflow; }
 
     WEBCORE_EXPORT String scrollingTreeAsText(ScrollingStateTreeAsTextBehavior = ScrollingStateTreeAsTextBehaviorNormal);
 
@@ -179,7 +179,7 @@ private:
     ScrollingTreeNodeMap m_nodeMap;
 
     RelatedNodesMap m_overflowRelatedNodesMap;
-    HashSet<ScrollingNodeID> m_positionedNodesWithRelatedOverflow;
+    HashSet<ScrollingNodeID> m_nodesWithRelatedOverflow;
 
     struct TreeState {
         ScrollingNodeID latchedNodeID { 0 };
index 3f131b7..8e4ac23 100644 (file)
@@ -32,6 +32,7 @@
 #import "ScrollingStateFixedNode.h"
 #import "ScrollingTree.h"
 #import "ScrollingTreeFrameScrollingNode.h"
+#import "ScrollingTreeOverflowScrollProxyNode.h"
 #import "ScrollingTreeOverflowScrollingNode.h"
 #import "ScrollingTreePositionedNode.h"
 #import "ScrollingTreeStickyNode.h"
@@ -87,6 +88,13 @@ void ScrollingTreeFixedNode::applyLayerPositions()
                 continue;
             }
 
+            if (is<ScrollingTreeOverflowScrollProxyNode>(*ancestor)) {
+                // To keep the layer still during async scrolling we adjust by how much the position has changed since layout.
+                auto& overflowNode = downcast<ScrollingTreeOverflowScrollProxyNode>(*ancestor);
+                overflowScrollDelta -= overflowNode.scrollDeltaSinceLastCommit();
+                continue;
+            }
+
             if (is<ScrollingTreePositionedNode>(*ancestor)) {
                 auto& positioningAncestor = downcast<ScrollingTreePositionedNode>(*ancestor);
                 // See if sticky node already handled this positioning node.
index e11e72a..94cd6a3 100644 (file)
@@ -62,7 +62,7 @@ void ScrollingTreeOverflowScrollProxyNode::commitStateBeforeChildren(const Scrol
         return Vector<ScrollingNodeID>();
     }).iterator->value.append(scrollingNodeID());
 
-    scrollingTree().positionedNodesWithRelatedOverflow().add(scrollingNodeID());
+    scrollingTree().nodesWithRelatedOverflow().add(scrollingNodeID());
 }
 
 FloatSize ScrollingTreeOverflowScrollProxyNode::scrollDeltaSinceLastCommit() const
index 63c200d..7d31361 100644 (file)
@@ -43,7 +43,6 @@ public:
 
     CALayer *layer() const { return m_layer.get(); }
 
-    ScrollPositioningBehavior scrollPositioningBehavior() const { return m_constraints.scrollPositioningBehavior(); }
     const Vector<ScrollingNodeID>& relatedOverflowScrollingNodes() const { return m_relatedOverflowScrollingNodes; }
 
     FloatSize scrollDeltaSinceLastCommit() const;
@@ -58,7 +57,7 @@ private:
     WEBCORE_EXPORT void dumpProperties(WTF::TextStream&, ScrollingStateTreeAsTextBehavior) const override;
 
     Vector<ScrollingNodeID> m_relatedOverflowScrollingNodes;
-    LayoutConstraints m_constraints;
+    AbsolutePositionConstraints m_constraints;
     RetainPtr<CALayer> m_layer;
 };
 
index 966cce5..adc74eb 100644 (file)
@@ -63,17 +63,8 @@ void ScrollingTreePositionedNode::commitStateBeforeChildren(const ScrollingState
     if (positionedStateNode.hasChangedProperty(ScrollingStatePositionedNode::LayoutConstraintData))
         m_constraints = positionedStateNode.layoutConstraints();
 
-    // Tell the ScrollingTree about non-ancestor overflow nodes which affect this node.
-    if (m_constraints.scrollPositioningBehavior() == ScrollPositioningBehavior::Moves) {
-        auto& relatedNodes = scrollingTree().overflowRelatedNodes();
-        for (auto overflowNodeID : m_relatedOverflowScrollingNodes) {
-            relatedNodes.ensure(overflowNodeID, [] {
-                return Vector<ScrollingNodeID>();
-            }).iterator->value.append(scrollingNodeID());
-        }
-    }
-    if (!m_relatedOverflowScrollingNodes.isEmpty() && m_constraints.scrollPositioningBehavior() != ScrollPositioningBehavior::None)
-        scrollingTree().positionedNodesWithRelatedOverflow().add(scrollingNodeID());
+    if (!m_relatedOverflowScrollingNodes.isEmpty())
+        scrollingTree().nodesWithRelatedOverflow().add(scrollingNodeID());
 }
 
 FloatSize ScrollingTreePositionedNode::scrollDeltaSinceLastCommit() const
@@ -87,12 +78,9 @@ FloatSize ScrollingTreePositionedNode::scrollDeltaSinceLastCommit() const
             }
         }
     }
-    if (m_constraints.scrollPositioningBehavior() == ScrollPositioningBehavior::Stationary) {
-        // Stationary nodes move in the opposite direction.
-        return -delta;
-    }
-
-    return delta;
+    
+    // Positioned nodes compensate for scrolling, so negate the scroll delta.
+    return -delta;
 }
 
 void ScrollingTreePositionedNode::applyLayerPositions()
index 60e173e..d2841b6 100644 (file)
@@ -33,6 +33,7 @@
 #import "ScrollingTree.h"
 #import "ScrollingTreeFixedNode.h"
 #import "ScrollingTreeFrameScrollingNode.h"
+#import "ScrollingTreeOverflowScrollProxyNode.h"
 #import "ScrollingTreeOverflowScrollingNode.h"
 #import "WebCoreCALayerExtras.h"
 #import <wtf/text/TextStream.h>
@@ -81,27 +82,15 @@ FloatPoint ScrollingTreeStickyNode::computeLayerPosition() const
     };
 
     for (auto* ancestor = parent(); ancestor; ancestor = ancestor->parent()) {
-        if (is<ScrollingTreePositionedNode>(*ancestor)) {
-            auto& positioningAncestor = downcast<ScrollingTreePositionedNode>(*ancestor);
-
-            // FIXME: Do we need to do anything for ScrollPositioningBehavior::Stationary?
-            if (positioningAncestor.scrollPositioningBehavior() == ScrollPositioningBehavior::Moves) {
-                if (positioningAncestor.relatedOverflowScrollingNodes().isEmpty())
-                    break;
-                auto overflowNode = scrollingTree().nodeForID(positioningAncestor.relatedOverflowScrollingNodes()[0]);
-                if (!overflowNode)
-                    break;
-
-                auto position = computeLayerPositionForScrollingNode(*overflowNode);
-
-                if (positioningAncestor.layer() == m_layer) {
-                    // We'll also do the adjustment the positioning node would do.
-                    position -= positioningAncestor.scrollDeltaSinceLastCommit();
-                }
-
-                return position;
-            }
+        if (is<ScrollingTreeOverflowScrollProxyNode>(*ancestor)) {
+            auto& overflowProxyNode = downcast<ScrollingTreeOverflowScrollProxyNode>(*ancestor);
+            auto overflowNode = scrollingTree().nodeForID(overflowProxyNode.overflowScrollingNodeID());
+            if (!overflowNode)
+                break;
+
+            return computeLayerPositionForScrollingNode(*overflowNode);
         }
+
         if (is<ScrollingTreeScrollingNode>(*ancestor))
             return computeLayerPositionForScrollingNode(*ancestor);
 
index b8407ef..008d716 100644 (file)
@@ -354,6 +354,8 @@ public:
 
     WEBCORE_EXPORT void save();
     WEBCORE_EXPORT void restore();
+    
+    unsigned stackSize() const { return m_stack.size(); }
 
     // These draw methods will do both stroking and filling.
     // FIXME: ...except drawRect(), which fills properly but always strokes
@@ -697,6 +699,27 @@ private:
     bool m_saveAndRestore;
 };
 
+
+class GraphicsContextStateStackChecker {
+public:
+    GraphicsContextStateStackChecker(GraphicsContext& context)
+        : m_context(context)
+        , m_stackSize(context.stackSize())
+    { }
+    
+    ~GraphicsContextStateStackChecker()
+    {
+        if (m_context.stackSize() != m_stackSize)
+            WTFLogAlways("GraphicsContext %p stack changed by %d", this, (int)m_context.stackSize() - (int)m_stackSize);
+    }
+
+private:
+    GraphicsContext& m_context;
+    unsigned m_stackSize;
+};
+
+
+
 class InterpolationQualityMaintainer {
 public:
     explicit InterpolationQualityMaintainer(GraphicsContext& graphicsContext, InterpolationQuality interpolationQualityToUse)
diff --git a/Source/WebCore/rendering/LayerAncestorClippingStack.cpp b/Source/WebCore/rendering/LayerAncestorClippingStack.cpp
new file mode 100644 (file)
index 0000000..3c7ae30
--- /dev/null
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "LayerAncestorClippingStack.h"
+
+#include "GraphicsLayer.h"
+#include "ScrollingConstraints.h"
+#include "ScrollingCoordinator.h"
+#include <wtf/text/TextStream.h>
+
+namespace WebCore {
+
+LayerAncestorClippingStack::LayerAncestorClippingStack(Vector<CompositedClipData>&& clipDataStack)
+{
+    m_stack.reserveInitialCapacity(clipDataStack.size());
+    for (auto& clipDataEntry : clipDataStack)
+        m_stack.uncheckedAppend({ WTFMove(clipDataEntry), 0, nullptr });
+}
+
+bool LayerAncestorClippingStack::equalToClipData(const Vector<CompositedClipData>& clipDataStack) const
+{
+    if (m_stack.size() != clipDataStack.size())
+        return false;
+
+    for (unsigned i = 0; i < m_stack.size(); ++i) {
+        if (m_stack[i].clipData != clipDataStack[i])
+            return false;
+    }
+
+    return true;
+}
+
+bool LayerAncestorClippingStack::hasAnyScrollingLayers() const
+{
+    for (const auto& entry : m_stack) {
+        if (entry.clipData.isOverflowScroll)
+            return true;
+    }
+    
+    return false;
+}
+
+void LayerAncestorClippingStack::clear(ScrollingCoordinator* scrollingCoordinator)
+{
+    for (auto& entry : m_stack) {
+        if (entry.overflowScrollProxyNodeID) {
+            ASSERT(scrollingCoordinator);
+            scrollingCoordinator->unparentChildrenAndDestroyNode(entry.overflowScrollProxyNodeID);
+            entry.overflowScrollProxyNodeID = 0;
+        }
+
+        GraphicsLayer::unparentAndClear(entry.clippingLayer);
+    }
+}
+
+void LayerAncestorClippingStack::detachFromScrollingCoordinator(ScrollingCoordinator& scrollingCoordinator)
+{
+    for (auto& entry : m_stack) {
+        if (entry.overflowScrollProxyNodeID) {
+            scrollingCoordinator.unparentChildrenAndDestroyNode(entry.overflowScrollProxyNodeID);
+            entry.overflowScrollProxyNodeID = 0;
+        }
+    }
+}
+
+GraphicsLayer* LayerAncestorClippingStack::firstClippingLayer() const
+{
+    return m_stack.first().clippingLayer.get();
+}
+
+GraphicsLayer* LayerAncestorClippingStack::lastClippingLayer() const
+{
+    return m_stack.last().clippingLayer.get();
+}
+
+ScrollingNodeID LayerAncestorClippingStack::lastOverflowScrollProxyNodeID() const
+{
+    for (auto& entry : WTF::makeReversedRange(m_stack)) {
+        if (entry.overflowScrollProxyNodeID)
+            return entry.overflowScrollProxyNodeID;
+    }
+    
+    return 0;
+}
+
+void LayerAncestorClippingStack::updateScrollingNodeLayers(ScrollingCoordinator& scrollingCoordinator)
+{
+    for (const auto& entry : m_stack) {
+        if (!entry.clipData.isOverflowScroll)
+            continue;
+
+        scrollingCoordinator.setNodeLayers(entry.overflowScrollProxyNodeID, { entry.clippingLayer.get() });
+    }
+}
+
+bool LayerAncestorClippingStack::updateWithClipData(ScrollingCoordinator* scrollingCoordinator, Vector<CompositedClipData>&& clipDataStack)
+{
+    bool stackChanged = false;
+
+    int clipEntryCount = clipDataStack.size();
+    int stackEntryCount = m_stack.size();
+    for (int i = 0; i < clipEntryCount; ++i) {
+        auto& clipDataEntry = clipDataStack[i];
+        
+        if (i >= stackEntryCount) {
+            m_stack.append({ WTFMove(clipDataEntry), 0, nullptr });
+            stackChanged = true;
+            continue;
+        }
+        
+        auto& existingEntry = m_stack[i];
+        
+        if (existingEntry.clipData != clipDataEntry)
+            stackChanged = true;
+
+        if (existingEntry.clipData.isOverflowScroll && !clipDataEntry.isOverflowScroll) {
+            ASSERT(scrollingCoordinator);
+            scrollingCoordinator->unparentChildrenAndDestroyNode(existingEntry.overflowScrollProxyNodeID);
+            existingEntry.overflowScrollProxyNodeID = 0;
+        }
+        
+        existingEntry.clipData = WTFMove(clipDataEntry);
+    }
+    
+    if (stackEntryCount > clipEntryCount) {
+        for (int i = clipEntryCount; i < stackEntryCount; ++i) {
+            auto& entry = m_stack[i];
+            if (entry.overflowScrollProxyNodeID) {
+                ASSERT(scrollingCoordinator);
+                scrollingCoordinator->unparentChildrenAndDestroyNode(entry.overflowScrollProxyNodeID);
+            }
+            GraphicsLayer::unparentAndClear(entry.clippingLayer);
+        }
+
+        m_stack.shrink(clipEntryCount);
+        stackChanged = true;
+    } else
+        m_stack.shrinkToFit();
+
+    return stackChanged;
+}
+
+static TextStream& operator<<(TextStream& ts, const LayerAncestorClippingStack::ClippingStackEntry& entry)
+{
+    ts.dumpProperty("layer", entry.clipData.clippingLayer.get());
+    ts.dumpProperty("clip", entry.clipData.clipRect);
+    ts.dumpProperty("isOverflowScroll", entry.clipData.isOverflowScroll);
+    if (entry.overflowScrollProxyNodeID)
+        ts.dumpProperty("overflowScrollProxyNodeID", entry.overflowScrollProxyNodeID);
+    if (entry.clippingLayer)
+        ts.dumpProperty("clippingLayer", entry.clippingLayer->primaryLayerID());
+    return ts;
+}
+
+TextStream& operator<<(TextStream& ts, const LayerAncestorClippingStack& clipStack)
+{
+    TextStream multilineStream;
+    multilineStream.setIndent(ts.indent() + 2);
+
+    {
+        TextStream::GroupScope scope(ts);
+        multilineStream << "LayerAncestorClippingStack";
+
+        for (unsigned i = 0; i < clipStack.stack().size(); ++i) {
+            auto& entry = clipStack.stack()[i];
+            TextStream::GroupScope entryScope(multilineStream);
+            multilineStream << "entry " << i;
+            multilineStream << entry;
+        }
+
+        ts << multilineStream.release();
+    }
+    return ts;
+}
+
+} // namespace WebCore
+
diff --git a/Source/WebCore/rendering/LayerAncestorClippingStack.h b/Source/WebCore/rendering/LayerAncestorClippingStack.h
new file mode 100644 (file)
index 0000000..4cf4215
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "LayoutRect.h"
+#include "ScrollTypes.h"
+#include <wtf/Vector.h>
+#include <wtf/WeakPtr.h>
+
+namespace WTF {
+class TextStream;
+}
+
+namespace WebCore {
+
+class ScrollingCoordinator;
+
+struct CompositedClipData {
+    CompositedClipData(RenderLayer* layer, LayoutRect rect, bool isOverflowScrollEntry)
+        : clippingLayer(makeWeakPtr(layer))
+        , clipRect(rect)
+        , isOverflowScroll(isOverflowScrollEntry)
+    {
+    }
+
+    bool operator==(const CompositedClipData& other) const
+    {
+        return clippingLayer == other.clippingLayer
+            && clipRect == other.clipRect
+            && isOverflowScroll == other.isOverflowScroll;
+    }
+    
+    bool operator!=(const CompositedClipData& other) const
+    {
+        return !(*this == other);
+    }
+
+    WeakPtr<RenderLayer> clippingLayer; // For scroller entries, the scrolling layer. For other entries, the most-descendant layer that has a clip.
+    LayoutRect clipRect; // In the coordinate system of the RenderLayer that owns the stack.
+    bool isOverflowScroll { false };
+};
+
+
+// This class encapsulates the set of layers and their scrolling tree nodes representing clipping in the layer's containing block ancestry,
+// but not in its paint order ancestry.
+class LayerAncestorClippingStack {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    LayerAncestorClippingStack(Vector<CompositedClipData>&&);
+    ~LayerAncestorClippingStack() = default;
+
+    bool hasAnyScrollingLayers() const;
+    
+    bool equalToClipData(const Vector<CompositedClipData>&) const;
+    bool updateWithClipData(ScrollingCoordinator*, Vector<CompositedClipData>&&);
+
+    void clear(ScrollingCoordinator*);
+    void detachFromScrollingCoordinator(ScrollingCoordinator&);
+
+    void updateScrollingNodeLayers(ScrollingCoordinator&);
+
+    GraphicsLayer* firstClippingLayer() const;
+    GraphicsLayer* lastClippingLayer() const;
+    ScrollingNodeID lastOverflowScrollProxyNodeID() const;
+    
+    bool update(LayerAncestorClippingStack&&);
+    
+    struct ClippingStackEntry {
+        CompositedClipData clipData;
+        ScrollingNodeID overflowScrollProxyNodeID { 0 }; // The node for repositioning the scrolling proxy layer.
+        RefPtr<GraphicsLayer> clippingLayer;
+    };
+
+    Vector<ClippingStackEntry>& stack() { return m_stack; }
+    const Vector<ClippingStackEntry>& stack() const { return m_stack; }
+
+private:
+    // Order is ancestors to descendants.
+    Vector<ClippingStackEntry> m_stack;
+};
+
+TextStream& operator<<(TextStream&, const LayerAncestorClippingStack&);
+
+} // namespace WebCore
index 736c841..ca7290a 100644 (file)
@@ -4389,6 +4389,8 @@ void RenderLayer::paintLayerContents(GraphicsContext& context, const LayerPainti
     if (localPaintFlags & PaintLayerPaintingRootBackgroundOnly && !renderer().isRenderView() && !renderer().isDocumentElementRenderer())
         return;
 
+    GraphicsContextStateStackChecker checker(context);
+
     updateLayerListsIfNeeded();
 
     LayoutSize offsetFromRoot = offsetFromAncestor(paintingInfo.rootLayer);
index 499c165..b78a4c6 100644 (file)
@@ -47,6 +47,7 @@
 #include "HTMLPlugInElement.h"
 #include "InspectorInstrumentation.h"
 #include "KeyframeList.h"
+#include "LayerAncestorClippingStack.h"
 #include "Logging.h"
 #include "Page.h"
 #include "PerformanceLoggingClient.h"
@@ -238,7 +239,7 @@ RenderLayerBacking::RenderLayerBacking(RenderLayer& layer)
 RenderLayerBacking::~RenderLayerBacking()
 {
     // Note that m_owningLayer->backing() is null here.
-    updateAncestorClippingLayer(false);
+    updateAncestorClipping(false, nullptr);
     updateChildClippingStrategy(false);
     updateDescendantClippingLayer(false);
     updateOverflowControlsLayers(false, false, false);
@@ -424,8 +425,10 @@ void RenderLayerBacking::updateDebugIndicators(bool showBorder, bool showRepaint
     m_graphicsLayer->setShowDebugBorder(showBorder);
     m_graphicsLayer->setShowRepaintCounter(showRepaintCounter);
     
-    if (m_ancestorClippingLayer)
-        m_ancestorClippingLayer->setShowDebugBorder(showBorder);
+    if (m_ancestorClippingStack) {
+        for (auto& entry : m_ancestorClippingStack->stack())
+            entry.clippingLayer->setShowDebugBorder(showBorder);
+    }
 
     if (m_foregroundLayer) {
         m_foregroundLayer->setShowDebugBorder(showBorder);
@@ -539,7 +542,11 @@ void RenderLayerBacking::destroyGraphicsLayers()
 
     GraphicsLayer::clear(m_maskLayer);
 
-    GraphicsLayer::unparentAndClear(m_ancestorClippingLayer);
+    if (m_ancestorClippingStack) {
+        for (auto& entry : m_ancestorClippingStack->stack())
+            GraphicsLayer::unparentAndClear(entry.clippingLayer);
+    }
+
     GraphicsLayer::unparentAndClear(m_contentsContainmentLayer);
     GraphicsLayer::unparentAndClear(m_foregroundLayer);
     GraphicsLayer::unparentAndClear(m_backgroundLayer);
@@ -568,7 +575,7 @@ void RenderLayerBacking::updateTransform(const RenderStyle& style)
     
     if (m_contentsContainmentLayer) {
         m_contentsContainmentLayer->setTransform(t);
-        m_graphicsLayer->setTransform(TransformationMatrix());
+        m_graphicsLayer->setTransform({ });
     } else
         m_graphicsLayer->setTransform(t);
 }
@@ -611,9 +618,9 @@ void RenderLayerBacking::updateBackdropFiltersGeometry()
 #if ENABLE(CSS_COMPOSITING)
 void RenderLayerBacking::updateBlendMode(const RenderStyle& style)
 {
-    // FIXME: where is the blend mode updated when m_ancestorClippingLayers come and go?
-    if (m_ancestorClippingLayer) {
-        m_ancestorClippingLayer->setBlendMode(style.blendMode());
+    // FIXME: where is the blend mode updated when m_ancestorClippingStacks come and go?
+    if (m_ancestorClippingStack) {
+        m_ancestorClippingStack->stack().first().clippingLayer->setBlendMode(style.blendMode());
         m_graphicsLayer->setBlendMode(BlendMode::Normal);
     } else
         m_graphicsLayer->setBlendMode(style.blendMode());
@@ -736,8 +743,10 @@ void RenderLayerBacking::updateAfterLayout(bool needsClippingUpdate, bool needsF
         m_owningLayer.setNeedsCompositingGeometryUpdate();
         // This layer's geometry affects those of its children.
         m_owningLayer.setChildrenNeedCompositingGeometryUpdate();
-    } else if (needsClippingUpdate)
+    } else if (needsClippingUpdate) {
+        m_owningLayer.setNeedsCompositingConfigurationUpdate();
         m_owningLayer.setNeedsCompositingGeometryUpdate();
+    }
     
     if (needsFullRepaint && canIssueSetNeedsDisplay())
         setContentsNeedDisplay();
@@ -804,8 +813,8 @@ bool RenderLayerBacking::updateConfiguration()
     if (updateDescendantClippingLayer(needsDescendantsClippingLayer))
         layerConfigChanged = true;
 
-    // clippedByAncestor() does a tree walk.
-    if (updateAncestorClippingLayer(compositor.clippedByAncestor(m_owningLayer)))
+    auto* compositingAncestor = m_owningLayer.ancestorCompositingLayer();
+    if (updateAncestorClipping(compositor.clippedByAncestor(m_owningLayer, compositingAncestor), compositingAncestor))
         layerConfigChanged = true;
 
     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
@@ -949,7 +958,7 @@ static SnappedRectInfo snappedGraphicsLayer(const LayoutSize& offset, const Layo
     return snappedGraphicsLayer;
 }
 
-static LayoutSize computeOffsetFromAncestorGraphicsLayer(RenderLayer* compositedAncestor, const LayoutPoint& location, float deviceScaleFactor)
+static LayoutSize computeOffsetFromAncestorGraphicsLayer(const RenderLayer* compositedAncestor, const LayoutPoint& location, float deviceScaleFactor)
 {
     if (!compositedAncestor)
         return toLayoutSize(location);
@@ -1013,13 +1022,13 @@ private:
 
 LayoutRect RenderLayerBacking::computePrimaryGraphicsLayerRect(const LayoutRect& parentGraphicsLayerRect) const
 {
-    ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, LayoutRect());
+    ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, { });
     return LayoutRect(encloseRectToDevicePixels(LayoutRect(toLayoutPoint(compositedBoundsOffset.fromParentGraphicsLayer()), compositedBounds().size()),
         deviceScaleFactor()));
 }
 
 // FIXME: See if we need this now that updateGeometry() is always called in post-order traversal.
-LayoutRect RenderLayerBacking::computeParentGraphicsLayerRect(RenderLayer* compositedAncestor, LayoutSize& ancestorClippingLayerOffset) const
+LayoutRect RenderLayerBacking::computeParentGraphicsLayerRect(const RenderLayer* compositedAncestor) const
 {
     if (!compositedAncestor || !compositedAncestor->backing())
         return renderer().view().documentRect();
@@ -1048,20 +1057,6 @@ LayoutRect RenderLayerBacking::computeParentGraphicsLayerRect(RenderLayer* compo
         parentGraphicsLayerRect = LayoutRect((paddingBoxIncludingScrollbar.location() - toLayoutSize(ancestorCompositedBounds.location()) - toLayoutSize(scrollOffset)), paddingBoxIncludingScrollbar.size());
     }
 
-    if (m_ancestorClippingLayer) {
-        // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
-        // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
-        // for a compositing layer, rootLayer is the layer itself.
-        ShouldRespectOverflowClip shouldRespectOverflowClip = compositedAncestor->isolatesCompositedBlending() ? RespectOverflowClip : IgnoreOverflowClip;
-        RenderLayer::ClipRectsContext clipRectsContext(compositedAncestor, TemporaryClipRects, IgnoreOverlayScrollbarSize, shouldRespectOverflowClip);
-        LayoutRect parentClipRect = m_owningLayer.backgroundClipRect(clipRectsContext).rect(); // FIXME: Incorrect for CSS regions.
-        ASSERT(!parentClipRect.isInfinite());
-        LayoutSize clippingOffset = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, parentClipRect.location(), deviceScaleFactor());
-        LayoutRect snappedClippingLayerRect = snappedGraphicsLayer(clippingOffset, parentClipRect.size(), deviceScaleFactor()).m_snappedRect;
-        // The primary layer is then parented in, and positioned relative to this clipping layer.
-        ancestorClippingLayerOffset = snappedClippingLayerRect.location() - parentGraphicsLayerRect.location();
-        parentGraphicsLayerRect = snappedClippingLayerRect;
-    }
     return parentGraphicsLayerRect;
 }
 
@@ -1091,20 +1086,53 @@ void RenderLayerBacking::updateGeometry()
     updateBlendMode(style);
 #endif
 
-    // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
-    bool preserves3D = style.transformStyle3D() == TransformStyle3D::Preserve3D && !renderer().hasReflection();
-    m_graphicsLayer->setPreserves3D(preserves3D);
-    m_graphicsLayer->setBackfaceVisibility(style.backfaceVisibility() == BackfaceVisibility::Visible);
-
     auto* compositedAncestor = m_owningLayer.ancestorCompositingLayer();
-    LayoutSize ancestorClippingLayerOffset;
-    LayoutRect parentGraphicsLayerRect = computeParentGraphicsLayerRect(compositedAncestor, ancestorClippingLayerOffset);
+    LayoutRect parentGraphicsLayerRect = computeParentGraphicsLayerRect(compositedAncestor);
+
+    if (m_ancestorClippingStack) {
+        // All clipRects in the stack are computed relative to m_owningLayer, so convert them back to compositedAncestor.
+        auto offsetFromCompositedAncestor = toLayoutSize(m_owningLayer.convertToLayerCoords(compositedAncestor, { }, RenderLayer::AdjustForColumns));
+        LayoutRect lastClipLayerRect = parentGraphicsLayerRect;
+
+        for (auto& entry : m_ancestorClippingStack->stack()) {
+            auto clipRect = entry.clipData.clipRect;
+            LayoutSize clippingOffset = computeOffsetFromAncestorGraphicsLayer(compositedAncestor, clipRect.location() + offsetFromCompositedAncestor, deviceScaleFactor());
+            LayoutRect snappedClippingLayerRect = snappedGraphicsLayer(clippingOffset, clipRect.size(), deviceScaleFactor()).m_snappedRect;
+
+            entry.clippingLayer->setPosition(toLayoutPoint(snappedClippingLayerRect.location() - lastClipLayerRect.location()));
+            lastClipLayerRect = snappedClippingLayerRect;
+
+            entry.clippingLayer->setSize(snappedClippingLayerRect.size());
+
+            if (entry.clipData.isOverflowScroll) {
+                ScrollOffset scrollOffset = entry.clipData.clippingLayer->scrollOffset();
+
+                entry.clippingLayer->setBoundsOrigin(scrollOffset);
+                lastClipLayerRect.moveBy(-scrollOffset);
+            }
+        }
+
+        parentGraphicsLayerRect = lastClipLayerRect;
+    }
+
     LayoutRect primaryGraphicsLayerRect = computePrimaryGraphicsLayerRect(parentGraphicsLayerRect);
 
     ComputedOffsets compositedBoundsOffset(m_owningLayer, compositedBounds(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
+    ComputedOffsets rendererOffset(m_owningLayer, { }, parentGraphicsLayerRect, primaryGraphicsLayerRect);
+
     m_compositedBoundsOffsetFromGraphicsLayer = compositedBoundsOffset.fromPrimaryGraphicsLayer();
-    m_graphicsLayer->setPosition(primaryGraphicsLayerRect.location());
-    m_graphicsLayer->setSize(primaryGraphicsLayerRect.size());
+
+    auto primaryLayerPosition = primaryGraphicsLayerRect.location();
+
+    // FIXME: reflections should force transform-style to be flat in the style: https://bugs.webkit.org/show_bug.cgi?id=106959
+    bool preserves3D = style.transformStyle3D() == TransformStyle3D::Preserve3D && !renderer().hasReflection();
+    if (m_contentsContainmentLayer) {
+        m_contentsContainmentLayer->setPreserves3D(preserves3D);
+        m_contentsContainmentLayer->setPosition(primaryLayerPosition);
+        primaryLayerPosition = { };
+        // Use the same size as m_graphicsLayer so transforms behave correctly.
+        m_contentsContainmentLayer->setSize(primaryGraphicsLayerRect.size());
+    }
 
     auto computeAnimationExtent = [&] () -> Optional<FloatRect> {
         LayoutRect animatedBounds;
@@ -1113,22 +1141,11 @@ void RenderLayerBacking::updateGeometry()
         return { };
     };
     m_graphicsLayer->setAnimationExtent(computeAnimationExtent());
+    m_graphicsLayer->setPreserves3D(preserves3D);
+    m_graphicsLayer->setBackfaceVisibility(style.backfaceVisibility() == BackfaceVisibility::Visible);
 
-    ComputedOffsets rendererOffset(m_owningLayer, LayoutRect(), parentGraphicsLayerRect, primaryGraphicsLayerRect);
-    if (m_ancestorClippingLayer) {
-        // Clipping layer is parented in the ancestor layer.
-        m_ancestorClippingLayer->setPosition(toLayoutPoint(ancestorClippingLayerOffset));
-        m_ancestorClippingLayer->setSize(parentGraphicsLayerRect.size());
-        m_ancestorClippingLayer->setOffsetFromRenderer(-rendererOffset.fromParentGraphicsLayer());
-    }
-
-    if (m_contentsContainmentLayer) {
-        m_contentsContainmentLayer->setPreserves3D(preserves3D);
-        m_contentsContainmentLayer->setPosition(primaryGraphicsLayerRect.location());
-        m_graphicsLayer->setPosition(FloatPoint());
-        // Use the same size as m_graphicsLayer so transforms behave correctly.
-        m_contentsContainmentLayer->setSize(primaryGraphicsLayerRect.size());
-    }
+    m_graphicsLayer->setPosition(primaryLayerPosition);
+    m_graphicsLayer->setSize(primaryGraphicsLayerRect.size());
 
     // Compute renderer offset from primary graphics layer. Note that primaryGraphicsLayerRect is in parentGraphicsLayer's coordinate system which is not necessarily
     // the same as the ancestor graphics layer.
@@ -1395,13 +1412,24 @@ void RenderLayerBacking::updateInternalHierarchy()
 {
     // m_foregroundLayer has to be inserted in the correct order with child layers,
     // so it's not inserted here.
-    if (m_ancestorClippingLayer)
-        m_ancestorClippingLayer->removeAllChildren();
+    GraphicsLayer* lastClippingLayer = nullptr;
+    if (m_ancestorClippingStack) {
+        auto& clippingStack = m_ancestorClippingStack->stack();
+        for (unsigned i = 0; i < clippingStack.size() - 1; ++i) {
+            auto& entry = clippingStack.at(i);
+            Vector<Ref<GraphicsLayer>> children;
+            children.append(*clippingStack.at(i + 1).clippingLayer);
+            entry.clippingLayer->setChildren(WTFMove(children));
+        }
+        
+        lastClippingLayer = clippingStack.last().clippingLayer.get();
+        lastClippingLayer->removeAllChildren();
+    }
     
     if (m_contentsContainmentLayer) {
         m_contentsContainmentLayer->removeAllChildren();
-        if (m_ancestorClippingLayer)
-            m_ancestorClippingLayer->addChild(*m_contentsContainmentLayer);
+        if (lastClippingLayer)
+            lastClippingLayer->addChild(*m_contentsContainmentLayer);
     }
     
     if (m_backgroundLayer)
@@ -1409,8 +1437,8 @@ void RenderLayerBacking::updateInternalHierarchy()
 
     if (m_contentsContainmentLayer)
         m_contentsContainmentLayer->addChild(*m_graphicsLayer);
-    else if (m_ancestorClippingLayer)
-        m_ancestorClippingLayer->addChild(*m_graphicsLayer);
+    else if (lastClippingLayer)
+        lastClippingLayer->addChild(*m_graphicsLayer);
 
     if (m_childContainmentLayer)
         m_graphicsLayer->addChild(*m_childContainmentLayer);
@@ -1525,20 +1553,60 @@ void RenderLayerBacking::updateEventRegion()
 #endif
 }
 
+bool RenderLayerBacking::updateAncestorClippingStack(Vector<CompositedClipData>&& clippingData)
+{
+    if (!m_ancestorClippingStack && clippingData.isEmpty())
+        return false;
+
+    auto* scrollingCoordinator = m_owningLayer.page().scrollingCoordinator();
+
+    if (m_ancestorClippingStack && clippingData.isEmpty()) {
+        m_ancestorClippingStack->clear(scrollingCoordinator);
+        m_ancestorClippingStack = nullptr;
+        return true;
+    }
+    
+    if (!m_ancestorClippingStack) {
+        m_ancestorClippingStack = std::make_unique<LayerAncestorClippingStack>(WTFMove(clippingData));
+        LOG_WITH_STREAM(Compositing, stream << "layer " << &m_owningLayer << "  ancestorClippingStack " << *m_ancestorClippingStack);
+        return true;
+    }
+    
+    if (m_ancestorClippingStack->equalToClipData(clippingData)) {
+        LOG_WITH_STREAM(Compositing, stream << "layer " << &m_owningLayer << "  ancestorClippingStack " << *m_ancestorClippingStack);
+        return false;
+    }
+    
+    m_ancestorClippingStack->updateWithClipData(scrollingCoordinator, WTFMove(clippingData));
+    LOG_WITH_STREAM(Compositing, stream << "layer " << &m_owningLayer << "  ancestorClippingStack " << *m_ancestorClippingStack);
+    return true;
+}
+
 // Return true if the layer changed.
-bool RenderLayerBacking::updateAncestorClippingLayer(bool needsAncestorClip)
+bool RenderLayerBacking::updateAncestorClipping(bool needsAncestorClip, const RenderLayer* compositingAncestor)
 {
     bool layersChanged = false;
 
     if (needsAncestorClip) {
-        if (!m_ancestorClippingLayer) {
-            m_ancestorClippingLayer = createGraphicsLayer("ancestor clipping");
-            m_ancestorClippingLayer->setMasksToBounds(true);
+        if (compositor().updateAncestorClippingStack(m_owningLayer, compositingAncestor)) {
+            // Make any layers we don't have.
+            if (m_ancestorClippingStack) {
+                for (auto& entry : m_ancestorClippingStack->stack()) {
+                    if (!entry.clippingLayer) {
+                        entry.clippingLayer = createGraphicsLayer(entry.clipData.isOverflowScroll ? "clip for scroller" : "ancestor clipping");
+                        entry.clippingLayer->setMasksToBounds(true);
+                        entry.clippingLayer->setPaintingPhase({ });
+                    }
+                }
+            }
+
             layersChanged = true;
         }
-    } else if (hasAncestorClippingLayer()) {
-        willDestroyLayer(m_ancestorClippingLayer.get());
-        GraphicsLayer::unparentAndClear(m_ancestorClippingLayer);
+    } else if (m_ancestorClippingStack) {
+        for (auto& entry : m_ancestorClippingStack->stack())
+            GraphicsLayer::unparentAndClear(entry.clippingLayer);
+
+        m_ancestorClippingStack = nullptr;
         layersChanged = true;
     }
     
@@ -1860,29 +1928,9 @@ bool RenderLayerBacking::updateScrollingLayers(bool needsScrollingLayers)
     return true;
 }
 
-OptionSet<ScrollCoordinationRole> RenderLayerBacking::coordinatedScrollingRoles() const
-{
-    auto& compositor = this->compositor();
-
-    OptionSet<ScrollCoordinationRole> coordinationRoles;
-    if (compositor.isViewportConstrainedFixedOrStickyLayer(m_owningLayer))
-        coordinationRoles.add(ScrollCoordinationRole::ViewportConstrained);
-
-    if (compositor.useCoordinatedScrollingForLayer(m_owningLayer))
-        coordinationRoles.add(ScrollCoordinationRole::Scrolling);
-
-    if (compositor.isLayerForIFrameWithScrollCoordinatedContents(m_owningLayer))
-        coordinationRoles.add(ScrollCoordinationRole::FrameHosting);
-
-    if (compositor.computeCoordinatedPositioningForLayer(m_owningLayer) != ScrollPositioningBehavior::None)
-        coordinationRoles.add(ScrollCoordinationRole::Positioning);
-
-    return coordinationRoles;
-}
-
 void RenderLayerBacking::detachFromScrollingCoordinator(OptionSet<ScrollCoordinationRole> roles)
 {
-    if (!m_scrollingNodeID && !m_frameHostingNodeID && !m_viewportConstrainedNodeID && !m_positioningNodeID)
+    if (!m_scrollingNodeID && !m_ancestorClippingStack && !m_frameHostingNodeID && !m_viewportConstrainedNodeID && !m_positioningNodeID)
         return;
 
     auto* scrollingCoordinator = m_owningLayer.page().scrollingCoordinator();
@@ -1890,30 +1938,54 @@ void RenderLayerBacking::detachFromScrollingCoordinator(OptionSet<ScrollCoordina
         return;
 
     if (roles.contains(ScrollCoordinationRole::Scrolling) && m_scrollingNodeID) {
-        LOG(Compositing, "Detaching Scrolling node %" PRIu64, m_scrollingNodeID);
+        LOG_WITH_STREAM(Compositing, stream << "Detaching Scrolling node " << m_scrollingNodeID);
         scrollingCoordinator->unparentChildrenAndDestroyNode(m_scrollingNodeID);
         m_scrollingNodeID = 0;
     }
 
+    if (roles.contains(ScrollCoordinationRole::ScrollingProxy) && m_ancestorClippingStack) {
+        m_ancestorClippingStack->detachFromScrollingCoordinator(*scrollingCoordinator);
+        LOG_WITH_STREAM(Compositing, stream << "Detaching nodes in ancestor clipping stack");
+    }
+
     if (roles.contains(ScrollCoordinationRole::FrameHosting) && m_frameHostingNodeID) {
-        LOG(Compositing, "Detaching FrameHosting node %" PRIu64, m_frameHostingNodeID);
+        LOG_WITH_STREAM(Compositing, stream << "Detaching FrameHosting node " << m_frameHostingNodeID);
         scrollingCoordinator->unparentChildrenAndDestroyNode(m_frameHostingNodeID);
         m_frameHostingNodeID = 0;
     }
 
     if (roles.contains(ScrollCoordinationRole::ViewportConstrained) && m_viewportConstrainedNodeID) {
-        LOG(Compositing, "Detaching ViewportConstrained node %" PRIu64, m_viewportConstrainedNodeID);
+        LOG_WITH_STREAM(Compositing, stream << "Detaching ViewportConstrained node " << m_viewportConstrainedNodeID);
         scrollingCoordinator->unparentChildrenAndDestroyNode(m_viewportConstrainedNodeID);
         m_viewportConstrainedNodeID = 0;
     }
 
     if (roles.contains(ScrollCoordinationRole::Positioning) && m_positioningNodeID) {
-        LOG(Compositing, "Detaching Positioned node %" PRIu64, m_positioningNodeID);
+        LOG_WITH_STREAM(Compositing, stream << "Detaching Positioned node " << m_positioningNodeID);
         scrollingCoordinator->unparentChildrenAndDestroyNode(m_positioningNodeID);
         m_positioningNodeID = 0;
     }
 }
 
+ScrollingNodeID RenderLayerBacking::scrollingNodeIDForChildren() const
+{
+    if (m_frameHostingNodeID)
+        return m_frameHostingNodeID;
+
+    if (m_scrollingNodeID)
+        return m_scrollingNodeID;
+
+    if (m_viewportConstrainedNodeID)
+        return m_viewportConstrainedNodeID;
+
+    if (m_ancestorClippingStack) {
+        if (auto lastOverflowScrollProxyNode = m_ancestorClippingStack->lastOverflowScrollProxyNodeID())
+            return lastOverflowScrollProxyNode;
+    }
+
+    return m_positioningNodeID;
+}
+
 void RenderLayerBacking::setIsScrollCoordinatedWithViewportConstrainedRole(bool viewportCoordinated)
 {
     m_graphicsLayer->setIsViewportConstrained(viewportCoordinated);
@@ -2498,8 +2570,8 @@ GraphicsLayer* RenderLayerBacking::parentForSublayers() const
 
 GraphicsLayer* RenderLayerBacking::childForSuperlayers() const
 {
-    if (m_ancestorClippingLayer)
-        return m_ancestorClippingLayer.get();
+    if (m_ancestorClippingStack)
+        return m_ancestorClippingStack->firstClippingLayer();
 
     if (m_contentsContainmentLayer)
         return m_contentsContainmentLayer.get();
@@ -2655,6 +2727,8 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
         return;
     }
 
+    GraphicsContextStateStackChecker checker(context);
+
     OptionSet<RenderLayer::PaintLayerFlag> paintFlags;
     if (paintingPhase.contains(GraphicsLayerPaintingPhase::Background))
         paintFlags.add(RenderLayer::PaintLayerPaintingCompositingBackgroundPhase);
@@ -3311,7 +3385,7 @@ double RenderLayerBacking::backingStoreMemoryEstimate() const
 {
     double backingMemory;
     
-    // m_ancestorClippingLayer, m_contentsContainmentLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
+    // Layers in m_ancestorClippingStack, m_contentsContainmentLayer and m_childContainmentLayer are just used for masking or containment, so have no backing.
     backingMemory = m_graphicsLayer->backingStoreMemoryEstimate();
     if (m_foregroundLayer)
         backingMemory += m_foregroundLayer->backingStoreMemoryEstimate();
@@ -3353,6 +3427,10 @@ TextStream& operator<<(TextStream& ts, const RenderLayerBacking& backing)
         ts << " viewport constrained scrolling node " << nodeID;
     if (auto nodeID = backing.scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling))
         ts << " scrolling node " << nodeID;
+
+    if (backing.ancestorClippingStack())
+        ts << " ancestor clip stack " << *backing.ancestorClippingStack();
+
     if (auto nodeID = backing.scrollingNodeIDForRole(ScrollCoordinationRole::FrameHosting))
         ts << " frame hosting node " << nodeID;
     if (auto nodeID = backing.scrollingNodeIDForRole(ScrollCoordinationRole::Positioning))
index 45bef50..3b5dee2 100644 (file)
@@ -44,7 +44,7 @@ class TransformationMatrix;
 enum CompositingLayerType {
     NormalCompositingLayer, // non-tiled layer with backing store
     TiledCompositingLayer, // tiled layer (always has backing store)
-    MediaCompositingLayer, // layer that contains an image, video, webGL or plugin
+    MediaCompositingLayer, // layer that contains an image, video, WebGL or plugin
     ContainerCompositingLayer // layer with no backing store
 };
 
@@ -100,9 +100,9 @@ public:
     bool hasClippingLayer() const { return (m_childContainmentLayer && !m_isFrameLayerWithTiledBacking); }
     GraphicsLayer* clippingLayer() const { return !m_isFrameLayerWithTiledBacking ? m_childContainmentLayer.get() : nullptr; }
 
-    // Layer to get clipped by ancestor
-    bool hasAncestorClippingLayer() const { return m_ancestorClippingLayer != nullptr; }
-    GraphicsLayer* ancestorClippingLayer() const { return m_ancestorClippingLayer.get(); }
+    bool hasAncestorClippingLayers() const { return !!m_ancestorClippingStack; }
+    LayerAncestorClippingStack* ancestorClippingStack() const { return m_ancestorClippingStack.get(); }
+    bool updateAncestorClippingStack(Vector<CompositedClipData>&&);
 
     GraphicsLayer* contentsContainmentLayer() const { return m_contentsContainmentLayer.get(); }
 
@@ -117,8 +117,6 @@ public:
     GraphicsLayer* scrollContainerLayer() const { return m_scrollContainerLayer.get(); }
     GraphicsLayer* scrolledContentsLayer() const { return m_scrolledContentsLayer.get(); }
 
-    OptionSet<ScrollCoordinationRole> coordinatedScrollingRoles() const;
-
     void detachFromScrollingCoordinator(OptionSet<ScrollCoordinationRole>);
 
     ScrollingNodeID scrollingNodeIDForRole(ScrollCoordinationRole role) const
@@ -126,6 +124,10 @@ public:
         switch (role) {
         case ScrollCoordinationRole::Scrolling:
             return m_scrollingNodeID;
+        case ScrollCoordinationRole::ScrollingProxy:
+            // These nodeIDs are stored in m_ancestorClippingStack.
+            ASSERT_NOT_REACHED();
+            return 0;
         case ScrollCoordinationRole::FrameHosting:
             return m_frameHostingNodeID;
         case ScrollCoordinationRole::ViewportConstrained:
@@ -142,6 +144,10 @@ public:
         case ScrollCoordinationRole::Scrolling:
             m_scrollingNodeID = nodeID;
             break;
+        case ScrollCoordinationRole::ScrollingProxy:
+            // These nodeIDs are stored in m_ancestorClippingStack.
+            ASSERT_NOT_REACHED();
+            break;
         case ScrollCoordinationRole::FrameHosting:
             m_frameHostingNodeID = nodeID;
             break;
@@ -155,20 +161,7 @@ public:
         }
     }
 
-    ScrollingNodeID scrollingNodeIDForChildren() const
-    {
-        if (m_frameHostingNodeID)
-            return m_frameHostingNodeID;
-
-        if (m_scrollingNodeID)
-            return m_scrollingNodeID;
-
-        if (m_viewportConstrainedNodeID)
-            return m_viewportConstrainedNodeID;
-
-        return m_positioningNodeID;
-    }
-
+    ScrollingNodeID scrollingNodeIDForChildren() const;
     void setIsScrollCoordinatedWithViewportConstrainedRole(bool);
 
     bool hasMaskLayer() const { return m_maskLayer; }
@@ -313,7 +306,7 @@ private:
     RenderLayerCompositor& compositor() const { return m_owningLayer.compositor(); }
 
     void updateInternalHierarchy();
-    bool updateAncestorClippingLayer(bool needsAncestorClip);
+    bool updateAncestorClipping(bool needsAncestorClip, const RenderLayer* compositingAncestor);
     bool updateDescendantClippingLayer(bool needsDescendantClip);
     bool updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer);
     bool updateForegroundLayer(bool needsForegroundLayer);
@@ -391,15 +384,16 @@ private:
     static AnimatedPropertyID cssToGraphicsLayerProperty(CSSPropertyID);
 
     bool canIssueSetNeedsDisplay() const { return !paintsIntoWindow() && !paintsIntoCompositedAncestor(); }
-    LayoutRect computeParentGraphicsLayerRect(RenderLayer* compositedAncestor, LayoutSize& ancestorClippingLayerOffset) const;
+    LayoutRect computeParentGraphicsLayerRect(const RenderLayer* compositedAncestor) const;
     LayoutRect computePrimaryGraphicsLayerRect(const LayoutRect& parentGraphicsLayerRect) const;
 
     RenderLayer& m_owningLayer;
-
+    
     // A list other layers that paint into this backing store, later than m_owningLayer in paint order.
     Vector<WeakPtr<RenderLayer>> m_backingSharingLayers;
 
-    RefPtr<GraphicsLayer> m_ancestorClippingLayer; // Only used if we are clipped by an ancestor which is not a stacking context.
+    std::unique_ptr<LayerAncestorClippingStack> m_ancestorClippingStack; // Only used if we are clipped by an ancestor which is not a stacking context.
+
     RefPtr<GraphicsLayer> m_contentsContainmentLayer; // Only used if we have a background layer; takes the transform.
     RefPtr<GraphicsLayer> m_graphicsLayer;
     RefPtr<GraphicsLayer> m_foregroundLayer; // Only used in cases where we need to draw the foreground separately.
index 3058334..d6becc3 100644 (file)
@@ -42,6 +42,7 @@
 #include "HTMLNames.h"
 #include "HitTestResult.h"
 #include "InspectorInstrumentation.h"
+#include "LayerAncestorClippingStack.h"
 #include "LayerOverlapMap.h"
 #include "Logging.h"
 #include "NodeList.h"
@@ -576,6 +577,9 @@ void RenderLayerCompositor::didChangePlatformLayerForLayer(RenderLayer& layer, c
     if (auto nodeID = backing->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling))
         updateScrollingNodeLayers(nodeID, layer, *scrollingCoordinator);
 
+    if (auto* clippingStack = layer.backing()->ancestorClippingStack())
+        clippingStack->updateScrollingNodeLayers(*scrollingCoordinator);
+
     if (auto nodeID = backing->scrollingNodeIDForRole(ScrollCoordinationRole::ViewportConstrained))
         scrollingCoordinator->setNodeLayers(nodeID, { backing->graphicsLayer() });
 
@@ -1228,7 +1232,7 @@ void RenderLayerCompositor::updateBackingAndHierarchy(RenderLayer& layer, Vector
 
         // FIXME: do based on dirty flags. Need to do this for changes of geometry, configuration and hierarchy.
         // Need to be careful to do the right thing when a scroll-coordinated layer loses a scroll-coordinated ancestor.
-        stateForDescendants.parentNodeID = updateScrollCoordinationForLayer(layer, scrollingTreeState, layerBacking->coordinatedScrollingRoles(), scrollingNodeChanges);
+        stateForDescendants.parentNodeID = updateScrollCoordinationForLayer(layer, scrollingTreeState, scrollingNodeChanges);
         stateForDescendants.nextChildIndex = 0;
 
 #if !LOG_DISABLED
@@ -1469,9 +1473,34 @@ void RenderLayerCompositor::layerStyleChanged(StyleDifference diff, RenderLayer&
     if (queryData.reevaluateAfterLayout)
         layer.setNeedsPostLayoutCompositingUpdate();
 
-    if (diff >= StyleDifference::LayoutPositionedMovementOnly && hasContentCompositingLayers()) {
-        layer.setNeedsPostLayoutCompositingUpdate();
-        layer.setNeedsCompositingGeometryUpdate();
+    const auto& newStyle = layer.renderer().style();
+
+    if (hasContentCompositingLayers()) {
+        if (diff >= StyleDifference::LayoutPositionedMovementOnly) {
+            layer.setNeedsPostLayoutCompositingUpdate();
+            layer.setNeedsCompositingGeometryUpdate();
+        }
+
+        if (diff >= StyleDifference::Layout) {
+            // FIXME: only set flags here if we know we have a composited descendant, but we might not know at this point.
+            if (oldStyle && clippingChanged(*oldStyle, newStyle)) {
+                if (layer.isStackingContext()) {
+                    layer.setNeedsPostLayoutCompositingUpdate(); // Layer needs to become composited if it has composited descendants.
+                    layer.setNeedsCompositingConfigurationUpdate(); // If already composited, layer needs to create/destroy clipping layer.
+                } else {
+                    // Descendant (in containing block order) compositing layers need to re-evaluate their clipping,
+                    // but they might be siblings in z-order so go up to our stacking context.
+                    if (auto* stackingContext = layer.stackingContext())
+                        stackingContext->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
+                }
+            }
+
+            // These properties trigger compositing if some descendant is composited.
+            if (oldStyle && styleChangeMayAffectIndirectCompositingReasons(*oldStyle, newStyle))
+                layer.setNeedsPostLayoutCompositingUpdate();
+
+            layer.setNeedsCompositingGeometryUpdate();
+        }
     }
 
     auto* backing = layer.backing();
@@ -1480,8 +1509,6 @@ void RenderLayerCompositor::layerStyleChanged(StyleDifference diff, RenderLayer&
 
     backing->updateConfigurationAfterStyleChange();
 
-    const auto& newStyle = layer.renderer().style();
-
     if (diff >= StyleDifference::Repaint) {
         // Visibility change may affect geometry of the enclosing composited layer.
         if (oldStyle && oldStyle->visibility() != newStyle.visibility())
@@ -1503,27 +1530,6 @@ void RenderLayerCompositor::layerStyleChanged(StyleDifference diff, RenderLayer&
         layer.setNeedsPostLayoutCompositingUpdate();
         layer.setNeedsCompositingGeometryUpdate();
     }
-
-    if (diff >= StyleDifference::Layout) {
-        // FIXME: only set flags here if we know we have a composited descendant, but we might not know at this point.
-        if (oldStyle && clippingChanged(*oldStyle, newStyle)) {
-            if (layer.isStackingContext()) {
-                layer.setNeedsPostLayoutCompositingUpdate(); // Layer needs to become composited if it has composited descendants.
-                layer.setNeedsCompositingConfigurationUpdate(); // If already composited, layer needs to create/destroy clipping layer.
-            } else {
-                // Descendant (in containing block order) compositing layers need to re-evaluate their clipping,
-                // but they might be siblings in z-order so go up to our stacking context.
-                if (auto* stackingContext = layer.stackingContext())
-                    stackingContext->setDescendantsNeedUpdateBackingAndHierarchyTraversal();
-            }
-        }
-
-        // These properties trigger compositing if some descendant is composited.
-        if (oldStyle && styleChangeMayAffectIndirectCompositingReasons(*oldStyle, newStyle))
-            layer.setNeedsPostLayoutCompositingUpdate();
-
-        layer.setNeedsCompositingGeometryUpdate();
-    }
 }
 
 bool RenderLayerCompositor::needsCompositingUpdateForStyleChangeOnNonCompositedLayer(RenderLayer& layer, const RenderStyle* oldStyle) const
@@ -2586,14 +2592,9 @@ const char* RenderLayerCompositor::logReasonsForCompositing(const RenderLayer& l
 // Thus, a RenderLayer can be clipped by a RenderLayer that is an ancestor in the renderer hierarchy,
 // but a sibling in the z-order hierarchy.
 // FIXME: can we do this without a tree walk?
-bool RenderLayerCompositor::clippedByAncestor(RenderLayer& layer) const
+bool RenderLayerCompositor::clippedByAncestor(RenderLayer& layer, const RenderLayer* compositingAncestor) const
 {
     ASSERT(layer.isComposited());
-    if (!layer.parent())
-        return false;
-
-    // On first pass in WK1, the root may not have become composited yet.
-    auto* compositingAncestor = layer.ancestorCompositingLayer();
     if (!compositingAncestor)
         return false;
 
@@ -2622,6 +2623,74 @@ bool RenderLayerCompositor::clippedByAncestor(RenderLayer& layer) const
     return !layer.backgroundClipRect(RenderLayer::ClipRectsContext(computeClipRoot, TemporaryClipRects)).isInfinite(); // FIXME: Incorrect for CSS regions.
 }
 
+bool RenderLayerCompositor::updateAncestorClippingStack(const RenderLayer& layer, const RenderLayer* compositingAncestor) const
+{
+    ASSERT(layer.isComposited());
+
+    auto clippingStack = computeAncestorClippingStack(layer, compositingAncestor);
+    return layer.backing()->updateAncestorClippingStack(WTFMove(clippingStack));
+}
+
+Vector<CompositedClipData> RenderLayerCompositor::computeAncestorClippingStack(const RenderLayer& layer, const RenderLayer* compositingAncestor) const
+{
+    // On first pass in WK1, the root may not have become composited yet.
+    if (!compositingAncestor)
+        return { };
+
+    // We'll start by building a child-to-ancestors stack.
+    Vector<CompositedClipData> newStack;
+
+    // Walk up the containing block chain to composited ancestor, prepending an entry to the clip stack for:
+    // * each composited scrolling layer
+    // * each set of RenderLayers which contribute a clip.
+    bool haveNonScrollableClippingIntermediateLayer = false;
+    const RenderLayer* currentClippedLayer = &layer;
+    
+    auto pushNonScrollableClip = [&](const RenderLayer& clippedLayer, const RenderLayer& clippingRoot, ShouldRespectOverflowClip respectClip = IgnoreOverflowClip) {
+        // Pass IgnoreOverflowClip to ignore overflow contributed by clippingRoot (which may be a scroller).
+        auto clipRect = clippedLayer.backgroundClipRect(RenderLayer::ClipRectsContext(&clippingRoot, TemporaryClipRects, IgnoreOverlayScrollbarSize, respectClip)).rect();
+        auto offset = layer.convertToLayerCoords(&clippingRoot, { }, RenderLayer::AdjustForColumns);
+        clipRect.moveBy(-offset);
+
+        CompositedClipData clipData { const_cast<RenderLayer*>(&clippedLayer), clipRect, false };
+        newStack.insert(0, WTFMove(clipData));
+    };
+
+    traverseAncestorLayers(layer, [&](const RenderLayer& ancestorLayer, bool isContainingBlockChain, bool /*isPaintOrderAncestor*/) {
+        if (&ancestorLayer == compositingAncestor) {
+        
+            if (haveNonScrollableClippingIntermediateLayer)
+                pushNonScrollableClip(*currentClippedLayer, ancestorLayer, ancestorLayer.isolatesCompositedBlending() ? RespectOverflowClip : IgnoreOverflowClip);
+            else if (ancestorLayer.isolatesCompositedBlending() && newStack.isEmpty())
+                pushNonScrollableClip(*currentClippedLayer, ancestorLayer, RespectOverflowClip);
+
+            return AncestorTraversal::Stop;
+        }
+
+        if (isContainingBlockChain && ancestorLayer.renderer().hasClipOrOverflowClip()) {
+            if (ancestorLayer.hasCompositedScrollableOverflow()) {
+                if (haveNonScrollableClippingIntermediateLayer) {
+                    pushNonScrollableClip(*currentClippedLayer, ancestorLayer);
+                    haveNonScrollableClippingIntermediateLayer = false;
+                }
+
+                auto clipRect = parentRelativeScrollableRect(ancestorLayer, &ancestorLayer);
+                auto offset = layer.convertToLayerCoords(&ancestorLayer, { }, RenderLayer::AdjustForColumns);
+                clipRect.moveBy(-offset);
+
+                CompositedClipData clipData { const_cast<RenderLayer*>(&ancestorLayer), clipRect, true };
+                newStack.insert(0, WTFMove(clipData));
+                currentClippedLayer = &ancestorLayer;
+            } else
+                haveNonScrollableClippingIntermediateLayer = true;
+        }
+
+        return AncestorTraversal::Continue;
+    });
+    
+    return newStack;
+}
+
 // Return true if the given layer is a stacking context and has compositing child
 // layers that it needs to clip. In this case we insert a clipping GraphicsLayer
 // into the hierarchy between this layer and its children in the z-order hierarchy.
@@ -3183,36 +3252,23 @@ ScrollPositioningBehavior RenderLayerCompositor::computeCoordinatedPositioningFo
 
 static Vector<ScrollingNodeID> collectRelatedCoordinatedScrollingNodes(const RenderLayer& layer, ScrollPositioningBehavior positioningBehavior)
 {
-    Vector<ScrollingNodeID> overflowNodeData;
+    Vector<ScrollingNodeID> overflowNodeIDs;
 
     switch (positioningBehavior) {
-    case ScrollPositioningBehavior::Moves: {
-        // Collect all the composited scrollers between this layer and its composited ancestor.
-        auto* compositedAncestor = layer.ancestorCompositingLayer();
-        for (const auto* currLayer = layer.parent(); currLayer != compositedAncestor; currLayer = currLayer->parent()) {
-            if (currLayer->hasCompositedScrollableOverflow()) {
-                auto scrollingNodeID = currLayer->isComposited() ? currLayer->backing()->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling) : 0;
-                if (scrollingNodeID)
-                    overflowNodeData.append(scrollingNodeID);
-                else
-                    LOG(Scrolling, "Layer %p isn't composited or doesn't have scrolling node ID yet", &layer);
-            }
-        }
-        break;
-    }
     case ScrollPositioningBehavior::Stationary: {
         auto* compositedAncestor = layer.ancestorCompositingLayer();
         if (!compositedAncestor)
-            return overflowNodeData;
-        collectStationaryLayerRelatedOverflowNodes(layer, *compositedAncestor, overflowNodeData);
+            return overflowNodeIDs;
+        collectStationaryLayerRelatedOverflowNodes(layer, *compositedAncestor, overflowNodeIDs);
         break;
     }
+    case ScrollPositioningBehavior::Moves:
     case ScrollPositioningBehavior::None:
         ASSERT_NOT_REACHED();
         break;
     }
 
-    return overflowNodeData;
+    return overflowNodeIDs;
 }
 
 bool RenderLayerCompositor::isLayerForIFrameWithScrollCoordinatedContents(const RenderLayer& layer) const
@@ -4047,7 +4103,7 @@ void RenderLayerCompositor::removeFromScrollCoordinatedLayers(RenderLayer& layer
         m_legacyScrollingLayerCoordinator->removeLayer(layer);
 #endif
 
-    detachScrollCoordinatedLayer(layer, { ScrollCoordinationRole::Scrolling, ScrollCoordinationRole::ViewportConstrained, ScrollCoordinationRole::FrameHosting, ScrollCoordinationRole::Positioning });
+    detachScrollCoordinatedLayer(layer, allScrollCoordinationRoles());
 }
 
 FixedPositionViewportConstraints RenderLayerCompositor::computeFixedViewportConstraints(RenderLayer& layer) const
@@ -4109,6 +4165,8 @@ static inline ScrollCoordinationRole scrollCoordinationRoleForNodeType(Scrolling
     case ScrollingNodeType::Subframe:
     case ScrollingNodeType::Overflow:
         return ScrollCoordinationRole::Scrolling;
+    case ScrollingNodeType::OverflowProxy:
+        return ScrollCoordinationRole::ScrollingProxy;
     case ScrollingNodeType::FrameHosting:
         return ScrollCoordinationRole::FrameHosting;
     case ScrollingNodeType::Fixed:
@@ -4116,8 +4174,6 @@ static inline ScrollCoordinationRole scrollCoordinationRoleForNodeType(Scrolling
         return ScrollCoordinationRole::ViewportConstrained;
     case ScrollingNodeType::Positioned:
         return ScrollCoordinationRole::Positioning;
-    case ScrollingNodeType::OverflowProxy:
-        break;
     }
     ASSERT_NOT_REACHED();
     return ScrollCoordinationRole::Scrolling;
@@ -4137,18 +4193,32 @@ ScrollingNodeID RenderLayerCompositor::attachScrollingNode(RenderLayer& layer, S
 
     ScrollCoordinationRole role = scrollCoordinationRoleForNodeType(nodeType);
     ScrollingNodeID nodeID = backing->scrollingNodeIDForRole(role);
-    if (!nodeID)
-        nodeID = scrollingCoordinator->uniqueScrollingNodeID();
+    
+    nodeID = registerScrollingNodeID(*scrollingCoordinator, nodeID, nodeType, treeState);
 
     LOG_WITH_STREAM(Scrolling, stream << "RenderLayerCompositor " << this << " attachScrollingNode " << nodeID << " (layer " << backing->graphicsLayer()->primaryLayerID() << ") type " << nodeType << " parent " << treeState.parentNodeID.valueOr(0));
 
+    if (!nodeID)
+        return 0;
+    
+    backing->setScrollingNodeIDForRole(nodeID, role);
+    m_scrollingNodeToLayerMap.add(nodeID, &layer);
+    
+    return nodeID;
+}
+
+ScrollingNodeID RenderLayerCompositor::registerScrollingNodeID(ScrollingCoordinator& scrollingCoordinator, ScrollingNodeID nodeID, ScrollingNodeType nodeType, struct ScrollingTreeState& treeState)
+{
+    if (!nodeID)
+        nodeID = scrollingCoordinator.uniqueScrollingNodeID();
+
     if (nodeType == ScrollingNodeType::Subframe && !treeState.parentNodeID)
-        nodeID = scrollingCoordinator->createNode(nodeType, nodeID);
+        nodeID = scrollingCoordinator.createNode(nodeType, nodeID);
     else {
-        auto newNodeID = scrollingCoordinator->insertNode(nodeType, nodeID, treeState.parentNodeID.valueOr(0), treeState.nextChildIndex);
+        auto newNodeID = scrollingCoordinator.insertNode(nodeType, nodeID, treeState.parentNodeID.valueOr(0), treeState.nextChildIndex);
         if (newNodeID != nodeID) {
             // We'll get a new nodeID if the type changed (and not if the node is new).
-            scrollingCoordinator->unparentChildrenAndDestroyNode(nodeID);
+            scrollingCoordinator.unparentChildrenAndDestroyNode(nodeID);
             m_scrollingNodeToLayerMap.remove(nodeID);
         }
         nodeID = newNodeID;
@@ -4158,27 +4228,41 @@ ScrollingNodeID RenderLayerCompositor::attachScrollingNode(RenderLayer& layer, S
     if (!nodeID)
         return 0;
     
-    backing->setScrollingNodeIDForRole(nodeID, role);
-    m_scrollingNodeToLayerMap.add(nodeID, &layer);
-    
     ++treeState.nextChildIndex;
     return nodeID;
 }
 
 void RenderLayerCompositor::detachScrollCoordinatedLayerWithRole(RenderLayer& layer, ScrollingCoordinator& scrollingCoordinator, ScrollCoordinationRole role)
 {
+    auto unregisterNode = [&](ScrollingNodeID nodeID) {
+        auto childNodes = scrollingCoordinator.childrenOfNode(nodeID);
+        for (auto childNodeID : childNodes) {
+            if (auto* layer = m_scrollingNodeToLayerMap.get(childNodeID))
+                layer->setNeedsScrollingTreeUpdate();
+        }
+
+        m_scrollingNodeToLayerMap.remove(nodeID);
+    };
+
+    if (role == ScrollCoordinationRole::ScrollingProxy) {
+        ASSERT(layer.isComposited());
+        auto* clippingStack = layer.backing()->ancestorClippingStack();
+        if (!clippingStack)
+            return;
+        
+        auto& stack = clippingStack->stack();
+        for (auto& entry : stack) {
+            if (entry.overflowScrollProxyNodeID)
+                unregisterNode(entry.overflowScrollProxyNodeID);
+        }
+        return;
+    }
+
     auto nodeID = layer.backing()->scrollingNodeIDForRole(role);
     if (!nodeID)
         return;
 
-    auto childNodes = scrollingCoordinator.childrenOfNode(nodeID);
-    for (auto childNodeID : childNodes) {
-        // FIXME: The child might be in a child frame. Need to do something that crosses frame boundaries.
-        if (auto* layer = m_scrollingNodeToLayerMap.get(childNodeID))
-            layer->setNeedsScrollingTreeUpdate();
-    }
-
-    m_scrollingNodeToLayerMap.remove(nodeID);
+    unregisterNode(nodeID);
 }
 
 void RenderLayerCompositor::detachScrollCoordinatedLayer(RenderLayer& layer, OptionSet<ScrollCoordinationRole> roles)
@@ -4192,6 +4276,9 @@ void RenderLayerCompositor::detachScrollCoordinatedLayer(RenderLayer& layer, Opt
     if (roles.contains(ScrollCoordinationRole::Scrolling))
         detachScrollCoordinatedLayerWithRole(layer, *scrollingCoordinator, ScrollCoordinationRole::Scrolling);
 
+    if (roles.contains(ScrollCoordinationRole::ScrollingProxy))
+        detachScrollCoordinatedLayerWithRole(layer, *scrollingCoordinator, ScrollCoordinationRole::ScrollingProxy);
+
     if (roles.contains(ScrollCoordinationRole::FrameHosting))
         detachScrollCoordinatedLayerWithRole(layer, *scrollingCoordinator, ScrollCoordinationRole::FrameHosting);
 
@@ -4204,8 +4291,37 @@ void RenderLayerCompositor::detachScrollCoordinatedLayer(RenderLayer& layer, Opt
     backing->detachFromScrollingCoordinator(roles);
 }
 
-ScrollingNodeID RenderLayerCompositor::updateScrollCoordinationForLayer(RenderLayer& layer, ScrollingTreeState& treeState, OptionSet<ScrollCoordinationRole> roles, OptionSet<ScrollingNodeChangeFlags> changes)
+OptionSet<ScrollCoordinationRole> RenderLayerCompositor::coordinatedScrollingRolesForLayer(const RenderLayer& layer) const
 {
+    OptionSet<ScrollCoordinationRole> coordinationRoles;
+    if (isViewportConstrainedFixedOrStickyLayer(layer))
+        coordinationRoles.add(ScrollCoordinationRole::ViewportConstrained);
+
+    if (useCoordinatedScrollingForLayer(layer))
+        coordinationRoles.add(ScrollCoordinationRole::Scrolling);
+
+    auto coordinatedPositioning = computeCoordinatedPositioningForLayer(layer);
+    switch (coordinatedPositioning) {
+    case ScrollPositioningBehavior::Moves:
+        coordinationRoles.add(ScrollCoordinationRole::ScrollingProxy);
+        break;
+    case ScrollPositioningBehavior::Stationary:
+        coordinationRoles.add(ScrollCoordinationRole::Positioning);
+        break;
+    case ScrollPositioningBehavior::None:
+        break;
+    }
+
+    if (isLayerForIFrameWithScrollCoordinatedContents(layer))
+        coordinationRoles.add(ScrollCoordinationRole::FrameHosting);
+
+    return coordinationRoles;
+}
+
+ScrollingNodeID RenderLayerCompositor::updateScrollCoordinationForLayer(RenderLayer& layer, ScrollingTreeState& treeState, OptionSet<ScrollingNodeChangeFlags> changes)
+{
+    auto roles = coordinatedScrollingRolesForLayer(layer);
+
     bool isViewportConstrained = roles.contains(ScrollCoordinationRole::ViewportConstrained);
 #if PLATFORM(IOS_FAMILY)
     if (m_legacyScrollingLayerCoordinator) {
@@ -4237,6 +4353,14 @@ ScrollingNodeID RenderLayerCompositor::updateScrollCoordinationForLayer(RenderLa
     } else
         detachScrollCoordinatedLayer(layer, ScrollCoordinationRole::Positioning);
 
+    // If there's a scrolling proxy node, it's the parent scrolling node for fixed/sticky/scrolling/frame hosting.
+    if (roles.contains(ScrollCoordinationRole::ScrollingProxy)) {
+        newNodeID = updateScrollingNodeForScrollingProxyRole(layer, *currentTreeState, changes);
+        childTreeState.parentNodeID = newNodeID;
+        currentTreeState = &childTreeState;
+    } else
+        detachScrollCoordinatedLayer(layer, ScrollCoordinationRole::ScrollingProxy);
+
     // If is fixed or sticky, it's the parent scrolling node for scrolling/frame hosting.
     if (roles.contains(ScrollCoordinationRole::ViewportConstrained)) {
         newNodeID = updateScrollingNodeForViewportConstrainedRole(layer, *currentTreeState, changes);
@@ -4383,6 +4507,46 @@ ScrollingNodeID RenderLayerCompositor::updateScrollingNodeForScrollingRole(Rende
     return newNodeID;
 }
 
+ScrollingNodeID RenderLayerCompositor::updateScrollingNodeForScrollingProxyRole(RenderLayer& layer, ScrollingTreeState& treeState, OptionSet<ScrollingNodeChangeFlags> changes)
+{
+    auto* scrollingCoordinator = this->scrollingCoordinator();
+    auto* clippingStack = layer.backing()->ancestorClippingStack();
+    if (!clippingStack)
+        return 0;
+
+    ScrollingNodeID nodeID = 0;
+    for (auto& entry : clippingStack->stack()) {
+        if (!entry.clipData.isOverflowScroll)
+            continue;
+
+        nodeID = registerScrollingNodeID(*scrollingCoordinator, entry.overflowScrollProxyNodeID, ScrollingNodeType::OverflowProxy, treeState);
+        if (!nodeID) {
+            ASSERT_NOT_REACHED();
+            return treeState.parentNodeID.valueOr(0);
+        }
+        entry.overflowScrollProxyNodeID = nodeID;
+
+        if (changes & ScrollingNodeChangeFlags::Layer)
+            scrollingCoordinator->setNodeLayers(entry.overflowScrollProxyNodeID, { entry.clippingLayer.get() });
+
+        if (changes & ScrollingNodeChangeFlags::LayerGeometry) {
+            ASSERT(entry.clipData.clippingLayer);
+            ASSERT(entry.clipData.clippingLayer->isComposited());
+
+            auto overflowScrollNodeID = 0;
+            if (auto* backing = entry.clipData.clippingLayer->backing())
+                overflowScrollNodeID = backing->scrollingNodeIDForRole(ScrollCoordinationRole::Scrolling);
+        
+            Vector<ScrollingNodeID> scrollingNodeIDs;
+            if (overflowScrollNodeID)
+                scrollingNodeIDs.append(overflowScrollNodeID);
+            scrollingCoordinator->setRelatedOverflowScrollingNodes(entry.overflowScrollProxyNodeID, WTFMove(scrollingNodeIDs));
+        }
+    }
+
+    return nodeID;
+}
+
 ScrollingNodeID RenderLayerCompositor::updateScrollingNodeForFrameHostingRole(RenderLayer& layer, ScrollingTreeState& treeState, OptionSet<ScrollingNodeChangeFlags> changes)
 {
     auto* scrollingCoordinator = this->scrollingCoordinator();
@@ -4426,11 +4590,10 @@ ScrollingNodeID RenderLayerCompositor::updateScrollingNodeForPositioningRole(Ren
         scrollingCoordinator->setRelatedOverflowScrollingNodes(newNodeID, WTFMove(relatedNodeIDs));
 
         auto* graphicsLayer = layer.backing()->graphicsLayer();
-        LayoutConstraints constraints;
+        AbsolutePositionConstraints constraints;
         constraints.setAlignmentOffset(graphicsLayer->pixelAlignmentOffset());
         constraints.setLayerPositionAtLastLayout(graphicsLayer->position());
-        constraints.setScrollPositioningBehavior(positioningBehavior);
-        scrollingCoordinator->setPositionedNodeGeometry(newNodeID, constraints);
+        scrollingCoordinator->setPositionedNodeConstraints(newNodeID, constraints);
     }
 
     return newNodeID;
index 9134779..21c06d9 100644 (file)
@@ -28,6 +28,7 @@
 #include "ChromeClient.h"
 #include "GraphicsLayerClient.h"
 #include "GraphicsLayerUpdater.h"
+#include "LayerAncestorClippingStack.h"
 #include "RenderLayer.h"
 #include <wtf/HashMap.h>
 #include <wtf/OptionSet.h>
@@ -88,10 +89,22 @@ enum class CompositingReason {
 enum class ScrollCoordinationRole {
     ViewportConstrained = 1 << 0,
     Scrolling           = 1 << 1,
-    FrameHosting        = 1 << 2,
-    Positioning         = 1 << 3,
+    ScrollingProxy      = 1 << 2,
+    FrameHosting        = 1 << 3,
+    Positioning         = 1 << 4,
 };
 
+static constexpr OptionSet<ScrollCoordinationRole> allScrollCoordinationRoles()
+{
+    return {
+        ScrollCoordinationRole::Scrolling,
+        ScrollCoordinationRole::ScrollingProxy,
+        ScrollCoordinationRole::ViewportConstrained,
+        ScrollCoordinationRole::FrameHosting,
+        ScrollCoordinationRole::Positioning
+    };
+}
+
 #if PLATFORM(IOS_FAMILY)
 class LegacyWebKitScrollingLayerCoordinator {
 public:
@@ -201,7 +214,10 @@ public:
     bool updateLayerCompositingState(RenderLayer&, RequiresCompositingData&, CompositingChangeRepaint = CompositingChangeRepaintNow);
 
     // Whether layer's backing needs a graphics layer to do clipping by an ancestor (non-