Changeset 245656 in webkit
- Timestamp:
- May 22, 2019 3:58:25 PM (5 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r245651 r245656 1 2019-05-22 Simon Fraser <simon.fraser@apple.com> 2 3 Fix scrolling tree state for more obscure combinations of positioning and paint order 4 https://bugs.webkit.org/show_bug.cgi?id=198139 5 6 Reviewed by Antti Koivisto. 7 8 * platform/ios-wk2/scrollingcoordinator/scrolling-tree/absolute-in-nested-sc-scrollers-expected.txt: Added. 9 * platform/ios-wk2/scrollingcoordinator/scrolling-tree/composited-in-absolute-in-overflow-expected.txt: Added. 10 * scrollingcoordinator/scrolling-tree/absolute-in-nested-sc-scrollers-expected.txt: Added. 11 * scrollingcoordinator/scrolling-tree/absolute-in-nested-sc-scrollers.html: Added. 12 * scrollingcoordinator/scrolling-tree/composited-in-absolute-in-overflow-expected.txt: Added. 13 * scrollingcoordinator/scrolling-tree/composited-in-absolute-in-overflow.html: Added. 14 1 15 2019-05-22 Simon Fraser <simon.fraser@apple.com> 2 16 -
trunk/Source/WebCore/ChangeLog
r245651 r245656 1 2019-05-22 Simon Fraser <simon.fraser@apple.com> 2 3 Fix scrolling tree state for more obscure combinations of positioning and paint order 4 https://bugs.webkit.org/show_bug.cgi?id=198139 5 6 Reviewed by Antti Koivisto. 7 8 There were three places in RenderLayerCompositor that used a version of ancestor 9 layer traversal looking at containing blocks, and all three had issues. So make a 10 shared function to do the ancestor walk, and use it thrice. 11 12 isScrolledByOverflowScrollLayer() fumbled containingBlockCanSkipLayers, so failed 13 to create a scrolling tree node for a composited layer inside position:fixed in 14 overflow (tested by composited-in-absolute-in-overflow.html). 15 16 collectStationaryLayerRelatedOverflowNodes() failed to handle nested 17 overflow:scroll; it needs to find all the composited scrollers that affect the 18 position of the given layer relative to its compositing ancestor, which may be the 19 scroller, or a descendant of the scroller. However, it didn't walk up far enough 20 and find more that one ancestor. Tested by absolute-in-nested-sc-scrollers.html. 21 22 enclosingClippingScopes() was OK but now uses the share function. 23 24 Tests: scrollingcoordinator/scrolling-tree/absolute-in-nested-sc-scrollers.html 25 scrollingcoordinator/scrolling-tree/composited-in-absolute-in-overflow.html 26 27 * rendering/RenderLayerCompositor.cpp: 28 (WebCore::traverseAncestorLayers): 29 (WebCore::enclosingClippingScopes): 30 (WebCore::isScrolledByOverflowScrollLayer): 31 (WebCore::collectStationaryLayerRelatedOverflowNodes): 32 (WebCore::collectRelatedCoordinatedScrollingNodes): 33 1 34 2019-05-22 Simon Fraser <simon.fraser@apple.com> 2 35 -
trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp
r245651 r245656 1795 1795 } 1796 1796 1797 enum class AncestorTraversal { Continue, Stop }; 1798 1799 // This is a simplified version of containing block walking that only handles absolute position. 1800 template <typename Function> 1801 static AncestorTraversal traverseAncestorLayers(const RenderLayer& layer, Function&& function) 1802 { 1803 bool containingBlockCanSkipLayers = layer.renderer().isAbsolutelyPositioned(); 1804 RenderLayer* nextPaintOrderParent = layer.paintOrderParent(); 1805 1806 for (const auto* ancestorLayer = layer.parent(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) { 1807 bool inContainingBlockChain = true; 1808 1809 if (containingBlockCanSkipLayers) 1810 inContainingBlockChain = ancestorLayer->renderer().canContainAbsolutelyPositionedObjects(); 1811 1812 if (function(*ancestorLayer, inContainingBlockChain, ancestorLayer == nextPaintOrderParent) == AncestorTraversal::Stop) 1813 return AncestorTraversal::Stop; 1814 1815 if (inContainingBlockChain) 1816 containingBlockCanSkipLayers = ancestorLayer->renderer().isAbsolutelyPositioned(); 1817 1818 if (ancestorLayer == nextPaintOrderParent) 1819 nextPaintOrderParent = ancestorLayer->paintOrderParent(); 1820 } 1821 1822 return AncestorTraversal::Continue; 1823 } 1824 1797 1825 static bool createsClippingScope(const RenderLayer& layer) 1798 1826 { … … 1808 1836 return clippingScopes; 1809 1837 1810 bool containingBlockCanSkipLayers = layer.renderer().isAbsolutelyPositioned(); 1811 for (const auto* ancestorLayer = layer.parent(); ancestorLayer; ancestorLayer = ancestorLayer->parent()) { 1812 bool inContainingBlockChain = true; 1813 if (containingBlockCanSkipLayers) { 1814 inContainingBlockChain = ancestorLayer->renderer().canContainAbsolutelyPositionedObjects(); 1815 if (inContainingBlockChain) 1816 containingBlockCanSkipLayers = ancestorLayer->renderer().isAbsolutelyPositioned(); 1817 } 1818 1819 if (inContainingBlockChain && createsClippingScope(*ancestorLayer)) { 1838 traverseAncestorLayers(layer, [&](const RenderLayer& ancestorLayer, bool inContainingBlockChain, bool) { 1839 if (inContainingBlockChain && createsClippingScope(ancestorLayer)) { 1820 1840 LayoutRect clipRect; 1821 if (is<RenderBox>(ancestorLayer ->renderer())) {1841 if (is<RenderBox>(ancestorLayer.renderer())) { 1822 1842 // FIXME: This is expensive. Broken with transforms. 1823 LayoutPoint offsetFromRoot = ancestorLayer ->convertToLayerCoords(&rootLayer, { });1824 clipRect = downcast<RenderBox>(ancestorLayer ->renderer()).overflowClipRect(offsetFromRoot);1843 LayoutPoint offsetFromRoot = ancestorLayer.convertToLayerCoords(&rootLayer, { }); 1844 clipRect = downcast<RenderBox>(ancestorLayer.renderer()).overflowClipRect(offsetFromRoot); 1825 1845 } 1826 1846 1827 LayerOverlapMap::LayerAndBounds layerAndBounds { const_cast<RenderLayer&>( *ancestorLayer), clipRect };1847 LayerOverlapMap::LayerAndBounds layerAndBounds { const_cast<RenderLayer&>(ancestorLayer), clipRect }; 1828 1848 clippingScopes.insert(1, layerAndBounds); // Order is roots to leaves. 1829 1849 } 1830 } 1850 return AncestorTraversal::Continue; 1851 }); 1831 1852 1832 1853 return clippingScopes; … … 3041 3062 } 3042 3063 3043 // Return true if overflowScrollLayer is in layer's containing block chain.3044 3064 static bool isScrolledByOverflowScrollLayer(const RenderLayer& layer, const RenderLayer& overflowScrollLayer) 3045 3065 { 3046 bool containingBlockCanSkipLayers = layer.renderer().isAbsolutelyPositioned(); 3047 3048 for (const auto* currLayer = layer.parent(); currLayer; currLayer = currLayer->parent()) { 3049 bool inContainingBlockChain = true; 3050 if (containingBlockCanSkipLayers) { 3051 inContainingBlockChain = currLayer->renderer().canContainAbsolutelyPositionedObjects(); 3052 if (inContainingBlockChain) 3053 containingBlockCanSkipLayers = currLayer->renderer().isAbsolutelyPositioned(); 3054 } 3055 3056 if (currLayer == &overflowScrollLayer) 3057 return inContainingBlockChain; 3058 } 3059 3060 return false; 3066 bool scrolledByOverflowScroll = false; 3067 traverseAncestorLayers(layer, [&](const RenderLayer& ancestorLayer, bool inContainingBlockChain, bool) { 3068 if (&ancestorLayer == &overflowScrollLayer) { 3069 scrolledByOverflowScroll = inContainingBlockChain; 3070 return AncestorTraversal::Stop; 3071 } 3072 return AncestorTraversal::Continue; 3073 }); 3074 return scrolledByOverflowScroll; 3061 3075 } 3062 3076 … … 3084 3098 } 3085 3099 3086 static void collectStationaryLayerRelatedOverflowNodes(const RenderLayer& layer, const RenderLayer& /*compositedAncestor*/, Vector<ScrollingNodeID>& scrollingNodes)3100 static void collectStationaryLayerRelatedOverflowNodes(const RenderLayer& layer, const RenderLayer&, Vector<ScrollingNodeID>& scrollingNodes) 3087 3101 { 3088 3102 ASSERT(layer.isComposited()); … … 3098 3112 3099 3113 ASSERT(layer.renderer().isAbsolutelyPositioned()); 3100 bool containingBlockCanSkipLayers = true; 3101 3102 for (const auto* currLayer = layer.parent(); currLayer; currLayer = currLayer->parent()) { 3103 bool inContainingBlockChain = true; 3104 if (containingBlockCanSkipLayers) { 3105 inContainingBlockChain = currLayer->renderer().canContainAbsolutelyPositionedObjects(); 3106 if (inContainingBlockChain) 3107 containingBlockCanSkipLayers = currLayer->renderer().isAbsolutelyPositioned(); 3108 } 3109 3110 if (currLayer->hasCompositedScrollableOverflow()) { 3111 appendOverflowLayerNodeID(*currLayer); 3112 break; 3113 } 3114 } 3115 } 3116 3114 3115 // Collect all the composited scrollers which affect the position of this layer relative to its compositing ancestor (which might be inside the scroller or the scroller itself). 3116 bool seenPaintOrderAncestor = false; 3117 traverseAncestorLayers(layer, [&](const RenderLayer& ancestorLayer, bool isContainingBlockChain, bool isPaintOrderAncestor) { 3118 seenPaintOrderAncestor |= isPaintOrderAncestor; 3119 if (isContainingBlockChain && isPaintOrderAncestor) 3120 return AncestorTraversal::Stop; 3121 3122 if (seenPaintOrderAncestor && !isContainingBlockChain && ancestorLayer.hasCompositedScrollableOverflow()) 3123 appendOverflowLayerNodeID(ancestorLayer); 3124 3125 return AncestorTraversal::Continue; 3126 }); 3127 } 3117 3128 3118 3129 ScrollPositioningBehavior RenderLayerCompositor::computeCoordinatedPositioningForLayer(const RenderLayer& layer) const … … 3183 3194 case ScrollPositioningBehavior::Stationary: { 3184 3195 ASSERT(layer.renderer().isAbsolutelyPositioned()); 3185 // Collect all the composited scrollers between this layer and its composited ancestor.3186 3196 auto* compositedAncestor = layer.ancestorCompositingLayer(); 3187 3197 if (!compositedAncestor)
Note: See TracChangeset
for help on using the changeset viewer.