https://bugs.webkit.org/show_bug.cgi?id=196848
Reviewed by Zalan Bujtas.
Maintain a bit on RenderLayer which says if a layer has a composited scrolling ancestor
in the layer tree. We only need to do work related to making positioned scrolling tree nodes
for layers which are layer tree descendants of overflow:scroll.
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::RenderLayer):
(WebCore::RenderLayer::updateLayerPositions):
(WebCore::outputPaintOrderTreeLegend):
(WebCore::outputPaintOrderTreeRecursive):
* rendering/RenderLayer.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::requiresCompositingForPosition const):
(WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason const):
(WebCore::RenderLayerCompositor::isViewportConstrainedFixedOrStickyLayer const):
(WebCore::RenderLayerCompositor::fixedLayerIntersectsViewport const):
(WebCore::RenderLayerCompositor::computeCoordinatedPositioningForLayer const):
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@244209
268f45cc-cd09-0410-ab3c-
d52691b4dbfc
+2019-04-11 Simon Fraser <simon.fraser@apple.com>
+
+ Avoid doing positioned scrolling tree node work for layers not inside overflow:scroll
+ https://bugs.webkit.org/show_bug.cgi?id=196848
+
+ Reviewed by Zalan Bujtas.
+
+ Maintain a bit on RenderLayer which says if a layer has a composited scrolling ancestor
+ in the layer tree. We only need to do work related to making positioned scrolling tree nodes
+ for layers which are layer tree descendants of overflow:scroll.
+
+ * rendering/RenderLayer.cpp:
+ (WebCore::RenderLayer::RenderLayer):
+ (WebCore::RenderLayer::updateLayerPositions):
+ (WebCore::outputPaintOrderTreeLegend):
+ (WebCore::outputPaintOrderTreeRecursive):
+ * rendering/RenderLayer.h:
+ * rendering/RenderLayerCompositor.cpp:
+ (WebCore::RenderLayerCompositor::requiresCompositingForPosition const):
+ (WebCore::RenderLayerCompositor::requiresCompositingForIndirectReason const):
+ (WebCore::RenderLayerCompositor::isViewportConstrainedFixedOrStickyLayer const):
+ (WebCore::RenderLayerCompositor::fixedLayerIntersectsViewport const):
+ (WebCore::RenderLayerCompositor::computeCoordinatedPositioningForLayer const):
+
2019-04-11 Zalan Bujtas <zalan@apple.com>
Try to fix Windows build.
, m_3DTransformedDescendantStatusDirty(true)
, m_has3DTransformedDescendant(false)
, m_hasCompositingDescendant(false)
+ , m_hasCompositedScrollingAncestor(false)
, m_hasTransformedAncestor(false)
, m_has3DTransformedAncestor(false)
, m_indirectCompositingReason(static_cast<unsigned>(IndirectCompositingReason::None))
m_repaintStatus = NeedsNormalRepaint;
m_hasTransformedAncestor = flags.contains(SeenTransformedLayer);
m_has3DTransformedAncestor = flags.contains(Seen3DTransformedLayer);
+ setHasCompositedScrollingAncestor(flags.contains(SeenCompositedScrollingLayer));
// Update the reflection's position and size.
if (m_reflection)
if (!transform()->isAffine())
flags.add(Seen3DTransformedLayer);
}
+
+ if (hasCompositedScrollableOverflow())
+ flags.add(SeenCompositedScrollingLayer);
for (RenderLayer* child = firstChild(); child; child = child->nextSibling())
child->updateLayerPositions(geometryMap, flags);
m_updatingMarqueePosition = oldUpdatingMarqueePosition;
}
- if (renderer().isOutOfFlowPositioned() && renderer().style().position() == PositionType::Fixed && renderer().settings().acceleratedCompositingForFixedPositionEnabled()) {
+ if (renderer().isFixedPositioned() && renderer().settings().acceleratedCompositingForFixedPositionEnabled()) {
bool intersectsViewport = compositor().fixedLayerIntersectsViewport(*this);
if (intersectsViewport != m_isFixedIntersectingViewport) {
m_isFixedIntersectingViewport = intersectsViewport;
static void outputPaintOrderTreeLegend(TextStream& stream)
{
stream.nextLine();
- stream << "(S)tacking Context, (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\n"
+ stream << "(S)tacking Context, (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"
"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";
stream << (layer.renderer().isFixedPositioned() ? "X" : "-");
stream << (layer.isComposited() ? "C" : "-");
stream << (layer.hasCompositingDescendant() ? "c" : "-");
+ stream << (layer.hasCompositedScrollingAncestor() ? "s" : "-");
stream << " ";
UpdatePagination = 1 << 3,
SeenTransformedLayer = 1 << 4,
Seen3DTransformedLayer = 1 << 5,
+ SeenCompositedScrollingLayer = 1 << 6,
};
static constexpr OptionSet<UpdateLayerPositionsFlag> updateLayerPositionsDefaultFlags() { return { CheckForRepaint }; }
bool usesCompositedScrolling() const override;
bool usesAsyncScrolling() const override;
+ bool hasCompositedScrollingAncestor() const { return m_hasCompositedScrollingAncestor; }
+ void setHasCompositedScrollingAncestor(bool hasCompositedScrollingAncestor) { m_hasCompositedScrollingAncestor = hasCompositedScrollingAncestor; }
+
bool paintsWithTransparency(OptionSet<PaintBehavior> paintBehavior) const
{
return (isTransparent() || hasBlendMode() || (isolatesBlending() && !renderer().isDocumentElementRenderer())) && ((paintBehavior & PaintBehavior::FlattenCompositingLayers) || !isComposited());
// in a preserves3D hierarchy. Hint to do 3D-aware hit testing.
bool m_hasCompositingDescendant : 1; // In the z-order tree.
+ bool m_hasCompositedScrollingAncestor : 1; // In the layer-order tree.
+
bool m_hasTransformedAncestor : 1;
bool m_has3DTransformedAncestor : 1;
#endif
auto position = renderer.style().position();
- bool isFixed = renderer.isOutOfFlowPositioned() && position == PositionType::Fixed;
+ bool isFixed = renderer.isFixedPositioned();
if (isFixed && !layer.isStackingContext())
return false;
}
}
- if (renderer.isAbsolutelyPositioned() && compositingAncestor) {
+ if (renderer.isAbsolutelyPositioned() && compositingAncestor && layer.hasCompositedScrollingAncestor()) {
if (layerContainingBlockCrossesCoordinatedScrollingBoundary(layer, *compositingAncestor)) {
reason = RenderLayer::IndirectCompositingReason::OverflowScrollPositioning;
return true;
if (layer.renderer().isStickilyPositioned())
return isAsyncScrollableStickyLayer(layer);
- if (layer.renderer().style().position() != PositionType::Fixed)
+ if (!layer.renderer().isFixedPositioned())
return false;
// FIXME: Handle fixed inside of a transform, which should not behave as fixed.
bool RenderLayerCompositor::fixedLayerIntersectsViewport(const RenderLayer& layer) const
{
- ASSERT(layer.renderer().style().position() == PositionType::Fixed);
+ ASSERT(layer.renderer().isFixedPositioned());
// Fixed position elements that are invisible in the current view don't get their own layer.
// FIXME: We shouldn't have to check useFixedLayout() here; one of the viewport rects needs to give the correct answer.
if (layer.renderer().isFixedPositioned())
return ScrollPositioningBehavior::None;
+
+ if (!layer.hasCompositedScrollingAncestor())
+ return ScrollPositioningBehavior::None;
auto* scrollingCoordinator = this->scrollingCoordinator();
if (!scrollingCoordinator)