Implement backing-sharing in compositing layers, allowing overlap layers to paint...
authorsimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 May 2019 05:18:02 +0000 (05:18 +0000)
committersimon.fraser@apple.com <simon.fraser@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 10 May 2019 05:18:02 +0000 (05:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=197561
<rdar://problem/50445998>

Reviewed by Antti Koivisto.
Source/WebCore:

This change introduces the concept of layers that share backing store for compositing. A layer
which is sharing its backing store first paints itself, and then some set of layers which come
later in paint order in the same stacking context. This reduces the composited layer count in
some overflow scrolling scenarios, thereby also simplifying the scrolling tree.

A backing-shared layer stores a vector of "sharing" RenderLayer* in its RenderLayerBacking. At
paint time, the owning layer is painted, then the sharing layers, setting the owning layer as the
painting root so that positioning and clipping just work.

Sharing layer relationships are constructed in RenderLayerCompositor::computeCompositingRequirements().
We track the last layer which was composited in paint order as a shared candidate. If a later layer
would composite for overlap (and no other reasons), then we allow it to share with the candidate
if the candidate is in its ancestor containing block chain. Sharing is currently limited to layers
in the same stacking context.

isComposited() returns false for sharing layers, but they are like composited layers in that
they behave as painting boundaries, so RenderLayer::paintLayer() needs to stop at them,
and repaints in shared layers have to be directed to their shared layer, hence
changes to RenderLayer::clippingRootForPainting() and RenderLayer::enclosingCompositingLayerForRepaint().

The clipping boundary logic in RenderLayer::backgroundClipRect() needed to be generalized so that
all calls to RenderLayer::parentClipRects() check for crossing painting boundaries and use
TemporaryClipRects in that case.

Tests: compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller.html
       compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller.html
       compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow.html
       compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness.html
       compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping.html
       compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping.html
       compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll.html
       compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content.html
       compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip.html
       compositing/shared-backing/overflow-scroll/shared-layer-clipping.html
       compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds.html
       compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking.html
       compositing/shared-backing/overflow-scroll/shared-layer-repaint.html
       compositing/shared-backing/partial-compositing-update.html
       compositing/shared-backing/partial-compositing-update2.html
       compositing/shared-backing/remove-sharing-layer.html
       compositing/shared-backing/sharing-cached-clip-rects.html

* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::~RenderLayer):
(WebCore::RenderLayer::ancestorLayerIsInContainingBlockChain const):
(WebCore::RenderLayer::setBackingProviderLayer):
(WebCore::RenderLayer::disconnectFromBackingProviderLayer):
(WebCore::RenderLayer::enclosingCompositingLayerForRepaint const):
(WebCore::RenderLayer::clippingRootForPainting const):
(WebCore::RenderLayer::clipToRect):
(WebCore::RenderLayer::paintLayer):
(WebCore::RenderLayer::updateClipRects):
(WebCore::RenderLayer::clipCrossesPaintingBoundary const):
(WebCore::RenderLayer::calculateClipRects const):
(WebCore::outputPaintOrderTreeLegend):
(WebCore::outputPaintOrderTreeRecursive):
(WebCore::inContainingBlockChain): Deleted.
* rendering/RenderLayer.h:
* rendering/RenderLayerBacking.cpp:
(WebCore::RenderLayerBacking::willBeDestroyed):
(WebCore::clearBackingSharingLayerProviders):
(WebCore::RenderLayerBacking::setBackingSharingLayers):
(WebCore::RenderLayerBacking::removeBackingSharingLayer):
(WebCore::RenderLayerBacking::clearBackingSharingLayers):
(WebCore::RenderLayerBacking::updateCompositedBounds):
(WebCore::RenderLayerBacking::updateDrawsContent):
(WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer const):
(WebCore::RenderLayerBacking::paintIntoLayer):
(WebCore::RenderLayerBacking::paintContents):
* rendering/RenderLayerBacking.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::CompositingState::stateForPaintOrderChildren const):
(WebCore::RenderLayerCompositor::CompositingState::propagateStateFromChildren):
(WebCore::RenderLayerCompositor::CompositingState::propagateStateFromChildrenForUnchangedSubtree):
(WebCore::RenderLayerCompositor::BackingSharingState::resetBackingProviderCandidate):
(WebCore::RenderLayerCompositor::updateCompositingLayers):
(WebCore::backingProviderLayerCanIncludeLayer):
(WebCore::RenderLayerCompositor::computeCompositingRequirements):
(WebCore::RenderLayerCompositor::traverseUnchangedSubtree):
(WebCore::RenderLayerCompositor::updateBacking):
(WebCore::RenderLayerCompositor::layerWillBeRemoved):
(WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason const):
* rendering/RenderLayerCompositor.h:
* rendering/RenderTreeAsText.cpp:

LayoutTests:

New tests for backing sharing, and new baselines of tests whose behavior is changed.

Scrolling tree tests that would be invalidate by sharing are changed to defeat sharing by adding
compositing layers early in stacking order.

* TestExpectations:
* compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
* compositing/layer-creation/overflow-scroll-overlap-expected.txt:
* compositing/layer-creation/overflow-scroll-overlap.html:
* compositing/overflow/scrolling-content-clip-to-viewport.html:
* compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt:
* compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt.
* compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller.html: Added.
* compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt: Added.
* compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller.html: Added.
* compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt: Added.
* compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow.html: Copied from LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow.html.
* compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt: Added.
* compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness.html: Added.
* compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping-expected.txt: Added.
* compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping.html: Added.
* compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping-expected.txt: Added.
* compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping.html: Added.
* compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt.
* compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll.html: Added.
* compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt.
* compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content.html: Added.
* compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip-expected.html: Added.
* compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip.html: Added.
* compositing/shared-backing/overflow-scroll/shared-layer-clipping-expected.html: Added.
* compositing/shared-backing/overflow-scroll/shared-layer-clipping.html: Added.
* compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds-expected.txt: Added.
* compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds.html: Added.
* compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking-expected.txt: Added.
* compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking.html: Added.
* compositing/shared-backing/overflow-scroll/shared-layer-repaint-expected.txt: Added.
* compositing/shared-backing/overflow-scroll/shared-layer-repaint.html: Added.
* compositing/shared-backing/partial-compositing-update-expected.txt: Added.
* compositing/shared-backing/partial-compositing-update.html: Added.
* compositing/shared-backing/partial-compositing-update2-expected.txt: Added.
* compositing/shared-backing/partial-compositing-update2.html: Added.
* compositing/shared-backing/remove-sharing-layer-expected.txt: Added.
* compositing/shared-backing/remove-sharing-layer.html: Added.
* compositing/shared-backing/sharing-cached-clip-rects-expected.txt: Added.
* compositing/shared-backing/sharing-cached-clip-rects.html: Added.
* platform/ios-wk2/TestExpectations:
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt.
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt: Added.
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt: Added.
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt: Added.
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping-expected.txt: Added.
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping-expected.txt: Added.
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt.
* platform/ios-wk2/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-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/positioned-nodes-complex-expected.txt:
* platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
* platform/ios/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants-expected.txt:
* platform/ios/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants2-expected.txt:
* platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt:
* platform/mac-wk1/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt:
* platform/mac-wk2/TestExpectations:
* platform/mac/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants-expected.txt:
* platform/mac/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants2-expected.txt:
* scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt:
* scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow.html:
* scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt:
* scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow.html:
* scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt:
* scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow.html:
* scrollingcoordinator/scrolling-tree/positioned-nodes-complex-expected.txt:
* scrollingcoordinator/scrolling-tree/positioned-nodes-complex.html:

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

78 files changed:
LayoutTests/ChangeLog
LayoutTests/TestExpectations
LayoutTests/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt
LayoutTests/compositing/layer-creation/overflow-scroll-overlap-expected.txt
LayoutTests/compositing/layer-creation/overflow-scroll-overlap.html
LayoutTests/compositing/overflow/scrolling-content-clip-to-viewport.html
LayoutTests/compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt
LayoutTests/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip-expected.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-clipping-expected.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-clipping.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-repaint-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-repaint.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/partial-compositing-update-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/partial-compositing-update.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/partial-compositing-update2-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/partial-compositing-update2.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/remove-sharing-layer-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/remove-sharing-layer.html [new file with mode: 0644]
LayoutTests/compositing/shared-backing/sharing-cached-clip-rects-expected.txt [new file with mode: 0644]
LayoutTests/compositing/shared-backing/sharing-cached-clip-rects.html [new file with mode: 0644]
LayoutTests/platform/ios-wk2/TestExpectations
LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-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 [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll-expected.txt [new file with mode: 0644]
LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content-expected.txt [new file with mode: 0644]
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/positioned-nodes-complex-expected.txt
LayoutTests/platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt
LayoutTests/platform/ios/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants-expected.txt
LayoutTests/platform/ios/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants2-expected.txt
LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt
LayoutTests/platform/mac-wk1/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt
LayoutTests/platform/mac-wk2/TestExpectations
LayoutTests/platform/mac/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants-expected.txt
LayoutTests/platform/mac/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants2-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow.html
LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow.html
LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow.html
LayoutTests/scrollingcoordinator/scrolling-tree/positioned-nodes-complex-expected.txt
LayoutTests/scrollingcoordinator/scrolling-tree/positioned-nodes-complex.html
Source/WebCore/ChangeLog
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderLayerBacking.cpp
Source/WebCore/rendering/RenderLayerBacking.h
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerCompositor.h
Source/WebCore/rendering/RenderTreeAsText.cpp

index 031f523..72cecf9 100644 (file)
@@ -1,3 +1,86 @@
+2019-05-09  Simon Fraser  <simon.fraser@apple.com>
+
+        Implement backing-sharing in compositing layers, allowing overlap layers to paint into the backing store of another layer
+        https://bugs.webkit.org/show_bug.cgi?id=197561
+        <rdar://problem/50445998>
+
+        Reviewed by Antti Koivisto.
+        
+        New tests for backing sharing, and new baselines of tests whose behavior is changed.
+
+        Scrolling tree tests that would be invalidate by sharing are changed to defeat sharing by adding
+        compositing layers early in stacking order.
+
+        * TestExpectations:
+        * compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
+        * compositing/layer-creation/overflow-scroll-overlap-expected.txt:
+        * compositing/layer-creation/overflow-scroll-overlap.html:
+        * compositing/overflow/scrolling-content-clip-to-viewport.html:
+        * compositing/rtl/rtl-scrolling-with-transformed-descendants-expected.txt:
+        * compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt.
+        * compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller.html: Added.
+        * compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt: Added.
+        * compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller.html: Added.
+        * compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt: Added.
+        * compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow.html: Copied from LayoutTests/scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow.html.
+        * compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt: Added.
+        * compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness.html: Added.
+        * compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping-expected.txt: Added.
+        * compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping.html: Added.
+        * compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping-expected.txt: Added.
+        * compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping.html: Added.
+        * compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt.
+        * compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll.html: Added.
+        * compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt.
+        * compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content.html: Added.
+        * compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip-expected.html: Added.
+        * compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip.html: Added.
+        * compositing/shared-backing/overflow-scroll/shared-layer-clipping-expected.html: Added.
+        * compositing/shared-backing/overflow-scroll/shared-layer-clipping.html: Added.
+        * compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds-expected.txt: Added.
+        * compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds.html: Added.
+        * compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking-expected.txt: Added.
+        * compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking.html: Added.
+        * compositing/shared-backing/overflow-scroll/shared-layer-repaint-expected.txt: Added.
+        * compositing/shared-backing/overflow-scroll/shared-layer-repaint.html: Added.
+        * compositing/shared-backing/partial-compositing-update-expected.txt: Added.
+        * compositing/shared-backing/partial-compositing-update.html: Added.
+        * compositing/shared-backing/partial-compositing-update2-expected.txt: Added.
+        * compositing/shared-backing/partial-compositing-update2.html: Added.
+        * compositing/shared-backing/remove-sharing-layer-expected.txt: Added.
+        * compositing/shared-backing/remove-sharing-layer.html: Added.
+        * compositing/shared-backing/sharing-cached-clip-rects-expected.txt: Added.
+        * compositing/shared-backing/sharing-cached-clip-rects.html: Added.
+        * platform/ios-wk2/TestExpectations:
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt.
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt: Added.
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt: Added.
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt: Added.
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping-expected.txt: Added.
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping-expected.txt: Added.
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt.
+        * platform/ios-wk2/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content-expected.txt: Copied from LayoutTests/platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-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/positioned-nodes-complex-expected.txt:
+        * platform/ios/compositing/geometry/limit-layer-bounds-clipping-ancestor-expected.txt:
+        * platform/ios/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants-expected.txt:
+        * platform/ios/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants2-expected.txt:
+        * platform/ios/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt:
+        * platform/mac-wk1/compositing/overflow/scrolling-content-clip-to-viewport-expected.txt:
+        * platform/mac-wk2/TestExpectations:
+        * platform/mac/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants-expected.txt:
+        * platform/mac/compositing/overflow/clipping-behaviour-change-is-not-propagated-to-descendants2-expected.txt:
+        * scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow-expected.txt:
+        * scrollingcoordinator/scrolling-tree/nested-absolute-in-absolute-overflow.html:
+        * scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow-expected.txt:
+        * scrollingcoordinator/scrolling-tree/nested-absolute-in-relative-in-overflow.html:
+        * scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow-expected.txt:
+        * scrollingcoordinator/scrolling-tree/nested-absolute-in-sc-overflow.html:
+        * scrollingcoordinator/scrolling-tree/positioned-nodes-complex-expected.txt:
+        * scrollingcoordinator/scrolling-tree/positioned-nodes-complex.html:
+
 2019-05-09  Daniel Bates  <dabates@apple.com>
 
         [iOS] Right command key has wrong value for property code
index 7d105a1..5650727 100644 (file)
@@ -59,6 +59,9 @@ editing/pasteboard/ios [ Skip ]
 editing/pasteboard/mac [ Skip ]
 fast/media/ios [ Skip ]
 
+# Requires async overflow scrolling
+compositing/shared-backing/overflow-scroll [ Skip ]
+
 # WebKit2 only.
 printing/printing-events.html [ Skip ]
 
index 76ce8cd..8620e41 100644 (file)
@@ -11,7 +11,7 @@ middlebottom
     (GraphicsLayer
       (bounds 785.00 2618.00)
       (contentsOpaque 1)
-      (children 6
+      (children 3
         (GraphicsLayer
           (position 21.00 21.00)
           (bounds 100.00 100.00)
@@ -23,50 +23,12 @@ middlebottom
         )
         (GraphicsLayer
           (offsetFromRenderer width=0 height=100)
-          (position 28.00 20.00)
-          (bounds 200.00 200.00)
-          (children 1
-            (GraphicsLayer
-              (offsetFromRenderer width=0 height=100)
-              (bounds 110.00 200.00)
-              (contentsOpaque 1)
-              (drawsContent 1)
-            )
-          )
-        )
-        (GraphicsLayer
-          (offsetFromRenderer width=-5 height=-145)
-          (position 28.00 20.00)
-          (bounds 200.00 200.00)
-          (children 1
-            (GraphicsLayer
-              (position 5.00 145.00)
-              (bounds 144.00 24.00)
-              (drawsContent 1)
-            )
-          )
-        )
-        (GraphicsLayer
-          (offsetFromRenderer width=0 height=100)
           (position 28.00 250.00)
           (bounds 185.00 200.00)
           (children 1
             (GraphicsLayer
               (offsetFromRenderer width=0 height=100)
-              (bounds 110.00 200.00)
-              (contentsOpaque 1)
-              (drawsContent 1)
-            )
-          )
-        )
-        (GraphicsLayer
-          (offsetFromRenderer width=-5 height=-145)
-          (position 28.00 250.00)
-          (bounds 185.00 200.00)
-          (children 1
-            (GraphicsLayer
-              (position 5.00 145.00)
-              (bounds 144.00 24.00)
+              (bounds 149.00 200.00)
               (drawsContent 1)
             )
           )
index eb930f3..7aea48b 100644 (file)
@@ -5,7 +5,7 @@
     (GraphicsLayer
       (bounds 800.00 600.00)
       (contentsOpaque 1)
-      (children 3
+      (children 2
         (GraphicsLayer
           (position 8.00 8.00)
           (bounds 30.00 30.00)
           (bounds 306.00 206.00)
           (drawsContent 1)
         )
-        (GraphicsLayer
-          (offsetFromRenderer width=-20 height=-45)
-          (position 23.00 23.00)
-          (bounds 285.00 200.00)
-          (children 1
-            (GraphicsLayer
-              (position 20.00 45.00)
-              (bounds 210.00 100.00)
-              (contentsOpaque 1)
-            )
-          )
-        )
       )
     )
   )
index 752cc58..3f5b275 100644 (file)
@@ -52,7 +52,7 @@
           document.getElementById('results').innerText = window.internals.layerTreeAsText(document);
           testRunner.notifyDone();
         }
-      }, 150);
+      }, 0);
     }
     
     window.addEventListener('load', doTest, false);
index bf0e90a..1d85826 100644 (file)
@@ -23,7 +23,7 @@
       height: 1200px;
       background: silver;
       border: 2px solid blue;
-      z-index: 0;
+      transform: translateZ(0);
     }
   </style>
   <script>
index ae33193..c70ede2 100644 (file)
@@ -6,7 +6,7 @@
     (GraphicsLayer
       (bounds 800.00 600.00)
       (contentsOpaque 1)
-      (children 4
+      (children 3
         (GraphicsLayer
           (position 8.00 8.00)
           (bounds 404.00 223.00)
           )
         )
         (GraphicsLayer
-          (offsetFromRenderer width=-250 height=0)
-          (position 10.00 10.00)
-          (bounds 400.00 204.00)
-          (children 1
-            (GraphicsLayer
-              (position 250.00 0.00)
-              (bounds 150.00 200.00)
-              (contentsOpaque 1)
-            )
-          )
-        )
-        (GraphicsLayer
           (offsetFromRenderer width=-96 height=0)
           (position 10.00 10.00)
           (bounds 400.00 204.00)
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt
new file mode 100644 (file)
index 0000000..e1be290
--- /dev/null
@@ -0,0 +1,34 @@
+relativeabsolute
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 304.00 304.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 285.00 285.00)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=2 height=2)
+                  (anchor 0.00 0.00)
+                  (bounds 285.00 682.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller.html b/LayoutTests/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller.html
new file mode 100644 (file)
index 0000000..b00d101
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests sharing with absolute inside a stacking relative in overflow</title>
+    <style>
+        .scroller {
+            overflow: scroll;
+            height: 300px;
+            width: 300px;
+            border: 2px solid black;
+            margin: 20px;
+        }
+
+        .relative {
+            position: relative;
+            border: 2px solid orange;
+            margin: 20px;
+            padding: 20px;
+            margin-top: 100px;
+        }
+        
+        .stacking {
+            z-index: 0;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 50px;
+            left: 20px;
+            height: 150px;
+            width: 150px;
+            background-color: silver;
+        }
+
+        .spacer {
+            height: 500px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="stacking relative">
+            relative
+            <div class="absolute">absolute</div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt
new file mode 100644 (file)
index 0000000..85d8ade
--- /dev/null
@@ -0,0 +1,45 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 404.00 404.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 385.00 400.00)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=2 height=2)
+                  (anchor 0.00 0.00)
+                  (bounds 385.00 1044.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (offsetFromRenderer width=-34 height=-134)
+          (position 10.00 10.00)
+          (bounds 385.00 400.00)
+          (children 1
+            (GraphicsLayer
+              (position 34.00 134.00)
+              (bounds 220.00 220.00)
+              (contentsOpaque 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller.html b/LayoutTests/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller.html
new file mode 100644 (file)
index 0000000..0ab0aee
--- /dev/null
@@ -0,0 +1,67 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .scroller {
+            overflow-x: hidden;
+            width: 400px;
+            height: 400px;
+            border: 2px solid black;
+        }
+        
+        .relative {
+            position: relative;
+            margin: 20px;
+            padding: 20px;
+            height: 200px;
+            border: 4px solid orange;
+        }
+        
+        .absolute {
+            position: absolute;
+            background-color: silver;
+            top: 10px;
+            left: 10px;
+            padding: 10px;
+            width: 200px;
+            height: 50px;
+        }
+
+        .spacer {
+            height: 1000px;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+        }
+        
+        .composited.absolute {
+            background-color: silver;
+            top: 100px;
+            left: 0;
+            width: 200px;
+            height: 200px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="relative">
+            <div class="absolute">
+                <div class="composited absolute"></div>
+            </div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt
new file mode 100644 (file)
index 0000000..5c32192
--- /dev/null
@@ -0,0 +1,47 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 304.00 304.00)
+          (opacity 0.80)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 285.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=2 height=2)
+                  (anchor 0.00 0.00)
+                  (bounds 285.00 500.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (position 20.00 78.00)
+                      (bounds 140.00 140.00)
+                      (contentsOpaque 1)
+                      (drawsContent 1)
+                      (children 1
+                        (GraphicsLayer
+                          (bounds 140.00 140.00)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow.html b/LayoutTests/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow.html
new file mode 100644 (file)
index 0000000..a95edc8
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .scroller {
+            margin: 20px;
+            width: 300px;
+            height: 300px;
+            overflow: auto;
+            border: 2px solid black;
+            opacity: 0.8;
+        }
+
+        .absolute {
+            position: absolute;
+            width: 100px;
+            height: 100px;
+            top: 100px;
+            left: 50px;
+            padding: 20px;
+            background-color: silver;
+        }
+        
+        .clipping {
+            overflow: hidden;
+        }
+
+        .inner {
+            top: 50px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+
+        .spacer {
+            height: 500px;
+            background-image: repeating-linear-gradient(white, silver 200px);
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="clipping absolute">
+            <div class="inner absolute"></div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt
new file mode 100644 (file)
index 0000000..2344046
--- /dev/null
@@ -0,0 +1,62 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 3
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 324.00 324.00)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 320.00 320.00)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 10.00)
+                  (bounds 300.00 300.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (offsetFromRenderer width=2 height=2)
+                      (position 2.00 2.00)
+                      (bounds 281.00 296.00)
+                      (children 1
+                        (GraphicsLayer
+                          (offsetFromRenderer width=2 height=2)
+                          (anchor 0.00 0.00)
+                          (bounds 281.00 364.00)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 110.00 110.00)
+          (bounds 100.00 100.00)
+          (contentsOpaque 1)
+        )
+        (GraphicsLayer
+          (offsetFromRenderer width=-20 height=-20)
+          (position 42.00 34.00)
+          (bounds 281.00 296.00)
+          (children 1
+            (GraphicsLayer
+              (position 20.00 20.00)
+              (bounds 241.00 24.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness.html b/LayoutTests/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness.html
new file mode 100644 (file)
index 0000000..4da38b4
--- /dev/null
@@ -0,0 +1,64 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .container {
+            width: 300px;
+            height: 300px;
+            border: 2px solid gray;
+            margin: 20px;
+            overflow-y: hidden;
+            padding: 10px;
+        }
+        
+        .scroller {
+            overflow-x: auto;
+            width: 100%;
+            height: 100%;
+            border: 2px solid black;
+            box-sizing: border-box;
+        }
+        
+        .relative {
+            position: relative;
+            padding: 10px;
+            margin: 20px;
+            border: 2px solid orange;
+            z-index: 0;
+        }
+        
+        .absolute {
+            position: absolute;
+            top: 100px;
+            left: 100px;
+            margin: 10px;
+            width: 100px;
+            height: 100px;
+            background-color: silver;
+        }
+        
+        .spacer {
+            height: 300px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="absolute"></div>
+    <div class="container">
+        <div class="scroller">
+            <div class="relative"></div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping-expected.txt
new file mode 100644 (file)
index 0000000..d381099
--- /dev/null
@@ -0,0 +1,47 @@
+Text
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 324.00 324.00)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 320.00 320.00)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 10.00)
+                  (bounds 300.00 300.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (offsetFromRenderer width=2 height=2)
+                      (position 2.00 2.00)
+                      (bounds 281.00 296.00)
+                      (children 1
+                        (GraphicsLayer
+                          (offsetFromRenderer width=2 height=2)
+                          (anchor 0.00 0.00)
+                          (bounds 281.00 466.00)
+                          (drawsContent 1)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping.html b/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping.html
new file mode 100644 (file)
index 0000000..9157a64
--- /dev/null
@@ -0,0 +1,63 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .container {
+            width: 300px;
+            height: 300px;
+            border: 2px solid gray;
+            margin: 20px;
+            padding: 10px;
+            overflow-y: hidden;
+        }
+        
+        .scroller {
+            overflow-x: auto;
+            width: 100%;
+            height: 100%;
+            border: 2px solid black;
+            box-sizing: border-box;
+        }
+        
+        .clipping {
+            overflow: hidden;
+            width: 200px;
+            border: 2px solid black;
+            margin: 50px 10px;
+            padding: 10px;
+        }
+        
+        .relative {
+            position: relative;
+            padding: 10px;
+            border: 2px solid orange;
+        }
+        
+        .spacer {
+            height: 300px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="container">
+        <div class="scroller">
+            <div class="clipping">
+                <div class="relative">
+                    Text
+                </div>
+            </div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping-expected.txt
new file mode 100644 (file)
index 0000000..e03bc86
--- /dev/null
@@ -0,0 +1,48 @@
+Clipping
+Relative
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 324.00 324.00)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 320.00 320.00)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 10.00)
+                  (bounds 304.00 304.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (offsetFromRenderer width=2 height=2)
+                      (position 2.00 2.00)
+                      (bounds 285.00 300.00)
+                      (children 1
+                        (GraphicsLayer
+                          (offsetFromRenderer width=2 height=2)
+                          (anchor 0.00 0.00)
+                          (bounds 285.00 426.00)
+                          (drawsContent 1)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping.html b/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping.html
new file mode 100644 (file)
index 0000000..c61370a
--- /dev/null
@@ -0,0 +1,64 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .container {
+            width: 300px;
+            height: 300px;
+            border: 2px solid gray;
+            margin: 20px;
+            padding: 10px;
+            position: relative;
+            overflow-y: hidden;
+        }
+        
+        .scroller {
+            overflow-x: auto;
+            width: 100%;
+            height: 100%;
+            border: 2px solid black;
+        }
+        
+        .clipping {
+            overflow: hidden;
+            width: 200px;
+            border: 2px solid black;
+            margin: 10px;
+            padding: 20px;
+        }
+        
+        .relative {
+            position: relative;
+            border: 2px solid orange;
+            height: 40px;
+        }
+
+        .spacer {
+            height: 300px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="container">
+        <div class="scroller">
+            <div class="clipping">
+                Clipping
+                <div class="relative">
+                    Relative
+                </div>
+            </div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll-expected.txt
new file mode 100644 (file)
index 0000000..06002b0
--- /dev/null
@@ -0,0 +1,34 @@
+relative
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 324.00 324.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 305.00 305.00)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=2 height=2)
+                  (anchor 0.00 0.00)
+                  (bounds 414.00 374.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll.html b/LayoutTests/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll.html
new file mode 100644 (file)
index 0000000..27a2c01
--- /dev/null
@@ -0,0 +1,47 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .scroller {
+            margin: 20px;
+            width: 300px;
+            height: 300px;
+            overflow: auto;
+            border: 2px solid black;
+            padding: 10px;
+        }
+
+        .relative {
+            position: relative;
+            top: 50px;
+            left: 200px;
+            height: 200px;
+            width: 200px;
+            border: 2px solid orange;
+        }
+
+        .spacer {
+            height: 150px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div> <!-- here to test that extra container don't break sharing -->
+            <div class="relative inside">relative</div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content-expected.txt
new file mode 100644 (file)
index 0000000..bcf60e2
--- /dev/null
@@ -0,0 +1,34 @@
+Relative foreground
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 304.00 304.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 285.00 285.00)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=2 height=2)
+                  (anchor 0.00 0.00)
+                  (bounds 285.00 364.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content.html b/LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content.html
new file mode 100644 (file)
index 0000000..91594d3
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Tests that "has painted content" is triggered by sharing</title>
+    <style>
+        .scroller {
+            overflow: scroll;
+            width: 300px;
+            height: 300px;
+            border: 2px solid black;
+        }
+        
+        .relative {
+            position: relative;
+            margin: 20px;
+            padding: 10px;
+            height: 100px;
+            border: 2px solid orange;
+            background-color: silver;
+        }
+        
+        .spacer {
+            height: 200px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="scroller">
+        <div class="relative">
+            Relative foreground
+        </div>
+        <div class="spacer"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip-expected.html b/LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip-expected.html
new file mode 100644 (file)
index 0000000..a136c06
--- /dev/null
@@ -0,0 +1,45 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .scroller {
+            overflow: scroll;
+            width: 300px;
+            height: 300px;
+            border: 2px solid black;
+        }
+        
+        .relative {
+            position: relative;
+            margin: 0px 20px 0 10px;
+            padding: 10px;
+            height: 100px;
+            border: 4px solid green;
+            background-color: silver;
+        }
+        
+        .spacer {
+            height: 400px;
+        }
+
+        .scrollbar-hider {
+            position: absolute;
+            width: 16px;
+            height: 300px;
+            top: 10px;
+            left: calc(310px - 16px);
+            background-color: gray;
+        }
+    </style>
+</head>
+<body>
+    <div id="scroller" class="scroller">
+            <div class="relative">
+                Relative foreground
+            </div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+    <div class="scrollbar-hider"></div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip.html b/LayoutTests/compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip.html
new file mode 100644 (file)
index 0000000..6ff79ae
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .scroller {
+            overflow: scroll;
+            width: 300px;
+            height: 300px;
+            border: 2px solid black;
+        }
+        
+        .relative {
+            position: relative;
+            margin: 200px 20px 0 10px;
+            padding: 10px;
+            height: 100px;
+            border: 4px solid green;
+            background-color: silver;
+        }
+        
+        .spacer {
+            height: 400px;
+        }
+
+        .scrollbar-hider {
+            position: absolute;
+            width: 16px;
+            height: 300px;
+            top: 10px;
+            left: calc(310px - 16px);
+            background-color: gray;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.waitUntilDone();
+
+        window.addEventListener('load', () => {
+            setTimeout(() => {
+                document.getElementById('scroller').scrollTop = 200;
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div id="scroller" class="scroller">
+            <div class="relative">
+                Relative foreground
+            </div>
+            <div class="spacer"></div>
+        </div>
+    </div>
+    <div class="scrollbar-hider"></div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-clipping-expected.html b/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-clipping-expected.html
new file mode 100644 (file)
index 0000000..f62f674
--- /dev/null
@@ -0,0 +1,38 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .container {
+            position: relative;
+            width: 200px;
+            height: 200px;
+            margin: 30px;
+            border: 3px solid black;
+            overflow: hidden;
+        }
+
+        .compositing-trigger {
+            position: absolute;
+            left: 20px;
+            top: 10px;
+            transform: translateZ(0);
+            padding: 20px;
+            background-color: gray;
+        }
+        
+        .box {
+            margin-top: 150px;
+            margin-left: 150px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+    </style>
+</head>
+<body>
+    <div class="compositing-trigger"></div>
+    <div class="container">
+        <div class="box"></div>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-clipping.html b/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-clipping.html
new file mode 100644 (file)
index 0000000..80e0820
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .container {
+            position: relative;
+            width: 200px;
+            height: 200px;
+            margin: 30px;
+            border: 3px solid black;
+            overflow: hidden;
+        }
+
+        .compositing-trigger {
+            position: absolute;
+            left: 20px;
+            top: 10px;
+            transform: translateZ(0);
+            padding: 20px;
+            background-color: gray;
+        }
+        
+        .relative {
+            position: relative;
+            top: 150px;
+            left: 150px;
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+        }
+    </style>
+</head>
+<body>
+    <div class="compositing-trigger"></div>
+    <div class="container">
+        <div class="relative"></div>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds-expected.txt
new file mode 100644 (file)
index 0000000..b128598
--- /dev/null
@@ -0,0 +1,23 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 20.00 10.00)
+          (bounds 50.00 50.00)
+          (contentsOpaque 1)
+        )
+        (GraphicsLayer
+          (position 38.00 30.00)
+          (bounds 261.00 261.00)
+          (drawsContent 1)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds.html b/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds.html
new file mode 100644 (file)
index 0000000..f2baf07
--- /dev/null
@@ -0,0 +1,53 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .container {
+            position: relative;
+            width: 200px;
+            height: 200px;
+            margin: 30px;
+            border: 1px solid black;
+        }
+        
+        .box {
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+            margin: 10px;
+        }
+
+        .trigger {
+            position: absolute;
+            left: 20px;
+            top: 10px;
+            width: 50px;
+            height: 50px;
+            transform: translateZ(0);
+            background-color: gray;
+        }
+        
+        .relative {
+            position: relative;
+            top: 150px;
+            left: 150px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="trigger"></div>
+    <div class="container">
+        <div class="relative box"></div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking-expected.txt
new file mode 100644 (file)
index 0000000..cc72916
--- /dev/null
@@ -0,0 +1,33 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 4
+        (GraphicsLayer
+          (position 20.00 10.00)
+          (bounds 50.00 50.00)
+          (contentsOpaque 1)
+        )
+        (GraphicsLayer
+          (position 38.00 30.00)
+          (bounds 202.00 202.00)
+          (drawsContent 1)
+        )
+        (GraphicsLayer
+          (position 160.00 160.00)
+          (bounds 100.00 100.00)
+          (contentsOpaque 1)
+        )
+        (GraphicsLayer
+          (position 199.00 191.00)
+          (bounds 100.00 100.00)
+          (contentsOpaque 1)
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking.html b/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking.html
new file mode 100644 (file)
index 0000000..57ea924
--- /dev/null
@@ -0,0 +1,62 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .container {
+            position: relative;
+            width: 200px;
+            height: 200px;
+            margin: 30px;
+            border: 1px solid black;
+        }
+        
+        .box {
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+            margin: 10px;
+        }
+        
+        .trigger {
+            position: absolute;
+            left: 20px;
+            top: 10px;
+            width: 50px;
+            height: 50px;
+            transform: translateZ(0);
+            background-color: gray;
+        }
+        
+        .relative {
+            position: relative;
+            top: 150px;
+            left: 150px;
+            z-index: 2;
+        }
+        
+        .interposer {
+            position: absolute;
+            left: 150px;
+            top: 150px;
+            background-color: orange;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+
+        window.addEventListener('load', () => {
+            if (window.internals)
+                document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="trigger"></div>
+    <div class="container">
+        <div class="relative box"></div>
+    </div>
+    <div class="interposer box"></div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-repaint-expected.txt b/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-repaint-expected.txt
new file mode 100644 (file)
index 0000000..6013ec9
--- /dev/null
@@ -0,0 +1,29 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 20.00 10.00)
+          (bounds 50.00 50.00)
+          (contentsOpaque 1)
+        )
+        (GraphicsLayer
+          (offsetFromRenderer width=-20 height=-20)
+          (position 38.00 30.00)
+          (bounds 242.00 242.00)
+          (drawsContent 1)
+          (repaint rects
+            (rect 151.00 81.00 71.00 110.00)
+            (rect 151.00 81.00 71.00 110.00)
+            (rect 151.00 81.00 71.00 110.00)
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-repaint.html b/LayoutTests/compositing/shared-backing/overflow-scroll/shared-layer-repaint.html
new file mode 100644 (file)
index 0000000..547137a
--- /dev/null
@@ -0,0 +1,75 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <title>Test repainting with layer sharing</title>
+    <style>
+        .container {
+            position: relative;
+            width: 200px;
+            height: 200px;
+            margin: 50px;
+            border: 1px solid black;
+            overflow: hidden;
+            box-shadow: 0 0 14px gray;
+        }
+        
+        .box {
+            width: 100px;
+            height: 100px;
+            background-color: blue;
+            margin: 10px;
+        }
+        
+        .box.changed {
+            background-color: orange;
+        }
+        
+        .trigger {
+            position: absolute;
+            left: 20px;
+            top: 10px;
+            width: 50px;
+            height: 50px;
+            background-color: gray;
+            transform: translateZ(0);
+        }
+        
+        .relative {
+            position: relative;
+            top: 50px;
+            left: 120px;
+            border: 5px solid green;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        window.addEventListener('load', () => {
+            setTimeout(() => {
+                document.body.offsetTop;
+                if (window.internals)
+                    window.internals.startTrackingRepaints();
+
+                document.getElementById('target').classList.add('changed');
+            
+                if (window.internals)
+                    document.getElementById('layers').textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_REPAINT_RECTS);
+
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="trigger"></div>
+    <div class="container">
+        <div id="target" class="relative box">
+        </div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/partial-compositing-update-expected.txt b/LayoutTests/compositing/shared-backing/partial-compositing-update-expected.txt
new file mode 100644 (file)
index 0000000..d02f680
--- /dev/null
@@ -0,0 +1,30 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 302.00 302.00)
+          (drawsContent 1)
+          (children 2
+            (GraphicsLayer
+              (position 11.00 11.00)
+              (bounds 280.00 50.00)
+              (contentsOpaque 1)
+            )
+            (GraphicsLayer
+              (position 11.00 51.00)
+              (bounds 280.00 224.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/partial-compositing-update.html b/LayoutTests/compositing/shared-backing/partial-compositing-update.html
new file mode 100644 (file)
index 0000000..56b77dd
--- /dev/null
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title></title>
+    <style>
+        
+        .container {
+            position: relative;
+            margin: 20px;
+            width: 300px;
+            height: 300px;
+            border: 1px solid black;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+        }
+        
+        .relative {
+            position: relative;
+            top: -20px;
+            margin: 10px;
+            padding: 10px;
+            border: 2px solid orange;
+        }
+        
+        .clipping {
+            overflow: hidden;
+            height: 200px;
+        }
+        
+        .trigger {
+            margin: 10px;
+            height: 50px;
+            background-color: silver;
+        }
+        
+        .composited.relative {
+            height: 200px;
+        }
+        
+        .absolute {
+            position: absolute;
+            margin: 10px;
+            height: 10px;
+            width: 100px;
+            background-color: silver;
+        }
+        
+        body.changed .absolute {
+            width: 120px;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+        }
+
+        window.addEventListener('load', () => {
+            setTimeout(() => {
+                document.body.classList.add('changed');
+                if (window.internals)
+                    document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="composited container">
+        <div class="composited trigger"></div>
+        <div class="relative clipping">
+            <div class="absolute" style="top: 10px;"></div>
+            <div class="absolute" style="top: 30px;"></div>
+            <div class="absolute" style="top: 50px;"></div>
+        </div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/partial-compositing-update2-expected.txt b/LayoutTests/compositing/shared-backing/partial-compositing-update2-expected.txt
new file mode 100644 (file)
index 0000000..d02f680
--- /dev/null
@@ -0,0 +1,30 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 302.00 302.00)
+          (drawsContent 1)
+          (children 2
+            (GraphicsLayer
+              (position 11.00 11.00)
+              (bounds 280.00 50.00)
+              (contentsOpaque 1)
+            )
+            (GraphicsLayer
+              (position 11.00 51.00)
+              (bounds 280.00 224.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/compositing/shared-backing/partial-compositing-update2.html b/LayoutTests/compositing/shared-backing/partial-compositing-update2.html
new file mode 100644 (file)
index 0000000..4d74f10
--- /dev/null
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title></title>
+    <style>
+        
+        .container {
+            position: relative;
+            margin: 20px;
+            width: 300px;
+            height: 300px;
+            border: 1px solid black;
+        }
+        
+        .composited {
+            transform: translateZ(0);
+        }
+        
+        .relative {
+            position: relative;
+            top: -20px;
+            margin: 10px;
+            padding: 10px;
+            border: 2px solid orange;
+        }
+        
+        .clipping {
+            overflow: hidden;
+            height: 200px;
+        }
+        
+        .trigger {
+            margin: 10px;
+            height: 50px;
+            background-color: silver;
+        }
+        
+        .composited.relative {
+            height: 200px;
+        }
+        
+        .absolute {
+            position: absolute;
+            margin: 10px;
+            height: 10px;
+            width: 100px;
+            background-color: silver;
+        }
+        
+        body.changed .changing {
+            width: 120px;
+        }
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.waitUntilDone();
+            testRunner.dumpAsText();
+        }
+
+        window.addEventListener('load', () => {
+            setTimeout(() => {
+                document.body.classList.add('changed');
+                if (window.internals)
+                    document.getElementById('layers').textContent = internals.layerTreeAsText(document);
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }, false);
+    </script>
+</head>
+<body>
+    <div class="composited container">
+        <div class="composited trigger"></div>
+        <div class="relative clipping">
+            <div class="relative changing"></div>
+            <div class="absolute" style="top: 10px;"></div>
+            <div class="absolute" style="top: 30px;"></div>
+            <div class="absolute" style="top: 50px;"></div>
+        </div>
+    </div>
+<pre id="layers"></pre>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/remove-sharing-layer-expected.txt b/LayoutTests/compositing/shared-backing/remove-sharing-layer-expected.txt
new file mode 100644 (file)
index 0000000..f9ea72a
--- /dev/null
@@ -0,0 +1,3 @@
+This test should not crash or assert.
+
+
diff --git a/LayoutTests/compositing/shared-backing/remove-sharing-layer.html b/LayoutTests/compositing/shared-backing/remove-sharing-layer.html
new file mode 100644 (file)
index 0000000..dc1e23b
--- /dev/null
@@ -0,0 +1,62 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Tests that there is no crash when a sharing layer is removed.</title>
+    <style>
+    .trigger {
+        position: absolute;
+        top: 0;
+        left: 0;
+        height: 100px;
+        width: 100px;
+        background-color: silver;
+        transform: translateZ(0);
+    }
+
+    .absolute {
+        position: absolute;
+        top: 50px;
+        left: 50px;
+        width: 200px;
+        height: 200px;
+        background: gray;
+    }
+    
+    .inner {
+        filter: drop-shadow(black 0 0 5px);
+        margin: 10px;
+        width: 100px;
+        height: 100px;
+        background-color: blue;
+    }
+
+    .inner.changed {
+        filter: none;
+    }
+
+    </style>
+    <script>
+        if (window.testRunner) {
+            testRunner.dumpAsText();
+            testRunner.waitUntilDone();
+        }
+
+        function doTest()
+        {
+            setTimeout(() => {
+                document.getElementById('target').classList.add('changed');
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }, 0);
+        }
+        window.addEventListener('load', doTest, false);
+    </script>
+</head>
+<body>
+    <p>This test should not crash or assert.</p>
+    <div class="trigger"></div>
+    <div class="absolute">
+        <div id="target" class="inner"></div>
+    </div>
+</body>
+</html>
diff --git a/LayoutTests/compositing/shared-backing/sharing-cached-clip-rects-expected.txt b/LayoutTests/compositing/shared-backing/sharing-cached-clip-rects-expected.txt
new file mode 100644 (file)
index 0000000..963d86e
--- /dev/null
@@ -0,0 +1,4 @@
+This test should not assert in debug builds.
+
+relative
+
diff --git a/LayoutTests/compositing/shared-backing/sharing-cached-clip-rects.html b/LayoutTests/compositing/shared-backing/sharing-cached-clip-rects.html
new file mode 100644 (file)
index 0000000..57493b4
--- /dev/null
@@ -0,0 +1,55 @@
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] -->
+<html>
+<head>
+    <style>
+        .scrollable {
+            overflow: scroll;
+            height: 300px;
+            width: 300px;
+            margin: 10px;
+            border: 1px solid black;
+        }
+
+        .nested {
+            margin: 10px;
+            padding: 10px;
+            border: 1px solid gray;
+        }
+
+        .nested > .nested > .layer {
+            margin-left: 100px;
+            background-color: silver;
+            opacity: 0.5;
+        }
+        
+        .relative {
+            position: relative;
+            margin-top: 300px;
+            border: 2px solid orange;
+        }
+    
+        .spacer {
+            height: 500px;
+        }
+    </style>
+    <script>
+        if (window.testRunner)
+            testRunner.dumpAsText();
+    </script>
+</head>
+<body>
+    <p>This test should not assert in debug builds.</p>
+    <div class="scrollable">
+        <div class="nested one">
+        </div>
+        <div class="nested two">
+            <div class="nested three">
+                <div class="layer two">
+                    <div class="relative third">relative</div>
+                </div>
+            </div>
+        </div>
+        <div class="spacer"></div>
+    </div>
+</body>
+</html>
index 5d44ff5..d10195a 100644 (file)
@@ -7,6 +7,7 @@
 #//////////////////////////////////////////////////////////////////////////////////////////
 
 compositing/ios [ Pass ]
+compositing/shared-backing/overflow-scroll [ Pass ]
 fast/device-orientation [ Pass ]
 fast/history/ios [ Pass ]
 fast/scrolling/ios [ Pass ]
@@ -1075,6 +1076,7 @@ webkit.org/b/156620 legacy-animation-engine/fast/animation/request-animation-fra
 webkit.org/b/153049 perf/array-binary-search.html [ Pass Failure Timeout ]
 
 fast/scrolling/ios/scroll-events-back-forward-after-pageshow.html [ Pass Failure ]
+webkit.org/b/197694 fast/scrolling/ios/overflow-scroll-overlap-4.html [ Failure ]
 
 webkit.org/b/157589 fast/text-autosizing/ios/text-autosizing-after-back.html [ Pass Timeout ]
 
diff --git a/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt b/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller-expected.txt
new file mode 100644 (file)
index 0000000..8947a59
--- /dev/null
@@ -0,0 +1,34 @@
+relativeabsolute
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 304.00 304.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 300.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=2 height=2)
+                  (anchor 0.00 0.00)
+                  (bounds 300.00 684.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt b/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller-expected.txt
new file mode 100644 (file)
index 0000000..57153e8
--- /dev/null
@@ -0,0 +1,45 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 2
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 404.00 404.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 400.00 400.00)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=2 height=2)
+                  (anchor 0.00 0.00)
+                  (bounds 400.00 1044.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (offsetFromRenderer width=-34 height=-134)
+          (position 10.00 10.00)
+          (bounds 400.00 400.00)
+          (children 1
+            (GraphicsLayer
+              (position 34.00 134.00)
+              (bounds 220.00 220.00)
+              (contentsOpaque 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt b/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow-expected.txt
new file mode 100644 (file)
index 0000000..7647e2e
--- /dev/null
@@ -0,0 +1,47 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 304.00 304.00)
+          (opacity 0.80)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 300.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=2 height=2)
+                  (anchor 0.00 0.00)
+                  (bounds 300.00 500.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (position 20.00 78.00)
+                      (bounds 140.00 140.00)
+                      (contentsOpaque 1)
+                      (drawsContent 1)
+                      (children 1
+                        (GraphicsLayer
+                          (bounds 140.00 140.00)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt b/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness-expected.txt
new file mode 100644 (file)
index 0000000..7071bf5
--- /dev/null
@@ -0,0 +1,62 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 3
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 324.00 324.00)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 320.00 320.00)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 10.00)
+                  (bounds 300.00 300.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (offsetFromRenderer width=2 height=2)
+                      (position 2.00 2.00)
+                      (bounds 296.00 296.00)
+                      (children 1
+                        (GraphicsLayer
+                          (offsetFromRenderer width=2 height=2)
+                          (anchor 0.00 0.00)
+                          (bounds 296.00 364.00)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+        (GraphicsLayer
+          (position 110.00 110.00)
+          (bounds 100.00 100.00)
+          (contentsOpaque 1)
+        )
+        (GraphicsLayer
+          (offsetFromRenderer width=-20 height=-20)
+          (position 42.00 34.00)
+          (bounds 296.00 296.00)
+          (children 1
+            (GraphicsLayer
+              (position 20.00 20.00)
+              (bounds 256.00 24.00)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping-expected.txt b/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping-expected.txt
new file mode 100644 (file)
index 0000000..ad4ed62
--- /dev/null
@@ -0,0 +1,47 @@
+Text
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 324.00 324.00)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 320.00 320.00)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 10.00)
+                  (bounds 300.00 300.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (offsetFromRenderer width=2 height=2)
+                      (position 2.00 2.00)
+                      (bounds 296.00 296.00)
+                      (children 1
+                        (GraphicsLayer
+                          (offsetFromRenderer width=2 height=2)
+                          (anchor 0.00 0.00)
+                          (bounds 296.00 468.00)
+                          (drawsContent 1)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping-expected.txt b/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping-expected.txt
new file mode 100644 (file)
index 0000000..ca6efa1
--- /dev/null
@@ -0,0 +1,48 @@
+Clipping
+Relative
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 324.00 324.00)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 320.00 320.00)
+              (children 1
+                (GraphicsLayer
+                  (position 10.00 10.00)
+                  (bounds 304.00 304.00)
+                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (offsetFromRenderer width=2 height=2)
+                      (position 2.00 2.00)
+                      (bounds 300.00 300.00)
+                      (children 1
+                        (GraphicsLayer
+                          (offsetFromRenderer width=2 height=2)
+                          (anchor 0.00 0.00)
+                          (bounds 300.00 428.00)
+                          (drawsContent 1)
+                        )
+                      )
+                    )
+                  )
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll-expected.txt b/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll-expected.txt
new file mode 100644 (file)
index 0000000..02e00b8
--- /dev/null
@@ -0,0 +1,34 @@
+relative
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 28.00 20.00)
+          (bounds 324.00 324.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 320.00 320.00)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=2 height=2)
+                  (anchor 0.00 0.00)
+                  (bounds 414.00 374.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
diff --git a/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content-expected.txt b/LayoutTests/platform/ios-wk2/compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content-expected.txt
new file mode 100644 (file)
index 0000000..284ed04
--- /dev/null
@@ -0,0 +1,34 @@
+Relative foreground
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (position 8.00 8.00)
+          (bounds 304.00 304.00)
+          (drawsContent 1)
+          (children 1
+            (GraphicsLayer
+              (offsetFromRenderer width=2 height=2)
+              (position 2.00 2.00)
+              (bounds 300.00 300.00)
+              (children 1
+                (GraphicsLayer
+                  (offsetFromRenderer width=2 height=2)
+                  (anchor 0.00 0.00)
+                  (bounds 300.00 364.00)
+                  (drawsContent 1)
+                )
+              )
+            )
+          )
+        )
+      )
+    )
+  )
+)
+
index f91ad09..ba7ad1a 100644 (file)
@@ -1,4 +1,5 @@
-absabs
+abs
+abs
 
 (Frame scrolling node
   (scrollable area size 800 600)
@@ -13,10 +14,10 @@ absabs
   (min layout viewport origin (0,0))
   (max layout viewport origin (0,0))
   (behavior for fixed 0)
-  (children 3
+  (children 5
     (Overflow scrolling node
       (scrollable area size 300 300)
-      (contents size 381 500)
+      (contents size 381 530)
       (parent relative scrollable rect at (30,35) size 300x300)
       (scrollable area parameters 
         (horizontal scroll elasticity 1)
@@ -28,12 +29,24 @@ absabs
     )
     (Positioned node
       (layout constraints 
+        (layer-position-at-last-layout (10,10))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+    )
+    (Positioned node
+      (layout constraints 
         (layer-position-at-last-layout (50,50))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
     (Positioned node
       (layout constraints 
+        (layer-position-at-last-layout (62,82))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+    )
+    (Positioned node
+      (layout constraints 
         (layer-position-at-last-layout (77,77))
         (positioning-behavior moves))
       (related overflow nodes 1)
index 9270eee..af9309b 100644 (file)
@@ -1,4 +1,5 @@
-absabs
+abs
+abs
 
 (Frame scrolling node
   (scrollable area size 800 600)
@@ -13,10 +14,10 @@ absabs
   (min layout viewport origin (0,0))
   (max layout viewport origin (0,0))
   (behavior for fixed 0)
-  (children 4
+  (children 7
     (Overflow scrolling node
       (scrollable area size 300 300)
-      (contents size 300 526)
+      (contents size 300 556)
       (parent relative scrollable rect at (30,22) size 300x300)
       (scrollable area parameters 
         (horizontal scroll elasticity 1)
@@ -27,19 +28,37 @@ absabs
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (0,0))
+        (layer-position-at-last-layout (10,10))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (53,53))
+        (layer-position-at-last-layout (0,30))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (80,80))
+        (layer-position-at-last-layout (13,43))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+    )
+    (Positioned node
+      (layout constraints 
+        (layer-position-at-last-layout (53,83))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+    )
+    (Positioned node
+      (layout constraints 
+        (layer-position-at-last-layout (65,115))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+    )
+    (Positioned node
+      (layout constraints 
+        (layer-position-at-last-layout (80,110))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
index dced88a..45cb0eb 100644 (file)
@@ -1,4 +1,5 @@
-absabs
+abs
+abs
 
 (Frame scrolling node
   (scrollable area size 800 600)
@@ -16,7 +17,7 @@ absabs
   (children 1
     (Overflow scrolling node
       (scrollable area size 300 300)
-      (contents size 300 500)
+      (contents size 300 530)
       (parent relative scrollable rect at (30,22) size 300x300)
       (scrollable area parameters 
         (horizontal scroll elasticity 1)
index 216a6ae..161f398 100644 (file)
@@ -26,7 +26,7 @@ Stacking
   (min layout viewport origin (0,0))
   (max layout viewport origin (0,229))
   (behavior for fixed 0)
-  (children 12
+  (children 19
     (Overflow scrolling node
       (scrollable area size 220 170)
       (contents size 220 1020)
@@ -40,13 +40,19 @@ Stacking
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (10,30))
+        (layer-position-at-last-layout (20,40))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (10,50))
+        (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)
     )
@@ -63,7 +69,13 @@ Stacking
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (10,30))
+        (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)
     )
@@ -78,6 +90,12 @@ 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 scrolling node
       (scrollable area size 220 170)
       (contents size 220 1020)
@@ -89,6 +107,12 @@ 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 scrolling node
       (scrollable area size 220 170)
       (contents size 220 1020)
@@ -102,13 +126,25 @@ Stacking
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (10,30))
+        (layer-position-at-last-layout (20,40))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (110,50))
+        (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)
     )
@@ -125,13 +161,19 @@ Stacking
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (10,30))
+        (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)
       (children 1
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (79,20))
+            (layer-position-at-last-layout (79,50))
             (positioning-behavior stationary))
           (related overflow nodes 1)
         )
index 8c4d7a8..b30dbb9 100644 (file)
@@ -11,7 +11,7 @@ middlebottom
     (GraphicsLayer
       (bounds 800.00 2618.00)
       (contentsOpaque 1)
-      (children 6
+      (children 3
         (GraphicsLayer
           (position 21.00 21.00)
           (bounds 100.00 100.00)
@@ -23,52 +23,12 @@ middlebottom
         )
         (GraphicsLayer
           (offsetFromRenderer width=0 height=100)
-          (position 28.00 20.00)
-          (bounds 200.00 200.00)
-          (children 1
-            (GraphicsLayer
-              (offsetFromRenderer width=0 height=100)
-              (bounds 110.00 200.00)
-              (contentsOpaque 1)
-              (drawsContent 1)
-            )
-          )
-        )
-        (GraphicsLayer
-          (offsetFromRenderer width=-5 height=-145)
-          (position 28.00 20.00)
-          (bounds 200.00 200.00)
-          (children 1
-            (GraphicsLayer
-              (offsetFromRenderer width=0 height=-1)
-              (position 5.00 144.00)
-              (bounds 144.00 25.00)
-              (drawsContent 1)
-            )
-          )
-        )
-        (GraphicsLayer
-          (offsetFromRenderer width=0 height=100)
           (position 28.00 250.00)
           (bounds 185.00 200.00)
           (children 1
             (GraphicsLayer
               (offsetFromRenderer width=0 height=100)
-              (bounds 110.00 200.00)
-              (contentsOpaque 1)
-              (drawsContent 1)
-            )
-          )
-        )
-        (GraphicsLayer
-          (offsetFromRenderer width=-5 height=-145)
-          (position 28.00 250.00)
-          (bounds 185.00 200.00)
-          (children 1
-            (GraphicsLayer
-              (offsetFromRenderer width=0 height=-1)
-              (position 5.00 144.00)
-              (bounds 144.00 25.00)
+              (bounds 149.00 200.00)
               (drawsContent 1)
             )
           )
index 3b15c25..80cde01 100644 (file)
@@ -19,7 +19,7 @@ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
       (coverage rect 0.00, 0.00 800.00 x 600.00)
       (intersects coverage rect 1)
       (contentsScale 2.00)
-      (children 6
+      (children 4
         (GraphicsLayer
           (position 8.00 102.00)
           (bounds 22.00 22.00)
@@ -48,39 +48,12 @@ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
           (contentsScale 2.00)
         )
         (GraphicsLayer
-          (position 9.00 91.00)
-          (bounds 100.00 20.00)
-          (visible rect 0.00, 0.00 100.00 x 20.00)
-          (coverage rect 0.00, 0.00 100.00 x 20.00)
-          (intersects coverage rect 1)
-          (contentsScale 2.00)
-          (children 1
-            (GraphicsLayer
-              (bounds 100.00 20.00)
-              (drawsContent 1)
-              (visible rect 0.00, 0.00 100.00 x 20.00)
-              (coverage rect 0.00, 0.00 100.00 x 20.00)
-              (intersects coverage rect 1)
-              (contentsScale 2.00)
-            )
-          )
-        )
-        (GraphicsLayer
-          (position 8.00 134.00)
-          (bounds 102.00 22.00)
-          (drawsContent 1)
-          (visible rect 0.00, 0.00 102.00 x 22.00)
-          (coverage rect -8.00, -134.00 800.00 x 600.00)
-          (intersects coverage rect 1)
-          (contentsScale 2.00)
-        )
-        (GraphicsLayer
-          (offsetFromRenderer width=-9 height=0)
-          (position 0.00 135.00)
-          (bounds 807.00 20.00)
+          (offsetFromRenderer width=-17 height=0)
+          (position -9.00 134.00)
+          (bounds 816.00 22.00)
           (drawsContent 1)
-          (visible rect 0.00, 0.00 800.00 x 20.00)
-          (coverage rect 0.00, -135.00 800.00 x 600.00)
+          (visible rect 9.00, 0.00 800.00 x 22.00)
+          (coverage rect 9.00, -134.00 800.00 x 600.00)
           (intersects coverage rect 1)
           (contentsScale 2.00)
         )
index 199a547..176bef0 100644 (file)
@@ -19,7 +19,7 @@ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
       (coverage rect 0.00, 0.00 800.00 x 600.00)
       (intersects coverage rect 1)
       (contentsScale 2.00)
-      (children 6
+      (children 4
         (GraphicsLayer
           (position 8.00 102.00)
           (bounds 22.00 22.00)
@@ -48,41 +48,14 @@ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
           (contentsScale 2.00)
         )
         (GraphicsLayer
-          (position 9.00 91.00)
-          (bounds 100.00 20.00)
-          (visible rect 0.00, 0.00 100.00 x 20.00)
-          (coverage rect 0.00, 0.00 100.00 x 20.00)
-          (intersects coverage rect 1)
-          (contentsScale 2.00)
-          (children 1
-            (GraphicsLayer
-              (bounds 100.00 20.00)
-              (drawsContent 1)
-              (visible rect 0.00, 0.00 100.00 x 20.00)
-              (coverage rect 0.00, 0.00 100.00 x 20.00)
-              (intersects coverage rect 1)
-              (contentsScale 2.00)
-            )
-          )
-        )
-        (GraphicsLayer
           (position 8.00 134.00)
-          (bounds 102.00 22.00)
+          (bounds 799.00 22.00)
           (drawsContent 1)
-          (visible rect 0.00, 0.00 102.00 x 22.00)
+          (visible rect 0.00, 0.00 792.00 x 22.00)
           (coverage rect -8.00, -134.00 800.00 x 600.00)
           (intersects coverage rect 1)
           (contentsScale 2.00)
         )
-        (GraphicsLayer
-          (position 9.00 135.00)
-          (bounds 798.00 20.00)
-          (drawsContent 1)
-          (visible rect 0.00, 0.00 791.00 x 20.00)
-          (coverage rect -9.00, -135.00 800.00 x 600.00)
-          (intersects coverage rect 1)
-          (contentsScale 2.00)
-        )
       )
     )
   )
index bb66841..581adf0 100644 (file)
                 (GraphicsLayer
                   (anchor 0.00 0.00)
                   (bounds 320.00 1224.00)
-                  (drawsContent 1)
+                  (children 1
+                    (GraphicsLayer
+                      (position 10.00 10.00)
+                      (bounds 284.00 1204.00)
+                      (contentsOpaque 1)
+                      (drawsContent 1)
+                    )
+                  )
                 )
               )
             )
index 8b13789..6bc82b3 100644 (file)
@@ -1 +1,25 @@
+(GraphicsLayer
+  (anchor 0.00 0.00)
+  (bounds 800.00 600.00)
+  (children 1
+    (GraphicsLayer
+      (bounds 800.00 600.00)
+      (contentsOpaque 1)
+      (children 1
+        (GraphicsLayer
+          (offsetFromRenderer width=-10 height=-10)
+          (bounds 305.00 325.00)
+          (children 1
+            (GraphicsLayer
+              (position 10.00 10.00)
+              (bounds 284.00 1204.00)
+              (contentsOpaque 1)
+              (drawsContent 1)
+            )
+          )
+        )
+      )
+    )
+  )
+)
 
index 4241ad9..450afa4 100644 (file)
@@ -5,6 +5,7 @@
 # Platform-specific directories. Skipped globally, then re-enabled here.
 #//////////////////////////////////////////////////////////////////////////////////////////
 
+compositing/shared-backing/overflow-scroll [ Pass ]
 editing/find [ Pass ]
 editing/undo-manager [ Pass ]
 fast/forms/select/mac-wk2 [ Pass ]
index cb258fd..70080d1 100644 (file)
@@ -19,7 +19,7 @@ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
       (coverage rect 0.00, 0.00 800.00 x 585.00)
       (intersects coverage rect 1)
       (contentsScale 1.00)
-      (children 6
+      (children 4
         (GraphicsLayer
           (position 8.00 96.00)
           (bounds 22.00 22.00)
@@ -48,39 +48,12 @@ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
           (contentsScale 1.00)
         )
         (GraphicsLayer
-          (position 9.00 87.00)
-          (bounds 100.00 18.00)
-          (visible rect 0.00, 0.00 100.00 x 18.00)
-          (coverage rect 0.00, 0.00 100.00 x 18.00)
-          (intersects coverage rect 1)
-          (contentsScale 1.00)
-          (children 1
-            (GraphicsLayer
-              (bounds 100.00 18.00)
-              (drawsContent 1)
-              (visible rect 0.00, 0.00 100.00 x 18.00)
-              (coverage rect 0.00, 0.00 100.00 x 18.00)
-              (intersects coverage rect 1)
-              (contentsScale 1.00)
-            )
-          )
-        )
-        (GraphicsLayer
-          (position 8.00 128.00)
-          (bounds 102.00 20.00)
-          (drawsContent 1)
-          (visible rect 0.00, 0.00 102.00 x 20.00)
-          (coverage rect -8.00, -128.00 800.00 x 585.00)
-          (intersects coverage rect 1)
-          (contentsScale 1.00)
-        )
-        (GraphicsLayer
-          (offsetFromRenderer width=-9 height=0)
-          (position 0.00 129.00)
-          (bounds 807.00 18.00)
+          (offsetFromRenderer width=-16 height=0)
+          (position -8.00 128.00)
+          (bounds 815.00 20.00)
           (drawsContent 1)
-          (visible rect 0.00, 0.00 800.00 x 18.00)
-          (coverage rect 0.00, -129.00 800.00 x 585.00)
+          (visible rect 8.00, 0.00 800.00 x 20.00)
+          (coverage rect 8.00, -128.00 800.00 x 585.00)
           (intersects coverage rect 1)
           (contentsScale 1.00)
         )
index ac2b42c..8f7ac9c 100644 (file)
@@ -19,7 +19,7 @@ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
       (coverage rect 0.00, 0.00 800.00 x 585.00)
       (intersects coverage rect 1)
       (contentsScale 1.00)
-      (children 6
+      (children 4
         (GraphicsLayer
           (position 8.00 96.00)
           (bounds 22.00 22.00)
@@ -48,41 +48,14 @@ Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
           (contentsScale 1.00)
         )
         (GraphicsLayer
-          (position 9.00 87.00)
-          (bounds 100.00 18.00)
-          (visible rect 0.00, 0.00 100.00 x 18.00)
-          (coverage rect 0.00, 0.00 100.00 x 18.00)
-          (intersects coverage rect 1)
-          (contentsScale 1.00)
-          (children 1
-            (GraphicsLayer
-              (bounds 100.00 18.00)
-              (drawsContent 1)
-              (visible rect 0.00, 0.00 100.00 x 18.00)
-              (coverage rect 0.00, 0.00 100.00 x 18.00)
-              (intersects coverage rect 1)
-              (contentsScale 1.00)
-            )
-          )
-        )
-        (GraphicsLayer
           (position 8.00 128.00)
-          (bounds 102.00 20.00)
+          (bounds 799.00 20.00)
           (drawsContent 1)
-          (visible rect 0.00, 0.00 102.00 x 20.00)
+          (visible rect 0.00, 0.00 792.00 x 20.00)
           (coverage rect -8.00, -128.00 800.00 x 585.00)
           (intersects coverage rect 1)
           (contentsScale 1.00)
         )
-        (GraphicsLayer
-          (position 9.00 129.00)
-          (bounds 798.00 18.00)
-          (drawsContent 1)
-          (visible rect 0.00, 0.00 791.00 x 18.00)
-          (coverage rect -9.00, -129.00 800.00 x 585.00)
-          (intersects coverage rect 1)
-          (contentsScale 1.00)
-        )
       )
     )
   )
index 59c823c..81be073 100644 (file)
@@ -1,4 +1,5 @@
-absabs
+abs
+abs
 
 (Frame scrolling node
   (scrollable area size 800 600)
@@ -13,10 +14,10 @@ absabs
   (min layout viewport origin (0,0))
   (max layout viewport origin (0,0))
   (behavior for fixed 0)
-  (children 3
+  (children 5
     (Overflow scrolling node
       (scrollable area size 285 285)
-      (contents size 381 500)
+      (contents size 381 530)
       (parent relative scrollable rect at (30,35) size 285x285)
       (scrollable area parameters 
         (horizontal scroll elasticity 0)
@@ -28,12 +29,24 @@ absabs
     )
     (Positioned node
       (layout constraints 
+        (layer-position-at-last-layout (10,10))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+    )
+    (Positioned node
+      (layout constraints 
         (layer-position-at-last-layout (50,50))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
     (Positioned node
       (layout constraints 
+        (layer-position-at-last-layout (62,80))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+    )
+    (Positioned node
+      (layout constraints 
         (layer-position-at-last-layout (77,77))
         (positioning-behavior moves))
       (related overflow nodes 1)
index 526f732..249826e 100644 (file)
             height: 500px;
             background-image: repeating-linear-gradient(white, silver 200px);
         }
+        
+        .sharing-preventer {
+            transform: translateZ(0);
+            margin: 10px;
+            width: 10px;
+            height: 10px;
+        }
     </style>
     <script>
         if (window.testRunner)
@@ -48,7 +55,9 @@
 </head>
 <body>
     <div class="scroller">
+        <div class="sharing-preventer"></div>
         <div class="absolute">abs
+            <div class="sharing-preventer"></div>
             <div class="inner absolute">abs</div>
         </div>
         <div class="scrollcontent"></div>
index f25a749..1ac1643 100644 (file)
@@ -1,4 +1,5 @@
-absabs
+abs
+abs
 
 (Frame scrolling node
   (scrollable area size 800 600)
@@ -13,10 +14,10 @@ absabs
   (min layout viewport origin (0,0))
   (max layout viewport origin (0,0))
   (behavior for fixed 0)
-  (children 4
+  (children 7
     (Overflow scrolling node
       (scrollable area size 285 285)
-      (contents size 285 526)
+      (contents size 285 556)
       (parent relative scrollable rect at (30,22) size 285x285)
       (scrollable area parameters 
         (horizontal scroll elasticity 0)
@@ -27,19 +28,37 @@ absabs
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (0,0))
+        (layer-position-at-last-layout (10,10))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (53,53))
+        (layer-position-at-last-layout (0,30))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (80,80))
+        (layer-position-at-last-layout (13,43))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+    )
+    (Positioned node
+      (layout constraints 
+        (layer-position-at-last-layout (53,83))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+    )
+    (Positioned node
+      (layout constraints 
+        (layer-position-at-last-layout (65,113))
+        (positioning-behavior moves))
+      (related overflow nodes 1)
+    )
+    (Positioned node
+      (layout constraints 
+        (layer-position-at-last-layout (80,110))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
index 8deb6d0..19f9cf0 100644 (file)
             height: 500px;
             background-image: repeating-linear-gradient(white, silver 200px);
         }
+
+        .sharing-preventer {
+            transform: translateZ(0);
+            margin: 10px;
+            width: 10px;
+            height: 10px;
+        }
     </style>
     <script>
         if (window.testRunner)
 <body>
 
     <div class="scroller">
+        <div class="sharing-preventer"></div>
         <div class="relative">
+            <div class="sharing-preventer"></div>
             <div class="absolute">abs
+                <div class="sharing-preventer"></div>
                 <div class="inner absolute">abs</div>
             </div>
         </div>
index 5a9cfd9..80aeb63 100644 (file)
@@ -1,4 +1,5 @@
-absabs
+abs
+abs
 
 (Frame scrolling node
   (scrollable area size 800 600)
@@ -16,7 +17,7 @@ absabs
   (children 1
     (Overflow scrolling node
       (scrollable area size 285 285)
-      (contents size 285 500)
+      (contents size 285 530)
       (parent relative scrollable rect at (30,22) size 285x285)
       (scrollable area parameters 
         (horizontal scroll elasticity 0)
index 6cc87bb..df0ad87 100644 (file)
             height: 500px;
             background-image: repeating-linear-gradient(white, silver 200px);
         }
+
+        .sharing-preventer {
+            transform: translateZ(0);
+            margin: 10px;
+            width: 10px;
+            height: 10px;
+        }
     </style>
     <script>
         if (window.testRunner)
@@ -48,7 +55,9 @@
 </head>
 <body>
     <div class="scroller">
+        <div class="sharing-preventer"></div>
         <div class="absolute">abs
+            <div class="sharing-preventer"></div>
             <div class="inner absolute">abs</div>
         </div>
         <div class="scrollcontent"></div>
index b7a8681..8fa8d8b 100644 (file)
@@ -27,7 +27,7 @@ Stacking
   (min layout viewport origin (0,0))
   (max layout viewport origin (0,229))
   (behavior for fixed 0)
-  (children 12
+  (children 19
     (Overflow scrolling node
       (scrollable area size 205 155)
       (contents size 210 1020)
@@ -42,13 +42,19 @@ Stacking
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (10,28))
+        (layer-position-at-last-layout (20,38))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (10,46))
+        (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)
     )
@@ -66,7 +72,13 @@ Stacking
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (10,28))
+        (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)
     )
@@ -81,6 +93,12 @@ 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 scrolling node
       (scrollable area size 205 155)
       (contents size 205 1020)
@@ -92,6 +110,12 @@ 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 scrolling node
       (scrollable area size 205 155)
       (contents size 210 1020)
@@ -106,13 +130,25 @@ Stacking
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (10,28))
+        (layer-position-at-last-layout (20,38))
         (positioning-behavior moves))
       (related overflow nodes 1)
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (110,46))
+        (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)
     )
@@ -129,13 +165,19 @@ Stacking
     )
     (Positioned node
       (layout constraints 
-        (layer-position-at-last-layout (10,28))
+        (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)
       (children 1
         (Positioned node
           (layout constraints 
-            (layer-position-at-last-layout (79,18))
+            (layer-position-at-last-layout (79,48))
             (positioning-behavior stationary))
           (related overflow nodes 1)
         )
index afca83c..1d74f6e 100644 (file)
@@ -47,6 +47,7 @@
         .absolute {
             position: absolute;
             left: 100px;
+            transform: translateZ(0);
         }
 
         .composited {
         .scrolling-content {
             height: 1000px;
         }
+
+        .sharing-preventer {
+            transform: translateZ(0);
+            margin: 10px;
+            width: 10px;
+            height: 10px;
+        }
         </style>
         <script>
         if (window.testRunner)
             <div class="scroller">
                 <div class="scrolling-content">
                     Scrolling content
+                    <div class="sharing-preventer"></div>
                     <div class="stacking">
                         Stacking
+                        <div class="sharing-preventer"></div>
                         <div class="absolute box"></div>
                     </div>
                 </div>
             <div class="scroller">
                 <div class="scrolling-content">
                     Scrolling content
+                    <div class="sharing-preventer"></div>
                     <div class="containing">
                         Containing
+                        <div class="sharing-preventer"></div>
                         <div class="absolute box"></div>
                     </div>
                 </div>
             <div class="scroller">
                 <div class="scrolling-content">
                     Scrolling content
+                    <div class="sharing-preventer"></div>
                     <div class="absolute box"></div>
                 </div>
             </div>
                     <div class="scroller">
                         <div class="scrolling-content">
                             Scrolling content
+                            <div class="sharing-preventer"></div>
                             <div class="absolute box"></div>
                         </div>
                     </div>
             <div class="scroller">
                 <div class="scrolling-content">
                     Scrolling content
+                    <div class="sharing-preventer"></div>
                     <div class="stacking">
                         Stacking
                         <div class="containing">
                             Containing
+                            <div class="sharing-preventer"></div>
                             <div class="absolute box"></div>
                         </div>
                     </div>
             <div class="scroller">
                 <div class="scrolling-content">
                     Scrolling content
+                    <div class="sharing-preventer"></div>
                     <div class="containing">
                         Containing
                         <div class="stacking">
                             Stacking
+                            <div class="sharing-preventer"></div>
                             <div class="absolute box"></div>
                         </div>
                     </div>
index a72ad88..8cb18e7 100644 (file)
@@ -1,3 +1,96 @@
+2019-05-09  Simon Fraser  <simon.fraser@apple.com>
+
+        Implement backing-sharing in compositing layers, allowing overlap layers to paint into the backing store of another layer
+        https://bugs.webkit.org/show_bug.cgi?id=197561
+        <rdar://problem/50445998>
+
+        Reviewed by Antti Koivisto.
+
+        This change introduces the concept of layers that share backing store for compositing. A layer
+        which is sharing its backing store first paints itself, and then some set of layers which come
+        later in paint order in the same stacking context. This reduces the composited layer count in
+        some overflow scrolling scenarios, thereby also simplifying the scrolling tree.
+        
+        A backing-shared layer stores a vector of "sharing" RenderLayer* in its RenderLayerBacking. At
+        paint time, the owning layer is painted, then the sharing layers, setting the owning layer as the
+        painting root so that positioning and clipping just work.
+        
+        Sharing layer relationships are constructed in RenderLayerCompositor::computeCompositingRequirements().
+        We track the last layer which was composited in paint order as a shared candidate. If a later layer
+        would composite for overlap (and no other reasons), then we allow it to share with the candidate
+        if the candidate is in its ancestor containing block chain. Sharing is currently limited to layers
+        in the same stacking context.
+        
+        isComposited() returns false for sharing layers, but they are like composited layers in that
+        they behave as painting boundaries, so RenderLayer::paintLayer() needs to stop at them,
+        and repaints in shared layers have to be directed to their shared layer, hence
+        changes to RenderLayer::clippingRootForPainting() and RenderLayer::enclosingCompositingLayerForRepaint().
+        
+        The clipping boundary logic in RenderLayer::backgroundClipRect() needed to be generalized so that
+        all calls to RenderLayer::parentClipRects() check for crossing painting boundaries and use
+        TemporaryClipRects in that case.
+
+        Tests: compositing/shared-backing/overflow-scroll/absolute-in-stacking-relative-in-scroller.html
+               compositing/shared-backing/overflow-scroll/composited-absolute-in-absolute-in-relative-in-scroller.html
+               compositing/shared-backing/overflow-scroll/nested-absolute-with-clipping-in-stacking-overflow.html
+               compositing/shared-backing/overflow-scroll/previous-sibling-prevents-inclusiveness.html
+               compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-clipping.html
+               compositing/shared-backing/overflow-scroll/relative-in-clipping-in-scroller-in-relative-clipping.html
+               compositing/shared-backing/overflow-scroll/relative-in-div-in-overflow-scroll.html
+               compositing/shared-backing/overflow-scroll/scrolled-contents-has-painted-content.html
+               compositing/shared-backing/overflow-scroll/scrolled-contents-unconstrained-clip.html
+               compositing/shared-backing/overflow-scroll/shared-layer-clipping.html
+               compositing/shared-backing/overflow-scroll/shared-layer-composited-bounds.html
+               compositing/shared-backing/overflow-scroll/shared-layer-nested-relative-stacking.html
+               compositing/shared-backing/overflow-scroll/shared-layer-repaint.html
+               compositing/shared-backing/partial-compositing-update.html
+               compositing/shared-backing/partial-compositing-update2.html
+               compositing/shared-backing/remove-sharing-layer.html
+               compositing/shared-backing/sharing-cached-clip-rects.html
+
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::~RenderLayer):
+        (WebCore::RenderLayer::ancestorLayerIsInContainingBlockChain const):
+        (WebCore::RenderLayer::setBackingProviderLayer):
+        (WebCore::RenderLayer::disconnectFromBackingProviderLayer):
+        (WebCore::RenderLayer::enclosingCompositingLayerForRepaint const):
+        (WebCore::RenderLayer::clippingRootForPainting const):
+        (WebCore::RenderLayer::clipToRect):
+        (WebCore::RenderLayer::paintLayer):
+        (WebCore::RenderLayer::updateClipRects):
+        (WebCore::RenderLayer::clipCrossesPaintingBoundary const):
+        (WebCore::RenderLayer::calculateClipRects const):
+        (WebCore::outputPaintOrderTreeLegend):
+        (WebCore::outputPaintOrderTreeRecursive):
+        (WebCore::inContainingBlockChain): Deleted.
+        * rendering/RenderLayer.h:
+        * rendering/RenderLayerBacking.cpp:
+        (WebCore::RenderLayerBacking::willBeDestroyed):
+        (WebCore::clearBackingSharingLayerProviders):
+        (WebCore::RenderLayerBacking::setBackingSharingLayers):
+        (WebCore::RenderLayerBacking::removeBackingSharingLayer):
+        (WebCore::RenderLayerBacking::clearBackingSharingLayers):
+        (WebCore::RenderLayerBacking::updateCompositedBounds):
+        (WebCore::RenderLayerBacking::updateDrawsContent):
+        (WebCore::RenderLayerBacking::isSimpleContainerCompositingLayer const):
+        (WebCore::RenderLayerBacking::paintIntoLayer):
+        (WebCore::RenderLayerBacking::paintContents):
+        * rendering/RenderLayerBacking.h:
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::CompositingState::stateForPaintOrderChildren const):
+        (WebCore::RenderLayerCompositor::CompositingState::propagateStateFromChildren):
+        (WebCore::RenderLayerCompositor::CompositingState::propagateStateFromChildrenForUnchangedSubtree):
+        (WebCore::RenderLayerCompositor::BackingSharingState::resetBackingProviderCandidate):
+        (WebCore::RenderLayerCompositor::updateCompositingLayers):
+        (WebCore::backingProviderLayerCanIncludeLayer):
+        (WebCore::RenderLayerCompositor::computeCompositingRequirements):
+        (WebCore::RenderLayerCompositor::traverseUnchangedSubtree):
+        (WebCore::RenderLayerCompositor::updateBacking):
+        (WebCore::RenderLayerCompositor::layerWillBeRemoved):
+        (WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason const):
+        * rendering/RenderLayerCompositor.h:
+        * rendering/RenderTreeAsText.cpp:
+
 2019-05-09  Daniel Bates  <dabates@apple.com>
 
         [iOS] Right command key has wrong value for property code
index a3ff520..a25dbd1 100644 (file)
@@ -366,6 +366,12 @@ RenderLayer::~RenderLayer()
 
     clearLayerFilters();
 
+    if (paintsIntoProvidedBacking()) {
+        auto* backingProviderLayer = this->backingProviderLayer();
+        if (backingProviderLayer->backing())
+            backingProviderLayer->backing()->removeBackingSharingLayer(*this);
+    }
+
     // Child layers will be deleted by their corresponding render objects, so
     // we don't need to delete them ourselves.
 
@@ -1663,6 +1669,23 @@ static inline bool isContainerForPositioned(RenderLayer& layer, PositionType pos
     }
 }
 
+bool RenderLayer::ancestorLayerIsInContainingBlockChain(const RenderLayer& ancestor, const RenderLayer* checkLimit) const
+{
+    if (&ancestor == this)
+        return true;
+
+    for (const auto* currentBlock = renderer().containingBlock(); currentBlock && !is<RenderView>(*currentBlock); currentBlock = currentBlock->containingBlock()) {
+        auto* currLayer = currentBlock->layer();
+        if (currLayer == &ancestor)
+            return true;
+        
+        if (currLayer && currLayer == checkLimit)
+            return false;
+    }
+    
+    return false;
+}
+
 RenderLayer* RenderLayer::enclosingAncestorForPosition(PositionType position) const
 {
     RenderLayer* curr = parent();
@@ -1746,6 +1769,27 @@ inline bool RenderLayer::shouldRepaintAfterLayout() const
     return !isComposited() || backing()->paintsIntoCompositedAncestor();
 }
 
+void RenderLayer::setBackingProviderLayer(RenderLayer* backingProvider)
+{
+    if (backingProvider == m_backingProviderLayer)
+        return;
+
+    if (!renderer().renderTreeBeingDestroyed())
+        clearClipRectsIncludingDescendants();
+
+    m_backingProviderLayer = makeWeakPtr(backingProvider);
+}
+
+void RenderLayer::disconnectFromBackingProviderLayer()
+{
+    if (!m_backingProviderLayer)
+        return;
+    
+    ASSERT(m_backingProviderLayer->isComposited());
+    if (m_backingProviderLayer->isComposited())
+        m_backingProviderLayer->backing()->removeBackingSharingLayer(*this);
+}
+
 bool compositedWithOwnBackingStore(const RenderLayer& layer)
 {
     return layer.isComposited() && !layer.backing()->paintsIntoCompositedAncestor();
@@ -1766,12 +1810,23 @@ RenderLayer* RenderLayer::enclosingCompositingLayer(IncludeSelfOrNot includeSelf
 
 RenderLayer* RenderLayer::enclosingCompositingLayerForRepaint(IncludeSelfOrNot includeSelf) const
 {
-    if (includeSelf == IncludeSelf && compositedWithOwnBackingStore(*this))
-        return const_cast<RenderLayer*>(this);
+    auto repaintTargetForLayer = [](const RenderLayer& layer) -> RenderLayer* {
+        if (compositedWithOwnBackingStore(layer))
+            return const_cast<RenderLayer*>(&layer);
+        
+        if (layer.paintsIntoProvidedBacking())
+            return layer.backingProviderLayer();
+        
+        return nullptr;
+    };
+
+    RenderLayer* repaintTarget = nullptr;
+    if (includeSelf == IncludeSelf && (repaintTarget = repaintTargetForLayer(*this)))
+        return repaintTarget;
 
     for (const RenderLayer* curr = paintOrderParent(); curr; curr = curr->paintOrderParent()) {
-        if (compositedWithOwnBackingStore(*curr))
-            return const_cast<RenderLayer*>(curr);
+        if ((repaintTarget = repaintTargetForLayer(*curr)))
+            return repaintTarget;
     }
          
     return nullptr;
@@ -1853,6 +1908,9 @@ RenderLayer* RenderLayer::clippingRootForPainting() const
     if (isComposited())
         return const_cast<RenderLayer*>(this);
 
+    if (paintsIntoProvidedBacking())
+        return backingProviderLayer();
+
     const RenderLayer* current = this;
     while (current) {
         if (current->isRenderViewLayer())
@@ -1862,6 +1920,9 @@ RenderLayer* RenderLayer::clippingRootForPainting() const
         ASSERT(current);
         if (current->transform() || compositedWithOwnBackingStore(*current))
             return const_cast<RenderLayer*>(current);
+
+        if (current->paintsIntoProvidedBacking())
+            return current->backingProviderLayer();
     }
 
     ASSERT_NOT_REACHED();
@@ -3928,18 +3989,6 @@ void RenderLayer::paintOverlayScrollbars(GraphicsContext& context, const LayoutR
     m_containsDirtyOverlayScrollbars = false;
 }
 
-static bool inContainingBlockChain(RenderLayer* startLayer, RenderLayer* endLayer)
-{
-    if (startLayer == endLayer)
-        return true;
-    for (const auto* currentBlock = startLayer->renderer().containingBlock(); currentBlock && !is<RenderView>(*currentBlock); currentBlock = currentBlock->containingBlock()) {
-        if (currentBlock->layer() == endLayer)
-            return true;
-    }
-    
-    return false;
-}
-
 void RenderLayer::clipToRect(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, const ClipRect& clipRect, BorderRadiusClippingRule rule)
 {
     float deviceScaleFactor = renderer().document().deviceScaleFactor();
@@ -3958,7 +4007,7 @@ void RenderLayer::clipToRect(GraphicsContext& context, const LayerPaintingInfo&
         // any layers with overflow. The condition for being able to apply these clips is that the overflow object be in our
         // containing block chain so we check that also.
         for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
-            if (layer->renderer().hasOverflowClip() && layer->renderer().style().hasBorderRadius() && inContainingBlockChain(this, layer)) {
+            if (layer->renderer().hasOverflowClip() && layer->renderer().style().hasBorderRadius() && ancestorLayerIsInContainingBlockChain(*layer)) {
                 LayoutRect adjustedClipRect = LayoutRect(toLayoutPoint(layer->offsetFromAncestor(paintingInfo.rootLayer, AdjustForColumns)), layer->size());
                 adjustedClipRect.move(paintingInfo.subpixelOffset);
                 FloatRoundedRect roundedRect = layer->renderer().style().getRoundedInnerBorderFor(adjustedClipRect).pixelSnappedRoundedRectForPainting(deviceScaleFactor);
@@ -4020,19 +4069,31 @@ static inline bool paintForFixedRootBackground(const RenderLayer* layer, OptionS
 
 void RenderLayer::paintLayer(GraphicsContext& context, const LayerPaintingInfo& paintingInfo, OptionSet<PaintLayerFlag> paintFlags)
 {
-    if (isComposited()) {
-        // The performingPaintInvalidation() painting pass goes through compositing layers,
-        // but we need to ensure that we don't cache clip rects computed with the wrong root in this case.
-        if (context.performingPaintInvalidation() || (paintingInfo.paintBehavior & PaintBehavior::FlattenCompositingLayers))
-            paintFlags.add(PaintLayerTemporaryClipRects);
-        else if (!backing()->paintsIntoWindow()
-            && !backing()->paintsIntoCompositedAncestor()
-            && !shouldDoSoftwarePaint(this, paintFlags.contains(PaintLayerPaintingReflection))
-            && !paintForFixedRootBackground(this, paintFlags)) {
-            // If this RenderLayer should paint into its backing, that will be done via RenderLayerBacking::paintIntoLayer().
+    auto shouldContinuePaint = [&] () {
+        return backing()->paintsIntoWindow()
+            || backing()->paintsIntoCompositedAncestor()
+            || shouldDoSoftwarePaint(this, paintFlags.contains(PaintLayerPaintingReflection))
+            || paintForFixedRootBackground(this, paintFlags);
+    };
+
+    auto paintsIntoDifferentCompositedDestination = [&]() {
+        if (paintsIntoProvidedBacking())
+            return true;
+    
+        if (isComposited() && !shouldContinuePaint())
+            return true;
+
+        return false;
+    };
+    
+    if (paintsIntoDifferentCompositedDestination()) {
+        if (!context.performingPaintInvalidation() && !(paintingInfo.paintBehavior & PaintBehavior::FlattenCompositingLayers))
             return;
-        }
-    } else if (viewportConstrainedNotCompositedReason() == NotCompositedForBoundsOutOfView) {
+
+        paintFlags.add(PaintLayerTemporaryClipRects);
+    }
+
+    if (viewportConstrainedNotCompositedReason() == NotCompositedForBoundsOutOfView) {
         // Don't paint out-of-view viewport constrained layers (when doing prepainting) because they will never be visible
         // unless their position or viewport size is changed.
         ASSERT(renderer().isFixedPositioned());
@@ -5440,7 +5501,7 @@ Ref<ClipRects> RenderLayer::updateClipRects(const ClipRectsContext& clipRectsCon
     // For transformed layers, the root layer was shifted to be us, so there is no need to
     // examine the parent. We want to cache clip rects with us as the root.
     if (auto* parentLayer = (clipRectsContext.rootLayer != this ? parent() : nullptr))
-        parentClipRects = parentLayer->updateClipRects(clipRectsContext);
+        parentClipRects = this->parentClipRects(clipRectsContext);
 
     auto clipRects = ClipRects::create();
     calculateClipRects(clipRectsContext, clipRects);
@@ -5461,6 +5522,12 @@ ClipRects* RenderLayer::clipRects(const ClipRectsContext& context) const
     return m_clipRectsCache->getClipRects(context.clipRectsType, context.respectOverflowClip);
 }
 
+bool RenderLayer::clipCrossesPaintingBoundary() const
+{
+    return parent()->enclosingPaginationLayer(IncludeCompositedPaginatedLayers) != enclosingPaginationLayer(IncludeCompositedPaginatedLayers)
+        || parent()->enclosingCompositingLayerForRepaint() != enclosingCompositingLayerForRepaint();
+}
+
 void RenderLayer::calculateClipRects(const ClipRectsContext& clipRectsContext, ClipRects& clipRects) const
 {
     if (!parent()) {
@@ -5483,6 +5550,10 @@ void RenderLayer::calculateClipRects(const ClipRectsContext& clipRectsContext, C
         else {
             ClipRectsContext parentContext(clipRectsContext);
             parentContext.overlayScrollbarSizeRelevancy = IgnoreOverlayScrollbarSize; // FIXME: why?
+            
+            if (clipCrossesPaintingBoundary())
+                parentContext.clipRectsType = TemporaryClipRects;
+
             parentLayer->calculateClipRects(parentContext, clipRects);
         }
     } else
@@ -5534,10 +5605,19 @@ Ref<ClipRects> RenderLayer::parentClipRects(const ClipRectsContext& clipRectsCon
 {
     ASSERT(parent());
 
-    if (clipRectsContext.clipRectsType == TemporaryClipRects) {
+    auto temporaryParentClipRects = [&](const ClipRectsContext& clipContext) {
         auto parentClipRects = ClipRects::create();
-        parent()->calculateClipRects(clipRectsContext, parentClipRects);
+        parent()->calculateClipRects(clipContext, parentClipRects);
         return parentClipRects;
+    };
+
+    if (clipRectsContext.clipRectsType == TemporaryClipRects)
+        return temporaryParentClipRects(clipRectsContext);
+
+    if (clipCrossesPaintingBoundary()) {
+        ClipRectsContext tempClipRectsContext(clipRectsContext);
+        tempClipRectsContext.clipRectsType = TemporaryClipRects;
+        return temporaryParentClipRects(tempClipRectsContext);
     }
 
     return parent()->updateClipRects(clipRectsContext);
@@ -5557,21 +5637,7 @@ static inline ClipRect backgroundClipRectForPosition(const ClipRects& parentRect
 ClipRect RenderLayer::backgroundClipRect(const ClipRectsContext& clipRectsContext) const
 {
     ASSERT(parent());
-    auto computeParentRects = [&] {
-        if (clipRectsContext.clipRectsType == TemporaryClipRects)
-            return parentClipRects(clipRectsContext);
-        // If we cross into a different composition/pagination context, then we can't rely on the cache since the root layer differs.
-        bool crossesPaginationBoundary = parent()->enclosingPaginationLayer(IncludeCompositedPaginatedLayers) != enclosingPaginationLayer(IncludeCompositedPaginatedLayers);
-        bool crossesCompositingBoundary = parent()->enclosingCompositingLayerForRepaint() != enclosingCompositingLayerForRepaint();
-        if (!crossesPaginationBoundary && !crossesCompositingBoundary)
-            return parentClipRects(clipRectsContext);
-
-        ClipRectsContext tempContext(clipRectsContext);
-        tempContext.clipRectsType = TemporaryClipRects;
-        return parentClipRects(tempContext);
-    };
-    
-    auto parentRects = computeParentRects();
+    auto parentRects = parentClipRects(clipRectsContext);
     ClipRect backgroundClipRect = backgroundClipRectForPosition(parentRects, renderer().style().position());
     RenderView& view = renderer().view();
     // Note: infinite clipRects should not be scrolled here, otherwise they will accidentally no longer be considered infinite.
@@ -5944,7 +6010,7 @@ LayoutRect RenderLayer::calculateLayerBounds(const RenderLayer* ancestorLayer, c
 #endif
 
     auto computeLayersUnion = [this, &unionBounds, flags, descendantFlags] (const RenderLayer& childLayer) {
-        if (!(flags & IncludeCompositedDescendants) && childLayer.isComposited())
+        if (!(flags & IncludeCompositedDescendants) && (childLayer.isComposited() || childLayer.paintsIntoProvidedBacking()))
             return;
         LayoutRect childBounds = childLayer.calculateLayerBounds(this, childLayer.offsetFromAncestor(this), descendantFlags);
         // Ignore child layer (and behave as if we had overflow: hidden) when it is positioned off the parent layer so much
@@ -6791,7 +6857,7 @@ void showLayerTree(const WebCore::RenderObject* renderer)
 static void outputPaintOrderTreeLegend(TextStream& stream)
 {
     stream.nextLine();
-    stream << "(S)tacking Context/(F)orced SC/O(P)portunistic SC, (N)ormal flow only, (O)verflow clip, (A)lpha (opacity or mask), has (B)lend mode, (I)solates blending, (T)ransform-ish, (F)ilter, Fi(X)ed position, (C)omposited, (c)omposited descendant, (s)scrolling ancestor\n"
+    stream << "(S)tacking Context/(F)orced SC/O(P)portunistic SC, (N)ormal flow only, (O)verflow clip, (A)lpha (opacity or mask), has (B)lend mode, (I)solates blending, (T)ransform-ish, (F)ilter, Fi(X)ed position, (C)omposited, (P)rovides backing/uses (p)rovided backing, (c)omposited descendant, (s)scrolling ancestor\n"
         "Dirty (z)-lists, Dirty (n)ormal flow lists\n"
         "Traversal needs: requirements (t)raversal on descendants, (b)acking or hierarchy traversal on descendants, (r)equirements traversal on all descendants, requirements traversal on all (s)ubsequent layers, (h)ierarchy traversal on all descendants, update of paint (o)rder children\n"
         "Update needs:    post-(l)ayout requirements, (g)eometry, (k)ids geometry, (c)onfig, layer conne(x)ion, (s)crolling tree\n";
@@ -6817,6 +6883,7 @@ static void outputPaintOrderTreeRecursive(TextStream& stream, const WebCore::Ren
     stream << (layer.hasFilter() ? "F" : "-");
     stream << (layer.renderer().isFixedPositioned() ? "X" : "-");
     stream << (layer.isComposited() ? "C" : "-");
+    stream << ((layer.isComposited() && layer.backing()->hasBackingSharingLayers()) ? "P" : (layer.paintsIntoProvidedBacking() ? "p" : "-"));
     stream << (layer.hasCompositingDescendant() ? "c" : "-");
     stream << (layer.hasCompositedScrollingAncestor() ? "s" : "-");
 
index 7aad196..da4beb9 100644 (file)
@@ -603,6 +603,8 @@ public:
     // Part of the issue is with subtree relayout: we don't check if our ancestors have some descendant flags dirty, missing some updates.
     bool hasSelfPaintingLayerDescendant() const { return m_hasSelfPaintingLayerDescendant; }
 
+    bool ancestorLayerIsInContainingBlockChain(const RenderLayer& ancestor, const RenderLayer* checkLimit = nullptr) const;
+
     // Gets the nearest enclosing positioned ancestor layer (also includes
     // the <html> layer and the root layer).
     RenderLayer* enclosingAncestorForPosition(PositionType) const;
@@ -701,6 +703,8 @@ public:
     LayoutRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space.
     LayoutRect localClipRect(bool& clipExceedsBounds) const; // Returns the background clip rect of the layer in the local coordinate space.
 
+    bool clipCrossesPaintingBoundary() const;
+
     // Pass offsetFromRoot if known.
     bool intersectsDamageRect(const LayoutRect& layerBounds, const LayoutRect& damageRect, const RenderLayer* rootLayer, const LayoutSize& offsetFromRoot, const LayoutRect* cachedBoundingBox = nullptr) const;
 
@@ -813,6 +817,13 @@ public:
     bool hasCompositingDescendant() const { return m_hasCompositingDescendant; }
     bool hasCompositedMask() const;
 
+    // If non-null, a non-ancestor composited layer that this layer paints into (it is sharing its backing store with this layer).
+    RenderLayer* backingProviderLayer() const { return m_backingProviderLayer.get(); }
+    void setBackingProviderLayer(RenderLayer*);
+    void disconnectFromBackingProviderLayer();
+
+    bool paintsIntoProvidedBacking() const { return !!m_backingProviderLayer; }
+
     RenderLayerBacking* backing() const { return m_backing.get(); }
     RenderLayerBacking* ensureBacking();
     void clearBacking(bool layerBeingDestroyed = false);
@@ -1257,6 +1268,8 @@ private:
     RenderLayer* m_first { nullptr };
     RenderLayer* m_last { nullptr };
 
+    WeakPtr<RenderLayer> m_backingProviderLayer;
+
     // For layers that establish stacking contexts, m_posZOrderList holds a sorted list of all the
     // descendant layers within the stacking context that have z-indices of 0 or greater
     // (auto will count as 0). m_negZOrderList holds descendants within our stacking context with negative
index 1921292..0ed800c 100644 (file)
@@ -259,6 +259,10 @@ void RenderLayerBacking::willBeDestroyed()
 {
     ASSERT(m_owningLayer.backing() == this);
     compositor().removeFromScrollCoordinatedLayers(m_owningLayer);
+
+    LOG(Compositing, "RenderLayer(backing) %p willBeDestroyed", &m_owningLayer);
+
+    clearBackingSharingLayers();
 }
 
 void RenderLayerBacking::willDestroyLayer(const GraphicsLayer* layer)
@@ -267,6 +271,44 @@ void RenderLayerBacking::willDestroyLayer(const GraphicsLayer* layer)
         compositor().layerTiledBackingUsageChanged(layer, false);
 }
 
+static void clearBackingSharingLayerProviders(Vector<WeakPtr<RenderLayer>>& sharingLayers)
+{
+    for (auto& layerWeakPtr : sharingLayers) {
+        if (!layerWeakPtr)
+            continue;
+        layerWeakPtr->setBackingProviderLayer(nullptr);
+    }
+}
+
+void RenderLayerBacking::setBackingSharingLayers(Vector<WeakPtr<RenderLayer>>&& sharingLayers)
+{
+    if (m_backingSharingLayers == sharingLayers) {
+        sharingLayers.clear();
+        return;
+    }
+
+    clearBackingSharingLayerProviders(m_backingSharingLayers);
+    m_backingSharingLayers = WTFMove(sharingLayers);
+    for (auto& layerWeakPtr : m_backingSharingLayers)
+        layerWeakPtr->setBackingProviderLayer(&m_owningLayer);
+}
+
+void RenderLayerBacking::removeBackingSharingLayer(RenderLayer& layer)
+{
+    LOG(Compositing, "RenderLayer %p removeBackingSharingLayer %p", &m_owningLayer, &layer);
+
+    layer.setBackingProviderLayer(nullptr);
+    m_backingSharingLayers.removeAll(&layer);
+}
+
+void RenderLayerBacking::clearBackingSharingLayers()
+{
+    LOG(Compositing, "RenderLayer %p clearBackingSharingLayers", &m_owningLayer);
+
+    clearBackingSharingLayerProviders(m_backingSharingLayers);
+    m_backingSharingLayers.clear();
+}
+
 Ref<GraphicsLayer> RenderLayerBacking::createGraphicsLayer(const String& name, GraphicsLayer::Type layerType)
 {
     auto* graphicsLayerFactory = renderer().page().chrome().client().graphicsLayerFactory();
@@ -606,7 +648,7 @@ static bool hasNonZeroTransformOrigin(const RenderObject& renderer)
 
 bool RenderLayerBacking::updateCompositedBounds()
 {
-    LayoutRect layerBounds = m_owningLayer.calculateLayerBounds(&m_owningLayer, LayoutSize(), RenderLayer::defaultCalculateLayerBoundsFlags() | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask);
+    LayoutRect layerBounds = m_owningLayer.calculateLayerBounds(&m_owningLayer, { }, RenderLayer::defaultCalculateLayerBoundsFlags() | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask);
     // Clip to the size of the document or enclosing overflow-scroll layer.
     // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
     // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
@@ -628,7 +670,15 @@ bool RenderLayerBacking::updateCompositedBounds()
 
         layerBounds.intersect(clippingBounds);
     }
-    
+
+    for (auto& layerWeakPtr : m_backingSharingLayers) {
+        auto* boundsRootLayer = &m_owningLayer;
+        ASSERT(layerWeakPtr->isDescendantOf(m_owningLayer));
+        auto offset = layerWeakPtr->offsetFromAncestor(&m_owningLayer);
+        auto bounds = layerWeakPtr->calculateLayerBounds(boundsRootLayer, offset, RenderLayer::defaultCalculateLayerBoundsFlags() | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask);
+        layerBounds.unite(bounds);
+    }
+
     // If the element has a transform-origin that has fixed lengths, and the renderer has zero size,
     // then we need to ensure that the compositing layer has non-zero size so that we can apply
     // the transform-origin via the GraphicsLayer anchorPoint (which is expressed as a fractional value).
@@ -1397,7 +1447,7 @@ void RenderLayerBacking::updateDrawsContent(PaintedContentsInfo& contentsInfo)
         bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasVisibleBoxDecorationsOrBackground();
         m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
 
-        bool hasScrollingPaintedContent = m_owningLayer.hasVisibleContent() && (renderer().hasBackground() || contentsInfo.paintsContent());
+        bool hasScrollingPaintedContent = hasBackingSharingLayers() || (m_owningLayer.hasVisibleContent() && (renderer().hasBackground() || contentsInfo.paintsContent()));
         m_scrolledContentsLayer->setDrawsContent(hasScrollingPaintedContent);
         return;
     }
@@ -2133,6 +2183,9 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer(PaintedContentsInfo&
     if (m_owningLayer.isRenderViewLayer())
         return false;
 
+    if (hasBackingSharingLayers())
+        return false;
+
     if (renderer().isRenderReplaced() && (!isCompositedPlugin(renderer()) || isRestartedPlugin(renderer())))
         return false;
 
@@ -2603,23 +2656,46 @@ void RenderLayerBacking::paintIntoLayer(const GraphicsLayer* graphicsLayer, Grap
     RenderElement::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(&renderer());
 #endif
 
-    FrameView::PaintingState paintingState;
-    if (m_owningLayer.isRenderViewLayer())
-        renderer().view().frameView().willPaintContents(context, paintDirtyRect, paintingState);
+    auto paintOneLayer = [&](RenderLayer& layer, OptionSet<RenderLayer::PaintLayerFlag> paintFlags) {
+        InspectorInstrumentation::willPaint(layer.renderer());
 
-    RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, -m_subpixelOffsetFromRenderer);
+        FrameView::PaintingState paintingState;
+        if (layer.isRenderViewLayer())
+            renderer().view().frameView().willPaintContents(context, paintDirtyRect, paintingState);
 
-    m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags);
+        RenderLayer::LayerPaintingInfo paintingInfo(&m_owningLayer, paintDirtyRect, paintBehavior, -m_subpixelOffsetFromRenderer);
 
-    if (m_owningLayer.containsDirtyOverlayScrollbars())
-        m_owningLayer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
+        layer.paintLayerContents(context, paintingInfo, paintFlags);
 
-    if (m_owningLayer.isRenderViewLayer())
-        renderer().view().frameView().didPaintContents(context, paintDirtyRect, paintingState);
+        if (layer.containsDirtyOverlayScrollbars())
+            layer.paintLayerContents(context, paintingInfo, paintFlags | RenderLayer::PaintLayerPaintingOverlayScrollbars);
 
-    compositor().didPaintBacking(this);
+        if (layer.isRenderViewLayer())
+            renderer().view().frameView().didPaintContents(context, paintDirtyRect, paintingState);
+
+        ASSERT(!m_owningLayer.m_usedTransparency);
 
-    ASSERT(!m_owningLayer.m_usedTransparency);
+        InspectorInstrumentation::didPaint(layer.renderer(), paintDirtyRect);
+    };
+
+    paintOneLayer(m_owningLayer, paintFlags);
+    
+    // FIXME: Need to check m_foregroundLayer, masking etc. webkit.org/b/197565.
+    GraphicsLayer* destinationForSharingLayers = m_scrolledContentsLayer ? m_scrolledContentsLayer.get() : m_graphicsLayer.get();
+
+    if (graphicsLayer == destinationForSharingLayers) {
+        OptionSet<RenderLayer::PaintLayerFlag> sharingLayerPaintFlags = {
+            RenderLayer::PaintLayerPaintingCompositingBackgroundPhase,
+            RenderLayer::PaintLayerPaintingCompositingForegroundPhase };
+
+        if (paintingPhase & GraphicsLayerPaintOverflowContents)
+            sharingLayerPaintFlags.add(RenderLayer::PaintLayerPaintingOverflowContents);
+
+        for (auto& layerWeakPtr : m_backingSharingLayers)
+            paintOneLayer(*layerWeakPtr, sharingLayerPaintFlags);
+    }
+
+    compositor().didPaintBacking(this);
 }
 
 // Up-call from compositing layer drawing callback.
@@ -2647,7 +2723,6 @@ void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, Graph
         || graphicsLayer == m_maskLayer.get()
         || graphicsLayer == m_childClippingMaskLayer.get()
         || graphicsLayer == m_scrolledContentsLayer.get()) {
-        InspectorInstrumentation::willPaint(renderer());
 
         if (!(paintingPhase & GraphicsLayerPaintOverflowContents))
             dirtyRect.intersect(enclosingIntRect(compositedBoundsIncludingMargin()));
@@ -2661,21 +2736,18 @@ void RenderLayerBacking::paintContents(const GraphicsLayer* graphicsLayer, Graph
             behavior.add(PaintBehavior::TileFirstPaint);
 
         paintIntoLayer(graphicsLayer, context, dirtyRect, behavior, paintingPhase);
-
-        InspectorInstrumentation::didPaint(renderer(), dirtyRect);
     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
         paintScrollbar(m_owningLayer.horizontalScrollbar(), context, dirtyRect);
     } else if (graphicsLayer == layerForVerticalScrollbar()) {
         paintScrollbar(m_owningLayer.verticalScrollbar(), context, dirtyRect);
     } else if (graphicsLayer == layerForScrollCorner()) {
         const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollCornerAndResizerRect();
-        context.save();
+        GraphicsContextStateSaver stateSaver(context);
         context.translate(-scrollCornerAndResizer.location());
         LayoutRect transformedClip = LayoutRect(clip);
         transformedClip.moveBy(scrollCornerAndResizer.location());
         m_owningLayer.paintScrollCorner(context, IntPoint(), snappedIntRect(transformedClip));
         m_owningLayer.paintResizer(context, IntPoint(), transformedClip);
-        context.restore();
     }
 #ifndef NDEBUG
     renderer().page().setIsPainting(false);
index 4c57146..28d5a78 100644 (file)
@@ -69,6 +69,15 @@ public:
 
     RenderLayer& owningLayer() const { return m_owningLayer; }
 
+    // Included layers are non-z-order descendant layers that are painted into this backing.
+    const Vector<WeakPtr<RenderLayer>>& backingSharingLayers() const { return m_backingSharingLayers; }
+    void setBackingSharingLayers(Vector<WeakPtr<RenderLayer>>&&);
+
+    bool hasBackingSharingLayers() const { return !m_backingSharingLayers.isEmpty(); }
+
+    void removeBackingSharingLayer(RenderLayer&);
+    void clearBackingSharingLayers();
+
     void updateConfigurationAfterStyleChange();
 
     // Returns true if layer configuration changed.
@@ -387,6 +396,9 @@ private:
 
     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.
     RefPtr<GraphicsLayer> m_contentsContainmentLayer; // Only used if we have a background layer; takes the transform.
     RefPtr<GraphicsLayer> m_graphicsLayer;
index 3c6f90f..e3a4c9f 100644 (file)
@@ -232,23 +232,43 @@ struct RenderLayerCompositor::CompositingState {
     {
     }
     
-    CompositingState(const CompositingState& other)
-        : compositingAncestor(other.compositingAncestor)
-        , subtreeIsCompositing(other.subtreeIsCompositing)
-        , testingOverlap(other.testingOverlap)
-        , fullPaintOrderTraversalRequired(other.fullPaintOrderTraversalRequired)
-        , descendantsRequireCompositingUpdate(other.descendantsRequireCompositingUpdate)
-        , ancestorHasTransformAnimation(other.ancestorHasTransformAnimation)
+    CompositingState stateForPaintOrderChildren(RenderLayer& layer) const
+    {
+        UNUSED_PARAM(layer);
+        CompositingState childState(compositingAncestor);
+        if (layer.isStackingContext())
+            childState.stackingContextAncestor = &layer;
+        else
+            childState.stackingContextAncestor = stackingContextAncestor;
+
+        childState.subtreeIsCompositing = false;
+        childState.testingOverlap = testingOverlap;
+        childState.fullPaintOrderTraversalRequired = fullPaintOrderTraversalRequired;
+        childState.descendantsRequireCompositingUpdate = descendantsRequireCompositingUpdate;
+        childState.ancestorHasTransformAnimation = ancestorHasTransformAnimation;
 #if ENABLE(CSS_COMPOSITING)
-        , hasNotIsolatedCompositedBlendingDescendants(other.hasNotIsolatedCompositedBlendingDescendants)
+        childState.hasNotIsolatedCompositedBlendingDescendants = false; // FIXME: should this only be reset for stacking contexts?
 #endif
 #if ENABLE(TREE_DEBUGGING)
-        , depth(other.depth + 1)
+        childState.depth = depth + 1;
 #endif
+        return childState;
+    }
+
+    void propagateStateFromChildren(const CompositingState& childState)
     {
+        // Subsequent layers in the parent stacking context also need to composite.
+        subtreeIsCompositing |= childState.subtreeIsCompositing;
+        fullPaintOrderTraversalRequired |= childState.fullPaintOrderTraversalRequired;
     }
-    
+
+    void propagateStateFromChildrenForUnchangedSubtree(const CompositingState& childState)
+    {
+        subtreeIsCompositing |= childState.subtreeIsCompositing;
+    }
+
     RenderLayer* compositingAncestor;
+    RenderLayer* stackingContextAncestor { nullptr };
     bool subtreeIsCompositing { false };
     bool testingOverlap { true };
     bool fullPaintOrderTraversalRequired { false };
@@ -262,6 +282,22 @@ struct RenderLayerCompositor::CompositingState {
 #endif
 };
 
+struct RenderLayerCompositor::BackingSharingState {
+    RenderLayer* backingProviderCandidate { nullptr };
+    RenderLayer* backingProviderStackingContext { nullptr };
+    Vector<WeakPtr<RenderLayer>> backingSharingLayers;
+
+    void resetBackingProviderCandidate(RenderLayer* candidateLayer = nullptr, RenderLayer* candidateStackingContext = nullptr)
+    {
+        if (!backingSharingLayers.isEmpty()) {
+            ASSERT(backingProviderCandidate);
+            backingProviderCandidate->backing()->setBackingSharingLayers(WTFMove(backingSharingLayers));
+        }
+        backingProviderCandidate = candidateLayer;
+        backingProviderStackingContext = candidateLayer ? candidateStackingContext : nullptr;
+    }
+};
+
 struct RenderLayerCompositor::OverlapExtent {
     LayoutRect bounds;
     bool extentComputed { false };
@@ -765,10 +801,11 @@ bool RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
     // FIXME: optimize root-only update.
     if (updateRoot->hasDescendantNeedingCompositingRequirementsTraversal() || updateRoot->needsCompositingRequirementsTraversal()) {
         CompositingState compositingState(updateRoot);
+        BackingSharingState backingSharingState;
         OverlapMap overlapMap;
 
         bool descendantHas3DTransform = false;
-        computeCompositingRequirements(nullptr, rootRenderLayer(), overlapMap, compositingState, descendantHas3DTransform);
+        computeCompositingRequirements(nullptr, rootRenderLayer(), overlapMap, compositingState, backingSharingState, descendantHas3DTransform);
     }
 
     LOG(Compositing, "\nRenderLayerCompositor::updateCompositingLayers - mid");
@@ -821,15 +858,23 @@ bool RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update
     return true;
 }
 
-void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer& layer, OverlapMap& overlapMap, CompositingState& compositingState, bool& descendantHas3DTransform)
+static bool backingProviderLayerCanIncludeLayer(const RenderLayer& sharedLayer, const RenderLayer& layer)
 {
-    if (!layer.hasDescendantNeedingCompositingRequirementsTraversal() && !layer.needsCompositingRequirementsTraversal() && !compositingState.fullPaintOrderTraversalRequired && !compositingState.descendantsRequireCompositingUpdate) {
-        traverseUnchangedSubtree(ancestorLayer, layer, overlapMap, compositingState, descendantHas3DTransform);
+    return layer.ancestorLayerIsInContainingBlockChain(sharedLayer);
+}
+
+void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer& layer, OverlapMap& overlapMap, CompositingState& compositingState, BackingSharingState& backingSharingState, bool& descendantHas3DTransform)
+{
+    if (!layer.hasDescendantNeedingCompositingRequirementsTraversal()
+        && !layer.needsCompositingRequirementsTraversal()
+        && !compositingState.fullPaintOrderTraversalRequired
+        && !compositingState.descendantsRequireCompositingUpdate) {
+        traverseUnchangedSubtree(ancestorLayer, layer, overlapMap, compositingState, backingSharingState, descendantHas3DTransform);
         return;
     }
 
 #if ENABLE(TREE_DEBUGGING)
-    LOG(Compositing, "%*p computeCompositingRequirements", 12 + compositingState.depth * 2, &layer);
+    LOG(Compositing, "%*p %s computeCompositingRequirements (backing provider candidate %p)", 12 + compositingState.depth * 2, &layer, layer.isNormalFlowOnly() ? "n" : "s", backingSharingState.backingProviderCandidate);
 #endif
 
     // FIXME: maybe we can avoid updating all remaining layers in paint order.
@@ -840,6 +885,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
     layer.updateLayerListsIfNeeded();
 
     layer.setHasCompositingDescendant(false);
+    layer.setBackingProviderLayer(nullptr);
 
     // We updated compositing for direct reasons in layerStyleChanged(). Here, check for compositing that can only be evaluated after layout.
     RequiresCompositingData queryData;
@@ -861,12 +907,23 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
     overlapMap.geometryMap().pushMappingsToAncestor(&layer, ancestorLayer, respectTransforms);
 
     RenderLayer::IndirectCompositingReason compositingReason = compositingState.subtreeIsCompositing ? RenderLayer::IndirectCompositingReason::Stacking : RenderLayer::IndirectCompositingReason::None;
+    bool layerPaintsIntoProvidedBacking = false;
 
     // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map
     if (!willBeComposited && !overlapMap.isEmpty() && compositingState.testingOverlap) {
         computeExtent(overlapMap, layer, layerExtent);
+
         // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
-        compositingReason = overlapMap.overlapsLayers(layerExtent.bounds) ? RenderLayer::IndirectCompositingReason::Overlap : RenderLayer::IndirectCompositingReason::None;
+        if (overlapMap.overlapsLayers(layerExtent.bounds)) {
+            if (backingSharingState.backingProviderCandidate && backingProviderLayerCanIncludeLayer(*backingSharingState.backingProviderCandidate, layer)) {
+                backingSharingState.backingSharingLayers.append(makeWeakPtr(layer));
+                LOG(Compositing, " layer %p can share with %p", &layer, backingSharingState.backingProviderCandidate);
+                compositingReason = RenderLayer::IndirectCompositingReason::None;
+                layerPaintsIntoProvidedBacking = true;
+            } else
+                compositingReason = RenderLayer::IndirectCompositingReason::Overlap;
+        } else
+            compositingReason = RenderLayer::IndirectCompositingReason::None;
     }
 
 #if ENABLE(VIDEO)
@@ -888,27 +945,42 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
     // The children of this layer don't need to composite, unless there is
     // a compositing layer among them, so start by inheriting the compositing
     // ancestor with subtreeIsCompositing set to false.
-    CompositingState childState(compositingState);
-    childState.subtreeIsCompositing = false;
-#if ENABLE(CSS_COMPOSITING)
-    childState.hasNotIsolatedCompositedBlendingDescendants = false;
-#endif
+    CompositingState childState = compositingState.stateForPaintOrderChildren(layer);
 
-    if (willBeComposited) {
-        // Tell the parent it has compositing descendants.
-        compositingState.subtreeIsCompositing = true;
+    auto layerWillComposite = [&](bool postDescendants = false) {
         // This layer now acts as the ancestor for kids.
         childState.compositingAncestor = &layer;
-
         overlapMap.pushCompositingContainer();
+        
+        if (postDescendants) {
+            childState.subtreeIsCompositing = true;
+            addToOverlapMapRecursive(overlapMap, layer);
+        }
+
         // This layer is going to be composited, so children can safely ignore the fact that there's an
         // animation running behind this layer, meaning they can rely on the overlap map testing again.
         childState.testingOverlap = true;
+        willBeComposited = true;
+
+        layerPaintsIntoProvidedBacking = false;
+        layer.disconnectFromBackingProviderLayer();
+        backingSharingState.backingSharingLayers.removeAll(&layer);
+    };
+
+    if (willBeComposited) {
+        // Tell the parent it has compositing descendants.
+        compositingState.subtreeIsCompositing = true;
+        
+        layerWillComposite();
 
         computeExtent(overlapMap, layer, layerExtent);
         childState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation;
         // Too hard to compute animated bounds if both us and some ancestor is animating transform.
         layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation;
+
+        // Compositing for any reason disables backing sharing.
+        LOG_WITH_STREAM(Compositing, stream << &layer << " is compositing - flushing sharing to " << backingSharingState.backingProviderCandidate << " with " << backingSharingState.backingSharingLayers.size() << " sharing layers");
+        backingSharingState.resetBackingProviderCandidate();
     }
 
 #if !ASSERT_DISABLED
@@ -918,27 +990,22 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
     bool anyDescendantHas3DTransform = false;
 
     for (auto* childLayer : layer.negativeZOrderLayers()) {
-        computeCompositingRequirements(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
+        computeCompositingRequirements(&layer, *childLayer, overlapMap, childState, backingSharingState, anyDescendantHas3DTransform);
 
         // If we have to make a layer for this child, make one now so we can have a contents layer
         // (since we need to ensure that the -ve z-order child renders underneath our contents).
         if (!willBeComposited && childState.subtreeIsCompositing) {
             // make layer compositing
             layer.setIndirectCompositingReason(RenderLayer::IndirectCompositingReason::BackgroundLayer);
-            childState.compositingAncestor = &layer;
-            overlapMap.pushCompositingContainer();
-            // This layer is going to be composited, so children can safely ignore the fact that there's an
-            // animation running behind this layer, meaning they can rely on the overlap map testing again
-            childState.testingOverlap = true;
-            willBeComposited = true;
+            layerWillComposite();
         }
     }
     
     for (auto* childLayer : layer.normalFlowLayers())
-        computeCompositingRequirements(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
+        computeCompositingRequirements(&layer, *childLayer, overlapMap, childState, backingSharingState, anyDescendantHas3DTransform);
 
     for (auto* childLayer : layer.positiveZOrderLayers())
-        computeCompositingRequirements(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
+        computeCompositingRequirements(&layer, *childLayer, overlapMap, childState, backingSharingState, anyDescendantHas3DTransform);
 
     // If we just entered compositing mode, the root will have become composited (as long as accelerated compositing is enabled).
     if (layer.isRenderViewLayer()) {
@@ -967,13 +1034,9 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
     // Now check for reasons to become composited that depend on the state of descendant layers.
     RenderLayer::IndirectCompositingReason indirectCompositingReason;
     if (!willBeComposited && canBeComposited(layer)
-        && requiresCompositingForIndirectReason(layer.renderer(), compositingState.compositingAncestor, childState.subtreeIsCompositing, anyDescendantHas3DTransform, indirectCompositingReason)) {
+        && requiresCompositingForIndirectReason(layer, compositingState.compositingAncestor, childState.subtreeIsCompositing, anyDescendantHas3DTransform, layerPaintsIntoProvidedBacking, indirectCompositingReason)) {
         layer.setIndirectCompositingReason(indirectCompositingReason);
-        childState.compositingAncestor = &layer;
-        childState.subtreeIsCompositing = true;
-        overlapMap.pushCompositingContainer();
-        addToOverlapMapRecursive(overlapMap, layer);
-        willBeComposited = true;
+        layerWillComposite(true);
     }
     
     if (layer.reflectionLayer()) {
@@ -993,15 +1056,8 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
     if ((!childState.testingOverlap && !isCompositedClippingLayer) || layerExtent.knownToBeHaveExtentUncertainty())
         compositingState.testingOverlap = false;
     
-    if (isCompositedClippingLayer) {
-        if (!willBeComposited) {
-            childState.compositingAncestor = &layer;
-            childState.subtreeIsCompositing = true;
-            overlapMap.pushCompositingContainer();
-            addToOverlapMapRecursive(overlapMap, layer);
-            willBeComposited = true;
-        }
-    }
+    if (isCompositedClippingLayer & !willBeComposited)
+        layerWillComposite(true);
 
 #if ENABLE(CSS_COMPOSITING)
     if ((willBeComposited && layer.hasBlendMode()) || (layer.hasNotIsolatedCompositedBlendingDescendants() && !layer.isolatesCompositedBlending()))
@@ -1023,9 +1079,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
 #endif
     }
 
-    // Subsequent layers in the parent stacking context also need to composite.
-    compositingState.subtreeIsCompositing |= childState.subtreeIsCompositing;
-    compositingState.fullPaintOrderTraversalRequired |= childState.fullPaintOrderTraversalRequired;
+    compositingState.propagateStateFromChildren(childState);
 
     ASSERT(willBeComposited == needsToBeComposited(layer, queryData));
 
@@ -1037,6 +1091,16 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
         layer.setChildrenNeedCompositingGeometryUpdate();
         // The composited bounds of enclosing layers depends on which descendants are composited, so they need a geometry update.
         layer.setNeedsCompositingGeometryUpdateOnAncestors();
+    } else if (layer.isComposited())
+        layer.backing()->clearBackingSharingLayers();
+
+    if (backingSharingState.backingProviderCandidate && &layer == backingSharingState.backingProviderStackingContext) {
+        LOG_WITH_STREAM(Compositing, stream << &layer << " popping stacking context " << backingSharingState.backingProviderStackingContext << ", flushing candidate " << backingSharingState.backingProviderCandidate << " with " << backingSharingState.backingSharingLayers.size() << " sharing layers");
+        backingSharingState.resetBackingProviderCandidate();
+    } else if (!backingSharingState.backingProviderCandidate && layer.isComposited()) {
+        LOG_WITH_STREAM(Compositing, stream << &layer << " compositing - sharing candidate " << backingSharingState.backingProviderCandidate << " with " << backingSharingState.backingSharingLayers.size() << " sharing layers");
+        // Flush out any earlier candidate in this stacking context. This layer becomes a candidate.
+        backingSharingState.resetBackingProviderCandidate(&layer, compositingState.stackingContextAncestor);
     }
 
     if (layer.reflectionLayer() && updateLayerCompositingState(*layer.reflectionLayer(), queryData, CompositingChangeRepaintNow))
@@ -1051,7 +1115,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
     }
 
 #if ENABLE(TREE_DEBUGGING)
-    LOG(Compositing, "%*p computeCompositingRequirements - willBeComposited %d", 12 + compositingState.depth * 2, &layer, willBeComposited);
+    LOG(Compositing, "%*p computeCompositingRequirements - willBeComposited %d (backing provider candidate %p)", 12 + compositingState.depth * 2, &layer, willBeComposited, backingSharingState.backingProviderCandidate);
 #endif
 
     layer.clearCompositingRequirementsTraversalState();
@@ -1060,7 +1124,7 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor
 }
 
 // We have to traverse unchanged layers to fill in the overlap map.
-void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer, RenderLayer& layer, OverlapMap& overlapMap, CompositingState& compositingState, bool& descendantHas3DTransform)
+void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer, RenderLayer& layer, OverlapMap& overlapMap, CompositingState& compositingState, BackingSharingState& backingSharingState, bool& descendantHas3DTransform)
 {
     ASSERT(!compositingState.fullPaintOrderTraversalRequired);
     ASSERT(!layer.hasDescendantNeedingCompositingRequirementsTraversal());
@@ -1086,11 +1150,13 @@ void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer,
     if (!layerIsComposited && !overlapMap.isEmpty() && compositingState.testingOverlap)
         computeExtent(overlapMap, layer, layerExtent);
 
-    CompositingState childState(compositingState);
-    childState.subtreeIsCompositing = false;
-#if ENABLE(CSS_COMPOSITING)
-    childState.hasNotIsolatedCompositedBlendingDescendants = false;
-#endif
+    if (layer.paintsIntoProvidedBacking()) {
+        ASSERT(backingSharingState.backingProviderCandidate);
+        ASSERT(backingProviderLayerCanIncludeLayer(*backingSharingState.backingProviderCandidate, layer));
+        backingSharingState.backingSharingLayers.append(makeWeakPtr(layer));
+    }
+
+    CompositingState childState = compositingState.stateForPaintOrderChildren(layer);
 
     if (layerIsComposited) {
         // Tell the parent it has compositing descendants.
@@ -1107,6 +1173,10 @@ void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer,
         childState.ancestorHasTransformAnimation |= layerExtent.hasTransformAnimation;
         // Too hard to compute animated bounds if both us and some ancestor is animating transform.
         layerExtent.animationCausesExtentUncertainty |= layerExtent.hasTransformAnimation && compositingState.ancestorHasTransformAnimation;
+
+        // Compositing for any reason disables backing sharing.
+        LOG_WITH_STREAM(Compositing, stream << "tus: " << &layer << " is compositing - flushing sharing to " << backingSharingState.backingProviderCandidate << " with " << backingSharingState.backingSharingLayers.size() << " sharing layers");
+        backingSharingState.resetBackingProviderCandidate();
     }
 
 #if !ASSERT_DISABLED
@@ -1116,16 +1186,16 @@ void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer,
     bool anyDescendantHas3DTransform = false;
 
     for (auto* childLayer : layer.negativeZOrderLayers()) {
-        traverseUnchangedSubtree(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
+        traverseUnchangedSubtree(&layer, *childLayer, overlapMap, childState, backingSharingState, anyDescendantHas3DTransform);
         if (childState.subtreeIsCompositing)
             ASSERT(layerIsComposited);
     }
     
     for (auto* childLayer : layer.normalFlowLayers())
-        traverseUnchangedSubtree(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
+        traverseUnchangedSubtree(&layer, *childLayer, overlapMap, childState, backingSharingState, anyDescendantHas3DTransform);
 
     for (auto* childLayer : layer.positiveZOrderLayers())
-        traverseUnchangedSubtree(&layer, *childLayer, overlapMap, childState, anyDescendantHas3DTransform);
+        traverseUnchangedSubtree(&layer, *childLayer, overlapMap, childState, backingSharingState, anyDescendantHas3DTransform);
 
     // All layers (even ones that aren't being composited) need to get added to
     // the overlap map. Layers that do not composite will draw into their
@@ -1135,9 +1205,7 @@ void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer,
     if (childState.compositingAncestor && !childState.compositingAncestor->isRenderViewLayer())
         addToOverlapMap(overlapMap, layer, layerExtent);
 
-    // Subsequent layers in the parent stacking context also need to composite.
-    if (childState.subtreeIsCompositing)
-        compositingState.subtreeIsCompositing = true;
+    compositingState.propagateStateFromChildrenForUnchangedSubtree(childState);
 
     // Set the flag to say that this layer has compositing children.
     ASSERT(layer.hasCompositingDescendant() == childState.subtreeIsCompositing);
@@ -1163,6 +1231,18 @@ void RenderLayerCompositor::traverseUnchangedSubtree(RenderLayer* ancestorLayer,
     if (childState.compositingAncestor == &layer && !layer.isRenderViewLayer())
         overlapMap.popCompositingContainer();
 
+    if (layer.isComposited())
+        layer.backing()->clearBackingSharingLayers();
+
+    if (backingSharingState.backingProviderCandidate && &layer == backingSharingState.backingProviderStackingContext) {
+        LOG_WITH_STREAM(Compositing, stream << &layer << " tus: popping stacking context " << backingSharingState.backingProviderStackingContext << ", flushing candidate " << backingSharingState.backingProviderCandidate << " with " << backingSharingState.backingSharingLayers.size() << " sharing layers");
+        backingSharingState.resetBackingProviderCandidate();
+    } else if (!backingSharingState.backingProviderCandidate && layer.isComposited()) {
+        LOG_WITH_STREAM(Compositing, stream << &layer << " tus: compositing - sharing candidate " << backingSharingState.backingProviderCandidate << " with " << backingSharingState.backingSharingLayers.size() << " sharing layers");
+        // Flush out any earlier candidate in this stacking context. This layer becomes a candidate.
+        backingSharingState.resetBackingProviderCandidate(&layer, compositingState.stackingContextAncestor);
+    }
+
     descendantHas3DTransform |= anyDescendantHas3DTransform || layer.has3DTransform();
 
     ASSERT(!layer.needsCompositingRequirementsTraversal());
@@ -1581,6 +1661,8 @@ bool RenderLayerCompositor::updateBacking(RenderLayer& layer, RequiresCompositin
     }
 
     if (backingRequired == BackingRequired::Yes) {
+        layer.disconnectFromBackingProviderLayer();
+
         enableCompositingMode();
         
         if (!layer.backing()) {
@@ -1733,10 +1815,18 @@ void RenderLayerCompositor::layerWasAdded(RenderLayer&, RenderLayer&)
 
 void RenderLayerCompositor::layerWillBeRemoved(RenderLayer& parent, RenderLayer& child)
 {
-    if (!child.isComposited() || parent.renderer().renderTreeBeingDestroyed())
+    if (parent.renderer().renderTreeBeingDestroyed())
         return;
 
-    repaintInCompositedAncestor(child, child.backing()->compositedBounds()); // FIXME: do via dirty bits?
+    if (child.isComposited())
+        repaintInCompositedAncestor(child, child.backing()->compositedBounds()); // FIXME: do via dirty bits?
+    else if (child.paintsIntoProvidedBacking()) {
+        auto* backingProviderLayer = child.backingProviderLayer();
+        // FIXME: Optimize this repaint.
+        backingProviderLayer->setBackingNeedsRepaint();
+        backingProviderLayer->backing()->removeBackingSharingLayer(child);
+    } else
+        return;
 
     child.setNeedsCompositingLayerConnection();
 }
@@ -2799,12 +2889,11 @@ bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const Render
 }
 
 // FIXME: why doesn't this handle the clipping cases?
-bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderLayerModelObject& renderer, const RenderLayer* compositingAncestor, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason& reason) const
+bool RenderLayerCompositor::requiresCompositingForIndirectReason(const RenderLayer& layer, const RenderLayer* compositingAncestor, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, RenderLayer::IndirectCompositingReason& reason) const
 {
-    auto& layer = *renderer.layer();
-
     // When a layer has composited descendants, some effects, like 2d transforms, filters, masks etc must be implemented
     // via compositing so that they also apply to those composited descendants.
+    auto& renderer = layer.renderer();
     if (hasCompositedDescendants && (layer.isolatesCompositedBlending() || layer.transform() || renderer.createsGroup() || renderer.hasReflection())) {
         reason = RenderLayer::IndirectCompositingReason::GraphicalEffect;
         return true;
@@ -2824,7 +2913,7 @@ bool RenderLayerCompositor::requiresCompositingForIndirectReason(RenderLayerMode
         }
     }
 
-    if (renderer.isAbsolutelyPositioned() && compositingAncestor && layer.hasCompositedScrollingAncestor()) {
+    if (!paintsIntoProvidedBacking && renderer.isAbsolutelyPositioned() && compositingAncestor && layer.hasCompositedScrollingAncestor()) {
         if (layerContainingBlockCrossesCoordinatedScrollingBoundary(layer, *compositingAncestor)) {
             reason = RenderLayer::IndirectCompositingReason::OverflowScrollPositioning;
             return true;
index a5f94a0..54ca466 100644 (file)
@@ -369,6 +369,7 @@ public:
 private:
     class OverlapMap;
     struct CompositingState;
+    struct BackingSharingState;
     struct OverlapExtent;
 
     // Returns true if the policy changed.
@@ -410,8 +411,8 @@ private:
 
     void updateCompositingLayersTimerFired();
 
-    void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer&, OverlapMap&, CompositingState&, bool& descendantHas3DTransform);
-    void traverseUnchangedSubtree(RenderLayer* ancestorLayer, RenderLayer&, OverlapMap&, CompositingState&, bool& descendantHas3DTransform);
+    void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer&, OverlapMap&, CompositingState&, BackingSharingState&, bool& descendantHas3DTransform);
+    void traverseUnchangedSubtree(RenderLayer* ancestorLayer, RenderLayer&, OverlapMap&, CompositingState&, BackingSharingState&, bool& descendantHas3DTransform);
 
     enum class UpdateLevel {
         AllDescendants          = 1 << 0,
@@ -476,7 +477,7 @@ private:
     bool requiresCompositingForPosition(RenderLayerModelObject&, const RenderLayer&, RequiresCompositingData&) const;
     bool requiresCompositingForOverflowScrolling(const RenderLayer&, RequiresCompositingData&) const;
     bool requiresCompositingForEditableImage(RenderLayerModelObject&) const;
-    bool requiresCompositingForIndirectReason(RenderLayerModelObject&, const RenderLayer* compositingAncestor, bool hasCompositedDescendants, bool has3DTransformedDescendants, RenderLayer::IndirectCompositingReason&) const;
+    bool requiresCompositingForIndirectReason(const RenderLayer&, const RenderLayer* compositingAncestor, bool hasCompositedDescendants, bool has3DTransformedDescendants, bool paintsIntoProvidedBacking, RenderLayer::IndirectCompositingReason&) const;
 
     static bool layerContainingBlockCrossesCoordinatedScrollingBoundary(const RenderLayer&, const RenderLayer& compositedAncestor);
 
index 6f73c28..cfdd5ad 100644 (file)
@@ -654,7 +654,8 @@ static void writeLayer(TextStream& ts, const RenderLayer& layer, const LayoutRec
         if (layer.isComposited()) {
             ts << " (composited, bounds=" << layer.backing()->compositedBounds() << ", drawsContent=" << layer.backing()->graphicsLayer()->drawsContent()
                 << ", paints into ancestor=" << layer.backing()->paintsIntoCompositedAncestor() << ")";
-        }
+        } else if (layer.paintsIntoProvidedBacking())
+            ts << " (shared backing of " << layer.backingProviderLayer() << ")";
     }
 
 #if ENABLE(CSS_COMPOSITING)