Implement backing-sharing in compositing layers, allowing overlap layers to paint...
[WebKit-https.git] / Source / WebCore / rendering / RenderLayer.h
index ff911b5..da4beb9 100644 (file)
@@ -63,9 +63,11 @@ namespace WebCore {
 class CSSFilter;
 class ClipRects;
 class ClipRectsCache;
+class EventRegion;
 class HitTestRequest;
 class HitTestResult;
 class HitTestingTransformState;
+class Region;
 class RenderFragmentedFlow;
 class RenderGeometryMap;
 class RenderLayerBacking;
@@ -164,7 +166,15 @@ public:
     void removeOnlyThisLayer();
 
     bool isNormalFlowOnly() const { return m_isNormalFlowOnly; }
-    bool isStackingContext() const { return m_isStackingContext; }
+
+    // isStackingContext is true for layers that we've determined should be stacking contexts for painting.
+    // Not all stacking contexts are CSS stacking contexts.
+    bool isStackingContext() const { return isCSSStackingContext() || m_isOpportunisticStackingContext; }
+
+    // isCSSStackingContext is true for layers that are stacking contexts from a CSS perspective.
+    // isCSSStackingContext() => isStackingContext().
+    // FIXME: m_forcedStackingContext should affect isStackingContext(), not isCSSStackingContext(), but doing so breaks media control mix-blend-mode.
+    bool isCSSStackingContext() const { return m_isCSSStackingContext || m_forcedStackingContext; }
 
     // Gets the enclosing stacking context for this layer, excluding this layer itself.
     RenderLayer* stackingContext() const;
@@ -399,6 +409,7 @@ public:
 
     IntSize visibleSize() const override;
     IntSize contentsSize() const override;
+    IntSize reachableTotalContentsSize() const override;
 
     int scrollWidth() const;
     int scrollHeight() const;
@@ -408,18 +419,19 @@ public:
     // Scrolling methods for layers that can scroll their overflow.
     void scrollByRecursively(const IntSize& delta, ScrollableArea** scrolledArea = nullptr);
 
-    WEBCORE_EXPORT void scrollToOffset(const ScrollOffset&, ScrollClamping = ScrollClamping::Clamped);
-    void scrollToXOffset(int x, ScrollClamping clamping = ScrollClamping::Clamped) { scrollToOffset(ScrollOffset(x, scrollOffset().y()), clamping); }
-    void scrollToYOffset(int y, ScrollClamping clamping = ScrollClamping::Clamped) { scrollToOffset(ScrollOffset(scrollOffset().x(), y), clamping); }
+    WEBCORE_EXPORT void scrollToOffset(const ScrollOffset&, ScrollType = ScrollType::Programmatic, ScrollClamping = ScrollClamping::Clamped);
+
+    void scrollToXPosition(int x, ScrollType, ScrollClamping = ScrollClamping::Clamped);
+    void scrollToYPosition(int y, ScrollType, ScrollClamping = ScrollClamping::Clamped);
 
-    void scrollToXPosition(int x, ScrollClamping = ScrollClamping::Clamped);
-    void scrollToYPosition(int y, ScrollClamping = ScrollClamping::Clamped);
+    // These are only used by marquee.
+    void scrollToXOffset(int x) { scrollToOffset(ScrollOffset(x, scrollOffset().y()), ScrollType::Programmatic, ScrollClamping::Unclamped); }
+    void scrollToYOffset(int y) { scrollToOffset(ScrollOffset(scrollOffset().x(), y), ScrollType::Programmatic, ScrollClamping::Unclamped); }
 
     void setPostLayoutScrollPosition(Optional<ScrollPosition>);
     void applyPostLayoutScrollPositionIfNeeded();
 
     ScrollOffset scrollOffset() const { return scrollOffsetFromPosition(m_scrollPosition); }
-    IntSize scrollableContentsSize() const;
 
     void availableContentSizeChanged(AvailableSizeChangeReason) override;
 
@@ -437,18 +449,26 @@ public:
     bool hasHorizontalScrollbar() const { return horizontalScrollbar(); }
     bool hasVerticalScrollbar() const { return verticalScrollbar(); }
 
+    bool horizontalScrollbarHiddenByStyle() const override;
+    bool verticalScrollbarHiddenByStyle() const override;
+
     // ScrollableArea overrides
     ScrollPosition scrollPosition() const override { return m_scrollPosition; }
 
     Scrollbar* horizontalScrollbar() const override { return m_hBar.get(); }
     Scrollbar* verticalScrollbar() const override { return m_vBar.get(); }
     ScrollableArea* enclosingScrollableArea() const override;
+
     bool isScrollableOrRubberbandable() override;
     bool hasScrollableOrRubberbandableAncestor() override;
+    bool useDarkAppearance() const final;
 #if ENABLE(CSS_SCROLL_SNAP)
     void updateSnapOffsets() override;
 #endif
 
+    bool requiresScrollPositionReconciliation() const { return m_requiresScrollPositionReconciliation; }
+    void setRequiresScrollPositionReconciliation(bool requiresReconciliation = true) { m_requiresScrollPositionReconciliation = requiresReconciliation; }
+
 #if PLATFORM(IOS_FAMILY)
 #if ENABLE(IOS_TOUCH_EVENTS)
     bool handleTouchEvent(const PlatformTouchEvent&) override;
@@ -457,12 +477,6 @@ public:
     void didStartScroll() override;
     void didEndScroll() override;
     void didUpdateScroll() override;
-    void setIsUserScroll(bool isUserScroll) override { m_inUserScroll = isUserScroll; }
-
-    bool isInUserScroll() const { return m_inUserScroll; }
-
-    bool requiresScrollBoundsOriginUpdate() const { return m_requiresScrollBoundsOriginUpdate; }
-    void setRequiresScrollBoundsOriginUpdate(bool requiresUpdate = true) { m_requiresScrollBoundsOriginUpdate = requiresUpdate; }
 #endif
 
     // Returns true when the layer could do touch scrolling, but doesn't look at whether there is actually scrollable overflow.
@@ -494,6 +508,7 @@ public:
 
     bool isRenderViewLayer() const { return m_isRenderViewLayer; }
     bool isForcedStackingContext() const { return m_forcedStackingContext; }
+    bool isOpportunisticStackingContext() const { return m_isOpportunisticStackingContext; }
 
     RenderLayerCompositor& compositor() const;
     
@@ -504,11 +519,13 @@ public:
     bool canRender3DTransforms() const;
 
     enum UpdateLayerPositionsFlag {
-        CheckForRepaint                 = 1 << 0,
-        NeedsFullRepaintInBacking       = 1 << 1,
-        UpdatePagination                = 1 << 2,
-        SeenTransformedLayer            = 1 << 3,
-        Seen3DTransformedLayer          = 1 << 4,
+        CheckForRepaint                     = 1 << 0,
+        NeedsFullRepaintInBacking           = 1 << 1,
+        ContainingClippingLayerChangedSize  = 1 << 2,
+        UpdatePagination                    = 1 << 3,
+        SeenTransformedLayer                = 1 << 4,
+        Seen3DTransformedLayer              = 1 << 5,
+        SeenCompositedScrollingLayer        = 1 << 6,
     };
     static constexpr OptionSet<UpdateLayerPositionsFlag> updateLayerPositionsDefaultFlags() { return { CheckForRepaint }; }
 
@@ -586,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;
@@ -638,8 +657,9 @@ public:
         PaintLayerPaintingRootBackgroundOnly            = 1 << 11,
         PaintLayerPaintingSkipRootBackground            = 1 << 12,
         PaintLayerPaintingChildClippingMaskPhase        = 1 << 13,
+        PaintLayerCollectingEventRegion                 = 1 << 14,
     };
-    static constexpr OptionSet<PaintLayerFlag> paintLayerPaintingCompositingAllPhasesFlags() { return { PaintLayerPaintingCompositingBackgroundPhase,  PaintLayerPaintingCompositingForegroundPhase }; }
+    static constexpr OptionSet<PaintLayerFlag> paintLayerPaintingCompositingAllPhasesFlags() { return { PaintLayerPaintingCompositingBackgroundPhase, PaintLayerPaintingCompositingForegroundPhase }; }
 
     enum class SecurityOriginPaintPolicy { AnyOrigin, AccessibleOriginOnly };
 
@@ -683,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;
 
@@ -772,14 +794,14 @@ public:
     bool hasBlendMode() const { return renderer().hasBlendMode(); }
     BlendMode blendMode() const { return static_cast<BlendMode>(m_blendMode); }
 
-    bool isolatesCompositedBlending() const { return m_hasNotIsolatedCompositedBlendingDescendants && isStackingContext(); }
+    bool isolatesCompositedBlending() const { return m_hasNotIsolatedCompositedBlendingDescendants && isCSSStackingContext(); }
     bool hasNotIsolatedCompositedBlendingDescendants() const { return m_hasNotIsolatedCompositedBlendingDescendants; }
     void setHasNotIsolatedCompositedBlendingDescendants(bool hasNotIsolatedCompositedBlendingDescendants)
     {
         m_hasNotIsolatedCompositedBlendingDescendants = hasNotIsolatedCompositedBlendingDescendants;
     }
 
-    bool isolatesBlending() const { return hasNotIsolatedBlendingDescendants() && isStackingContext(); }
+    bool isolatesBlending() const { return hasNotIsolatedBlendingDescendants() && isCSSStackingContext(); }
     
     // FIXME: We should ASSERT(!m_hasNotIsolatedBlendingDescendantsStatusDirty); here but we hit the same bugs as visible content above.
     bool hasNotIsolatedBlendingDescendants() const { return m_hasNotIsolatedBlendingDescendants; }
@@ -795,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);
@@ -806,6 +835,9 @@ public:
     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());
@@ -855,6 +887,10 @@ public:
     void simulateFrequentPaint() { SinglePaintFrequencyTracking { m_paintFrequencyTracker }; }
     bool paintingFrequently() const { return m_paintFrequencyTracker.paintingFrequently(); }
 
+    WEBCORE_EXPORT bool isTransparentOrFullyClippedRespectingParentFrames() const;
+
+    void invalidateEventRegion();
+
 private:
 
     void setNextSibling(RenderLayer* next) { m_next = next; }
@@ -866,11 +902,15 @@ private:
     void dirtyPaintOrderListsOnChildChange(RenderLayer&);
 
     bool shouldBeNormalFlowOnly() const;
-    bool shouldBeStackingContext() const;
-    
+    bool shouldBeCSSStackingContext() const;
+
     // Return true if changed.
     bool setIsNormalFlowOnly(bool);
-    bool setIsStackingContext(bool);
+
+    bool setIsOpportunisticStackingContext(bool);
+    bool setIsCSSStackingContext(bool);
+    
+    void isStackingContextChanged();
 
     bool isDirtyStackingContext() const { return m_zOrderListsDirty && isStackingContext(); }
 
@@ -901,6 +941,7 @@ private:
         OptionSet<PaintBehavior> paintBehavior;
         bool requireSecurityOriginAccessForWidgets;
         bool clipToDirtyRect { true };
+        EventRegion* eventRegion { nullptr };
     };
 
     // Compute, cache and return clip rects computed with the given layer as the root.
@@ -930,7 +971,7 @@ private:
     void updateScrollbarsAfterLayout();
 
     // Returns true if the position changed.
-    bool updateLayerPosition();
+    bool updateLayerPosition(OptionSet<UpdateLayerPositionsFlag>* = nullptr);
 
     void updateLayerPositions(RenderGeometryMap* = nullptr, OptionSet<UpdateLayerPositionsFlag> = updateLayerPositionsDefaultFlags());
 
@@ -978,6 +1019,7 @@ private:
     void paintMaskForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintBehavior>, RenderObject* paintingRootForRenderer);
     void paintChildClippingMaskForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintBehavior>, RenderObject* paintingRootForRenderer);
     void paintTransformedLayerIntoFragments(GraphicsContext&, const LayerPaintingInfo&, OptionSet<PaintLayerFlag>);
+    void collectEventRegionForFragments(const LayerFragments&, GraphicsContext&, const LayerPaintingInfo&);
 
     RenderLayer* transparentPaintingAncestor();
     void beginTransparencyLayers(GraphicsContext&, const LayerPaintingInfo&, const LayoutRect& dirtyRect);
@@ -1030,6 +1072,7 @@ private:
     IntPoint convertFromContainingViewToScrollbar(const Scrollbar&, const IntPoint&) const override;
     int scrollSize(ScrollbarOrientation) const override;
     void setScrollOffset(const ScrollOffset&) override;
+    ScrollingNodeID scrollingNodeID() const override;
 
     IntRect visibleContentRectInternal(VisibleContentRectIncludesScrollbars, VisibleContentRectBehavior) const override;
     IntSize overhangAmount() const override;
@@ -1115,6 +1158,7 @@ private:
     enum class IndirectCompositingReason {
         None,
         Stacking,
+        OverflowScrollPositioning,
         Overlap,
         BackgroundLayer,
         GraphicalEffect, // opacity, mask, filter, transform etc.
@@ -1149,7 +1193,8 @@ private:
     const bool m_forcedStackingContext : 1;
 
     bool m_isNormalFlowOnly : 1;
-    bool m_isStackingContext : 1;
+    bool m_isCSSStackingContext : 1;
+    bool m_isOpportunisticStackingContext : 1;
 
     bool m_zOrderListsDirty : 1;
     bool m_normalFlowListDirty: 1;
@@ -1185,6 +1230,8 @@ private:
                                             // 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;
 
@@ -1192,14 +1239,13 @@ private:
     unsigned m_viewportConstrainedNotCompositedReason : 2;
 
 #if PLATFORM(IOS_FAMILY)
-    bool m_adjustForIOSCaretWhenScrolling : 1;
 #if ENABLE(IOS_TOUCH_EVENTS)
     bool m_registeredAsTouchEventListenerForScrolling : 1;
 #endif
-    bool m_inUserScroll : 1;
-    bool m_requiresScrollBoundsOriginUpdate : 1;
+    bool m_adjustForIOSCaretWhenScrolling : 1;
 #endif
 
+    bool m_requiresScrollPositionReconciliation : 1;
     bool m_containsDirtyOverlayScrollbars : 1;
     bool m_updatingMarqueePosition : 1;
 
@@ -1222,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