--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -417,17 +417,17 @@ public:
mAnimatedGeometryRoot(nullptr),
mScrollClip(nullptr),
mReferenceFrame(nullptr),
mLayer(nullptr),
mSolidColor(NS_RGBA(0, 0, 0, 0)),
mIsSolidColorInVisibleRegion(false),
mFontSmoothingBackgroundColor(NS_RGBA(0,0,0,0)),
mExclusiveToOneItem(false),
- mSingleItemFixedToViewport(false),
+ mClipMovesWithLayer(true),
mIsCaret(false),
mNeedComponentAlpha(false),
mForceTransparentSurface(false),
mHideAllLayersBelow(false),
mOpaqueForAnimatedGeometryRootParent(false),
mDisableFlattening(false),
mBackfaceHidden(false),
mImage(nullptr),
@@ -576,20 +576,20 @@ public:
* transparent parts of the layer.
*/
nscolor mFontSmoothingBackgroundColor;
/**
* True if only one display item can be assigned to this layer.
*/
bool mExclusiveToOneItem;
/**
- * True if the layer contains exactly one item that returned true for
- * ShouldFixToViewport.
+ * True unless the layer contains exactly one item whose clip scrolls
+ * relative to the layer rather than moving with the layer.
*/
- bool mSingleItemFixedToViewport;
+ bool mClipMovesWithLayer;
/**
* True if the layer contains exactly one item for the caret.
*/
bool mIsCaret;
/**
* True if there is any text visible in the layer that's over
* transparent pixels in the layer.
*/
@@ -3136,17 +3136,17 @@ void ContainerState::FinishPaintedLayerD
FLB_LOG_PAINTED_LAYER_DECISION(data, " Selected painted layer=%p\n", layer.get());
}
// If the layer is a fixed background layer, the clip on the fixed background
// display item was not applied to the opaque region in
// ContainerState::ComputeOpaqueRect(), but was saved in data->mItemClip.
// Apply it to the opaque region now. Note that it's important to do this
// before the opaque region is propagated to the NewLayerEntry below.
- if (data->mSingleItemFixedToViewport && data->mItemClip.HasClip()) {
+ if (!data->mClipMovesWithLayer && data->mItemClip.HasClip()) {
nsRect clipRect = data->mItemClip.GetClipRect();
nsRect insideRoundedCorners = data->mItemClip.ApproximateIntersectInward(clipRect);
nsIntRect insideRoundedCornersScaled = ScaleToInsidePixels(insideRoundedCorners);
data->mOpaqueRegion.AndWith(insideRoundedCornersScaled);
}
if (mLayerBuilder->IsBuildingRetainedLayers()) {
newLayerEntry->mVisibleRegion = data->mVisibleRegion;
@@ -3210,17 +3210,17 @@ void ContainerState::FinishPaintedLayerD
// use a mask layer for rounded rect clipping.
// data->mCommonClipCount may be -1 if we haven't put any actual
// drawable items in this layer (i.e. it's only catching events).
int32_t commonClipCount;
// If the layer contains a single item fixed to the viewport, we removed
// its clip in ProcessDisplayItems() and saved it to set on the layer instead.
// Set the clip on the layer now.
- if (data->mSingleItemFixedToViewport && data->mItemClip.HasClip()) {
+ if (!data->mClipMovesWithLayer && 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<ParentLayerPixel>(layerClipRect));
scrolledClip.SetMaskLayerIndex(
SetupMaskLayerForScrolledClip(data->mLayer, data->mItemClip));
@@ -3521,24 +3521,24 @@ PaintedLayerData::AccumulateEventRegions
mScaledMaybeHitRegionBounds = aState->ScaleToOutsidePixels(mMaybeHitRegion.GetBounds());
}
PaintedLayerData
ContainerState::NewPaintedLayerData(nsDisplayItem* aItem,
AnimatedGeometryRoot* aAnimatedGeometryRoot,
const DisplayItemScrollClip* aScrollClip,
const nsPoint& aTopLeft,
- bool aShouldFixToViewport)
+ bool aClipMovesWithLayer)
{
PaintedLayerData data;
data.mAnimatedGeometryRoot = aAnimatedGeometryRoot;
data.mScrollClip = aScrollClip;
data.mAnimatedGeometryRootOffset = aTopLeft;
data.mReferenceFrame = aItem->ReferenceFrame();
- data.mSingleItemFixedToViewport = aShouldFixToViewport;
+ data.mClipMovesWithLayer = aClipMovesWithLayer;
data.mBackfaceHidden = aItem->Frame()->In3DContextAndBackfaceIsHidden();
data.mIsCaret = aItem->GetType() == nsDisplayItem::TYPE_CARET;
data.mNewChildLayersIndex = mNewChildLayers.Length();
NewLayerEntry* newLayerEntry = mNewChildLayers.AppendElement();
newLayerEntry->mAnimatedGeometryRoot = aAnimatedGeometryRoot;
newLayerEntry->mScrollClip = aScrollClip;
newLayerEntry->mIsCaret = data.mIsCaret;
@@ -3873,27 +3873,23 @@ ContainerState::ProcessDisplayItems(nsDi
clip.IntersectWith(*scrollClip->mClip);
}
}
item->SetClip(mBuilder, clip);
}
bool clipMovesWithLayer = (animatedGeometryRoot == animatedGeometryRootForClip);
- bool shouldFixToViewport = !clipMovesWithLayer &&
- !(*animatedGeometryRoot)->GetParent() &&
- item->ShouldFixToViewport(mBuilder);
-
- // For items that are fixed to the viewport, remove their clip at the
- // display item level because additional areas could be brought into
- // view by async scrolling. Save the clip so we can set it on the layer
- // instead later.
- DisplayItemClip fixedToViewportClip = DisplayItemClip::NoClip();
- if (shouldFixToViewport) {
- fixedToViewportClip = item->GetClip();
+ // For items whose clip scrolls relative to the layer rather than moving
+ // with the layer, remove their clip at the display item level because
+ // additional areas could be brought into view by async scrolling.
+ // Save the clip so we can set it on the layer instead later.
+ DisplayItemClip scrollingClip = DisplayItemClip::NoClip();
+ if (!clipMovesWithLayer) {
+ scrollingClip = item->GetClip();
item->SetClip(mBuilder, DisplayItemClip::NoClip());
}
bool snap;
nsRect itemContent = item->GetBounds(mBuilder, &snap);
if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
nsDisplayLayerEventRegions* eventRegions =
static_cast<nsDisplayLayerEventRegions*>(item);
@@ -3916,17 +3912,17 @@ ContainerState::ProcessDisplayItems(nsDi
nsRect bounds = itemContent;
bool dummy;
if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
bounds = item->GetBounds(mBuilder, &dummy);
if (itemClip.HasClip()) {
bounds.IntersectRect(bounds, itemClip.GetClipRect());
}
}
- bounds = fixedToViewportClip.ApplyNonRoundedIntersection(bounds);
+ bounds = scrollingClip.ApplyNonRoundedIntersection(bounds);
if (!bounds.IsEmpty()) {
for (const DisplayItemScrollClip* scrollClip = itemScrollClip;
scrollClip && scrollClip != mContainerScrollClip;
scrollClip = scrollClip->mParent) {
if (scrollClip->mClip) {
if (scrollClip->mIsAsyncScrollable) {
bounds = scrollClip->mClip->GetClipRect();
} else {
@@ -4009,17 +4005,17 @@ ContainerState::ProcessDisplayItems(nsDi
// geometry root that we give it, but it can't easily figure about
// overflow:hidden clips on ancestors just by looking at the frame.
// So we'll do a little hand holding and pass the clip instead of the
// visible rect for the two important cases.
nscolor uniformColor = NS_RGBA(0,0,0,0);
nscolor* uniformColorPtr = (mayDrawOutOfOrder || IsInInactiveLayer()) ? nullptr :
&uniformColor;
nsIntRect clipRectUntyped;
- const DisplayItemClip& layerClip = shouldFixToViewport ? fixedToViewportClip : itemClip;
+ const DisplayItemClip& layerClip = clipMovesWithLayer ? itemClip : scrollingClip;
ParentLayerIntRect layerClipRect;
nsIntRect* clipPtr = nullptr;
if (layerClip.HasClip()) {
layerClipRect = ViewAs<ParentLayerPixel>(
ScaleToNearestPixels(layerClip.GetClipRect()) + mParameters.mOffset);
clipRectUntyped = layerClipRect.ToUnknownRect();
clipPtr = &clipRectUntyped;
}
@@ -4109,37 +4105,34 @@ ContainerState::ProcessDisplayItems(nsDi
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()) {
- // For layers fixed to the viewport, the clip becomes part of the
- // layer's scrolled clip. However, BasicLayerManager doesn't support
- // scrolled clips, and doesn't care about the distinction anyways
- // (it only matters for async scrolling), so only set a scrolled clip
- // if we have a widget layer manager.
- if (shouldFixToViewport) {
+ // If the clip moves with the layer, it becomes part of the layer
+ // clip. Otherwise, it becomes part of the scrolled clip.
+ if (clipMovesWithLayer) {
+ ownLayer->SetClipRect(Some(layerClipRect));
+
+ // rounded rectangle clipping using mask layers
+ // (must be done after visible rect is set on layer)
+ if (layerClip.IsRectClippedByRoundedCorner(itemContent)) {
+ SetupMaskLayer(ownLayer, layerClip, itemVisibleRect);
+ }
+ } else {
LayerClip scrolledClip;
scrolledClip.SetClipRect(layerClipRect);
if (layerClip.IsRectClippedByRoundedCorner(itemContent)) {
scrolledClip.SetMaskLayerIndex(
SetupMaskLayerForScrolledClip(ownLayer.get(), layerClip));
}
ownLayer->SetScrolledClip(Some(scrolledClip));
- } else {
- ownLayer->SetClipRect(Some(layerClipRect));
-
- // 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();
if (oldContainer && oldContainer != mContainerLayer) {
oldContainer->RemoveChild(ownLayer);
}
NS_ASSERTION(FindIndexOfLayerIn(mNewChildLayers, ownLayer) < 0,
@@ -4223,17 +4216,17 @@ ContainerState::ProcessDisplayItems(nsDi
PaintedLayerData* paintedLayerData =
mPaintedLayerDataTree.FindPaintedLayerFor(animatedGeometryRoot, agrScrollClip,
itemVisibleRect, false,
item->Frame()->In3DContextAndBackfaceIsHidden(),
avoidCreatingLayer,
[&]() {
layerCount++;
return NewPaintedLayerData(item, animatedGeometryRoot, agrScrollClip,
- topLeft, shouldFixToViewport);
+ topLeft, clipMovesWithLayer);
});
if (itemType == nsDisplayItem::TYPE_LAYER_EVENT_REGIONS) {
nsDisplayLayerEventRegions* eventRegions =
static_cast<nsDisplayLayerEventRegions*>(item);
paintedLayerData->AccumulateEventRegions(this, eventRegions);
} else {
// check to see if the new item has rounded rect clips in common with
@@ -4248,18 +4241,18 @@ ContainerState::ProcessDisplayItems(nsDi
MOZ_ASSERT(nsIntRegion(itemDrawRect).Contains(opaquePixels));
opaquePixels.AndWith(itemVisibleRect);
paintedLayerData->Accumulate(this, item, opaquePixels,
itemVisibleRect, itemClip, layerState);
// If we removed the clip from the display item above because it's
// fixed to the viewport, save it on the PaintedLayerData so we can
// set it on the layer later.
- if (fixedToViewportClip.HasClip()) {
- paintedLayerData->mItemClip = fixedToViewportClip;
+ if (scrollingClip.HasClip()) {
+ paintedLayerData->mItemClip = scrollingClip;
}
if (!paintedLayerData->mLayer) {
// Try to recycle the old layer of this display item.
RefPtr<PaintedLayer> layer =
AttemptToRecyclePaintedLayer(animatedGeometryRoot, item, topLeft);
if (layer) {
paintedLayerData->mLayer = layer;