Implement backing-sharing in compositing layers, allowing overlap layers to paint...
[WebKit-https.git] / Source / WebCore / rendering / RenderLayer.h
index 8cb856e..da4beb9 100644 (file)
@@ -63,6 +63,7 @@ namespace WebCore {
 class CSSFilter;
 class ClipRects;
 class ClipRectsCache;
+class EventRegion;
 class HitTestRequest;
 class HitTestResult;
 class HitTestingTransformState;
@@ -80,10 +81,6 @@ class RenderView;
 class Scrollbar;
 class TransformationMatrix;
 
-#if ENABLE(POINTER_EVENTS)
-class TouchActionRegion;
-#endif
-
 enum BorderRadiusClippingRule { IncludeSelfForBorderRadius, DoNotIncludeSelfForBorderRadius };
 enum IncludeSelfOrNot { IncludeSelf, ExcludeSelf };
 
@@ -169,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;
@@ -503,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;
     
@@ -519,6 +525,7 @@ public:
         UpdatePagination                    = 1 << 3,
         SeenTransformedLayer                = 1 << 4,
         Seen3DTransformedLayer              = 1 << 5,
+        SeenCompositedScrollingLayer        = 1 << 6,
     };
     static constexpr OptionSet<UpdateLayerPositionsFlag> updateLayerPositionsDefaultFlags() { return { CheckForRepaint }; }
 
@@ -596,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;
@@ -694,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;
 
@@ -783,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; }
@@ -806,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);
@@ -817,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());
@@ -881,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(); }
 
@@ -916,10 +941,7 @@ private:
         OptionSet<PaintBehavior> paintBehavior;
         bool requireSecurityOriginAccessForWidgets;
         bool clipToDirtyRect { true };
-        Region* eventRegion { nullptr };
-#if ENABLE(POINTER_EVENTS)
-        TouchActionRegion* touchActionRegion { nullptr };
-#endif
+        EventRegion* eventRegion { nullptr };
     };
 
     // Compute, cache and return clip rects computed with the given layer as the root.
@@ -1171,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;
@@ -1207,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;
 
@@ -1243,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