mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-01 22:07:41 +00:00
Bug 972713. Part 1: Make all callers of GetAnimatedGeometryRootFor pass a display item so we can stop searching when we reach the item's reference frame. r=mattwoodrow
This guarantees that the animated geometry root for an item is always in the same display list coordinate system as the frame. --HG-- extra : rebase_source : 974434342459b76d62d89fdc04c22c518bf0c58b
This commit is contained in:
parent
e8ba1b680b
commit
d34ff747ee
@ -3098,18 +3098,23 @@ void nsDisplayWrapList::Paint(nsDisplayListBuilder* aBuilder,
|
||||
NS_ERROR("nsDisplayWrapList should have been flattened away for painting");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all descendant display items can be placed in the same
|
||||
* ThebesLayer --- GetLayerState returns LAYER_INACTIVE or LAYER_NONE,
|
||||
* and they all have the expected animated geometry root.
|
||||
*/
|
||||
static LayerState
|
||||
RequiredLayerStateForChildrenInternal(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aParameters,
|
||||
const nsDisplayList& aList,
|
||||
nsIFrame* aAnimatedGeometryRoot)
|
||||
RequiredLayerStateForChildren(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aParameters,
|
||||
const nsDisplayList& aList,
|
||||
nsIFrame* aExpectedAnimatedGeometryRootForChildren)
|
||||
{
|
||||
LayerState result = LAYER_INACTIVE;
|
||||
for (nsDisplayItem* i = aList.GetBottom(); i; i = i->GetAbove()) {
|
||||
nsIFrame* f = i->Frame();
|
||||
if (result == LAYER_INACTIVE &&
|
||||
nsLayoutUtils::GetAnimatedGeometryRootFor(f) != aAnimatedGeometryRoot) {
|
||||
nsLayoutUtils::GetAnimatedGeometryRootFor(i, aBuilder) !=
|
||||
aExpectedAnimatedGeometryRootForChildren) {
|
||||
result = LAYER_ACTIVE;
|
||||
}
|
||||
|
||||
@ -3125,8 +3130,8 @@ RequiredLayerStateForChildrenInternal(nsDisplayListBuilder* aBuilder,
|
||||
nsDisplayList* list = i->GetSameCoordinateSystemChildren();
|
||||
if (list) {
|
||||
LayerState childState =
|
||||
RequiredLayerStateForChildrenInternal(aBuilder, aManager, aParameters, *list,
|
||||
aAnimatedGeometryRoot);
|
||||
RequiredLayerStateForChildren(aBuilder, aManager, aParameters, *list,
|
||||
aExpectedAnimatedGeometryRootForChildren);
|
||||
if (childState > result) {
|
||||
result = childState;
|
||||
}
|
||||
@ -3136,18 +3141,6 @@ RequiredLayerStateForChildrenInternal(nsDisplayListBuilder* aBuilder,
|
||||
return result;
|
||||
}
|
||||
|
||||
LayerState
|
||||
nsDisplayWrapList::RequiredLayerStateForChildren(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aParameters,
|
||||
const nsDisplayList& aList,
|
||||
nsIFrame* aItemFrame)
|
||||
{
|
||||
return RequiredLayerStateForChildrenInternal(
|
||||
aBuilder, aManager, aParameters, aList,
|
||||
nsLayoutUtils::GetAnimatedGeometryRootFor(aItemFrame));
|
||||
}
|
||||
|
||||
nsRect nsDisplayWrapList::GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder)
|
||||
{
|
||||
nsRect bounds;
|
||||
@ -3324,7 +3317,8 @@ nsDisplayOpacity::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
if (NeedsActiveLayer())
|
||||
return LAYER_ACTIVE;
|
||||
|
||||
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList, mFrame);
|
||||
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters, mList,
|
||||
nsLayoutUtils::GetAnimatedGeometryRootFor(this, aBuilder));
|
||||
}
|
||||
|
||||
bool
|
||||
@ -4793,11 +4787,12 @@ nsDisplayTransform::GetLayerState(nsDisplayListBuilder* aBuilder,
|
||||
return LAYER_ACTIVE;
|
||||
}
|
||||
|
||||
return mStoredList.RequiredLayerStateForChildren(aBuilder,
|
||||
aManager,
|
||||
aParameters,
|
||||
*mStoredList.GetChildren(),
|
||||
mFrame);
|
||||
// Expect the child display items to have this frame as their animated
|
||||
// geometry root (since it will be their reference frame). If they have a
|
||||
// different animated geometry root, we'll make this an active layer so the
|
||||
// animation can be accelerated.
|
||||
return RequiredLayerStateForChildren(aBuilder, aManager, aParameters,
|
||||
*mStoredList.GetChildren(), Frame());
|
||||
}
|
||||
|
||||
bool nsDisplayTransform::ComputeVisibility(nsDisplayListBuilder *aBuilder,
|
||||
|
@ -2618,17 +2618,6 @@ public:
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if all descendant display items can be placed in the same
|
||||
* ThebesLayer --- GetLayerState returns LAYER_INACTIVE or LAYER_NONE,
|
||||
* and they all have the given aAnimatedGeometryRoot.
|
||||
*/
|
||||
static LayerState RequiredLayerStateForChildren(nsDisplayListBuilder* aBuilder,
|
||||
LayerManager* aManager,
|
||||
const ContainerLayerParameters& aParameters,
|
||||
const nsDisplayList& aList,
|
||||
nsIFrame* aItemFrame);
|
||||
|
||||
protected:
|
||||
nsDisplayWrapList() {}
|
||||
|
||||
|
@ -1529,23 +1529,24 @@ nsLayoutUtils::IsFixedPosFrameInDisplayPort(const nsIFrame* aFrame, nsRect* aDis
|
||||
return ViewportHasDisplayPort(aFrame->PresContext(), aDisplayPort);
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsLayoutUtils::GetAnimatedGeometryRootFor(nsIFrame* aFrame,
|
||||
const nsIFrame* aStopAtAncestor)
|
||||
static nsIFrame*
|
||||
GetAnimatedGeometryRootForFrame(nsIFrame* aFrame,
|
||||
const nsIFrame* aStopAtAncestor)
|
||||
{
|
||||
nsIFrame* f = aFrame;
|
||||
nsIFrame* stickyFrame = nullptr;
|
||||
while (f != aStopAtAncestor) {
|
||||
if (IsPopup(f))
|
||||
if (nsLayoutUtils::IsPopup(f))
|
||||
break;
|
||||
if (ActiveLayerTracker::IsOffsetOrMarginStyleAnimated(f))
|
||||
break;
|
||||
if (!f->GetParent() && ViewportHasDisplayPort(f->PresContext())) {
|
||||
if (!f->GetParent() &&
|
||||
nsLayoutUtils::ViewportHasDisplayPort(f->PresContext())) {
|
||||
// Viewport frames in a display port need to be animated geometry roots
|
||||
// for background-attachment:fixed elements.
|
||||
break;
|
||||
}
|
||||
nsIFrame* parent = GetCrossDocParentFrame(f);
|
||||
nsIFrame* parent = nsLayoutUtils::GetCrossDocParentFrame(f);
|
||||
if (!parent)
|
||||
break;
|
||||
nsIAtom* parentType = parent->GetType();
|
||||
@ -1576,7 +1577,7 @@ nsLayoutUtils::GetAnimatedGeometryRootFor(nsIFrame* aFrame,
|
||||
}
|
||||
}
|
||||
// Fixed-pos frames are parented by the viewport frame, which has no parent
|
||||
if (IsFixedPosFrameInDisplayPort(f)) {
|
||||
if (nsLayoutUtils::IsFixedPosFrameInDisplayPort(f)) {
|
||||
return f;
|
||||
}
|
||||
f = parent;
|
||||
@ -1593,7 +1594,7 @@ nsLayoutUtils::GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
|
||||
nsDisplayScrollLayer* scrollLayerItem =
|
||||
static_cast<nsDisplayScrollLayer*>(aItem);
|
||||
nsIFrame* scrolledFrame = scrollLayerItem->GetScrolledFrame();
|
||||
return nsLayoutUtils::GetAnimatedGeometryRootFor(scrolledFrame,
|
||||
return GetAnimatedGeometryRootForFrame(scrolledFrame,
|
||||
aBuilder->FindReferenceFrameFor(scrolledFrame));
|
||||
}
|
||||
if (aItem->ShouldFixToViewport(aBuilder)) {
|
||||
@ -1604,10 +1605,10 @@ nsLayoutUtils::GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
|
||||
nsIFrame* viewportFrame =
|
||||
nsLayoutUtils::GetClosestFrameOfType(f, nsGkAtoms::viewportFrame);
|
||||
NS_ASSERTION(viewportFrame, "no viewport???");
|
||||
return nsLayoutUtils::GetAnimatedGeometryRootFor(viewportFrame,
|
||||
return GetAnimatedGeometryRootForFrame(viewportFrame,
|
||||
aBuilder->FindReferenceFrameFor(viewportFrame));
|
||||
}
|
||||
return nsLayoutUtils::GetAnimatedGeometryRootFor(f, aItem->ReferenceFrame());
|
||||
return GetAnimatedGeometryRootForFrame(f, aItem->ReferenceFrame());
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -474,28 +474,22 @@ public:
|
||||
nsRect* aDisplayPort = nullptr);
|
||||
|
||||
/**
|
||||
* Finds the nearest ancestor frame that is considered to have (or will have)
|
||||
* "animated geometry". For example the scrolled frames of scrollframes which
|
||||
* are actively being scrolled fall into this category. Frames with certain
|
||||
* CSS properties that are being animated (e.g. 'left'/'top' etc) are also
|
||||
* placed in this category. Frames with animated CSS transforms are not
|
||||
* put in this category because they can be handled directly by
|
||||
* nsDisplayTransform.
|
||||
* Stop searching at aStopAtAncestor if there is no such ancestor before it
|
||||
* in the ancestor chain.
|
||||
* Finds the nearest ancestor frame to aItem that is considered to have (or
|
||||
* will have) "animated geometry". For example the scrolled frames of
|
||||
* scrollframes which are actively being scrolled fall into this category.
|
||||
* Frames with certain CSS properties that are being animated (e.g.
|
||||
* 'left'/'top' etc) are also placed in this category.
|
||||
* Frames with different active geometry roots are in different ThebesLayers,
|
||||
* so that we can animate the geometry root by changing its transform (either
|
||||
* on the main thread or in the compositor).
|
||||
* This function is idempotent: a frame returned by GetAnimatedGeometryRootFor
|
||||
* is always returned again if you pass it to GetAnimatedGeometryRootFor.
|
||||
* The animated geometry root is required to be a descendant (or equal to)
|
||||
* aItem's ReferenceFrame(), which means that we will fall back to
|
||||
* returning aItem->ReferenceFrame() when we can't find another animated
|
||||
* geometry root.
|
||||
*/
|
||||
static nsIFrame* GetAnimatedGeometryRootFor(nsIFrame* aFrame,
|
||||
const nsIFrame* aStopAtAncestor = nullptr);
|
||||
|
||||
static nsIFrame* GetAnimatedGeometryRootFor(nsDisplayItem* aItem,
|
||||
nsDisplayListBuilder* aBuilder);
|
||||
|
||||
|
||||
/**
|
||||
* GetScrollableFrameFor returns the scrollable frame for a scrolled frame
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user