diff --git a/gfx/ipc/GfxMessageUtils.h b/gfx/ipc/GfxMessageUtils.h index 44f06883a2a0..22476cf8bb8b 100644 --- a/gfx/ipc/GfxMessageUtils.h +++ b/gfx/ipc/GfxMessageUtils.h @@ -789,24 +789,6 @@ struct ParamTraits } }; -template <> -struct ParamTraits -{ - typedef mozilla::layers::LayerClip paramType; - - static void Write(Message* aMsg, const paramType& aParam) - { - WriteParam(aMsg, aParam.mClipRect); - WriteParam(aMsg, aParam.mMaskLayerIndex); - } - - static bool Read(const Message* aMsg, void** aIter, paramType* aResult) - { - return (ReadParam(aMsg, aIter, &aResult->mClipRect) && - ReadParam(aMsg, aIter, &aResult->mMaskLayerIndex)); - } -}; - template <> struct ParamTraits : BitfieldHelper @@ -822,7 +804,8 @@ struct ParamTraits WriteParam(aMsg, aParam.GetContentDescription()); WriteParam(aMsg, aParam.mLineScrollAmount); WriteParam(aMsg, aParam.mPageScrollAmount); - WriteParam(aMsg, aParam.mScrollClip); + WriteParam(aMsg, aParam.mMaskLayerIndex); + WriteParam(aMsg, aParam.mClipRect); WriteParam(aMsg, aParam.mHasScrollgrab); WriteParam(aMsg, aParam.mAllowVerticalScrollWithWheel); WriteParam(aMsg, aParam.mIsLayersIdRoot); @@ -849,7 +832,8 @@ struct ParamTraits ReadContentDescription(aMsg, aIter, aResult) && ReadParam(aMsg, aIter, &aResult->mLineScrollAmount) && ReadParam(aMsg, aIter, &aResult->mPageScrollAmount) && - ReadParam(aMsg, aIter, &aResult->mScrollClip) && + ReadParam(aMsg, aIter, &aResult->mMaskLayerIndex) && + ReadParam(aMsg, aIter, &aResult->mClipRect) && ReadBoolForBitfield(aMsg, aIter, aResult, ¶mType::SetHasScrollgrab) && ReadBoolForBitfield(aMsg, aIter, aResult, ¶mType::SetAllowVerticalScrollWithWheel) && ReadBoolForBitfield(aMsg, aIter, aResult, ¶mType::SetIsLayersIdRoot) && diff --git a/gfx/layers/FrameMetrics.h b/gfx/layers/FrameMetrics.h index e86bf5f1e803..b813b7cc0b36 100644 --- a/gfx/layers/FrameMetrics.h +++ b/gfx/layers/FrameMetrics.h @@ -679,54 +679,6 @@ struct ScrollSnapInfo { nsTArray mScrollSnapCoordinates; }; -/** - * A clip that applies to a layer, that may be scrolled by some of the - * scroll frames associated with the layer. - */ -struct LayerClip { - friend struct IPC::ParamTraits; - -public: - LayerClip() - : mClipRect() - , mMaskLayerIndex() - {} - - explicit LayerClip(const ParentLayerIntRect& aClipRect) - : mClipRect(aClipRect) - , mMaskLayerIndex() - {} - - bool operator==(const LayerClip& aOther) const - { - return mClipRect == aOther.mClipRect && - mMaskLayerIndex == aOther.mMaskLayerIndex; - } - - void SetClipRect(const ParentLayerIntRect& aClipRect) { - mClipRect = aClipRect; - } - const ParentLayerIntRect& GetClipRect() const { - return mClipRect; - } - - void SetMaskLayerIndex(const Maybe& aIndex) { - mMaskLayerIndex = aIndex; - } - const Maybe& GetMaskLayerIndex() const { - return mMaskLayerIndex; - } - -private: - ParentLayerIntRect mClipRect; - - // Optionally, specifies a mask layer that's part of the clip. - // This is an index into the MetricsMaskLayers array on the Layer. - Maybe mMaskLayerIndex; -}; - -typedef Maybe MaybeLayerClip; // for passing over IPDL - /** * Metadata about a scroll frame that's stored in the layer tree for use by * the compositor (including APZ). This includes the scroll frame's FrameMetrics, @@ -749,7 +701,8 @@ public: , mContentDescription() , mLineScrollAmount(0, 0) , mPageScrollAmount(0, 0) - , mScrollClip() + , mMaskLayerIndex() + , mClipRect() , mHasScrollgrab(false) , mAllowVerticalScrollWithWheel(false) , mIsLayersIdRoot(false) @@ -766,7 +719,8 @@ public: // don't compare mContentDescription mLineScrollAmount == aOther.mLineScrollAmount && mPageScrollAmount == aOther.mPageScrollAmount && - mScrollClip == aOther.mScrollClip && + mMaskLayerIndex == aOther.mMaskLayerIndex && + mClipRect == aOther.mClipRect && mHasScrollgrab == aOther.mHasScrollgrab && mAllowVerticalScrollWithWheel == aOther.mAllowVerticalScrollWithWheel && mIsLayersIdRoot == aOther.mIsLayersIdRoot && @@ -826,28 +780,26 @@ public: void SetPageScrollAmount(const LayoutDeviceIntSize& size) { mPageScrollAmount = size; } - - void SetScrollClip(const Maybe& aScrollClip) { - mScrollClip = aScrollClip; + void SetMaskLayerIndex(const Maybe& aIndex) { + mMaskLayerIndex = aIndex; } - const Maybe& GetScrollClip() const { - return mScrollClip; - } - bool HasScrollClip() const { - return mScrollClip.isSome(); - } - const LayerClip& ScrollClip() const { - return mScrollClip.ref(); - } - LayerClip& ScrollClip() { - return mScrollClip.ref(); + const Maybe& GetMaskLayerIndex() const { + return mMaskLayerIndex; } - bool HasMaskLayer() const { - return HasScrollClip() && ScrollClip().GetMaskLayerIndex(); + void SetClipRect(const Maybe& aClipRect) + { + mClipRect = aClipRect; } - Maybe GetClipRect() const { - return mScrollClip.isSome() ? Some(mScrollClip->GetClipRect()) : Nothing(); + const Maybe& GetClipRect() const + { + return mClipRect; + } + bool HasClipRect() const { + return mClipRect.isSome(); + } + const ParentLayerIntRect& ClipRect() const { + return mClipRect.ref(); } void SetHasScrollgrab(bool aHasScrollgrab) { @@ -904,13 +856,13 @@ private: // The value of GetPageScrollAmount(), for scroll frames. LayoutDeviceIntSize mPageScrollAmount; - // A clip to apply when compositing the layer bearing this ScrollMetadata, - // after applying any transform arising from scrolling this scroll frame. - // Note that, unlike most other fields of ScrollMetadata, this is allowed - // to differ between different layers scrolled by the same scroll frame. - // TODO: Group the fields of ScrollMetadata into sub-structures to separate - // fields with this property better. - Maybe mScrollClip; + // An extra clip mask layer to use when compositing a layer with this + // FrameMetrics. This is an index into the MetricsMaskLayers array on + // the Layer. + Maybe mMaskLayerIndex; + + // The clip rect to use when compositing a layer with this FrameMetrics. + Maybe mClipRect; // Whether or not this frame is for an element marked 'scrollgrab'. bool mHasScrollgrab:1; diff --git a/gfx/layers/LayerMetricsWrapper.h b/gfx/layers/LayerMetricsWrapper.h index d98a37513b1e..8537dfdd9165 100644 --- a/gfx/layers/LayerMetricsWrapper.h +++ b/gfx/layers/LayerMetricsWrapper.h @@ -372,14 +372,10 @@ public: Maybe result; - // The layer can have a clip rect and a scrolled clip, which are considered - // to apply only to the bottommost LayerMetricsWrapper. - // TODO: These actually apply in a different coordinate space than the - // scroll clip of the bottommost metrics, so we shouldn't be intersecting - // them with the scroll clip; bug 1269537 tracks fixing this. + // The layer can have a clip rect, which is considered to apply + // only to the bottommost LayerMetrics. if (AtBottomLayer()) { result = mLayer->GetClipRect(); - result = IntersectMaybeRects(result, mLayer->GetScrolledClipRect()); } // The scroll metadata can have a clip rect as well. diff --git a/gfx/layers/Layers.cpp b/gfx/layers/Layers.cpp index d66caa9c80bb..cef8efe4c7db 100644 --- a/gfx/layers/Layers.cpp +++ b/gfx/layers/Layers.cpp @@ -851,12 +851,6 @@ Layer::CalculateScissorRect(const RenderTargetIntRect& aCurrentScissorRect) return currentClip.Intersect(scissor); } -Maybe -Layer::GetScrolledClipRect() const -{ - return mScrolledClip ? Some(mScrolledClip->GetClipRect()) : Nothing(); -} - const ScrollMetadata& Layer::GetScrollMetadata(uint32_t aIndex) const { @@ -1106,10 +1100,17 @@ Layer::GetCombinedClipRect() const { Maybe clip = GetClipRect(); - clip = IntersectMaybeRects(clip, GetScrolledClipRect()); - for (size_t i = 0; i < mScrollMetadata.Length(); i++) { - clip = IntersectMaybeRects(clip, mScrollMetadata[i].GetClipRect()); + if (!mScrollMetadata[i].HasClipRect()) { + continue; + } + + const ParentLayerIntRect& other = mScrollMetadata[i].ClipRect(); + if (clip) { + clip = Some(clip.value().Intersect(other)); + } else { + clip = Some(other); + } } return clip; @@ -1910,9 +1911,6 @@ Layer::PrintInfo(std::stringstream& aStream, const char* aPrefix) if (mClipRect) { AppendToString(aStream, *mClipRect, " [clip=", "]"); } - if (mScrolledClip) { - AppendToString(aStream, mScrolledClip->GetClipRect(), " [scrolled-clip=", "]"); - } if (1.0 != mPostXScale || 1.0 != mPostYScale) { aStream << nsPrintfCString(" [postScale=%g, %g]", mPostXScale, mPostYScale).get(); } @@ -1968,10 +1966,11 @@ Layer::PrintInfo(std::stringstream& aStream, const char* aPrefix) } if (GetIsFixedPosition()) { LayerPoint anchor = GetFixedPositionAnchor(); - aStream << nsPrintfCString(" [isFixedPosition scrollId=%lld sides=0x%x anchor=%s]", + aStream << nsPrintfCString(" [isFixedPosition scrollId=%lld sides=0x%x anchor=%s%s]", GetFixedPositionScrollContainerId(), GetFixedPositionSides(), - ToString(anchor).c_str()).get(); + ToString(anchor).c_str(), + IsClipFixed() ? "" : " scrollingClip").get(); } if (GetIsStickyPosition()) { aStream << nsPrintfCString(" [isStickyPosition scrollId=%d outer=%f,%f %fx%f " diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index 1887afc2cfc8..c43d8e32f860 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -1035,26 +1035,6 @@ public: } } - /** - * CONSTRUCTION PHASE ONLY - * Set an optional scrolled clip on the layer. - * The scrolled clip, if present, consists of a clip rect and an optional mask. - * This scrolled clip is always scrolled by all scroll frames associated with - * this layer. (By contrast, the scroll clips stored in ScrollMetadata are - * only scrolled by scroll frames above that ScrollMetadata, and the layer's - * mClipRect is always fixed to the layer contents (which may or may not be - * scrolled by some of the scroll frames associated with the layer, depending - * on whether the layer is fixed).) - */ - void SetScrolledClip(const Maybe& aScrolledClip) - { - if (mScrolledClip != aScrolledClip) { - MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) ScrolledClip", this)); - mScrolledClip = aScrolledClip; - Mutated(); - } - } - /** * CONSTRUCTION PHASE ONLY * Set a layer to mask this layer. @@ -1088,7 +1068,7 @@ public: /** * CONSTRUCTION PHASE ONLY - * Add mask layers associated with LayerClips. + * Add a FrameMetrics-associated mask layer. */ void SetAncestorMaskLayers(const nsTArray>& aLayers) { if (aLayers != mAncestorMaskLayers) { @@ -1098,15 +1078,6 @@ public: } } - /** - * CONSTRUCTION PHASE ONLY - * Add a mask layer associated with a LayerClip. - */ - void AddAncestorMaskLayer(const RefPtr& aLayer) { - mAncestorMaskLayers.AppendElement(aLayer); - Mutated(); - } - /** * CONSTRUCTION PHASE ONLY * Tell this layer what its transform should be. The transformation @@ -1218,15 +1189,22 @@ public: * This is used if the viewport size is changed in the compositor and * fixed position items need to shift accordingly. This value is made up * combining appropriate values from mozilla::SideBits. + * + * - |aIsClipFixed| is true if this layer's clip rect and mask layer + * should also remain fixed during async scrolling/animations. + * This is the case for fixed position layers, but not for + * fixed background layers. */ void SetFixedPositionData(FrameMetrics::ViewID aScrollId, const LayerPoint& aAnchor, - int32_t aSides) + int32_t aSides, + bool aIsClipFixed) { if (!mFixedPositionData || mFixedPositionData->mScrollId != aScrollId || mFixedPositionData->mAnchor != aAnchor || - mFixedPositionData->mSides != aSides) { + mFixedPositionData->mSides != aSides || + mFixedPositionData->mIsClipFixed != aIsClipFixed) { MOZ_LAYERS_LOG_IF_SHADOWABLE(this, ("Layer::Mutated(%p) FixedPositionData", this)); if (!mFixedPositionData) { mFixedPositionData = MakeUnique(); @@ -1234,6 +1212,7 @@ public: mFixedPositionData->mScrollId = aScrollId; mFixedPositionData->mAnchor = aAnchor; mFixedPositionData->mSides = aSides; + mFixedPositionData->mIsClipFixed = aIsClipFixed; Mutated(); } } @@ -1302,8 +1281,6 @@ public: float GetOpacity() { return mOpacity; } gfx::CompositionOp GetMixBlendMode() const { return mMixBlendMode; } const Maybe& GetClipRect() const { return mClipRect; } - const Maybe& GetScrolledClip() const { return mScrolledClip; } - Maybe GetScrolledClipRect() const; uint32_t GetContentFlags() { return mContentFlags; } const gfx::IntRect& GetLayerBounds() const { return mLayerBounds; } const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; } @@ -1335,6 +1312,7 @@ public: FrameMetrics::ViewID GetFixedPositionScrollContainerId() { return mFixedPositionData ? mFixedPositionData->mScrollId : FrameMetrics::NULL_SCROLL_ID; } LayerPoint GetFixedPositionAnchor() { return mFixedPositionData ? mFixedPositionData->mAnchor : LayerPoint(); } int32_t GetFixedPositionSides() { return mFixedPositionData ? mFixedPositionData->mSides : eSideBitsNone; } + bool IsClipFixed() { return mFixedPositionData ? mFixedPositionData->mIsClipFixed : false; } FrameMetrics::ViewID GetStickyScrollContainerId() { return mStickyPositionData->mScrollId; } const LayerRect& GetStickyScrollRangeOuter() { return mStickyPositionData->mOuter; } const LayerRect& GetStickyScrollRangeInner() { return mStickyPositionData->mInner; } @@ -1352,9 +1330,6 @@ public: Layer* GetAncestorMaskLayerAt(size_t aIndex) const { return mAncestorMaskLayers.ElementAt(aIndex); } - const nsTArray>& GetAllAncestorMaskLayers() const { - return mAncestorMaskLayers; - } bool HasMaskLayers() const { return GetMaskLayer() || mAncestorMaskLayers.Length() > 0; @@ -1875,7 +1850,6 @@ protected: gfx::CompositionOp mMixBlendMode; bool mForceIsolatedGroup; Maybe mClipRect; - Maybe mScrolledClip; gfx::IntRect mTileSourceRect; gfx::TiledIntRegion mInvalidRegion; nsTArray > mApzcs; @@ -1887,6 +1861,7 @@ protected: FrameMetrics::ViewID mScrollId; LayerPoint mAnchor; int32_t mSides; + bool mIsClipFixed; }; UniquePtr mFixedPositionData; struct StickyPositionData { diff --git a/gfx/layers/LayersLogging.cpp b/gfx/layers/LayersLogging.cpp index 3398a9f38b90..1d7203807d10 100644 --- a/gfx/layers/LayersLogging.cpp +++ b/gfx/layers/LayersLogging.cpp @@ -154,8 +154,8 @@ AppendToString(std::stringstream& aStream, const ScrollMetadata& m, if (m.GetScrollParentId() != FrameMetrics::NULL_SCROLL_ID) { AppendToString(aStream, m.GetScrollParentId(), "] [scrollParent="); } - if (m.HasScrollClip()) { - AppendToString(aStream, m.ScrollClip().GetClipRect(), "] [clip="); + if (m.HasClipRect()) { + AppendToString(aStream, m.ClipRect(), "] [clip="); } aStream << "] }" << sfx; } diff --git a/gfx/layers/apz/src/AsyncPanZoomController.cpp b/gfx/layers/apz/src/AsyncPanZoomController.cpp index fbb3a1f2fb56..68a22c354459 100644 --- a/gfx/layers/apz/src/AsyncPanZoomController.cpp +++ b/gfx/layers/apz/src/AsyncPanZoomController.cpp @@ -3521,10 +3521,8 @@ void AsyncPanZoomController::NotifyLayersUpdated(const ScrollMetadata& aScrollMe mScrollMetadata.SetLineScrollAmount(aScrollMetadata.GetLineScrollAmount()); mScrollMetadata.SetPageScrollAmount(aScrollMetadata.GetPageScrollAmount()); mScrollMetadata.SetSnapInfo(ScrollSnapInfo(aScrollMetadata.GetSnapInfo())); - // The scroll clip can differ between layers associated a given scroll frame, - // so APZC (which keeps a single copy of ScrollMetadata per scroll frame) - // has no business using it. - mScrollMetadata.SetScrollClip(Nothing()); + mScrollMetadata.SetClipRect(aScrollMetadata.GetClipRect()); + mScrollMetadata.SetMaskLayerIndex(aScrollMetadata.GetMaskLayerIndex()); mScrollMetadata.SetIsLayersIdRoot(aScrollMetadata.IsLayersIdRoot()); mScrollMetadata.SetUsesContainerScrolling(aScrollMetadata.UsesContainerScrolling()); mFrameMetrics.SetIsScrollInfoLayer(aLayerMetrics.IsScrollInfoLayer()); diff --git a/gfx/layers/apz/test/gtest/TestHitTesting.cpp b/gfx/layers/apz/test/gtest/TestHitTesting.cpp index 63db02759b4f..15678bffdf89 100644 --- a/gfx/layers/apz/test/gtest/TestHitTesting.cpp +++ b/gfx/layers/apz/test/gtest/TestHitTesting.cpp @@ -560,7 +560,7 @@ TEST_F(APZHitTestingTester, HitTestingRespectsScrollClip_Bug1257288) { ScrollMetadata subframeMetadata = BuildScrollMetadata( FrameMetrics::START_SCROLL_ID + 1, CSSRect(0,0,200,200), ParentLayerRect(0,0,200,100)); - subframeMetadata.SetScrollClip(Some(LayerClip(ParentLayerIntRect(0,0,200,100)))); + subframeMetadata.SetClipRect(Some(ParentLayerIntRect(0,0,200,100))); layers[2]->SetScrollMetadata({subframeMetadata, rootMetadata}); layers[2]->SetClipRect(Some(ParentLayerIntRect(0,0,200,200))); SetEventRegionsBasedOnBottommostMetrics(layers[2]); diff --git a/gfx/layers/composite/AsyncCompositionManager.cpp b/gfx/layers/composite/AsyncCompositionManager.cpp index 34c7fafc919b..b947f037991f 100644 --- a/gfx/layers/composite/AsyncCompositionManager.cpp +++ b/gfx/layers/composite/AsyncCompositionManager.cpp @@ -215,20 +215,6 @@ TransformClipRect(Layer* aLayer, } } -// Similar to TransformFixedClip(), but only transforms the fixed part of the -// clip. -static void -TransformFixedClip(Layer* aLayer, - const ParentLayerToParentLayerMatrix4x4& aTransform, - AsyncCompositionManager::ClipParts& aClipParts) -{ - MOZ_ASSERT(aTransform.Is2D()); - if (aClipParts.mFixedClip) { - *aClipParts.mFixedClip = TransformBy(aTransform, *aClipParts.mFixedClip); - aLayer->AsLayerComposite()->SetShadowClipRect(aClipParts.Intersect()); - } -} - /** * Set the given transform as the shadow transform on the layer, assuming * that the given transform already has the pre- and post-scales applied. @@ -254,8 +240,7 @@ SetShadowTransform(Layer* aLayer, LayerToParentLayerMatrix4x4 aTransform) static void TranslateShadowLayer(Layer* aLayer, const gfxPoint& aTranslation, - bool aAdjustClipRect, - AsyncCompositionManager::ClipPartsCache* aClipPartsCache = nullptr) + bool aAdjustClipRect) { // This layer might also be a scrollable layer and have an async transform. // To make sure we don't clobber that, we start with the shadow transform. @@ -272,21 +257,13 @@ TranslateShadowLayer(Layer* aLayer, aLayer->AsLayerComposite()->SetShadowTransformSetByAnimation(false); if (aAdjustClipRect) { - auto transform = ParentLayerToParentLayerMatrix4x4::Translation(aTranslation.x, aTranslation.y, 0); - // If we're passed a clip parts cache, only transform the fixed part of - // the clip. - if (aClipPartsCache) { - auto iter = aClipPartsCache->find(aLayer); - MOZ_ASSERT(iter != aClipPartsCache->end()); - TransformFixedClip(aLayer, transform, iter->second); - } else { - TransformClipRect(aLayer, transform); - } + TransformClipRect(aLayer, + ParentLayerToParentLayerMatrix4x4::Translation(aTranslation.x, aTranslation.y, 0)); // If a fixed- or sticky-position layer has a mask layer, that mask should // move along with the layer, so apply the translation to the mask layer too. if (Layer* maskLayer = aLayer->GetMaskLayer()) { - TranslateShadowLayer(maskLayer, aTranslation, false, aClipPartsCache); + TranslateShadowLayer(maskLayer, aTranslation, false); } } } @@ -405,22 +382,6 @@ AsyncTransformShouldBeUnapplied(Layer* aFixedLayer, return false; } -// If |aLayer| is fixed or sticky, returns the scroll id of the scroll frame -// that it's fixed or sticky to. Otherwise, returns Nothing(). -static Maybe -IsFixedOrSticky(Layer* aLayer) -{ - bool isRootOfFixedSubtree = aLayer->GetIsFixedPosition() && - !aLayer->GetParent()->GetIsFixedPosition(); - if (isRootOfFixedSubtree) { - return Some(aLayer->GetFixedPositionScrollContainerId()); - } - if (aLayer->GetIsStickyPosition()) { - return Some(aLayer->GetStickyScrollContainerId()); - } - return Nothing(); -} - void AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer, Layer* aTransformedSubtreeRoot, @@ -428,12 +389,22 @@ AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer, const LayerToParentLayerMatrix4x4& aPreviousTransformForRoot, const LayerToParentLayerMatrix4x4& aCurrentTransformForRoot, const ScreenMargin& aFixedLayerMargins, - ClipPartsCache* aClipPartsCache) + bool aTransformAffectsLayerClip) { + FrameMetrics::ViewID fixedTo; // the scroll id of the scroll frame we are fixed/sticky to + bool isRootOfFixedSubtree = aLayer->GetIsFixedPosition() && + !aLayer->GetParent()->GetIsFixedPosition(); + if (isRootOfFixedSubtree) { + fixedTo = aLayer->GetFixedPositionScrollContainerId(); + } + bool isSticky = aLayer->GetIsStickyPosition(); + if (isSticky) { + fixedTo = aLayer->GetStickyScrollContainerId(); + } bool needsAsyncTransformUnapplied = false; - if (Maybe fixedTo = IsFixedOrSticky(aLayer)) { + if (isRootOfFixedSubtree || isSticky) { needsAsyncTransformUnapplied = AsyncTransformShouldBeUnapplied(aLayer, - *fixedTo, aTransformedSubtreeRoot, aTransformScrollId); + fixedTo, aTransformedSubtreeRoot, aTransformScrollId); } // We want to process all the fixed and sticky descendants of @@ -445,7 +416,7 @@ AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer, AlignFixedAndStickyLayers(child, aTransformedSubtreeRoot, aTransformScrollId, aPreviousTransformForRoot, aCurrentTransformForRoot, aFixedLayerMargins, - aClipPartsCache); + true /* descendants' clip rects are always affected */); } return; } @@ -528,8 +499,11 @@ AsyncCompositionManager::AlignFixedAndStickyLayers(Layer* aLayer, // clip rect, we need to apply the same translation to said clip rect, so // that the effective transform on the clip rect takes it back to where it was // originally, had there been no async scroll. - TranslateShadowLayer(aLayer, ThebesPoint(translation.ToUnknownPoint()), - true, aClipPartsCache); + // Also, some layers want async scrolling to move their clip rect + // (IsClipFixed() = false), so we don't make a compensating adjustment for + // those. + bool adjustClipRect = aTransformAffectsLayerClip && aLayer->IsClipFixed(); + TranslateShadowLayer(aLayer, ThebesPoint(translation.ToUnknownPoint()), adjustClipRect); } static void @@ -811,8 +785,7 @@ MoveScrollbarForLayerMargin(Layer* aRoot, FrameMetrics::ViewID aRootScrollId, bool AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer, bool* aOutFoundRoot, - Maybe& aClipDeferredToParent, - ClipPartsCache& clipPartsCache) + Maybe& aClipDeferredToParent) { Maybe clipDeferredFromChildren; bool appliedTransform = false; @@ -820,7 +793,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer, child; child = child->GetNextSibling()) { appliedTransform |= ApplyAsyncContentTransformToTree(child, aOutFoundRoot, - clipDeferredFromChildren, clipPartsCache); + clipDeferredFromChildren); } LayerToParentLayerMatrix4x4 oldTransform = aLayer->GetTransformTyped() * @@ -830,35 +803,18 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer, bool hasAsyncTransform = false; ScreenMargin fixedLayerMargins; - // Each layer has multiple clips: - // - Its local clip, which is fixed to the layer contents, i.e. it moves - // with those async transforms which the layer contents move with. - // - Its scrolled clip, which moves with all async transforms. - // - For each ScrollMetadata on the layer, a scroll clip. This includes - // the composition bounds and any other clips induced by layout. This - // moves with async transforms from ScrollMetadatas above it. - // In this function, these clips are combined into two shadow clip parts: - // - The fixed clip, which consists of the local clip only, initially - // transformed by all async transforms. - // - The scrolled clip, which consists of the other clips, transformed by - // the appropriate transforms. - // These two parts are kept separate for now, because for fixed layers, we - // need to adjust the fixed clip (to cancel out some async transforms). - // The parts are kept in a cache which is cleared at the beginning of every - // composite. - // The final shadow clip for the layer is the intersection of the (possibly - // adjusted) fixed clip and the scrolled clip. - ClipParts& clipParts = clipPartsCache[aLayer]; - clipParts.mFixedClip = aLayer->GetClipRect(); - clipParts.mScrolledClip = aLayer->GetScrolledClipRect(); + // Each layer has multiple clips. Its local clip, which must move with async + // transforms, and its scrollframe clips, which are the clips between each + // scrollframe and its ancestor scrollframe. Scrollframe clips include the + // composition bounds and any other clips induced by layout. + // + // The final clip for the layer is the intersection of these clips. + Maybe asyncClip = aLayer->GetClipRect(); // If we are a perspective transform ContainerLayer, apply the clip deferred // from our child (if there is any) before we iterate over our frame metrics, // because this clip is subject to all async transforms of this layer. - // Since this clip came from the a scroll clip on the child, it becomes part - // of our scrolled clip. - clipParts.mScrolledClip = IntersectMaybeRects( - clipDeferredFromChildren, clipParts.mScrolledClip); + asyncClip = IntersectMaybeRects(asyncClip, clipDeferredFromChildren); // The transform of a mask layer is relative to the masked layer's parent // layer. So whenever we apply an async transform to a layer, we need to @@ -872,15 +828,6 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer, // of all scroll frames inside the current one. nsTArray ancestorMaskLayers; - // The layer's scrolled clip can have an ancestor mask layer as well, - // which is moved by all async scrolls on this layer. - if (const Maybe& scrolledClip = aLayer->GetScrolledClip()) { - if (scrolledClip->GetMaskLayerIndex()) { - ancestorMaskLayers.AppendElement( - aLayer->GetAncestorMaskLayerAt(*scrolledClip->GetMaskLayerIndex())); - } - } - for (uint32_t i = 0; i < aLayer->GetScrollMetadataCount(); i++) { AsyncPanZoomController* controller = aLayer->GetAsyncPanZoomController(i); if (!controller) { @@ -949,21 +896,14 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer, mIsFirstPaint = false; #endif - // Transform the current local clips by this APZC's async transform. If we're + // Transform the current local clip by this APZC's async transform. If we're // using containerful scrolling, then the clip is not part of the scrolled // frame and should not be transformed. - if (!scrollMetadata.UsesContainerScrolling()) { + if (asyncClip && !scrollMetadata.UsesContainerScrolling()) { MOZ_ASSERT(asyncTransform.Is2D()); - if (clipParts.mFixedClip) { - clipParts.mFixedClip = Some(TransformBy(asyncTransform, *clipParts.mFixedClip)); - } - if (clipParts.mScrolledClip) { - clipParts.mScrolledClip = Some(TransformBy(asyncTransform, *clipParts.mScrolledClip)); - } + asyncClip = Some(TransformBy(asyncTransform, *asyncClip)); } - // Note: we don't set the layer's shadow clip rect property yet; - // AlignFixedAndStickyLayers will use the clip parts from the clip parts - // cache. + aLayer->AsLayerComposite()->SetShadowClipRect(asyncClip); combinedAsyncTransform *= asyncTransform; @@ -982,13 +922,18 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer, // Since fixed/sticky layers are relative to their nearest scrolling ancestor, // we use the ViewID from the bottommost scrollable metrics here. AlignFixedAndStickyLayers(aLayer, aLayer, metrics.GetScrollId(), oldTransform, - transformWithoutOverscrollOrOmta, fixedLayerMargins); + transformWithoutOverscrollOrOmta, fixedLayerMargins, + asyncClip.isSome()); - // Combine the scrolled portion of the local clip with the ancestor - // scroll clip. This is not included in the async transform above, since - // the ancestor clip should not move with this APZC. - if (scrollMetadata.HasScrollClip()) { - ParentLayerIntRect clip = scrollMetadata.ScrollClip().GetClipRect(); + // AlignFixedAndStickyLayers may have changed the clip rect, so we have to + // read it from the layer again. + asyncClip = aLayer->AsLayerComposite()->GetShadowClipRect(); + + // Combine the local clip with the ancestor scrollframe clip. This is not + // included in the async transform above, since the ancestor clip should not + // move with this APZC. + if (scrollMetadata.HasClipRect()) { + ParentLayerIntRect clip = scrollMetadata.ClipRect(); if (aLayer->GetParent() && aLayer->GetParent()->GetTransformIsPerspective()) { // If our parent layer has a perspective transform, we want to apply // our scroll clip to it instead of to this layer (see bug 1168263). @@ -1003,7 +948,7 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer, MOZ_ASSERT(!aClipDeferredToParent); aClipDeferredToParent = Some(clip); } else { - clipParts.mScrolledClip = IntersectMaybeRects(Some(clip), clipParts.mScrolledClip); + asyncClip = IntersectMaybeRects(Some(clip), asyncClip); } } @@ -1016,24 +961,15 @@ AsyncCompositionManager::ApplyAsyncContentTransformToTree(Layer *aLayer, } // Append the ancestor mask layer for this scroll frame to ancestorMaskLayers. - if (scrollMetadata.HasScrollClip()) { - const LayerClip& scrollClip = scrollMetadata.ScrollClip(); - if (scrollClip.GetMaskLayerIndex()) { - size_t maskLayerIndex = scrollClip.GetMaskLayerIndex().value(); - Layer* ancestorMaskLayer = aLayer->GetAncestorMaskLayerAt(maskLayerIndex); - ancestorMaskLayers.AppendElement(ancestorMaskLayer); - } + if (scrollMetadata.GetMaskLayerIndex()) { + size_t maskLayerIndex = scrollMetadata.GetMaskLayerIndex().value(); + Layer* ancestorMaskLayer = aLayer->GetAncestorMaskLayerAt(maskLayerIndex); + ancestorMaskLayers.AppendElement(ancestorMaskLayer); } } - bool clipChanged = (hasAsyncTransform || clipDeferredFromChildren); - if (clipChanged) { - // Intersect the two clip parts and apply them to the layer. - // During ApplyAsyncContentTransformTree on an ancestor layer, - // AlignFixedAndStickyLayers may overwrite this with a new clip it - // computes from the clip parts, but if that doesn't happen, this - // is the layer's final clip rect. - aLayer->AsLayerComposite()->SetShadowClipRect(clipParts.Intersect()); + if (hasAsyncTransform || clipDeferredFromChildren) { + aLayer->AsLayerComposite()->SetShadowClipRect(asyncClip); } if (hasAsyncTransform) { @@ -1421,7 +1357,7 @@ AsyncCompositionManager::TransformScrollableLayer(Layer* aLayer) // when we're asynchronously panning or zooming AlignFixedAndStickyLayers(aLayer, aLayer, metrics.GetScrollId(), oldTransform, aLayer->GetLocalTransformTyped(), - fixedLayerMargins); + fixedLayerMargins, false); ExpandRootClipRect(aLayer, fixedLayerMargins); } @@ -1451,12 +1387,6 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame, bool wantNextFrame = SampleAnimations(root, aCurrentFrame); if (!(aSkip & TransformsToSkip::APZ)) { - // Maps layers to their ClipParts during ApplyAsyncContentTransformToTree. - // The parts are not stored individually on the layer, but during - // AlignFixedAndStickyLayers we need access to the individual parts for - // descendant layers. - ClipPartsCache clipPartsCache; - // FIXME/bug 775437: unify this interface with the ~native-fennec // derived code // @@ -1470,8 +1400,7 @@ AsyncCompositionManager::TransformShadowTree(TimeStamp aCurrentFrame, // in Gecko and partially in Java. bool foundRoot = false; Maybe clipDeferredFromChildren; - if (ApplyAsyncContentTransformToTree(root, &foundRoot, clipDeferredFromChildren, - clipPartsCache)) { + if (ApplyAsyncContentTransformToTree(root, &foundRoot, clipDeferredFromChildren)) { #if defined(MOZ_ANDROID_APZ) MOZ_ASSERT(foundRoot); if (foundRoot && mFixedLayerMargins != ScreenMargin()) { diff --git a/gfx/layers/composite/AsyncCompositionManager.h b/gfx/layers/composite/AsyncCompositionManager.h index da982c27c5d2..cb727741e733 100644 --- a/gfx/layers/composite/AsyncCompositionManager.h +++ b/gfx/layers/composite/AsyncCompositionManager.h @@ -119,20 +119,6 @@ public: // from the recorded data in RecordShadowTransform void GetFrameUniformity(FrameUniformityData* aFrameUniformityData); - // Stores the clip rect of a layer in two parts: a fixed part and a scrolled - // part. When a layer is fixed, the clip needs to be adjusted to account for - // async transforms. Only the fixed part needs to be adjusted, so we need - // to store the two parts separately. - struct ClipParts { - Maybe mFixedClip; - Maybe mScrolledClip; - - Maybe Intersect() const { - return IntersectMaybeRects(mFixedClip, mScrolledClip); - } - }; - - typedef std::map ClipPartsCache; private: void TransformScrollableLayer(Layer* aLayer); // Return true if an AsyncPanZoomController content transform was @@ -141,12 +127,9 @@ private: // and its state was synced to the Java front-end. |aOutFoundRoot| must be // non-null. As the function recurses over the layer tree, a layer may // populate |aClipDeferredToParent| a clip rect it wants to set on its parent. - // |aClipPartsCache| is used to cache components of clips on descendant - // layers that may be needed while processing ancestor layers. bool ApplyAsyncContentTransformToTree(Layer* aLayer, bool* aOutFoundRoot, - Maybe& aClipDeferredToParent, - ClipPartsCache& aClipPartsCache); + Maybe& aClipDeferredToParent); /** * Update the shadow transform for aLayer assuming that is a scrollbar, * so that it stays in sync with the content that is being scrolled by APZ. @@ -191,15 +174,13 @@ private: * aTransformedSubtreeRoot affects aLayer's clip rects, so we know * whether we need to perform a corresponding unadjustment to keep * the clip rect fixed. - * aClipPartsCache optionally maps layers to separate fixed and scrolled - * clips, so we can only adjust the fixed portion. */ void AlignFixedAndStickyLayers(Layer* aLayer, Layer* aTransformedSubtreeRoot, FrameMetrics::ViewID aTransformScrollId, const LayerToParentLayerMatrix4x4& aPreviousTransformForRoot, const LayerToParentLayerMatrix4x4& aCurrentTransformForRoot, const ScreenMargin& aFixedLayerMargins, - ClipPartsCache* aClipPartsCache = nullptr); + bool aTransformAffectsLayerClip); /** * DRAWING PHASE ONLY diff --git a/gfx/layers/ipc/LayerTransactionParent.cpp b/gfx/layers/ipc/LayerTransactionParent.cpp index f1bcb282e037..a448a8d4d390 100644 --- a/gfx/layers/ipc/LayerTransactionParent.cpp +++ b/gfx/layers/ipc/LayerTransactionParent.cpp @@ -343,7 +343,6 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray&& cset, layer->SetContentFlags(common.contentFlags()); layer->SetOpacity(common.opacity()); layer->SetClipRect(common.useClipRect() ? Some(common.clipRect()) : Nothing()); - layer->SetScrolledClip(common.scrolledClip()); layer->SetBaseTransform(common.transform().value()); layer->SetTransformIsPerspective(common.transformIsPerspective()); layer->SetPostScale(common.postXScale(), common.postYScale()); @@ -351,7 +350,8 @@ LayerTransactionParent::RecvUpdate(InfallibleTArray&& cset, if (common.isFixedPosition()) { layer->SetFixedPositionData(common.fixedPositionScrollContainerId(), common.fixedPositionAnchor(), - common.fixedPositionSides()); + common.fixedPositionSides(), + common.isClipFixed()); } if (common.isStickyPosition()) { layer->SetStickyPositionData(common.stickyScrollContainerId(), diff --git a/gfx/layers/ipc/LayersMessages.ipdlh b/gfx/layers/ipc/LayersMessages.ipdlh index f84bc3f0d535..062053e13f12 100644 --- a/gfx/layers/ipc/LayersMessages.ipdlh +++ b/gfx/layers/ipc/LayersMessages.ipdlh @@ -45,7 +45,6 @@ using struct mozilla::layers::ScrollMetadata from "FrameMetrics.h"; using mozilla::layers::FrameMetrics::ViewID from "FrameMetrics.h"; using struct mozilla::layers::FenceHandle from "mozilla/layers/FenceUtils.h"; using mozilla::layers::LayersBackend from "mozilla/layers/LayersTypes.h"; -using mozilla::layers::MaybeLayerClip from "FrameMetrics.h"; namespace mozilla { namespace layers { @@ -219,11 +218,11 @@ struct CommonLayerAttributes { float opacity; bool useClipRect; ParentLayerIntRect clipRect; - MaybeLayerClip scrolledClip; bool isFixedPosition; uint64_t fixedPositionScrollContainerId; LayerPoint fixedPositionAnchor; int32_t fixedPositionSides; + bool isClipFixed; bool isStickyPosition; uint64_t stickyScrollContainerId; LayerRect stickyScrollRangeOuter; diff --git a/gfx/layers/ipc/ShadowLayers.cpp b/gfx/layers/ipc/ShadowLayers.cpp index c98e298b7acd..d2ac8d0182f2 100644 --- a/gfx/layers/ipc/ShadowLayers.cpp +++ b/gfx/layers/ipc/ShadowLayers.cpp @@ -828,12 +828,12 @@ ShadowLayerForwarder::EndTransaction(InfallibleTArray* aReplies, common.useClipRect() = !!mutant->GetClipRect(); common.clipRect() = (common.useClipRect() ? *mutant->GetClipRect() : ParentLayerIntRect()); - common.scrolledClip() = mutant->GetScrolledClip(); common.isFixedPosition() = mutant->GetIsFixedPosition(); if (mutant->GetIsFixedPosition()) { common.fixedPositionScrollContainerId() = mutant->GetFixedPositionScrollContainerId(); common.fixedPositionAnchor() = mutant->GetFixedPositionAnchor(); common.fixedPositionSides() = mutant->GetFixedPositionSides(); + common.isClipFixed() = mutant->IsClipFixed(); } common.isStickyPosition() = mutant->GetIsStickyPosition(); if (mutant->GetIsStickyPosition()) { diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp index a99c60a53d84..ef1f14e8a8dd 100644 --- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -1349,16 +1349,6 @@ protected: const nsIntRegion& aLayerVisibleRegion, uint32_t aRoundedRectClipCount = UINT32_MAX); - /** - * If |aClip| has rounded corners, create a mask layer for them, and - * add it to |aLayer|'s ancestor mask layers, returning an index into - * the array of ancestor mask layers. Returns an empty Maybe if - * |aClip| does not have rounded corners, or if no mask layer could - * be created. - */ - Maybe SetupMaskLayerForScrolledClip(Layer* aLayer, - const DisplayItemClip& aClip); - already_AddRefed CreateMaskLayer( Layer *aLayer, const DisplayItemClip& aClip, const Maybe& aForAncestorMaskLayer, @@ -2189,7 +2179,6 @@ ContainerState::RecyclePaintedLayer(PaintedLayer* aLayer, // Clear clip rect and mask layer so we don't accidentally stay clipped. // We will reapply any necessary clipping. aLayer->SetMaskLayer(nullptr); - aLayer->SetAncestorMaskLayers({}); aLayer->ClearExtraDumpInfo(); PaintedDisplayItemLayerUserData* data = @@ -3129,13 +3118,7 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB if (data->mSingleItemFixedToViewport && data->mItemClip.HasClip()) { nsIntRect layerClipRect = ScaleToNearestPixels(data->mItemClip.GetClipRect()); layerClipRect.MoveBy(mParameters.mOffset); - // The clip from such an item becomes part of the layer's scrolled clip, - // and the associated mask layer one of the layer's "ancestor mask layers". - LayerClip scrolledClip; - scrolledClip.SetClipRect(ViewAs(layerClipRect)); - scrolledClip.SetMaskLayerIndex( - SetupMaskLayerForScrolledClip(data->mLayer, data->mItemClip)); - data->mLayer->SetScrolledClip(Some(scrolledClip)); + data->mLayer->SetClipRect(Some(ViewAs(layerClipRect))); // There is only one item, so all of the clips are in common to all items. // data->mCommonClipCount will be zero because we removed the clip from // the display item. (It could also be -1 if we're inside an inactive @@ -3144,8 +3127,8 @@ void ContainerState::FinishPaintedLayerData(PaintedLayerData& aData, FindOpaqueB commonClipCount = data->mItemClip.GetRoundedRectCount(); } else { commonClipCount = std::max(0, data->mCommonClipCount); - SetupMaskLayer(layer, data->mItemClip, data->mVisibleRegion, commonClipCount); } + SetupMaskLayer(layer, data->mItemClip, data->mVisibleRegion, commonClipCount); // copy commonClipCount to the entry FrameLayerBuilder::PaintedLayerItemsEntry* entry = mLayerBuilder-> GetPaintedLayerItemsEntry(static_cast(layer.get())); @@ -3644,22 +3627,6 @@ InnermostScrollClipApplicableToAGR(const DisplayItemScrollClip* aItemScrollClip, return nullptr; } -Maybe -ContainerState::SetupMaskLayerForScrolledClip(Layer* aLayer, - const DisplayItemClip& aClip) -{ - if (aClip.GetRoundedRectCount() > 0) { - Maybe maskLayerIndex = Some(aLayer->GetAncestorMaskLayerCount()); - if (RefPtr maskLayer = CreateMaskLayer(aLayer, aClip, maskLayerIndex, - aClip.GetRoundedRectCount())) { - aLayer->AddAncestorMaskLayer(maskLayer); - return maskLayerIndex; - } - // Fall through to |return Nothing()|. - } - return Nothing(); -} - /* * Iterate through the non-clip items in aList and its descendants. * For each item we compute the effective clip rect. Each item is assigned @@ -4021,31 +3988,17 @@ ContainerState::ProcessDisplayItems(nsDisplayList* aList) NS_ASSERTION(layerClip.HasClip() || layerClip.GetRoundedRectCount() == 0, "If we have rounded rects, we must have a clip rect"); - // It has its own layer. Update that layer's clip and visible rects. - - ownLayer->SetClipRect(Nothing()); - ownLayer->SetScrolledClip(Nothing()); if (layerClip.HasClip()) { - if (shouldFixToViewport) { - // For layers fixed to the viewport, the clip becomes part of the - // layer's scrolled clip. - LayerClip scrolledClip; - scrolledClip.SetClipRect(layerClipRect); - if (layerClip.IsRectClippedByRoundedCorner(itemContent)) { - scrolledClip.SetMaskLayerIndex( - SetupMaskLayerForScrolledClip(ownLayer.get(), layerClip)); - } - ownLayer->SetScrolledClip(Some(scrolledClip)); - } else { - ownLayer->SetClipRect(Some(layerClipRect)); + ownLayer->SetClipRect(Some(layerClipRect)); + } else { + ownLayer->SetClipRect(Nothing()); + } - // rounded rectangle clipping using mask layers - // (must be done after visible rect is set on layer) - if (layerClip.IsRectClippedByRoundedCorner(itemContent)) { - SetupMaskLayer(ownLayer, layerClip, itemVisibleRect); - } - } + // rounded rectangle clipping using mask layers + // (must be done after visible rect is set on layer) + if (layerClip.IsRectClippedByRoundedCorner(itemContent)) { + SetupMaskLayer(ownLayer, layerClip, itemVisibleRect); } ContainerLayer* oldContainer = ownLayer->GetParent(); @@ -4670,14 +4623,11 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry) // The base FrameMetrics was not computed by the nsIScrollableframe, so it // should not have a mask layer. - MOZ_ASSERT(!aEntry->mBaseScrollMetadata->HasMaskLayer()); + MOZ_ASSERT(!aEntry->mBaseScrollMetadata->GetMaskLayerIndex()); } - // Any extra mask layers we need to attach to ScrollMetadatas. - // The list may already contain an entry added for the layer's scrolled clip - // so add to it rather than overwriting it (we clear the list when recycling - // a layer). - nsTArray> maskLayers(aEntry->mLayer->GetAllAncestorMaskLayers()); + // Any extra mask layers we need to attach to FrameMetrics. + nsTArray> maskLayers; for (const DisplayItemScrollClip* scrollClip = aEntry->mScrollClip; scrollClip && scrollClip != mContainerScrollClip; @@ -4710,8 +4660,7 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry) RefPtr maskLayer = CreateMaskLayer(aEntry->mLayer, *clip, nextIndex, clip->GetRoundedRectCount()); if (maskLayer) { - MOZ_ASSERT(metadata->HasScrollClip()); - metadata->ScrollClip().SetMaskLayerIndex(nextIndex); + metadata->SetMaskLayerIndex(nextIndex); maskLayers.AppendElement(maskLayer); } } @@ -4724,7 +4673,7 @@ ContainerState::SetupScrollingMetadata(NewLayerEntry* aEntry) aEntry->mLayer->SetAncestorMaskLayers(maskLayers); } -static inline Maybe +static inline const Maybe& GetStationaryClipInContainer(Layer* aLayer) { if (size_t metricsCount = aLayer->GetScrollMetadataCount()) { @@ -4758,7 +4707,7 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer if (hideAll) { e->mVisibleRegion.SetEmpty(); } else if (!e->mLayer->IsScrollbarContainer()) { - Maybe clipRect = GetStationaryClipInContainer(e->mLayer); + const Maybe& clipRect = GetStationaryClipInContainer(e->mLayer); if (clipRect && opaqueRegionForContainer >= 0 && opaqueRegions[opaqueRegionForContainer].mOpaqueRegion.Contains(clipRect->ToUnknownRect())) { e->mVisibleRegion.SetEmpty(); @@ -4794,7 +4743,7 @@ ContainerState::PostprocessRetainedLayers(nsIntRegion* aOpaqueRegionForContainer if (clipRect) { clippedOpaque.AndWith(clipRect->ToUnknownRect()); } - if (e->mLayer->GetIsFixedPosition() && e->mLayer->GetScrolledClip()) { + if (e->mLayer->GetIsFixedPosition() && !e->mLayer->IsClipFixed()) { // The clip can move asynchronously, so we can't rely on opaque parts // staying in the same place. clippedOpaque.SetEmpty(); @@ -5147,7 +5096,6 @@ FrameLayerBuilder::BuildContainerLayerFor(nsDisplayListBuilder* aBuilder, "Wrong layer type"); containerLayer = static_cast(oldLayer); containerLayer->SetMaskLayer(nullptr); - containerLayer->SetAncestorMaskLayers({}); } } } diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index f513ed7e9045..aa5eba2c4b7d 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -4930,7 +4930,7 @@ nsDisplayFixedPosition::BuildLayer(nsDisplayListBuilder* aBuilder, anchorRect.MoveTo(viewportFrame->GetOffsetToCrossDoc(ReferenceFrame())); nsLayoutUtils::SetFixedPositionLayerData(layer, - viewportFrame, anchorRect, fixedFrame, presContext, aContainerParameters); + viewportFrame, anchorRect, fixedFrame, presContext, aContainerParameters, !mIsFixedBackground); return layer.forget(); } @@ -4989,7 +4989,7 @@ nsDisplayStickyPosition::BuildLayer(nsDisplayListBuilder* aBuilder, nsLayoutUtils::SetFixedPositionLayerData(layer, scrollFrame, nsRect(scrollFrame->GetOffsetToCrossDoc(ReferenceFrame()), scrollFrameSize), - mFrame, presContext, aContainerParameters); + mFrame, presContext, aContainerParameters, /* clip is fixed = */ true); ViewID scrollId = nsLayoutUtils::FindOrCreateIDFor( stickyScrollContainer->ScrollFrame()->GetScrolledFrame()->GetContent()); diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index db6826c9b5b5..b4579f791c11 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1931,7 +1931,8 @@ nsLayoutUtils::SetFixedPositionLayerData(Layer* aLayer, const nsRect& aAnchorRect, const nsIFrame* aFixedPosFrame, nsPresContext* aPresContext, - const ContainerLayerParameters& aContainerParameters) { + const ContainerLayerParameters& aContainerParameters, + bool aIsClipFixed) { // Find out the rect of the viewport frame relative to the reference frame. // This, in conjunction with the container scale, will correspond to the // coordinate-space of the built layer. @@ -1990,7 +1991,7 @@ nsLayoutUtils::SetFixedPositionLayerData(Layer* aLayer, id = FindOrCreateIDFor(content); } } - aLayer->SetFixedPositionData(id, anchor, sides); + aLayer->SetFixedPositionData(id, anchor, sides, aIsClipFixed); } bool @@ -8898,7 +8899,7 @@ nsLayoutUtils::ComputeScrollMetadata(nsIFrame* aForFrame, ParentLayerRect rect = LayoutDeviceRect::FromAppUnits(*aClipRect, auPerDevPixel) * metrics.GetCumulativeResolution() * layerToParentLayerScale; - metadata.SetScrollClip(Some(LayerClip(RoundedToInt(rect)))); + metadata.SetClipRect(Some(RoundedToInt(rect))); } // For the root scroll frame of the root content document (RCD-RSF), the above calculation diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index 00635b180d05..b3f40075da0e 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -563,12 +563,16 @@ public: * properties (top, left, right, bottom) are auto. aAnchorRect is in the * coordinate space of aLayer's container layer (i.e. relative to the reference * frame of the display item which is building aLayer's container layer). + * aIsClipFixed is true if the layer's clip rect should also remain fixed + * during async-scrolling (true for fixed position elements, false for + * fixed backgrounds). */ static void SetFixedPositionLayerData(Layer* aLayer, const nsIFrame* aViewportFrame, const nsRect& aAnchorRect, const nsIFrame* aFixedPosFrame, nsPresContext* aPresContext, - const ContainerLayerParameters& aContainerParameters); + const ContainerLayerParameters& aContainerParameters, + bool aIsClipFixed); /** * Return true if aPresContext's viewport has a displayport.