Bug 1298218 - Apply the clip of a sticky item to the layer as a scrolled clip. r?mattwoodrow draft
authorMarkus Stange <mstange@themasta.com>
Thu, 25 Aug 2016 17:06:49 -0400
changeset 469209 a36f0f41c2ad9dd1729ec368a0b03ad4b31ff865
parent 469208 1b0993c16133f2c60a3037fd01ff529efbe07adc
child 469210 e1e215c6bda146c6af317992453883e70316aacd
push id43652
push userbmo:mstange@themasta.com
push dateWed, 01 Feb 2017 21:18:30 +0000
reviewersmattwoodrow
bugs1298218
milestone54.0a1
Bug 1298218 - Apply the clip of a sticky item to the layer as a scrolled clip. r?mattwoodrow MozReview-Commit-ID: JnHCj0oQjsM
layout/painting/FrameLayerBuilder.cpp
layout/painting/nsDisplayList.cpp
layout/painting/nsDisplayList.h
--- a/layout/painting/FrameLayerBuilder.cpp
+++ b/layout/painting/FrameLayerBuilder.cpp
@@ -4027,17 +4027,18 @@ ContainerState::ProcessDisplayItems(nsDi
       topLeft = lastAGRTopLeft;
       item->FuseClipChainUpTo(mBuilder, mContainerASR);
     } else {
       forceInactive = false;
       if (mManager->IsWidgetLayerManager()) {
         animatedGeometryRoot = item->GetAnimatedGeometryRoot();
         itemASR = item->GetActiveScrolledRoot();
         const DisplayItemClipChain* itemClipChain = item->GetClipChain();
-        if (itemClipChain && itemClipChain->mASR == itemASR) {
+        if (itemClipChain && itemClipChain->mASR == itemASR &&
+            itemType != nsDisplayItem::TYPE_STICKY_POSITION) {
           layerClipChain = itemClipChain->mParent;
         } else {
           layerClipChain = itemClipChain;
         }
       } else {
         // For inactive layer subtrees, splitting content into PaintedLayers
         // based on animated geometry roots is pointless. It's more efficient
         // to build the minimum number of layers.
@@ -4154,17 +4155,18 @@ ContainerState::ProcessDisplayItems(nsDi
       nsIntRect clipRectUntyped;
       nsIntRect* clipPtr = nullptr;
       if (itemClip.HasClip()) {
         clipRectUntyped = clipRect.ToUnknownRect();
         clipPtr = &clipRectUntyped;
       }
 
       bool hasScrolledClip = layerClipChain && layerClipChain->mClip.HasClip() &&
-        !ActiveScrolledRoot::IsAncestor(layerClipChain->mASR, itemASR);
+        (!ActiveScrolledRoot::IsAncestor(layerClipChain->mASR, itemASR) ||
+         itemType == nsDisplayItem::TYPE_STICKY_POSITION);
 
       if (hasScrolledClip) {
         // If the clip is scrolled, reserve just the area of the clip for
         // layerization, so that elements outside the clip can still merge
         // into the same layer.
         const ActiveScrolledRoot* clipASR = layerClipChain->mASR;
         AnimatedGeometryRoot* clipAGR = mBuilder->AnimatedGeometryRootForASR(clipASR);
         nsIntRect scrolledClipRect =
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -5698,16 +5698,24 @@ bool nsDisplayFixedPosition::TryMerge(ns
 
 nsDisplayStickyPosition::nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder,
                                                  nsIFrame* aFrame,
                                                  nsDisplayList* aList,
                                                  const ActiveScrolledRoot* aActiveScrolledRoot)
   : nsDisplayOwnLayer(aBuilder, aFrame, aList, aActiveScrolledRoot)
 {
   MOZ_COUNT_CTOR(nsDisplayStickyPosition);
+  mClip = nullptr;
+}
+
+void
+nsDisplayStickyPosition::SetClipChain(const DisplayItemClipChain* aClipChain)
+{
+  mClipChain = aClipChain;
+  MOZ_ASSERT(!mClip, "There should never be a clip on this item because no clip moves with it.");
 }
 
 #ifdef NS_BUILD_REFCNT_LOGGING
 nsDisplayStickyPosition::~nsDisplayStickyPosition() {
   MOZ_COUNT_DTOR(nsDisplayStickyPosition);
 }
 #endif
 
--- a/layout/painting/nsDisplayList.h
+++ b/layout/painting/nsDisplayList.h
@@ -3989,16 +3989,17 @@ class nsDisplayStickyPosition : public n
 public:
   nsDisplayStickyPosition(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
                           nsDisplayList* aList,
                           const ActiveScrolledRoot* aActiveScrolledRoot);
 #ifdef NS_BUILD_REFCNT_LOGGING
   virtual ~nsDisplayStickyPosition();
 #endif
 
+  void SetClipChain(const DisplayItemClipChain* aClipChain) override;
   virtual already_AddRefed<Layer> BuildLayer(nsDisplayListBuilder* aBuilder,
                                              LayerManager* aManager,
                                              const ContainerLayerParameters& aContainerParameters) override;
   NS_DISPLAY_DECL_NAME("StickyPosition", TYPE_STICKY_POSITION)
   virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder,
                                    LayerManager* aManager,
                                    const ContainerLayerParameters& aParameters) override
   {