WebKit Bugzilla
Attachment 370354 Details for
Bug 198091
: Layer flashing and poor perf during scrolling of message list on gmail.com and hotmail.com - overlap testing needs to constrained to clipping scopes
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-198091-20190521162731.patch (text/plain), 64.62 KB, created by
Simon Fraser (smfr)
on 2019-05-21 16:27:32 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Simon Fraser (smfr)
Created:
2019-05-21 16:27:32 PDT
Size:
64.62 KB
patch
obsolete
>Subversion Revision: 245597 >diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog >index 3223d0e91de1f3eda1604c81d342dc7351345977..8c66ed5b66577ccc9ed5288ddcd396d836a9ace4 100644 >--- a/Source/WebCore/ChangeLog >+++ b/Source/WebCore/ChangeLog >@@ -1,3 +1,81 @@ >+2019-05-21 Simon Fraser <simon.fraser@apple.com> >+ >+ Layer flashing and poor perf during scrolling of message list on gmail.com and hotmail.com - overlap testing needs to constrained to clipping scopes >+ https://bugs.webkit.org/show_bug.cgi?id=198091 >+ <rdar://problem/49403082> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ When overflow:scroll is scrolled asynchronously, we need to have already created compositing layers where necessary >+ for clipped-out layers in the scrolled content so that we have something to reveal. We also have ensure >+ that layers inside the scroller (but scrolled out of view) don't trigger overlap with layers outside the scroller. >+ All this has to work when the containing block hierarchy (clipping/scrolling) doesn't match the paint order hierarchy (structure >+ of the z-order and compositing trees). >+ >+ Overlap testing previously simply used a list of rectangles per compositing container (OverlapMapContainer). This is >+ a series of layer bounds, built up as we traver the layer tree in z-order. Layers contribute to container N-2, and test >+ against container N-1. >+ >+ To handle overlap with non-stacking-context scrollers, introduce the concept of a ClippingScope, which encompasses >+ a set of layers sharing the same composited-scrolling containing-block ancestor. Within a ClippingScope, layer bounds >+ are computed unclipped. Between them, bounds are tested clipped. >+ >+ Conceptually, each OverlapMapContainer has a tree of ClippingScopes (reflecting the containing-block order tree of >+ composited overflow scroll), and rects are added to the appropriate ClippingScope. This tree is currently always >+ root-relative; the root node is the RenderView's RenderLayer, and will accumulate the bounds of layers not inside >+ composited overflow scroll (just like the old code). >+ >+ When a OverlapMapContainer is popped, the list of rectangles in its ClippingScope tree is merged with that of the previous >+ container. >+ >+ Tests: compositing/layer-creation/clipping-scope/nested-scroller-overlap.html >+ compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller.html >+ compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller.html >+ compositing/layer-creation/clipping-scope/scroller-with-negative-z-children.html >+ compositing/layer-creation/clipping-scope/shared-layers-in-scroller.html >+ >+ * rendering/LayerOverlapMap.cpp: >+ (WebCore::operator<<): >+ (WebCore::OverlapMapContainer::OverlapMapContainer): >+ (WebCore::OverlapMapContainer::ClippingScope::ClippingScope): >+ (WebCore::OverlapMapContainer::ClippingScope::childWithLayer const): >+ (WebCore::OverlapMapContainer::ClippingScope::addChildWithLayerAndBounds): >+ (WebCore::OverlapMapContainer::ClippingScope::addChild): >+ (WebCore::OverlapMapContainer::ClippingScope::appendRect): >+ (WebCore::OverlapMapContainer::clippingScopeContainingLayerChildRecursive): >+ (WebCore::OverlapMapContainer::scopeContainingLayer const): >+ (WebCore::OverlapMapContainer::rootScope const): >+ (WebCore::OverlapMapContainer::rootScope): >+ (WebCore::OverlapMapContainer::add): >+ (WebCore::OverlapMapContainer::overlapsLayers const): >+ (WebCore::OverlapMapContainer::mergeClippingScopesRecursive): >+ (WebCore::OverlapMapContainer::append): >+ (WebCore::OverlapMapContainer::ensureClippingScopeForLayers): >+ (WebCore::OverlapMapContainer::findClippingScopeForLayers const): >+ (WebCore::OverlapMapContainer::recursiveOutputToStream const): >+ (WebCore::OverlapMapContainer::dump const): >+ (WebCore::LayerOverlapMap::LayerOverlapMap): >+ (WebCore::LayerOverlapMap::add): >+ (WebCore::LayerOverlapMap::overlapsLayers const): >+ (WebCore::LayerOverlapMap::pushCompositingContainer): >+ (WebCore::LayerOverlapMap::popCompositingContainer): >+ (WebCore::OverlapMapContainer::unite): Deleted. >+ (WebCore::OverlapMapContainer::rectList const): Deleted. >+ * rendering/LayerOverlapMap.h: >+ * rendering/RenderLayerCompositor.cpp: >+ (WebCore::RenderLayerCompositor::BackingSharingState::appendSharingLayer): >+ (WebCore::RenderLayerCompositor::BackingSharingState::updateBeforeDescendantTraversal): >+ (WebCore::RenderLayerCompositor::updateCompositingLayers): >+ (WebCore::RenderLayerCompositor::computeCompositingRequirements): >+ (WebCore::RenderLayerCompositor::traverseUnchangedSubtree): >+ (WebCore::RenderLayerCompositor::computeExtent const): >+ (WebCore::createsClippingScope): >+ (WebCore::enclosingClippingScopes): >+ (WebCore::RenderLayerCompositor::addToOverlapMap const): >+ (WebCore::RenderLayerCompositor::updateOverlapMap const): >+ (WebCore::RenderLayerCompositor::layerOverlaps const): >+ * rendering/RenderLayerCompositor.h: >+ > 2019-05-21 Antoine Quint <graouts@apple.com> > > [macOS] Compatibility mouse events aren't prevented by calling preventDefault() on pointerdown >diff --git a/Source/WebCore/rendering/LayerOverlapMap.cpp b/Source/WebCore/rendering/LayerOverlapMap.cpp >index 31f95508dcdbb5a426d8fe1c3c958beb15d21a1f..794a48372c3e5cbc72ee6515041505c2c47176b3 100644 >--- a/Source/WebCore/rendering/LayerOverlapMap.cpp >+++ b/Source/WebCore/rendering/LayerOverlapMap.cpp >@@ -25,6 +25,7 @@ > > #include "config.h" > #include "LayerOverlapMap.h" >+#include "RenderLayer.h" > #include <wtf/text/TextStream.h> > > namespace WebCore { >@@ -58,31 +59,215 @@ struct RectList { > } > }; > >+static TextStream& operator<<(TextStream& ts, const RectList& rectList) >+{ >+ ts << "bounds " << rectList.boundingRect << " (" << rectList.rects << " rects)"; >+ return ts; >+} >+ >+// Used to store overlap rects in a way that takes overflow into account. >+// It stores a tree whose nodes are layers with composited scrolling. The tree is built lazily as layers are added whose containing block >+// chains contain composited scrollers. The tree always starts at the root layer. >+// Checking for overlap involves finding the node for the clipping layer enclosing the given layer (or the root), >+// and comparing against the bounds of earlier siblings. > class OverlapMapContainer { > public: >- void add(const LayoutRect& bounds) >+ OverlapMapContainer(const RenderLayer& rootLayer) >+ : m_rootScope(rootLayer) > { >- m_rectList.append(bounds); > } > >- bool overlapsLayers(const LayoutRect& bounds) const >+ // Layers are added in z-order, lazily creating clipping scopes as necessary. >+ void add(const RenderLayer&, const LayoutRect& bounds, const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers); >+ bool overlapsLayers(const RenderLayer&, const LayoutRect& bounds, const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers) const; >+ void append(std::unique_ptr<OverlapMapContainer>&&); >+ >+ String dump(unsigned) const; >+ >+private: >+ struct ClippingScope { >+ ClippingScope(const RenderLayer& inLayer) >+ : layer(inLayer) >+ { >+ } >+ >+ ClippingScope(const LayerOverlapMap::LayerAndBounds& layerAndBounds) >+ : layer(layerAndBounds.layer) >+ , bounds(layerAndBounds.bounds) >+ { >+ } >+ >+ ClippingScope* childWithLayer(const RenderLayer& layer) const >+ { >+ for (auto& child : children) { >+ if (&child.layer == &layer) >+ return const_cast<ClippingScope*>(&child); >+ } >+ return nullptr; >+ } >+ >+ ClippingScope* addChildWithLayerAndBounds(const LayerOverlapMap::LayerAndBounds& layerAndBounds) >+ { >+ children.append({ layerAndBounds }); >+ return &children.last(); >+ } >+ >+ ClippingScope* addChild(const ClippingScope& child) >+ { >+ children.append(child); >+ return &children.last(); >+ } >+ >+ void appendRect(const LayoutRect& bounds) >+ { >+ rectList.append(bounds); >+ } >+ >+ const RenderLayer& layer; >+ LayoutRect bounds; // Bounds of the composited clip. >+ Vector<ClippingScope> children; >+ RectList rectList; >+ }; >+ >+ static ClippingScope* clippingScopeContainingLayerChildRecursive(const ClippingScope& currNode, const RenderLayer& layer) > { >- return m_rectList.intersects(bounds); >+ for (auto& child : currNode.children) { >+ if (&layer == &child.layer) >+ return const_cast<ClippingScope*>(&currNode); >+ >+ if (auto* foundNode = clippingScopeContainingLayerChildRecursive(child, layer)) >+ return foundNode; >+ } >+ >+ return nullptr; > } > >- void unite(const OverlapMapContainer& otherContainer) >+ ClippingScope* scopeContainingLayer(const RenderLayer& layer) const > { >- m_rectList.append(otherContainer.m_rectList); >+ return clippingScopeContainingLayerChildRecursive(m_rootScope, layer); > } > >- const RectList& rectList() const { return m_rectList; } >+ static void mergeClippingScopesRecursive(const ClippingScope& sourceScope, ClippingScope& destScope); > >-private: >- RectList m_rectList; >+ ClippingScope* ensureClippingScopeForLayers(const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers); >+ ClippingScope* findClippingScopeForLayers(const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers) const; >+ >+ void recursiveOutputToStream(TextStream&, const ClippingScope&, unsigned depth) const; >+ >+ const ClippingScope& rootScope() const { return m_rootScope; } >+ ClippingScope& rootScope() { return m_rootScope; } >+ >+ ClippingScope m_rootScope; > }; > >-LayerOverlapMap::LayerOverlapMap() >+void OverlapMapContainer::add(const RenderLayer&, const LayoutRect& bounds, const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers) >+{ >+ auto* layerScope = ensureClippingScopeForLayers(enclosingClippingLayers); >+ layerScope->appendRect(bounds); >+} >+ >+bool OverlapMapContainer::overlapsLayers(const RenderLayer&, const LayoutRect& bounds, const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers) const >+{ >+ if (m_rootScope.rectList.intersects(bounds)) >+ return true; >+ >+ if (m_rootScope.children.isEmpty()) >+ return false; >+ >+ // Find the ClippingScope for which this layer is a child. >+ auto* clippingScope = findClippingScopeForLayers(enclosingClippingLayers); >+ if (!clippingScope) >+ return false; >+ >+ if (clippingScope->rectList.intersects(bounds)) >+ return true; >+ >+ // FIXME: In some cases do we have to walk up the ancestor clipping scope chain? >+ return false; >+} >+ >+void OverlapMapContainer::mergeClippingScopesRecursive(const ClippingScope& sourceScope, ClippingScope& destScope) >+{ >+ ASSERT(&sourceScope.layer == &destScope.layer); >+ destScope.rectList.append(sourceScope.rectList); >+ >+ for (auto& sourceChildScope : sourceScope.children) { >+ ClippingScope* destChild = destScope.childWithLayer(sourceChildScope.layer); >+ if (destChild) { >+ destChild->rectList.append(sourceChildScope.rectList); >+ mergeClippingScopesRecursive(sourceChildScope, *destChild); >+ } else { >+ // New child, just copy the whole subtree. >+ destScope.addChild(sourceScope); >+ } >+ } >+} >+ >+void OverlapMapContainer::append(std::unique_ptr<OverlapMapContainer>&& otherContainer) >+{ >+ mergeClippingScopesRecursive(otherContainer->rootScope(), m_rootScope); >+} >+ >+OverlapMapContainer::ClippingScope* OverlapMapContainer::ensureClippingScopeForLayers(const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers) >+{ >+ ASSERT(enclosingClippingLayers.size()); >+ ASSERT(enclosingClippingLayers[0].layer.isRenderViewLayer()); >+ >+ auto* currScope = &m_rootScope; >+ for (unsigned i = 1; i < enclosingClippingLayers.size(); ++i) { >+ auto& scopeLayerAndBounds = enclosingClippingLayers[i]; >+ auto* childScope = currScope->childWithLayer(scopeLayerAndBounds.layer); >+ if (!childScope) { >+ currScope = currScope->addChildWithLayerAndBounds(scopeLayerAndBounds); >+ break; >+ } >+ >+ currScope = childScope; >+ } >+ >+ return const_cast<ClippingScope*>(currScope); >+} >+ >+OverlapMapContainer::ClippingScope* OverlapMapContainer::findClippingScopeForLayers(const Vector<LayerOverlapMap::LayerAndBounds>& enclosingClippingLayers) const >+{ >+ ASSERT(enclosingClippingLayers.size()); >+ ASSERT(enclosingClippingLayers[0].layer.isRenderViewLayer()); >+ >+ const auto* currScope = &m_rootScope; >+ for (unsigned i = 1; i < enclosingClippingLayers.size(); ++i) { >+ auto& scopeLayerAndBounds = enclosingClippingLayers[i]; >+ auto* childScope = currScope->childWithLayer(scopeLayerAndBounds.layer); >+ if (!childScope) >+ return nullptr; >+ >+ currScope = childScope; >+ } >+ >+ return const_cast<ClippingScope*>(currScope); >+} >+ >+void OverlapMapContainer::recursiveOutputToStream(TextStream& ts, const ClippingScope& scope, unsigned depth) const >+{ >+ ts << "\n" << indent << TextStream::Repeat { 2 * depth, ' ' } << " scope for layer " << &scope.layer << " rects " << scope.rectList; >+ for (auto& childScope : scope.children) >+ recursiveOutputToStream(ts, childScope, depth + 1); >+} >+ >+String OverlapMapContainer::dump(unsigned indent) const >+{ >+ TextStream multilineStream; >+ multilineStream.increaseIndent(indent); >+ multilineStream << "overlap container - root scope layer " << &m_rootScope.layer << " rects " << m_rootScope.rectList; >+ >+ for (auto& childScope : m_rootScope.children) >+ recursiveOutputToStream(multilineStream, childScope, 1); >+ >+ return multilineStream.release(); >+} >+ >+LayerOverlapMap::LayerOverlapMap(const RenderLayer& rootLayer) > : m_geometryMap(UseTransforms) >+ , m_rootLayer(rootLayer) > { > // Begin assuming the root layer will be composited so that there is > // something on the stack. The root layer should also never get an >@@ -92,41 +277,36 @@ LayerOverlapMap::LayerOverlapMap() > > LayerOverlapMap::~LayerOverlapMap() = default; > >-void LayerOverlapMap::add(const LayoutRect& bounds) >+void LayerOverlapMap::add(const RenderLayer& layer, const LayoutRect& bounds, const Vector<LayerAndBounds>& enclosingClippingLayers) > { > // Layers do not contribute to overlap immediately--instead, they will > // contribute to overlap as soon as their composited ancestor has been > // recursively processed and popped off the stack. > ASSERT(m_overlapStack.size() >= 2); >- m_overlapStack[m_overlapStack.size() - 2]->add(bounds); >+ m_overlapStack[m_overlapStack.size() - 2]->add(layer, bounds, enclosingClippingLayers); >+ > m_isEmpty = false; > } > >-bool LayerOverlapMap::overlapsLayers(const LayoutRect& bounds) const >+bool LayerOverlapMap::overlapsLayers(const RenderLayer& layer, const LayoutRect& bounds, const Vector<LayerAndBounds>& enclosingClippingLayers) const > { >- return m_overlapStack.last()->overlapsLayers(bounds); >+ return m_overlapStack.last()->overlapsLayers(layer, bounds, enclosingClippingLayers); > } > > void LayerOverlapMap::pushCompositingContainer() > { >- m_overlapStack.append(std::make_unique<OverlapMapContainer>()); >+ m_overlapStack.append(std::make_unique<OverlapMapContainer>(m_rootLayer)); > } > > void LayerOverlapMap::popCompositingContainer() > { >- m_overlapStack[m_overlapStack.size() - 2]->unite(*m_overlapStack.last()); >+ m_overlapStack[m_overlapStack.size() - 2]->append(WTFMove(m_overlapStack.last())); > m_overlapStack.removeLast(); > } > >-static TextStream& operator<<(TextStream& ts, const RectList& rectList) >-{ >- ts << "bounds " << rectList.boundingRect << " (" << rectList.rects << " rects)"; >- return ts; >-} >- > static TextStream& operator<<(TextStream& ts, const OverlapMapContainer& container) > { >- ts << container.rectList(); >+ ts << container.dump(ts.indent()); > return ts; > } > >@@ -135,13 +315,21 @@ TextStream& operator<<(TextStream& ts, const LayerOverlapMap& overlapMap) > TextStream multilineStream; > > TextStream::GroupScope scope(ts); >- multilineStream << indent << "LayerOverlapMap\n"; >+ multilineStream << "LayerOverlapMap\n"; >+ multilineStream.increaseIndent(2); > >- for (auto& container : overlapMap.overlapStack()) >- multilineStream << " " << *container << "\n"; >+ bool needNewline = false; >+ for (auto& container : overlapMap.overlapStack()) { >+ if (needNewline) >+ multilineStream << "\n"; >+ else >+ needNewline = true; >+ multilineStream << indent << *container; >+ } > > ts << multilineStream.release(); > return ts; > } > > } // namespace WebCore >+ >diff --git a/Source/WebCore/rendering/LayerOverlapMap.h b/Source/WebCore/rendering/LayerOverlapMap.h >index 2b40a43bf7acba784959722a5a7ffb17898d87f6..e3061f0940a6629710cccdf3c6693380e63b4425 100644 >--- a/Source/WebCore/rendering/LayerOverlapMap.h >+++ b/Source/WebCore/rendering/LayerOverlapMap.h >@@ -34,16 +34,23 @@ class TextStream; > > namespace WebCore { > >+class OverflowAwareOverlapContainer; > class OverlapMapContainer; >+class RenderLayer; > > class LayerOverlapMap { > WTF_MAKE_NONCOPYABLE(LayerOverlapMap); > public: >- LayerOverlapMap(); >+ LayerOverlapMap(const RenderLayer& rootLayer); > ~LayerOverlapMap(); >+ >+ struct LayerAndBounds { >+ RenderLayer& layer; >+ LayoutRect bounds; >+ }; > >- void add(const LayoutRect& bounds); >- bool overlapsLayers(const LayoutRect&) const; >+ void add(const RenderLayer&, const LayoutRect&, const Vector<LayerAndBounds>& enclosingClippingLayers); >+ bool overlapsLayers(const RenderLayer&, const LayoutRect&, const Vector<LayerAndBounds>& enclosingClippingLayers) const; > bool isEmpty() const { return m_isEmpty; } > > void pushCompositingContainer(); >@@ -57,6 +64,7 @@ public: > private: > Vector<std::unique_ptr<OverlapMapContainer>> m_overlapStack; > RenderGeometryMap m_geometryMap; >+ const RenderLayer& m_rootLayer; > bool m_isEmpty { true }; > }; > >diff --git a/Source/WebCore/rendering/RenderLayerCompositor.cpp b/Source/WebCore/rendering/RenderLayerCompositor.cpp >index f9bf2c5674fede227954cf754e6ea0de86bb1a32..93b44cf964919dff5a933358320be70da6a9004f 100644 >--- a/Source/WebCore/rendering/RenderLayerCompositor.cpp >+++ b/Source/WebCore/rendering/RenderLayerCompositor.cpp >@@ -205,7 +205,6 @@ public: > > void appendSharingLayer(RenderLayer& layer) > { >- LOG_WITH_STREAM(Compositing, stream << &layer << " appendSharingLayer " << &layer << " for backing provider " << m_backingProviderCandidate); > m_backingSharingLayers.append(makeWeakPtr(layer)); > } > >@@ -249,7 +248,6 @@ void RenderLayerCompositor::BackingSharingState::updateBeforeDescendantTraversal > // A layer that composites resets backing-sharing, since subsequent layers need to composite to overlap it. > if (willBeComposited) { > m_backingSharingLayers.removeAll(&layer); >- LOG_WITH_STREAM(Compositing, stream << "Pre-descendant compositing of " << &layer << ", ending sharing sequence for " << m_backingProviderCandidate << " with " << m_backingSharingLayers.size() << " sharing layers"); > endBackingSharingSequence(); > } > } >@@ -768,12 +766,13 @@ bool RenderLayerCompositor::updateCompositingLayers(CompositingUpdateType update > > // FIXME: optimize root-only update. > if (updateRoot->hasDescendantNeedingCompositingRequirementsTraversal() || updateRoot->needsCompositingRequirementsTraversal()) { >+ auto& rootLayer = rootRenderLayer(); > CompositingState compositingState(updateRoot); > BackingSharingState backingSharingState; >- LayerOverlapMap overlapMap; >+ LayerOverlapMap overlapMap(rootLayer); > > bool descendantHas3DTransform = false; >- computeCompositingRequirements(nullptr, rootRenderLayer(), overlapMap, compositingState, backingSharingState, descendantHas3DTransform); >+ computeCompositingRequirements(nullptr, rootLayer, overlapMap, compositingState, backingSharingState, descendantHas3DTransform); > } > > LOG(Compositing, "\nRenderLayerCompositor::updateCompositingLayers - mid"); >@@ -883,10 +882,8 @@ void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestor > > // 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. >- if (overlapMap.overlapsLayers(layerExtent.bounds)) { >+ if (layerOverlaps(overlapMap, layer, layerExtent)) { > if (backingSharingState.backingProviderCandidate() && canBeComposited(layer) && backingProviderLayerCanIncludeLayer(*backingSharingState.backingProviderCandidate(), layer)) { > backingSharingState.appendSharingLayer(layer); > LOG(Compositing, " layer %p can share with %p", &layer, backingSharingState.backingProviderCandidate()); >@@ -1786,7 +1783,6 @@ void RenderLayerCompositor::computeExtent(const LayerOverlapMap& overlapMap, con > if (extent.bounds.isEmpty()) > extent.bounds.setSize(LayoutSize(1, 1)); > >- > RenderLayerModelObject& renderer = layer.renderer(); > if (renderer.isFixedPositioned() && renderer.container() == &m_renderView) { > // Because fixed elements get moved around without re-computing overlap, we have to compute an overlap >@@ -1798,6 +1794,44 @@ void RenderLayerCompositor::computeExtent(const LayerOverlapMap& overlapMap, con > extent.extentComputed = true; > } > >+static bool createsClippingScope(const RenderLayer& layer) >+{ >+ return layer.hasCompositedScrollableOverflow(); >+} >+ >+static Vector<LayerOverlapMap::LayerAndBounds> enclosingClippingScopes(const RenderLayer& layer, const RenderLayer& rootLayer) >+{ >+ Vector<LayerOverlapMap::LayerAndBounds> clippingScopes; >+ clippingScopes.append({ const_cast<RenderLayer&>(rootLayer), { } }); >+ >+ if (!layer.hasCompositedScrollingAncestor()) >+ return clippingScopes; >+ >+ bool containingBlockCanSkipLayers = layer.renderer().isAbsolutelyPositioned(); >+ for (const auto* currLayer = layer.parent(); currLayer; currLayer = currLayer->parent()) { >+ bool inContainingBlockChain = true; >+ if (containingBlockCanSkipLayers) { >+ inContainingBlockChain = currLayer->renderer().canContainAbsolutelyPositionedObjects(); >+ if (inContainingBlockChain) >+ containingBlockCanSkipLayers = currLayer->renderer().isAbsolutelyPositioned(); >+ } >+ >+ if (inContainingBlockChain && createsClippingScope(*currLayer)) { >+ LayoutRect clipRect; >+ if (is<RenderBox>(currLayer->renderer())) { >+ // FIXME: This is expensive. Broken with transforms. >+ LayoutPoint offsetFromRoot = currLayer->convertToLayerCoords(&rootLayer, { }); >+ clipRect = downcast<RenderBox>(currLayer->renderer()).overflowClipRect(offsetFromRoot); >+ } >+ >+ LayerOverlapMap::LayerAndBounds layerAndBounds { const_cast<RenderLayer&>(*currLayer), clipRect }; >+ clippingScopes.insert(1, layerAndBounds); // Order is roots to leaves. >+ } >+ } >+ >+ return clippingScopes; >+} >+ > void RenderLayerCompositor::addToOverlapMap(LayerOverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& extent) const > { > if (layer.isRenderViewLayer()) >@@ -1805,13 +1839,29 @@ void RenderLayerCompositor::addToOverlapMap(LayerOverlapMap& overlapMap, const R > > computeExtent(overlapMap, layer, extent); > >- LayoutRect clipRect = layer.backgroundClipRect(RenderLayer::ClipRectsContext(&rootRenderLayer(), AbsoluteClipRects)).rect(); // FIXME: Incorrect for CSS regions. >+ // FIXME: constrain the scopes (by composited stacking context ancestor I think). >+ auto clippingScopes = enclosingClippingScopes(layer, rootRenderLayer()); > >- // On iOS, pageScaleFactor() is not applied by RenderView, so we should not scale here. >- if (!m_renderView.settings().delegatesPageScaling()) >- clipRect.scale(pageScaleFactor()); >- clipRect.intersect(extent.bounds); >- overlapMap.add(clipRect); >+ LayoutRect clipRect; >+ if (layer.hasCompositedScrollingAncestor()) { >+ // Compute a clip up to the composited scrolling ancestor, then convert it to absolute coordinates. >+ auto& scrollingScope = clippingScopes.last(); >+ clipRect = layer.backgroundClipRect(RenderLayer::ClipRectsContext(&scrollingScope.layer, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip)).rect(); >+ if (!clipRect.isInfinite()) >+ clipRect.setLocation(layer.convertToLayerCoords(&rootRenderLayer(), clipRect.location())); >+ } else >+ clipRect = layer.backgroundClipRect(RenderLayer::ClipRectsContext(&rootRenderLayer(), AbsoluteClipRects)).rect(); // FIXME: Incorrect for CSS regions. >+ >+ auto clippedBounds = extent.bounds; >+ if (!clipRect.isInfinite()) { >+ // On iOS, pageScaleFactor() is not applied by RenderView, so we should not scale here. >+ if (!m_renderView.settings().delegatesPageScaling()) >+ clipRect.scale(pageScaleFactor()); >+ >+ clippedBounds.intersect(clipRect); >+ } >+ >+ overlapMap.add(layer, clippedBounds, clippingScopes); > } > > void RenderLayerCompositor::addDescendantsToOverlapMapRecursive(LayerOverlapMap& overlapMap, const RenderLayer& layer, const RenderLayer* ancestorLayer) const >@@ -1847,6 +1897,7 @@ void RenderLayerCompositor::addDescendantsToOverlapMapRecursive(LayerOverlapMap& > void RenderLayerCompositor::updateOverlapMap(LayerOverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& layerExtent, bool didPushContainer, bool addLayerToOverlap, bool addDescendantsToOverlap) const > { > if (addLayerToOverlap) { >+ auto clippingScopes = enclosingClippingScopes(layer, rootRenderLayer()); > addToOverlapMap(overlapMap, layer, layerExtent); > LOG_WITH_STREAM(CompositingOverlap, stream << "layer " << &layer << " contributes to overlap, added to map " << overlapMap); > } >@@ -1863,6 +1914,14 @@ void RenderLayerCompositor::updateOverlapMap(LayerOverlapMap& overlapMap, const > } > } > >+bool RenderLayerCompositor::layerOverlaps(const LayerOverlapMap& overlapMap, const RenderLayer& layer, OverlapExtent& layerExtent) const >+{ >+ computeExtent(overlapMap, layer, layerExtent); >+ >+ auto clippingScopes = enclosingClippingScopes(layer, rootRenderLayer()); >+ return overlapMap.overlapsLayers(layer, layerExtent.bounds, clippingScopes); >+} >+ > #if ENABLE(VIDEO) > bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo& video) const > { >diff --git a/Source/WebCore/rendering/RenderLayerCompositor.h b/Source/WebCore/rendering/RenderLayerCompositor.h >index 7f66d1866dcc2b66b1112ab8487083eff2ca07df..12c1353c4faeda4f30d836933f1d64b847ebad10 100644 >--- a/Source/WebCore/rendering/RenderLayerCompositor.h >+++ b/Source/WebCore/rendering/RenderLayerCompositor.h >@@ -409,6 +409,7 @@ private: > void addToOverlapMap(LayerOverlapMap&, const RenderLayer&, OverlapExtent&) const; > void addDescendantsToOverlapMapRecursive(LayerOverlapMap&, const RenderLayer&, const RenderLayer* ancestorLayer = nullptr) const; > void updateOverlapMap(LayerOverlapMap&, const RenderLayer&, OverlapExtent&, bool didPushContainer, bool addLayerToOverlap, bool addDescendantsToOverlap = false) const; >+ bool layerOverlaps(const LayerOverlapMap&, const RenderLayer&, OverlapExtent&) const; > > void updateCompositingLayersTimerFired(); > >diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog >index 3920a3d34d0c89310aed986ddefb68e830a966db..082e95ceb52488863c11f153959c0b8e38db77cf 100644 >--- a/LayoutTests/ChangeLog >+++ b/LayoutTests/ChangeLog >@@ -1,3 +1,30 @@ >+2019-05-21 Simon Fraser <simon.fraser@apple.com> >+ >+ Layer flashing and poor perf during scrolling of message list on gmail.com and hotmail.com - overlap testing needs to constrained to clipping scopes >+ https://bugs.webkit.org/show_bug.cgi?id=198091 >+ <rdar://problem/49403082> >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * TestExpectations: >+ * compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt: Added. >+ * compositing/layer-creation/clipping-scope/nested-scroller-overlap.html: Added. >+ * compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt: Added. >+ * compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller.html: Added. >+ * compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt: Added. >+ * compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller.html: Added. >+ * compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt: Added. >+ * compositing/layer-creation/clipping-scope/scroller-with-negative-z-children.html: Added. >+ * compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt: Added. >+ * compositing/layer-creation/clipping-scope/shared-layers-in-scroller.html: Added. >+ * platform/ios-wk2/TestExpectations: >+ * platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt: Added. >+ * platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt: Added. >+ * platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt: Added. >+ * platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt: Added. >+ * platform/ios-wk2/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt: Added. >+ * platform/mac-wk2/TestExpectations: >+ > 2019-05-21 Antti Koivisto <antti@apple.com> > > RTL/overflow scroll tests fail with async overflow enabled >diff --git a/LayoutTests/TestExpectations b/LayoutTests/TestExpectations >index 09671192a5e8b12e45491d56c5175f7f5a401b11..99cfec5fc5b6e9fa792f02be904673c6f5096b91 100644 >--- a/LayoutTests/TestExpectations >+++ b/LayoutTests/TestExpectations >@@ -63,6 +63,7 @@ fast/media/ios [ Skip ] > # Requires async overflow scrolling > compositing/shared-backing/overflow-scroll [ Skip ] > compositing/scrolling/async-overflow-scrolling [ Skip ] >+compositing/layer-creation/clipping-scope [ Skip ] > > # WebKit2 only. > printing/printing-events.html [ Skip ] >diff --git a/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt b/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..a608569a373d443c9fd95ae783fd3e7a5afb2ce9 >--- /dev/null >+++ b/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt >@@ -0,0 +1,112 @@ >+(GraphicsLayer >+ (anchor 0.00 0.00) >+ (bounds 800.00 600.00) >+ (children 1 >+ (GraphicsLayer >+ (bounds 800.00 600.00) >+ (contentsOpaque 1) >+ (children 7 >+ (GraphicsLayer >+ (position 23.00 105.00) >+ (bounds 402.00 352.00) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 385.00 350.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 385.00 832.00) >+ (children 1 >+ (GraphicsLayer >+ (position 20.00 110.00) >+ (bounds 302.00 202.00) >+ (contentsOpaque 1) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 285.00 200.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 285.00 280.00) >+ (drawsContent 1) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-10) >+ (position 24.00 106.00) >+ (bounds 385.00 350.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 100.00 80.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 60.00 550.00) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-10) >+ (position 45.00 217.00) >+ (bounds 285.00 200.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 100.00 80.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-100) >+ (position 45.00 217.00) >+ (bounds 285.00 200.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 100.00) >+ (bounds 100.00 80.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-190) >+ (position 45.00 217.00) >+ (bounds 285.00 200.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 190.00) >+ (bounds 100.00 80.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (position 18.00 472.00) >+ (bounds 100.00 80.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ ) >+) >+ >diff --git a/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap.html b/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap.html >new file mode 100644 >index 0000000000000000000000000000000000000000..56fa0b794c07991caffc982c3146bbe3731f5aaf >--- /dev/null >+++ b/LayoutTests/compositing/layer-creation/clipping-scope/nested-scroller-overlap.html >@@ -0,0 +1,71 @@ >+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] --> >+<html> >+<head> >+ <style> >+ .scroller { >+ overflow-y: scroll; >+ margin: 15px; >+ height: 350px; >+ width: 400px; >+ border: 1px solid black; >+ } >+ >+ .inner { >+ width: 300px; >+ height: 200px; >+ margin: 20px; >+ background-color: white; >+ } >+ >+ .box { >+ position: relative; >+ width: 100px; >+ height: 80px; >+ margin: 10px; >+ background-color: green; >+ } >+ >+ .trigger { >+ position: absolute; >+ top: 10px; >+ left: 10px; >+ width: 60px; >+ height: 550px; >+ transform: translateZ(0); >+ background-color: rgba(128, 128, 200, 0.7); >+ } >+ >+ .outside { >+ background-color: gray; >+ } >+ >+ .spacer { >+ height: 500px; >+ } >+ </style> >+ <script> >+ if (window.testRunner) >+ testRunner.dumpAsText(); >+ >+ window.addEventListener('load', () => { >+ if (window.testRunner) >+ document.getElementById('layers').innerText = window.internals.layerTreeAsText(document); >+ }, false); >+ </script> >+</head> >+<body> >+ <div class="outside box"></div> >+ <div class="scroller"> >+ <div class="inner box"></div> >+ <div class="inner scroller"> >+ <div class="trigger"></div> >+ <div class="inside box"></div> >+ <div class="inside box"></div> >+ <div class="inside box"></div> >+ </div> >+ <div class="spacer"></div> >+ </div> >+ <div class="outside box"></div> >+<pre id="layers">Layer tree goes here</pre> >+</body> >+</html> >diff --git a/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt b/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2e6044ab21097210c3f3a13d725226fec1f16030 >--- /dev/null >+++ b/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt >@@ -0,0 +1,80 @@ >+(GraphicsLayer >+ (anchor 0.00 0.00) >+ (bounds 800.00 600.00) >+ (children 1 >+ (GraphicsLayer >+ (bounds 800.00 600.00) >+ (contentsOpaque 1) >+ (children 5 >+ (GraphicsLayer >+ (position 8.00 8.00) >+ (bounds 302.00 302.00) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 285.00 500.00) >+ ) >+ ) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-10) >+ (position 9.00 9.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 50.00 200.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-40 height=-20) >+ (position 9.00 9.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 40.00 20.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-40 height=-140) >+ (position 9.00 9.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 40.00 140.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-40 height=-260) >+ (position 9.00 9.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 40.00 260.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+) >+ >diff --git a/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller.html b/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller.html >new file mode 100644 >index 0000000000000000000000000000000000000000..fb6837281091d52af441b346060b472c591611d5 >--- /dev/null >+++ b/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller.html >@@ -0,0 +1,64 @@ >+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] --> >+<html> >+<head> >+ <style> >+ .scroller { >+ position: relative; >+ overflow-y: scroll; >+ width: 300px; >+ height: 300px; >+ border: 1px solid black; >+ } >+ >+ .box { >+ position: relative; >+ margin: 20px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ } >+ >+ .inside { >+ left: 20px; >+ } >+ >+ .outside { >+ position: relative; >+ margin: 20px; >+ width: 100px; >+ height: 100px; >+ background-color: silver; >+ } >+ >+ .trigger { >+ position: absolute; >+ top: 10px; >+ left: 10px; >+ width: 50px; >+ height: 200px; >+ background-color: silver; >+ transform: translateZ(0); >+ } >+ </style> >+ <script> >+ if (window.testRunner) >+ testRunner.dumpAsText(); >+ >+ window.addEventListener('load', () => { >+ if (window.testRunner) >+ document.getElementById('layers').innerText = window.internals.layerTreeAsText(document); >+ }, false); >+ </script> >+</head> >+<body> >+ <div class="scroller"> >+ <div class="trigger"></div> >+ <div class="inside box"></div> >+ <div class="inside box"></div> >+ <div class="inside box"></div> >+ <div class="inside box"></div> >+ </div> >+ <div class="outside"></div> >+<pre id="layers">Layer tree goes here</pre> >+</body> >+</html> >diff --git a/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt b/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..fa4f58ac991e1fd2e2322949ac66016589bc5576 >--- /dev/null >+++ b/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt >@@ -0,0 +1,50 @@ >+(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 302.00 302.00) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 285.00 500.00) >+ (drawsContent 1) >+ (children 3 >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 50.00 200.00) >+ (contentsOpaque 1) >+ ) >+ (GraphicsLayer >+ (position 40.00 20.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ (GraphicsLayer >+ (position 40.00 140.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+) >+ >diff --git a/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller.html b/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ad62b149d7eee487ee37b639dba860646c023ef9 >--- /dev/null >+++ b/LayoutTests/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller.html >@@ -0,0 +1,65 @@ >+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] --> >+<html> >+<head> >+ <style> >+ .scroller { >+ position: relative; >+ z-index: 0; >+ overflow-y: scroll; >+ width: 300px; >+ height: 300px; >+ border: 1px solid black; >+ } >+ >+ .box { >+ position: relative; >+ margin: 20px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ } >+ >+ .inside { >+ left: 20px; >+ } >+ >+ .outside { >+ position: relative; >+ margin: 20px; >+ width: 100px; >+ height: 100px; >+ background-color: silver; >+ } >+ >+ .trigger { >+ position: absolute; >+ top: 10px; >+ left: 10px; >+ width: 50px; >+ height: 200px; >+ background-color: silver; >+ transform: translateZ(0); >+ } >+ </style> >+ <script> >+ if (window.testRunner) >+ testRunner.dumpAsText(); >+ >+ window.addEventListener('load', () => { >+ if (window.testRunner) >+ document.getElementById('layers').innerText = window.internals.layerTreeAsText(document); >+ }, false); >+ </script> >+</head> >+<body> >+ <div class="scroller"> >+ <div class="trigger"></div> >+ <div class="inside box"></div> >+ <div class="inside box"></div> >+ <div class="inside box"></div> >+ <div class="inside box"></div> >+ </div> >+ <div class="outside"></div> >+<pre id="layers">Layer tree goes here</pre> >+</body> >+</html> >diff --git a/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt b/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..b8a99a2e00acc2f295e573ee5a5f75514a298d54 >--- /dev/null >+++ b/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt >@@ -0,0 +1,68 @@ >+(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 8.00 8.00) >+ (bounds 302.00 302.00) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 285.00 500.00) >+ ) >+ ) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-10) >+ (position 9.00 9.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 50.00 200.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-40 height=-20) >+ (position 9.00 9.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 40.00 20.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-40 height=-260) >+ (position 9.00 9.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 40.00 260.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+) >+ >diff --git a/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children.html b/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children.html >new file mode 100644 >index 0000000000000000000000000000000000000000..48b512457f3892d9e5bd1c96bffd4675849d9cea >--- /dev/null >+++ b/LayoutTests/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children.html >@@ -0,0 +1,68 @@ >+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] --> >+<html> >+<head> >+ <style> >+ .scroller { >+ position: relative; >+ overflow-y: scroll; >+ width: 300px; >+ height: 300px; >+ border: 1px solid black; >+ } >+ >+ .box { >+ position: relative; >+ margin: 20px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ } >+ >+ .inside { >+ left: 20px; >+ } >+ >+ .negative { >+ z-index: -1; >+ } >+ >+ .outside { >+ position: relative; >+ margin: 20px; >+ width: 100px; >+ height: 100px; >+ background-color: silver; >+ } >+ >+ .trigger { >+ position: absolute; >+ top: 10px; >+ left: 10px; >+ width: 50px; >+ height: 200px; >+ background-color: silver; >+ transform: translateZ(0); >+ } >+ </style> >+ <script> >+ if (window.testRunner) >+ testRunner.dumpAsText(); >+ >+ window.addEventListener('load', () => { >+ if (window.testRunner) >+ document.getElementById('layers').innerText = window.internals.layerTreeAsText(document); >+ }, false); >+ </script> >+</head> >+<body> >+ <div class="scroller"> >+ <div class="trigger"></div> >+ <div class="inside box"></div> >+ <div class="inside negative box"></div> >+ <div class="inside box"></div> >+ <div class="inside box"></div> >+ </div> >+ <div class="outside"></div> >+<pre id="layers">Layer tree goes here</pre> >+</body> >+</html> >diff --git a/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt b/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..230323bc94ccb4c4012f103988f66d246e2d82f6 >--- /dev/null >+++ b/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt >@@ -0,0 +1,38 @@ >+(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 302.00 302.00) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 285.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 285.00 500.00) >+ (drawsContent 1) >+ ) >+ ) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (position 78.00 300.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ ) >+) >+ >diff --git a/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller.html b/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller.html >new file mode 100644 >index 0000000000000000000000000000000000000000..287ddd910d12950e6995d099e42026a7c1623b65 >--- /dev/null >+++ b/LayoutTests/compositing/layer-creation/clipping-scope/shared-layers-in-scroller.html >@@ -0,0 +1,54 @@ >+<!DOCTYPE html> <!-- webkit-test-runner [ internal:AsyncOverflowScrollingEnabled=true ] --> >+<html> >+<head> >+ <style> >+ .scroller { >+ overflow-y: scroll; >+ width: 300px; >+ height: 300px; >+ border: 1px solid black; >+ } >+ >+ .box { >+ position: relative; >+ margin: 20px; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ } >+ >+ .spacer { >+ height: 200px; >+ width: 10px; >+ background-color: silver; >+ } >+ >+ .outside { >+ position: relative; >+ top: -30px; >+ left: 50px; >+ background-color: gray; >+ } >+ >+ </style> >+ <script> >+ if (window.testRunner) >+ testRunner.dumpAsText(); >+ >+ window.addEventListener('load', () => { >+ if (window.testRunner) >+ document.getElementById('layers').innerText = window.internals.layerTreeAsText(document); >+ }, false); >+ </script> >+</head> >+<body> >+ <div class="scroller"> >+ <div class="box"></div> >+ <div class="box"></div> >+ <div class="box"></div> >+ <div class="box"></div> >+ </div> >+ <div class="outside box"></div> >+<pre id="layers">Layer tree goes here</pre> >+</body> >+</html> >diff --git a/LayoutTests/platform/ios-wk2/TestExpectations b/LayoutTests/platform/ios-wk2/TestExpectations >index 08099aff1ed71e902d5e00510584b4c14ec39c95..680cad3ad13cb09b04197c024f2c83ba8a328cb6 100644 >--- a/LayoutTests/platform/ios-wk2/TestExpectations >+++ b/LayoutTests/platform/ios-wk2/TestExpectations >@@ -9,6 +9,7 @@ > compositing/ios [ Pass ] > compositing/shared-backing/overflow-scroll [ Pass ] > compositing/scrolling/async-overflow-scrolling [ Pass ] >+compositing/layer-creation/clipping-scope [ Pass ] > fast/device-orientation [ Pass ] > fast/history/ios [ Pass ] > fast/scrolling/ios [ Pass ] >diff --git a/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt b/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9ba74cdf35339c57bc707f0a850c3993d9a5d65b >--- /dev/null >+++ b/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/nested-scroller-overlap-expected.txt >@@ -0,0 +1,112 @@ >+(GraphicsLayer >+ (anchor 0.00 0.00) >+ (bounds 800.00 600.00) >+ (children 1 >+ (GraphicsLayer >+ (bounds 800.00 600.00) >+ (contentsOpaque 1) >+ (children 7 >+ (GraphicsLayer >+ (position 23.00 105.00) >+ (bounds 402.00 352.00) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 400.00 350.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 400.00 832.00) >+ (children 1 >+ (GraphicsLayer >+ (position 20.00 110.00) >+ (bounds 302.00 202.00) >+ (contentsOpaque 1) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 300.00 200.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 300.00 280.00) >+ (drawsContent 1) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-10) >+ (position 24.00 106.00) >+ (bounds 400.00 350.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 100.00 80.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 60.00 550.00) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-10) >+ (position 45.00 217.00) >+ (bounds 300.00 200.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 100.00 80.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-100) >+ (position 45.00 217.00) >+ (bounds 300.00 200.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 100.00) >+ (bounds 100.00 80.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-190) >+ (position 45.00 217.00) >+ (bounds 300.00 200.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 190.00) >+ (bounds 100.00 80.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (position 18.00 472.00) >+ (bounds 100.00 80.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ ) >+) >+ >diff --git a/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt b/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..88f83189ac956300705b3953d0b50719b2cc2037 >--- /dev/null >+++ b/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-scroller-expected.txt >@@ -0,0 +1,80 @@ >+(GraphicsLayer >+ (anchor 0.00 0.00) >+ (bounds 800.00 600.00) >+ (children 1 >+ (GraphicsLayer >+ (bounds 800.00 600.00) >+ (contentsOpaque 1) >+ (children 5 >+ (GraphicsLayer >+ (position 8.00 8.00) >+ (bounds 302.00 302.00) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 300.00 500.00) >+ ) >+ ) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-10) >+ (position 9.00 9.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 50.00 200.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-40 height=-20) >+ (position 9.00 9.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 40.00 20.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-40 height=-140) >+ (position 9.00 9.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 40.00 140.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-40 height=-260) >+ (position 9.00 9.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 40.00 260.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+) >+ >diff --git a/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt b/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..fb5b1ce1c3cd1dabad099d56029d316fa77b5495 >--- /dev/null >+++ b/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/overlap-constrained-inside-stacking-context-scroller-expected.txt >@@ -0,0 +1,50 @@ >+(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 302.00 302.00) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 300.00 500.00) >+ (drawsContent 1) >+ (children 3 >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 50.00 200.00) >+ (contentsOpaque 1) >+ ) >+ (GraphicsLayer >+ (position 40.00 20.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ (GraphicsLayer >+ (position 40.00 140.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+) >+ >diff --git a/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt b/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d4b42634558bc44ddaa245394b7956b6333e749a >--- /dev/null >+++ b/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/scroller-with-negative-z-children-expected.txt >@@ -0,0 +1,68 @@ >+(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 8.00 8.00) >+ (bounds 302.00 302.00) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 300.00 500.00) >+ ) >+ ) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-10 height=-10) >+ (position 9.00 9.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 10.00 10.00) >+ (bounds 50.00 200.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-40 height=-20) >+ (position 9.00 9.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 40.00 20.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (offsetFromRenderer width=-40 height=-260) >+ (position 9.00 9.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (position 40.00 260.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ ) >+ ) >+ ) >+) >+ >diff --git a/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt b/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..043f90332d7e12f0916117c309a72f3494f5f264 >--- /dev/null >+++ b/LayoutTests/platform/ios-wk2/compositing/layer-creation/clipping-scope/shared-layers-in-scroller-expected.txt >@@ -0,0 +1,38 @@ >+(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 302.00 302.00) >+ (drawsContent 1) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (position 1.00 1.00) >+ (bounds 300.00 300.00) >+ (children 1 >+ (GraphicsLayer >+ (offsetFromRenderer width=1 height=1) >+ (anchor 0.00 0.00) >+ (bounds 300.00 500.00) >+ (drawsContent 1) >+ ) >+ ) >+ ) >+ ) >+ ) >+ (GraphicsLayer >+ (position 78.00 300.00) >+ (bounds 100.00 100.00) >+ (contentsOpaque 1) >+ ) >+ ) >+ ) >+ ) >+) >+ >diff --git a/LayoutTests/platform/mac-wk2/TestExpectations b/LayoutTests/platform/mac-wk2/TestExpectations >index 4debed9044393c446d277fd0902c184c416506f5..b237cb9ea1ae77a27bbf2118b448d2db10ba8508 100644 >--- a/LayoutTests/platform/mac-wk2/TestExpectations >+++ b/LayoutTests/platform/mac-wk2/TestExpectations >@@ -7,6 +7,7 @@ > > compositing/shared-backing/overflow-scroll [ Pass ] > compositing/scrolling/async-overflow-scrolling [ Pass ] >+compositing/layer-creation/clipping-scope [ Pass ] > editing/find [ Pass ] > editing/undo-manager [ Pass ] > fast/forms/select/mac-wk2 [ Pass ]
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
koivisto
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 198091
: 370354